ReactOS 0.4.15-dev-7788-g1ad9096
rpc_message.c
Go to the documentation of this file.
1/*
2 * RPC messages
3 *
4 * Copyright 2001-2002 Ove Kåven, TransGaming Technologies
5 * Copyright 2004 Filip Navara
6 * Copyright 2006 CodeWeavers
7 *
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.
12 *
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.
17 *
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 */
22
23#include <stdarg.h>
24#include <stdio.h>
25#include <string.h>
26
27#include "windef.h"
28#include "winbase.h"
29#include "winerror.h"
30#include "winuser.h"
31
32#include "rpc.h"
33#include "rpcndr.h"
34#include "rpcdcep.h"
35
36#include "wine/debug.h"
37
38#include "rpc_binding.h"
39#include "rpc_defs.h"
40#include "rpc_message.h"
41#include "rpc_assoc.h"
42#include "ncastatus.h"
43
45
46/* note: the DCE/RPC spec says the alignment amount should be 4, but
47 * MS/RPC servers seem to always use 16 */
48#define AUTH_ALIGNMENT 16
49
50/* gets the amount needed to round a value up to the specified alignment */
51#define ROUND_UP_AMOUNT(value, alignment) \
52 (((alignment) - (((value) % (alignment)))) % (alignment))
53#define ROUND_UP(value, alignment) (((value) + ((alignment) - 1)) & ~((alignment)-1))
54
56
58{
59 static const DWORD header_sizes[] = {
60 sizeof(Header->request), 0, sizeof(Header->response),
61 sizeof(Header->fault), 0, 0, 0, 0, 0, 0, 0, sizeof(Header->bind),
62 sizeof(Header->bind_ack), sizeof(Header->bind_nack),
63 0, 0, sizeof(Header->auth3), 0, 0, 0, sizeof(Header->http)
64 };
65 ULONG ret = 0;
66
67 if (Header->common.ptype < ARRAY_SIZE(header_sizes)) {
68 ret = header_sizes[Header->common.ptype];
69 if (ret == 0)
70 FIXME("unhandled packet type %u\n", Header->common.ptype);
71 if (Header->common.flags & RPC_FLG_OBJECT_UUID)
72 ret += sizeof(UUID);
73 } else {
74 WARN("invalid packet type %u\n", Header->common.ptype);
75 }
76
77 return ret;
78}
79
81{
82 return (Header->common.ptype == PKT_FAULT) ||
83 (Header->common.ptype == PKT_REQUEST) ||
84 (Header->common.ptype == PKT_RESPONSE);
85}
86
88{
89 return !(Header->common.ptype == PKT_BIND_NACK) &&
90 !(Header->common.ptype == PKT_SHUTDOWN);
91}
92
94{
95 switch (Header->common.ptype)
96 {
97 case PKT_BIND:
98 case PKT_BIND_ACK:
99 case PKT_AUTH3:
102 return TRUE;
103 default:
104 return FALSE;
105 }
106}
107
108static VOID RPCRT4_BuildCommonHeader(RpcPktHdr *Header, unsigned char PacketType,
109 ULONG DataRepresentation)
110{
111 Header->common.rpc_ver = RPC_VER_MAJOR;
112 Header->common.rpc_ver_minor = RPC_VER_MINOR;
113 Header->common.ptype = PacketType;
114 Header->common.drep[0] = LOBYTE(LOWORD(DataRepresentation));
115 Header->common.drep[1] = HIBYTE(LOWORD(DataRepresentation));
116 Header->common.drep[2] = LOBYTE(HIWORD(DataRepresentation));
117 Header->common.drep[3] = HIBYTE(HIWORD(DataRepresentation));
118 Header->common.auth_len = 0;
119 Header->common.call_id = 1;
120 Header->common.flags = 0;
121 /* Flags and fragment length are computed in RPCRT4_Send. */
122}
123
124static RpcPktHdr *RPCRT4_BuildRequestHeader(ULONG DataRepresentation,
126 unsigned short ProcNum,
127 UUID *ObjectUuid)
128{
130 BOOL has_object;
132
133 has_object = (ObjectUuid != NULL && !UuidIsNil(ObjectUuid, &status));
135 sizeof(header->request) + (has_object ? sizeof(UUID) : 0));
136 if (header == NULL) {
137 return NULL;
138 }
139
140 RPCRT4_BuildCommonHeader(header, PKT_REQUEST, DataRepresentation);
141 header->common.frag_len = sizeof(header->request);
142 header->request.alloc_hint = BufferLength;
143 header->request.context_id = 0;
144 header->request.opnum = ProcNum;
145 if (has_object) {
146 header->common.flags |= RPC_FLG_OBJECT_UUID;
147 header->common.frag_len += sizeof(UUID);
148 memcpy(&header->request + 1, ObjectUuid, sizeof(UUID));
149 }
150
151 return header;
152}
153
155{
157
158 header = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(header->response));
159 if (header == NULL) {
160 return NULL;
161 }
162
163 RPCRT4_BuildCommonHeader(header, PKT_RESPONSE, DataRepresentation);
164 header->common.frag_len = sizeof(header->response);
165 header->response.alloc_hint = BufferLength;
166
167 return header;
168}
169
171{
173
175 if (header == NULL) {
176 return NULL;
177 }
178
179 RPCRT4_BuildCommonHeader(header, PKT_FAULT, DataRepresentation);
180 header->common.frag_len = sizeof(header->fault);
181 header->fault.status = Status;
182
183 return header;
184}
185
187 unsigned short MaxTransmissionSize,
188 unsigned short MaxReceiveSize,
189 ULONG AssocGroupId,
190 const RPC_SYNTAX_IDENTIFIER *AbstractId,
191 const RPC_SYNTAX_IDENTIFIER *TransferId)
192{
194 RpcContextElement *ctxt_elem;
195
197 sizeof(header->bind) + FIELD_OFFSET(RpcContextElement, transfer_syntaxes[1]));
198 if (header == NULL) {
199 return NULL;
200 }
201 ctxt_elem = (RpcContextElement *)(&header->bind + 1);
202
203 RPCRT4_BuildCommonHeader(header, PKT_BIND, DataRepresentation);
204 header->common.frag_len = sizeof(header->bind) + FIELD_OFFSET(RpcContextElement, transfer_syntaxes[1]);
205 header->bind.max_tsize = MaxTransmissionSize;
206 header->bind.max_rsize = MaxReceiveSize;
207 header->bind.assoc_gid = AssocGroupId;
208 header->bind.num_elements = 1;
209 ctxt_elem->num_syntaxes = 1;
210 ctxt_elem->abstract_syntax = *AbstractId;
211 ctxt_elem->transfer_syntaxes[0] = *TransferId;
212
213 return header;
214}
215
216static RpcPktHdr *RPCRT4_BuildAuthHeader(ULONG DataRepresentation)
217{
219
221 sizeof(header->auth3));
222 if (header == NULL)
223 return NULL;
224
225 RPCRT4_BuildCommonHeader(header, PKT_AUTH3, DataRepresentation);
226 header->common.frag_len = sizeof(header->auth3);
227
228 return header;
229}
230
232 unsigned char RpcVersion,
233 unsigned char RpcVersionMinor,
234 unsigned short RejectReason)
235{
237
239 if (header == NULL) {
240 return NULL;
241 }
242
243 RPCRT4_BuildCommonHeader(header, PKT_BIND_NACK, DataRepresentation);
244 header->common.frag_len = FIELD_OFFSET(RpcPktHdr, bind_nack.protocols[1]);
245 header->bind_nack.reject_reason = RejectReason;
246 header->bind_nack.protocols_count = 1;
247 header->bind_nack.protocols[0].rpc_ver = RpcVersion;
248 header->bind_nack.protocols[0].rpc_ver_minor = RpcVersionMinor;
249
250 return header;
251}
252
254 unsigned short MaxTransmissionSize,
255 unsigned short MaxReceiveSize,
256 ULONG AssocGroupId,
257 LPCSTR ServerAddress,
258 unsigned char ResultCount,
259 const RpcResult *Results)
260{
262 ULONG header_size;
263 RpcAddressString *server_address;
265
266 header_size = sizeof(header->bind_ack) +
267 ROUND_UP(FIELD_OFFSET(RpcAddressString, string[strlen(ServerAddress) + 1]), 4) +
268 FIELD_OFFSET(RpcResultList, results[ResultCount]);
269
271 if (header == NULL) {
272 return NULL;
273 }
274
275 RPCRT4_BuildCommonHeader(header, PKT_BIND_ACK, DataRepresentation);
276 header->common.frag_len = header_size;
277 header->bind_ack.max_tsize = MaxTransmissionSize;
278 header->bind_ack.max_rsize = MaxReceiveSize;
279 header->bind_ack.assoc_gid = AssocGroupId;
280 server_address = (RpcAddressString*)(&header->bind_ack + 1);
281 server_address->length = strlen(ServerAddress) + 1;
282 strcpy(server_address->string, ServerAddress);
283 /* results is 4-byte aligned */
284 results = (RpcResultList*)((ULONG_PTR)server_address + ROUND_UP(FIELD_OFFSET(RpcAddressString, string[server_address->length]), 4));
285 results->num_results = ResultCount;
286 memcpy(&results->results[0], Results, ResultCount * sizeof(*Results));
287
288 return header;
289}
290
292 unsigned short flags,
293 unsigned short num_data_items,
294 unsigned int payload_size)
295{
297
298 header = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(header->http) + payload_size);
299 if (header == NULL) {
300 ERR("failed to allocate memory\n");
301 return NULL;
302 }
303
304 RPCRT4_BuildCommonHeader(header, PKT_HTTP, DataRepresentation);
305 /* since the packet isn't current sent using RPCRT4_Send, set the flags
306 * manually here */
307 header->common.flags = RPC_FLG_FIRST|RPC_FLG_LAST;
308 header->common.call_id = 0;
309 header->common.frag_len = sizeof(header->http) + payload_size;
310 header->http.flags = flags;
311 header->http.num_data_items = num_data_items;
312
313 return header;
314}
315
316#define WRITE_HTTP_PAYLOAD_FIELD_UINT32(payload, type, value) \
317 do { \
318 *(unsigned int *)(payload) = (type); \
319 (payload) += 4; \
320 *(unsigned int *)(payload) = (value); \
321 (payload) += 4; \
322 } while (0)
323
324#define WRITE_HTTP_PAYLOAD_FIELD_UUID(payload, type, uuid) \
325 do { \
326 *(unsigned int *)(payload) = (type); \
327 (payload) += 4; \
328 *(UUID *)(payload) = (uuid); \
329 (payload) += sizeof(UUID); \
330 } while (0)
331
332#define WRITE_HTTP_PAYLOAD_FIELD_FLOW_CONTROL(payload, bytes_transmitted, flow_control_increment, uuid) \
333 do { \
334 *(unsigned int *)(payload) = 0x00000001; \
335 (payload) += 4; \
336 *(unsigned int *)(payload) = (bytes_transmitted); \
337 (payload) += 4; \
338 *(unsigned int *)(payload) = (flow_control_increment); \
339 (payload) += 4; \
340 *(UUID *)(payload) = (uuid); \
341 (payload) += sizeof(UUID); \
342 } while (0)
343
345 const UUID *connection_uuid,
346 const UUID *pipe_uuid,
347 const UUID *association_uuid)
348{
350 unsigned int size;
351 char *payload;
352
353 size = 8 + 4 + sizeof(UUID) + 4 + sizeof(UUID) + 8;
354 if (!out_pipe)
355 size += 8 + 4 + sizeof(UUID);
356
358 out_pipe ? 4 : 6, size);
359 if (!header) return NULL;
360 payload = (char *)(&header->http+1);
361
362 /* FIXME: what does this part of the payload do? */
363 WRITE_HTTP_PAYLOAD_FIELD_UINT32(payload, 0x00000006, 0x00000001);
364
365 WRITE_HTTP_PAYLOAD_FIELD_UUID(payload, 0x00000003, *connection_uuid);
366 WRITE_HTTP_PAYLOAD_FIELD_UUID(payload, 0x00000003, *pipe_uuid);
367
368 if (out_pipe)
369 /* FIXME: what does this part of the payload do? */
370 WRITE_HTTP_PAYLOAD_FIELD_UINT32(payload, 0x00000000, 0x00010000);
371 else
372 {
373 /* FIXME: what does this part of the payload do? */
374 WRITE_HTTP_PAYLOAD_FIELD_UINT32(payload, 0x00000004, 0x40000000);
375 /* FIXME: what does this part of the payload do? */
376 WRITE_HTTP_PAYLOAD_FIELD_UINT32(payload, 0x00000005, 0x000493e0);
377
378 WRITE_HTTP_PAYLOAD_FIELD_UUID(payload, 0x0000000c, *association_uuid);
379 }
380
381 return header;
382}
383
385 ULONG flow_control_increment,
386 const UUID *pipe_uuid)
387{
389 char *payload;
390
392 5 * sizeof(ULONG) + sizeof(UUID));
393 if (!header) return NULL;
394 payload = (char *)(&header->http+1);
395
396 WRITE_HTTP_PAYLOAD_FIELD_UINT32(payload, 0x0000000d, (server ? 0x0 : 0x3));
397
398 WRITE_HTTP_PAYLOAD_FIELD_FLOW_CONTROL(payload, bytes_transmitted,
399 flow_control_increment, *pipe_uuid);
400 return header;
401}
402
404{
406}
407
409{
410 switch (status)
411 {
415 case RPC_S_UNKNOWN_IF: return NCA_S_UNK_IF;
437 default: return status;
438 }
439}
440
442{
443 switch (status)
444 {
447 case NCA_S_UNK_IF: return RPC_S_UNKNOWN_IF;
478 default: return status;
479 }
480}
481
482/* assumes the common header fields have already been validated */
484 unsigned short data_len)
485{
486 unsigned short i;
487 BYTE *p = data;
488
489 for (i = 0; i < hdr->http.num_data_items; i++)
490 {
491 ULONG type;
492
493 if (data_len < sizeof(ULONG))
494 return FALSE;
495
496 type = *(ULONG *)p;
497 p += sizeof(ULONG);
498 data_len -= sizeof(ULONG);
499
500 switch (type)
501 {
502 case 0x3:
503 case 0xc:
504 if (data_len < sizeof(GUID))
505 return FALSE;
506 p += sizeof(GUID);
507 data_len -= sizeof(GUID);
508 break;
509 case 0x0:
510 case 0x2:
511 case 0x4:
512 case 0x5:
513 case 0x6:
514 case 0xd:
515 if (data_len < sizeof(ULONG))
516 return FALSE;
517 p += sizeof(ULONG);
518 data_len -= sizeof(ULONG);
519 break;
520 case 0x1:
521 if (data_len < 24)
522 return FALSE;
523 p += 24;
524 data_len -= 24;
525 break;
526 default:
527 FIXME("unimplemented type 0x%x\n", type);
528 break;
529 }
530 }
531 return TRUE;
532}
533
534/* assumes the HTTP packet has been validated */
535static unsigned char *RPCRT4_NextHttpHeaderField(unsigned char *data)
536{
537 ULONG type;
538
539 type = *(ULONG *)data;
540 data += sizeof(ULONG);
541
542 switch (type)
543 {
544 case 0x3:
545 case 0xc:
546 return data + sizeof(GUID);
547 case 0x0:
548 case 0x2:
549 case 0x4:
550 case 0x5:
551 case 0x6:
552 case 0xd:
553 return data + sizeof(ULONG);
554 case 0x1:
555 return data + 24;
556 default:
557 FIXME("unimplemented type 0x%x\n", type);
558 return data;
559 }
560}
561
562#define READ_HTTP_PAYLOAD_FIELD_TYPE(data) *(ULONG *)(data)
563#define GET_HTTP_PAYLOAD_FIELD_DATA(data) ((data) + sizeof(ULONG))
564
565/* assumes the HTTP packet has been validated */
567 unsigned char *data, ULONG *field1)
568{
569 ULONG type;
570 if (header->http.flags != 0x0)
571 {
572 ERR("invalid flags 0x%x\n", header->http.flags);
574 }
575 if (header->http.num_data_items != 1)
576 {
577 ERR("invalid number of data items %d\n", header->http.num_data_items);
579 }
581 if (type != 0x00000002)
582 {
583 ERR("invalid type 0x%08x\n", type);
585 }
587 return RPC_S_OK;
588}
589
590/* assumes the HTTP packet has been validated */
592 unsigned char *data, ULONG *field1,
593 ULONG *bytes_until_next_packet,
594 ULONG *field3)
595{
596 ULONG type;
597 if (header->http.flags != 0x0)
598 {
599 ERR("invalid flags 0x%x\n", header->http.flags);
601 }
602 if (header->http.num_data_items != 3)
603 {
604 ERR("invalid number of data items %d\n", header->http.num_data_items);
606 }
607
609 if (type != 0x00000006)
610 {
611 ERR("invalid type for field 1: 0x%08x\n", type);
613 }
616
618 if (type != 0x00000000)
619 {
620 ERR("invalid type for field 2: 0x%08x\n", type);
622 }
623 *bytes_until_next_packet = *(ULONG *)GET_HTTP_PAYLOAD_FIELD_DATA(data);
625
627 if (type != 0x00000002)
628 {
629 ERR("invalid type for field 3: 0x%08x\n", type);
631 }
633
634 return RPC_S_OK;
635}
636
638 unsigned char *data, BOOL server,
639 ULONG *bytes_transmitted,
640 ULONG *flow_control_increment,
641 UUID *pipe_uuid)
642{
643 ULONG type;
644 if (header->http.flags != 0x2)
645 {
646 ERR("invalid flags 0x%x\n", header->http.flags);
648 }
649 if (header->http.num_data_items != 2)
650 {
651 ERR("invalid number of data items %d\n", header->http.num_data_items);
653 }
654
656 if (type != 0x0000000d)
657 {
658 ERR("invalid type for field 1: 0x%08x\n", type);
660 }
661 if (*(ULONG *)GET_HTTP_PAYLOAD_FIELD_DATA(data) != (server ? 0x3 : 0x0))
662 {
663 ERR("invalid type for 0xd field data: 0x%08x\n", *(ULONG *)GET_HTTP_PAYLOAD_FIELD_DATA(data));
665 }
667
669 if (type != 0x00000001)
670 {
671 ERR("invalid type for field 2: 0x%08x\n", type);
673 }
674 *bytes_transmitted = *(ULONG *)GET_HTTP_PAYLOAD_FIELD_DATA(data);
675 *flow_control_increment = *(ULONG *)(GET_HTTP_PAYLOAD_FIELD_DATA(data) + 4);
676 *pipe_uuid = *(UUID *)(GET_HTTP_PAYLOAD_FIELD_DATA(data) + 8);
677
678 return RPC_S_OK;
679}
680
681
684 RpcPktHdr *hdr, unsigned int hdr_size,
685 unsigned char *stub_data, unsigned int stub_data_size,
686 RpcAuthVerifier *auth_hdr,
687 unsigned char *auth_value, unsigned int auth_value_size)
688{
691 SECURITY_STATUS sec_status;
692
693 message.ulVersion = SECBUFFER_VERSION;
694 message.cBuffers = ARRAY_SIZE(buffers);
695 message.pBuffers = buffers;
696
697 buffers[0].cbBuffer = hdr_size;
699 buffers[0].pvBuffer = hdr;
700 buffers[1].cbBuffer = stub_data_size;
701 buffers[1].BufferType = SECBUFFER_DATA;
702 buffers[1].pvBuffer = stub_data;
703 buffers[2].cbBuffer = sizeof(*auth_hdr);
705 buffers[2].pvBuffer = auth_hdr;
706 buffers[3].cbBuffer = auth_value_size;
707 buffers[3].BufferType = SECBUFFER_TOKEN;
708 buffers[3].pvBuffer = auth_value;
709
710 if (dir == SECURE_PACKET_SEND)
711 {
713 {
714 sec_status = EncryptMessage(&Connection->ctx, 0, &message, 0 /* FIXME */);
715 if (sec_status != SEC_E_OK)
716 {
717 ERR("EncryptMessage failed with 0x%08x\n", sec_status);
718 return RPC_S_SEC_PKG_ERROR;
719 }
720 }
721 else if (auth_hdr->auth_level != RPC_C_AUTHN_LEVEL_NONE)
722 {
723 sec_status = MakeSignature(&Connection->ctx, 0, &message, 0 /* FIXME */);
724 if (sec_status != SEC_E_OK)
725 {
726 ERR("MakeSignature failed with 0x%08x\n", sec_status);
727 return RPC_S_SEC_PKG_ERROR;
728 }
729 }
730 }
731 else if (dir == SECURE_PACKET_RECEIVE)
732 {
734 {
735 sec_status = DecryptMessage(&Connection->ctx, &message, 0 /* FIXME */, 0);
736 if (sec_status != SEC_E_OK)
737 {
738 ERR("DecryptMessage failed with 0x%08x\n", sec_status);
739 return RPC_S_SEC_PKG_ERROR;
740 }
741 }
742 else if (auth_hdr->auth_level != RPC_C_AUTHN_LEVEL_NONE)
743 {
744 sec_status = VerifySignature(&Connection->ctx, &message, 0 /* FIXME */, NULL);
745 if (sec_status != SEC_E_OK)
746 {
747 ERR("VerifySignature failed with 0x%08x\n", sec_status);
748 return RPC_S_SEC_PKG_ERROR;
749 }
750 }
751 }
752
753 return RPC_S_OK;
754}
755
756/***********************************************************************
757 * RPCRT4_SendWithAuth (internal)
758 *
759 * Transmit a packet with authorization data over connection in acceptable fragments.
760 */
762 void *Buffer, unsigned int BufferLength,
763 const void *Auth, unsigned int AuthLength)
764{
765 PUCHAR buffer_pos;
766 DWORD hdr_size;
767 LONG count;
768 unsigned char *pkt;
769 LONG alen;
771
773
774 buffer_pos = Buffer;
775 /* The packet building functions save the packet header size, so we can use it. */
776 hdr_size = Header->common.frag_len;
777 if (AuthLength)
778 Header->common.auth_len = AuthLength;
779 else if (Connection->AuthInfo && packet_has_auth_verifier(Header))
780 {
782 Header->common.auth_len = Connection->encryption_auth_len;
783 else
784 Header->common.auth_len = Connection->signature_auth_len;
785 }
786 else
787 Header->common.auth_len = 0;
788 Header->common.flags |= RPC_FLG_FIRST;
789 Header->common.flags &= ~RPC_FLG_LAST;
790
791 alen = RPC_AUTH_VERIFIER_LEN(&Header->common);
792
793 while (!(Header->common.flags & RPC_FLG_LAST)) {
794 unsigned char auth_pad_len = Header->common.auth_len ? ROUND_UP_AMOUNT(BufferLength, AUTH_ALIGNMENT) : 0;
795 unsigned int pkt_size = BufferLength + hdr_size + alen + auth_pad_len;
796
797 /* decide if we need to split the packet into fragments */
798 if (pkt_size <= Connection->MaxTransmissionSize) {
799 Header->common.flags |= RPC_FLG_LAST;
800 Header->common.frag_len = pkt_size;
801 } else {
802 auth_pad_len = 0;
803 /* make sure packet payload will be a multiple of 16 */
804 Header->common.frag_len =
805 ((Connection->MaxTransmissionSize - hdr_size - alen) & ~(AUTH_ALIGNMENT-1)) +
806 hdr_size + alen;
807 }
808
809 pkt = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Header->common.frag_len);
810
811 memcpy(pkt, Header, hdr_size);
812
813 /* fragment consisted of header only and is the last one */
814 if (hdr_size == Header->common.frag_len)
815 goto write;
816
817 memcpy(pkt + hdr_size, buffer_pos, Header->common.frag_len - hdr_size - auth_pad_len - alen);
818
819 /* add the authorization info */
820 if (Header->common.auth_len)
821 {
822 RpcAuthVerifier *auth_hdr = (RpcAuthVerifier *)&pkt[Header->common.frag_len - alen];
823
824 auth_hdr->auth_type = Connection->AuthInfo->AuthnSvc;
825 auth_hdr->auth_level = Connection->AuthInfo->AuthnLevel;
826 auth_hdr->auth_pad_length = auth_pad_len;
827 auth_hdr->auth_reserved = 0;
828 /* a unique number... */
829 auth_hdr->auth_context_id = Connection->auth_context_id;
830
831 if (AuthLength)
832 memcpy(auth_hdr + 1, Auth, AuthLength);
833 else
834 {
836 (RpcPktHdr *)pkt, hdr_size,
837 pkt + hdr_size, Header->common.frag_len - hdr_size - alen,
838 auth_hdr,
839 (unsigned char *)(auth_hdr + 1), Header->common.auth_len);
840 if (status != RPC_S_OK)
841 {
842 HeapFree(GetProcessHeap(), 0, pkt);
844 return status;
845 }
846 }
847 }
848
849write:
850 count = rpcrt4_conn_write(Connection, pkt, Header->common.frag_len);
851 HeapFree(GetProcessHeap(), 0, pkt);
852 if (count<0) {
853 WARN("rpcrt4_conn_write failed (auth)\n");
855 return RPC_S_CALL_FAILED;
856 }
857
858 buffer_pos += Header->common.frag_len - hdr_size - alen - auth_pad_len;
859 BufferLength -= Header->common.frag_len - hdr_size - alen - auth_pad_len;
860 Header->common.flags &= ~RPC_FLG_FIRST;
861 }
862
864 return RPC_S_OK;
865}
866
867/***********************************************************************
868 * RPCRT4_default_authorize (internal)
869 *
870 * Authorize a client connection.
871 */
873 unsigned char *in_buffer,
874 unsigned int in_size,
875 unsigned char *out_buffer,
876 unsigned int *out_size)
877{
879 SecBufferDesc out_desc;
880 SecBufferDesc inp_desc;
881 SecPkgContext_Sizes secctx_sizes;
882 BOOL continue_needed;
883 ULONG context_req;
885
886 if (!out_buffer)
887 {
888 *out_size = conn->AuthInfo->cbMaxToken;
889 return RPC_S_OK;
890 }
891
892 in.BufferType = SECBUFFER_TOKEN;
893 in.pvBuffer = in_buffer;
894 in.cbBuffer = in_size;
895
896 out.BufferType = SECBUFFER_TOKEN;
897 out.pvBuffer = out_buffer;
898 out.cbBuffer = *out_size;
899
900 out_desc.ulVersion = 0;
901 out_desc.cBuffers = 1;
902 out_desc.pBuffers = &out;
903
904 inp_desc.ulVersion = 0;
905 inp_desc.cBuffers = 1;
906 inp_desc.pBuffers = &in;
907
908 if (conn->server)
909 {
912
914 context_req |= ASC_REQ_INTEGRITY;
917
919 first_time ? NULL : &conn->ctx,
920 &inp_desc, context_req, SECURITY_NETWORK_DREP,
921 &conn->ctx,
922 &out_desc, &conn->attr, &conn->exp);
923 if (r == SEC_E_OK || r == SEC_I_COMPLETE_NEEDED)
924 {
925 /* authorisation done, so nothing more to send */
926 out.cbBuffer = 0;
927 }
928 }
929 else
930 {
933
935 context_req |= ISC_REQ_INTEGRITY;
938
940 first_time ? NULL: &conn->ctx,
941 first_time ? conn->AuthInfo->server_principal_name : NULL,
942 context_req, 0, SECURITY_NETWORK_DREP,
943 first_time ? NULL : &inp_desc, 0, &conn->ctx,
944 &out_desc, &conn->attr, &conn->exp);
945 }
946 if (FAILED(r))
947 {
948 WARN("InitializeSecurityContext failed with error 0x%08x\n", r);
949 goto failed;
950 }
951
952 TRACE("r = 0x%08x, attr = 0x%08x\n", r, conn->attr);
953 continue_needed = ((r == SEC_I_CONTINUE_NEEDED) ||
955
957 {
958 TRACE("complete needed\n");
959 r = CompleteAuthToken(&conn->ctx, &out_desc);
960 if (FAILED(r))
961 {
962 WARN("CompleteAuthToken failed with error 0x%08x\n", r);
963 goto failed;
964 }
965 }
966
967 TRACE("cbBuffer = %d\n", out.cbBuffer);
968
969 if (!continue_needed)
970 {
971 r = QueryContextAttributesA(&conn->ctx, SECPKG_ATTR_SIZES, &secctx_sizes);
972 if (FAILED(r))
973 {
974 WARN("QueryContextAttributes failed with error 0x%08x\n", r);
975 goto failed;
976 }
977 conn->signature_auth_len = secctx_sizes.cbMaxSignature;
978 conn->encryption_auth_len = secctx_sizes.cbSecurityTrailer;
979 }
980
981 *out_size = out.cbBuffer;
982 return RPC_S_OK;
983
984failed:
985 *out_size = 0;
986 return ERROR_ACCESS_DENIED; /* FIXME: is this correct? */
987}
988
989/***********************************************************************
990 * RPCRT4_ClientConnectionAuth (internal)
991 */
993 ULONG count)
994{
995 RpcPktHdr *resp_hdr;
997 unsigned char *out_buffer;
998 unsigned int out_len = 0;
999
1000 TRACE("challenge %s, %d bytes\n", challenge, count);
1001
1002 status = rpcrt4_conn_authorize(conn, FALSE, challenge, count, NULL, &out_len);
1003 if (status) return status;
1004 out_buffer = HeapAlloc(GetProcessHeap(), 0, out_len);
1006 status = rpcrt4_conn_authorize(conn, FALSE, challenge, count, out_buffer, &out_len);
1007 if (status) return status;
1008
1010
1011 if (resp_hdr)
1012 status = RPCRT4_SendWithAuth(conn, resp_hdr, NULL, 0, out_buffer, out_len);
1013 else
1015
1017 RPCRT4_FreeHeader(resp_hdr);
1018
1019 return status;
1020}
1021
1022/***********************************************************************
1023 * RPCRT4_ServerConnectionAuth (internal)
1024 */
1026 BOOL start,
1027 RpcAuthVerifier *auth_data_in,
1028 ULONG auth_length_in,
1029 unsigned char **auth_data_out,
1030 ULONG *auth_length_out)
1031{
1032 unsigned char *out_buffer;
1033 unsigned int out_size;
1035
1036 if (start)
1037 {
1038 /* remove any existing authentication information */
1039 if (conn->AuthInfo)
1040 {
1042 conn->AuthInfo = NULL;
1043 }
1044 if (SecIsValidHandle(&conn->ctx))
1045 {
1046 DeleteSecurityContext(&conn->ctx);
1047 SecInvalidateHandle(&conn->ctx);
1048 }
1049 if (auth_length_in >= sizeof(RpcAuthVerifier))
1050 {
1051 CredHandle cred;
1052 TimeStamp exp;
1053 ULONG max_token;
1054
1056 auth_data_in->auth_type, &cred, &exp, &max_token);
1057 if (status != RPC_S_OK)
1058 {
1059 ERR("unknown authentication service %u\n", auth_data_in->auth_type);
1060 return status;
1061 }
1062
1063 status = RpcAuthInfo_Create(auth_data_in->auth_level,
1064 auth_data_in->auth_type, cred, exp,
1065 max_token, NULL, &conn->AuthInfo);
1066 if (status != RPC_S_OK)
1067 {
1068 FreeCredentialsHandle(&cred);
1069 return status;
1070 }
1071
1072 /* FIXME: should auth_data_in->auth_context_id be checked in the !start case? */
1073 conn->auth_context_id = auth_data_in->auth_context_id;
1074 }
1075 }
1076
1077 if (auth_length_in < sizeof(RpcAuthVerifier))
1078 return RPC_S_OK;
1079
1080 if (!conn->AuthInfo)
1081 /* should have filled in authentication info by now */
1082 return RPC_S_PROTOCOL_ERROR;
1083
1085 conn, start, (unsigned char *)(auth_data_in + 1),
1086 auth_length_in - sizeof(RpcAuthVerifier), NULL, &out_size);
1087 if (status) return status;
1088
1091
1093 conn, start, (unsigned char *)(auth_data_in + 1),
1094 auth_length_in - sizeof(RpcAuthVerifier), out_buffer, &out_size);
1095 if (status != RPC_S_OK)
1096 {
1098 return status;
1099 }
1100
1101 if (out_size && !auth_length_out)
1102 {
1103 ERR("expected authentication to be complete but SSP returned data of "
1104 "%u bytes to be sent back to client\n", out_size);
1106 return RPC_S_SEC_PKG_ERROR;
1107 }
1108 else
1109 {
1110 *auth_data_out = out_buffer;
1111 *auth_length_out = out_size;
1112 }
1113
1114 return status;
1115}
1116
1117/***********************************************************************
1118 * RPCRT4_default_is_authorized (internal)
1119 *
1120 * Has a connection started the process of authorizing with the server?
1121 */
1123{
1124 return Connection->AuthInfo && SecIsValidHandle(&Connection->ctx);
1125}
1126
1127/***********************************************************************
1128 * RPCRT4_default_impersonate_client (internal)
1129 *
1130 */
1132{
1133 SECURITY_STATUS sec_status;
1134
1135 TRACE("(%p)\n", conn);
1136
1137 if (!conn->AuthInfo || !SecIsValidHandle(&conn->ctx))
1139 sec_status = ImpersonateSecurityContext(&conn->ctx);
1140 if (sec_status != SEC_E_OK)
1141 WARN("ImpersonateSecurityContext returned 0x%08x\n", sec_status);
1142 switch (sec_status)
1143 {
1145 return RPC_S_CANNOT_SUPPORT;
1148 case SEC_E_OK:
1149 return RPC_S_OK;
1150 default:
1151 return RPC_S_SEC_PKG_ERROR;
1152 }
1153}
1154
1155/***********************************************************************
1156 * RPCRT4_default_revert_to_self (internal)
1157 *
1158 */
1160{
1161 SECURITY_STATUS sec_status;
1162
1163 TRACE("(%p)\n", conn);
1164
1165 if (!conn->AuthInfo || !SecIsValidHandle(&conn->ctx))
1167 sec_status = RevertSecurityContext(&conn->ctx);
1168 if (sec_status != SEC_E_OK)
1169 WARN("RevertSecurityContext returned 0x%08x\n", sec_status);
1170 switch (sec_status)
1171 {
1173 return RPC_S_CANNOT_SUPPORT;
1176 case SEC_E_OK:
1177 return RPC_S_OK;
1178 default:
1179 return RPC_S_SEC_PKG_ERROR;
1180 }
1181}
1182
1183/***********************************************************************
1184 * RPCRT4_default_inquire_auth_client (internal)
1185 *
1186 * Default function to retrieve the authentication details that the client
1187 * is using to call the server.
1188 */
1190 RpcConnection *conn, RPC_AUTHZ_HANDLE *privs, RPC_WSTR *server_princ_name,
1191 ULONG *authn_level, ULONG *authn_svc, ULONG *authz_svc, ULONG flags)
1192{
1193 if (!conn->AuthInfo) return RPC_S_BINDING_HAS_NO_AUTH;
1194
1195 if (privs)
1196 {
1197 FIXME("privs not implemented\n");
1198 *privs = NULL;
1199 }
1200 if (server_princ_name)
1201 {
1202 *server_princ_name = RPCRT4_strdupW(conn->AuthInfo->server_principal_name);
1203 if (!*server_princ_name) return ERROR_OUTOFMEMORY;
1204 }
1205 if (authn_level) *authn_level = conn->AuthInfo->AuthnLevel;
1206 if (authn_svc) *authn_svc = conn->AuthInfo->AuthnSvc;
1207 if (authz_svc)
1208 {
1209 FIXME("authorization service not implemented\n");
1210 *authz_svc = RPC_C_AUTHZ_NONE;
1211 }
1212 if (flags)
1213 FIXME("flags 0x%x not implemented\n", flags);
1214
1215 return RPC_S_OK;
1216}
1217
1218/***********************************************************************
1219 * RPCRT4_Send (internal)
1220 *
1221 * Transmit a packet over connection in acceptable fragments.
1222 */
1224 void *Buffer, unsigned int BufferLength)
1225{
1226 RPC_STATUS r;
1227
1229 Connection->AuthInfo &&
1230 !rpcrt4_conn_is_authorized(Connection))
1231 {
1232 unsigned int out_size = 0;
1233 unsigned char *out_buffer;
1234
1235 r = rpcrt4_conn_authorize(Connection, TRUE, NULL, 0, NULL, &out_size);
1236 if (r != RPC_S_OK) return r;
1237
1240
1241 /* tack on a negotiate packet */
1242 r = rpcrt4_conn_authorize(Connection, TRUE, NULL, 0, out_buffer, &out_size);
1243 if (r == RPC_S_OK)
1245
1247 }
1248 else
1249 r = RPCRT4_SendWithAuth(Connection, Header, Buffer, BufferLength, NULL, 0);
1250
1251 return r;
1252}
1253
1254/* validates version and frag_len fields */
1256{
1257 DWORD hdr_length;
1258
1259 /* verify if the header really makes sense */
1260 if (hdr->rpc_ver != RPC_VER_MAJOR ||
1261 hdr->rpc_ver_minor != RPC_VER_MINOR)
1262 {
1263 WARN("unhandled packet version\n");
1264 return RPC_S_PROTOCOL_ERROR;
1265 }
1266
1267 hdr_length = RPCRT4_GetHeaderSize((const RpcPktHdr*)hdr);
1268 if (hdr_length == 0)
1269 {
1270 WARN("header length == 0\n");
1271 return RPC_S_PROTOCOL_ERROR;
1272 }
1273
1274 if (hdr->frag_len < hdr_length)
1275 {
1276 WARN("bad frag length %d\n", hdr->frag_len);
1277 return RPC_S_PROTOCOL_ERROR;
1278 }
1279
1280 return RPC_S_OK;
1281}
1282
1283/***********************************************************************
1284 * RPCRT4_default_receive_fragment (internal)
1285 *
1286 * Receive a fragment from a connection.
1287 */
1289{
1291 DWORD hdr_length;
1292 LONG dwRead;
1293 RpcPktCommonHdr common_hdr;
1294
1295 *Header = NULL;
1296 *Payload = NULL;
1297
1298 TRACE("(%p, %p, %p)\n", Connection, Header, Payload);
1299
1300 /* read packet common header */
1301 dwRead = rpcrt4_conn_read(Connection, &common_hdr, sizeof(common_hdr));
1302 if (dwRead != sizeof(common_hdr)) {
1303 WARN("Short read of header, %d bytes\n", dwRead);
1305 goto fail;
1306 }
1307
1308 status = RPCRT4_ValidateCommonHeader(&common_hdr);
1309 if (status != RPC_S_OK) goto fail;
1310
1311 hdr_length = RPCRT4_GetHeaderSize((RpcPktHdr*)&common_hdr);
1312 if (hdr_length == 0) {
1313 WARN("header length == 0\n");
1315 goto fail;
1316 }
1317
1318 *Header = HeapAlloc(GetProcessHeap(), 0, hdr_length);
1319 memcpy(*Header, &common_hdr, sizeof(common_hdr));
1320
1321 /* read the rest of packet header */
1322 dwRead = rpcrt4_conn_read(Connection, &(*Header)->common + 1, hdr_length - sizeof(common_hdr));
1323 if (dwRead != hdr_length - sizeof(common_hdr)) {
1324 WARN("bad header length, %d bytes, hdr_length %d\n", dwRead, hdr_length);
1326 goto fail;
1327 }
1328
1329 if (common_hdr.frag_len - hdr_length)
1330 {
1331 *Payload = HeapAlloc(GetProcessHeap(), 0, common_hdr.frag_len - hdr_length);
1332 if (!*Payload)
1333 {
1335 goto fail;
1336 }
1337
1338 dwRead = rpcrt4_conn_read(Connection, *Payload, common_hdr.frag_len - hdr_length);
1339 if (dwRead != common_hdr.frag_len - hdr_length)
1340 {
1341 WARN("bad data length, %d/%d\n", dwRead, common_hdr.frag_len - hdr_length);
1343 goto fail;
1344 }
1345 }
1346 else
1347 *Payload = NULL;
1348
1349 /* success */
1350 status = RPC_S_OK;
1351
1352fail:
1353 if (status != RPC_S_OK) {
1355 *Header = NULL;
1356 HeapFree(GetProcessHeap(), 0, *Payload);
1357 *Payload = NULL;
1358 }
1359 return status;
1360}
1361
1363{
1364 if (Connection->ops->receive_fragment)
1365 return Connection->ops->receive_fragment(Connection, Header, Payload);
1366 else
1367 return RPCRT4_default_receive_fragment(Connection, Header, Payload);
1368}
1369
1370/***********************************************************************
1371 * RPCRT4_ReceiveWithAuth (internal)
1372 *
1373 * Receive a packet from connection, merge the fragments and return the auth
1374 * data.
1375 */
1377 PRPC_MESSAGE pMsg,
1378 unsigned char **auth_data_out,
1379 ULONG *auth_length_out)
1380{
1382 DWORD hdr_length;
1383 unsigned short first_flag;
1384 ULONG data_length;
1385 ULONG buffer_length;
1386 ULONG auth_length = 0;
1387 unsigned char *auth_data = NULL;
1388 RpcPktHdr *CurrentHeader = NULL;
1389 void *payload = NULL;
1390
1391 *Header = NULL;
1392 pMsg->Buffer = NULL;
1393 if (auth_data_out) *auth_data_out = NULL;
1394 if (auth_length_out) *auth_length_out = 0;
1395
1396 TRACE("(%p, %p, %p, %p)\n", Connection, Header, pMsg, auth_data_out);
1397
1399
1400 status = RPCRT4_receive_fragment(Connection, Header, &payload);
1401 if (status != RPC_S_OK) goto fail;
1402
1403 hdr_length = RPCRT4_GetHeaderSize(*Header);
1404
1405 /* read packet body */
1406 switch ((*Header)->common.ptype) {
1407 case PKT_RESPONSE:
1408 pMsg->BufferLength = (*Header)->response.alloc_hint;
1409 break;
1410 case PKT_REQUEST:
1411 pMsg->BufferLength = (*Header)->request.alloc_hint;
1412 break;
1413 default:
1414 pMsg->BufferLength = (*Header)->common.frag_len - hdr_length - RPC_AUTH_VERIFIER_LEN(&(*Header)->common);
1415 }
1416
1417 TRACE("buffer length = %u\n", pMsg->BufferLength);
1418
1419 pMsg->Buffer = I_RpcAllocate(pMsg->BufferLength);
1420 if (!pMsg->Buffer)
1421 {
1423 goto fail;
1424 }
1425
1426 first_flag = RPC_FLG_FIRST;
1427 auth_length = (*Header)->common.auth_len;
1428 if (auth_length) {
1429 auth_data = HeapAlloc(GetProcessHeap(), 0, RPC_AUTH_VERIFIER_LEN(&(*Header)->common));
1430 if (!auth_data) {
1432 goto fail;
1433 }
1434 }
1435 CurrentHeader = *Header;
1436 buffer_length = 0;
1437 while (TRUE)
1438 {
1439 unsigned int header_auth_len = RPC_AUTH_VERIFIER_LEN(&CurrentHeader->common);
1440
1441 /* verify header fields */
1442
1443 if ((CurrentHeader->common.frag_len < hdr_length) ||
1444 (CurrentHeader->common.frag_len - hdr_length < header_auth_len)) {
1445 WARN("frag_len %d too small for hdr_length %d and auth_len %d\n",
1446 CurrentHeader->common.frag_len, hdr_length, CurrentHeader->common.auth_len);
1448 goto fail;
1449 }
1450
1451 if (CurrentHeader->common.auth_len != auth_length) {
1452 WARN("auth_len header field changed from %d to %d\n",
1453 auth_length, CurrentHeader->common.auth_len);
1455 goto fail;
1456 }
1457
1458 if ((CurrentHeader->common.flags & RPC_FLG_FIRST) != first_flag) {
1459 TRACE("invalid packet flags\n");
1461 goto fail;
1462 }
1463
1464 data_length = CurrentHeader->common.frag_len - hdr_length - header_auth_len;
1465 if (data_length + buffer_length > pMsg->BufferLength) {
1466 TRACE("allocation hint exceeded, new buffer length = %d\n",
1467 data_length + buffer_length);
1468 pMsg->BufferLength = data_length + buffer_length;
1470 if (status != RPC_S_OK) goto fail;
1471 }
1472
1473 memcpy((unsigned char *)pMsg->Buffer + buffer_length, payload, data_length);
1474
1475 if (header_auth_len) {
1476 if (header_auth_len < sizeof(RpcAuthVerifier) ||
1477 header_auth_len > RPC_AUTH_VERIFIER_LEN(&(*Header)->common)) {
1478 WARN("bad auth verifier length %d\n", header_auth_len);
1480 goto fail;
1481 }
1482
1483 /* FIXME: we should accumulate authentication data for the bind,
1484 * bind_ack, alter_context and alter_context_response if necessary.
1485 * however, the details of how this is done is very sketchy in the
1486 * DCE/RPC spec. for all other packet types that have authentication
1487 * verifier data then it is just duplicated in all the fragments */
1488 memcpy(auth_data, (unsigned char *)payload + data_length, header_auth_len);
1489
1490 /* these packets are handled specially, not by the generic SecurePacket
1491 * function */
1493 {
1495 CurrentHeader, hdr_length,
1496 (unsigned char *)pMsg->Buffer + buffer_length, data_length,
1497 (RpcAuthVerifier *)auth_data,
1498 auth_data + sizeof(RpcAuthVerifier),
1499 header_auth_len - sizeof(RpcAuthVerifier));
1500 if (status != RPC_S_OK) goto fail;
1501 }
1502 }
1503
1504 buffer_length += data_length;
1505 if (!(CurrentHeader->common.flags & RPC_FLG_LAST)) {
1506 TRACE("next header\n");
1507
1508 if (*Header != CurrentHeader)
1509 {
1510 RPCRT4_FreeHeader(CurrentHeader);
1511 CurrentHeader = NULL;
1512 }
1513 HeapFree(GetProcessHeap(), 0, payload);
1514 payload = NULL;
1515
1516 status = RPCRT4_receive_fragment(Connection, &CurrentHeader, &payload);
1517 if (status != RPC_S_OK) goto fail;
1518
1519 first_flag = 0;
1520 } else {
1521 break;
1522 }
1523 }
1524 pMsg->BufferLength = buffer_length;
1525
1526 /* success */
1527 status = RPC_S_OK;
1528
1529fail:
1531 if (CurrentHeader != *Header)
1532 RPCRT4_FreeHeader(CurrentHeader);
1533 if (status != RPC_S_OK) {
1534 I_RpcFree(pMsg->Buffer);
1535 pMsg->Buffer = NULL;
1537 *Header = NULL;
1538 }
1539 if (auth_data_out && status == RPC_S_OK) {
1540 *auth_length_out = auth_length;
1541 *auth_data_out = auth_data;
1542 }
1543 else
1544 HeapFree(GetProcessHeap(), 0, auth_data);
1545 HeapFree(GetProcessHeap(), 0, payload);
1546 return status;
1547}
1548
1549/***********************************************************************
1550 * RPCRT4_Receive (internal)
1551 *
1552 * Receive a packet from connection and merge the fragments.
1553 */
1555 PRPC_MESSAGE pMsg)
1556{
1557 return RPCRT4_ReceiveWithAuth(Connection, Header, pMsg, NULL, NULL);
1558}
1559
1560/***********************************************************************
1561 * I_RpcNegotiateTransferSyntax [RPCRT4.@]
1562 *
1563 * Negotiates the transfer syntax used by a client connection by connecting
1564 * to the server.
1565 *
1566 * PARAMS
1567 * pMsg [I] RPC Message structure.
1568 * pAsync [I] Asynchronous state to set.
1569 *
1570 * RETURNS
1571 * Success: RPC_S_OK.
1572 * Failure: Any error code.
1573 */
1575{
1576 RpcBinding* bind = pMsg->Handle;
1577 RpcConnection* conn;
1579
1580 TRACE("(%p)\n", pMsg);
1581
1582 if (!bind || bind->server)
1583 {
1584 ERR("no binding\n");
1585 return RPC_S_INVALID_BINDING;
1586 }
1587
1588 /* if we already have a connection, we don't need to negotiate again */
1589 if (!pMsg->ReservedForRuntime)
1590 {
1592 if (!cif) return RPC_S_INTERFACE_NOT_FOUND;
1593
1594 if (!bind->Endpoint || !bind->Endpoint[0])
1595 {
1596 TRACE("automatically resolving partially bound binding\n");
1598 if (status != RPC_S_OK) return status;
1599 }
1600
1602 &cif->InterfaceId, NULL);
1603
1604 if (status == RPC_S_OK)
1605 {
1606 pMsg->ReservedForRuntime = conn;
1608 }
1609 }
1610
1611 return status;
1612}
1613
1614/***********************************************************************
1615 * I_RpcGetBuffer [RPCRT4.@]
1616 *
1617 * Allocates a buffer for use by I_RpcSend or I_RpcSendReceive and binds to the
1618 * server interface.
1619 *
1620 * PARAMS
1621 * pMsg [I/O] RPC message information.
1622 *
1623 * RETURNS
1624 * Success: RPC_S_OK.
1625 * Failure: RPC_S_INVALID_BINDING if pMsg->Handle is invalid.
1626 * RPC_S_SERVER_UNAVAILABLE if unable to connect to server.
1627 * ERROR_OUTOFMEMORY if buffer allocation failed.
1628 *
1629 * NOTES
1630 * The pMsg->BufferLength field determines the size of the buffer to allocate,
1631 * in bytes.
1632 *
1633 * Use I_RpcFreeBuffer() to unbind from the server and free the message buffer.
1634 *
1635 * SEE ALSO
1636 * I_RpcFreeBuffer(), I_RpcSend(), I_RpcReceive(), I_RpcSendReceive().
1637 */
1639{
1641 RpcBinding* bind = pMsg->Handle;
1642
1643 TRACE("(%p): BufferLength=%d\n", pMsg, pMsg->BufferLength);
1644
1645 if (!bind)
1646 {
1647 ERR("no binding\n");
1648 return RPC_S_INVALID_BINDING;
1649 }
1650
1651 pMsg->Buffer = I_RpcAllocate(pMsg->BufferLength);
1652 TRACE("Buffer=%p\n", pMsg->Buffer);
1653
1654 if (!pMsg->Buffer)
1655 return ERROR_OUTOFMEMORY;
1656
1657 if (!bind->server)
1658 {
1660 if (status != RPC_S_OK)
1661 I_RpcFree(pMsg->Buffer);
1662 }
1663 else
1664 status = RPC_S_OK;
1665
1666 return status;
1667}
1668
1669/***********************************************************************
1670 * I_RpcReAllocateBuffer (internal)
1671 */
1673{
1674 TRACE("(%p): BufferLength=%d\n", pMsg, pMsg->BufferLength);
1675 pMsg->Buffer = HeapReAlloc(GetProcessHeap(), 0, pMsg->Buffer, pMsg->BufferLength);
1676
1677 TRACE("Buffer=%p\n", pMsg->Buffer);
1678 return pMsg->Buffer ? RPC_S_OK : ERROR_OUTOFMEMORY;
1679}
1680
1681/***********************************************************************
1682 * I_RpcFreeBuffer [RPCRT4.@]
1683 *
1684 * Frees a buffer allocated by I_RpcGetBuffer or I_RpcReceive and unbinds from
1685 * the server interface.
1686 *
1687 * PARAMS
1688 * pMsg [I/O] RPC message information.
1689 *
1690 * RETURNS
1691 * RPC_S_OK.
1692 *
1693 * SEE ALSO
1694 * I_RpcGetBuffer(), I_RpcReceive().
1695 */
1697{
1698 RpcBinding* bind = pMsg->Handle;
1699
1700 TRACE("(%p) Buffer=%p\n", pMsg, pMsg->Buffer);
1701
1702 if (!bind)
1703 {
1704 ERR("no binding\n");
1705 return RPC_S_INVALID_BINDING;
1706 }
1707
1708 if (pMsg->ReservedForRuntime)
1709 {
1710 RpcConnection *conn = pMsg->ReservedForRuntime;
1713 pMsg->ReservedForRuntime = NULL;
1714 }
1715 I_RpcFree(pMsg->Buffer);
1716 return RPC_S_OK;
1717}
1718
1720{
1722 state->u.APC.NotificationRoutine(state, NULL, state->Event);
1723}
1724
1726{
1727 RpcConnection *conn = p;
1729
1730 if (state && conn->ops->wait_for_incoming_data(conn) != -1)
1731 {
1732 state->Event = RpcCallComplete;
1733 switch (state->NotificationType)
1734 {
1736 TRACE("RpcNotificationTypeEvent %p\n", state->u.hEvent);
1737 SetEvent(state->u.hEvent);
1738 break;
1740 TRACE("RpcNotificationTypeApc %p\n", state->u.APC.hThread);
1742 break;
1744 TRACE("RpcNotificationTypeIoc %p, 0x%x, 0x%lx, %p\n",
1745 state->u.IOC.hIOPort, state->u.IOC.dwNumberOfBytesTransferred,
1746 state->u.IOC.dwCompletionKey, state->u.IOC.lpOverlapped);
1747 PostQueuedCompletionStatus(state->u.IOC.hIOPort,
1748 state->u.IOC.dwNumberOfBytesTransferred,
1749 state->u.IOC.dwCompletionKey,
1750 state->u.IOC.lpOverlapped);
1751 break;
1753 TRACE("RpcNotificationTypeHwnd %p 0x%x\n", state->u.HWND.hWnd,
1754 state->u.HWND.Msg);
1755 PostMessageW(state->u.HWND.hWnd, state->u.HWND.Msg, 0, 0);
1756 break;
1758 TRACE("RpcNotificationTypeCallback %p\n", state->u.NotificationRoutine);
1759 state->u.NotificationRoutine(state, NULL, state->Event);
1760 break;
1762 TRACE("RpcNotificationTypeNone\n");
1763 break;
1764 default:
1765 FIXME("unknown NotificationType: %d/0x%x\n", state->NotificationType, state->NotificationType);
1766 break;
1767 }
1768 }
1769
1770 return 0;
1771}
1772
1773/***********************************************************************
1774 * I_RpcSend [RPCRT4.@]
1775 *
1776 * Sends a message to the server.
1777 *
1778 * PARAMS
1779 * pMsg [I/O] RPC message information.
1780 *
1781 * RETURNS
1782 * Unknown.
1783 *
1784 * NOTES
1785 * The buffer must have been allocated with I_RpcGetBuffer().
1786 *
1787 * SEE ALSO
1788 * I_RpcGetBuffer(), I_RpcReceive(), I_RpcSendReceive().
1789 */
1791{
1792 RpcBinding* bind = pMsg->Handle;
1794 RpcConnection* conn;
1796 RpcPktHdr *hdr;
1797 BOOL from_cache = TRUE;
1798
1799 TRACE("(%p)\n", pMsg);
1800 if (!bind || bind->server || !pMsg->ReservedForRuntime) return RPC_S_INVALID_BINDING;
1801
1802 for (;;)
1803 {
1804 conn = pMsg->ReservedForRuntime;
1806 pMsg->BufferLength,
1808 &bind->ObjectUuid);
1809 if (!hdr)
1810 return ERROR_OUTOFMEMORY;
1811
1812 hdr->common.call_id = conn->NextCallId++;
1813 status = RPCRT4_Send(conn, hdr, pMsg->Buffer, pMsg->BufferLength);
1815 if (status == RPC_S_OK || conn->server || !from_cache)
1816 break;
1817
1818 WARN("Send failed, trying to reconnect\n");
1819 cif = pMsg->RpcInterfaceInformation;
1821 pMsg->ReservedForRuntime = NULL;
1822 status = RPCRT4_OpenBinding(bind, &conn, &cif->TransferSyntax, &cif->InterfaceId, &from_cache);
1823 if (status != RPC_S_OK) break;
1824 pMsg->ReservedForRuntime = conn;
1825 }
1826
1827 if (status == RPC_S_OK && pMsg->RpcFlags & RPC_BUFFER_ASYNC)
1828 {
1831 }
1832
1833 return status;
1834}
1835
1836/* is this status something that the server can't recover from? */
1838{
1839 switch (status)
1840 {
1841 case 0: /* user-defined fault */
1845 case RPC_S_CALL_FAILED:
1848 return TRUE;
1849 default:
1850 return FALSE;
1851 }
1852}
1853
1854/***********************************************************************
1855 * I_RpcReceive [RPCRT4.@]
1856 */
1858{
1859 RpcBinding* bind = pMsg->Handle;
1861 RpcPktHdr *hdr = NULL;
1862 RpcConnection *conn;
1863
1864 TRACE("(%p)\n", pMsg);
1865 if (!bind || bind->server || !pMsg->ReservedForRuntime) return RPC_S_INVALID_BINDING;
1866
1867 conn = pMsg->ReservedForRuntime;
1868 status = RPCRT4_Receive(conn, &hdr, pMsg);
1869 if (status != RPC_S_OK) {
1870 WARN("receive failed with error %x\n", status);
1871 goto fail;
1872 }
1873
1874 switch (hdr->common.ptype) {
1875 case PKT_RESPONSE:
1876 break;
1877 case PKT_FAULT:
1878 ERR ("we got fault packet with status 0x%x\n", hdr->fault.status);
1879 status = NCA2RPC_STATUS(hdr->fault.status);
1880 if (is_hard_error(status))
1881 goto fail;
1882 break;
1883 default:
1884 WARN("bad packet type %d\n", hdr->common.ptype);
1886 goto fail;
1887 }
1888
1889 /* success */
1891 return status;
1892
1893fail:
1896 pMsg->ReservedForRuntime = NULL;
1897 return status;
1898}
1899
1900/***********************************************************************
1901 * I_RpcSendReceive [RPCRT4.@]
1902 *
1903 * Sends a message to the server and receives the response.
1904 *
1905 * PARAMS
1906 * pMsg [I/O] RPC message information.
1907 *
1908 * RETURNS
1909 * Success: RPC_S_OK.
1910 * Failure: Any error code.
1911 *
1912 * NOTES
1913 * The buffer must have been allocated with I_RpcGetBuffer().
1914 *
1915 * SEE ALSO
1916 * I_RpcGetBuffer(), I_RpcSend(), I_RpcReceive().
1917 */
1919{
1921 void *original_buffer;
1922
1923 TRACE("(%p)\n", pMsg);
1924
1925 original_buffer = pMsg->Buffer;
1926 status = I_RpcSend(pMsg);
1927 if (status == RPC_S_OK)
1928 status = I_RpcReceive(pMsg);
1929 /* free the buffer replaced by a new buffer in I_RpcReceive */
1930 if (status == RPC_S_OK)
1931 I_RpcFree(original_buffer);
1932 return status;
1933}
1934
1935/***********************************************************************
1936 * I_RpcAsyncSetHandle [RPCRT4.@]
1937 *
1938 * Sets the asynchronous state of the handle contained in the RPC message
1939 * structure.
1940 *
1941 * PARAMS
1942 * pMsg [I] RPC Message structure.
1943 * pAsync [I] Asynchronous state to set.
1944 *
1945 * RETURNS
1946 * Success: RPC_S_OK.
1947 * Failure: Any error code.
1948 */
1950{
1951 RpcBinding* bind = pMsg->Handle;
1952 RpcConnection *conn;
1953
1954 TRACE("(%p, %p)\n", pMsg, pAsync);
1955
1956 if (!bind || bind->server || !pMsg->ReservedForRuntime) return RPC_S_INVALID_BINDING;
1957
1958 conn = pMsg->ReservedForRuntime;
1959 conn->async_state = pAsync;
1960
1961 return RPC_S_OK;
1962}
1963
1964/***********************************************************************
1965 * I_RpcAsyncAbortCall [RPCRT4.@]
1966 *
1967 * Aborts an asynchronous call.
1968 *
1969 * PARAMS
1970 * pAsync [I] Asynchronous state.
1971 * ExceptionCode [I] Exception code.
1972 *
1973 * RETURNS
1974 * Success: RPC_S_OK.
1975 * Failure: Any error code.
1976 */
1978{
1979 FIXME("(%p, %d): stub\n", pAsync, ExceptionCode);
1981}
static struct _test_info results[8]
Definition: SetCursorPos.c:31
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define write
Definition: acwin.h:97
static int state
Definition: maze.c:121
unsigned int dir
Definition: maze.c:112
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define ARRAY_SIZE(A)
Definition: main.h:33
#define FIXME(fmt,...)
Definition: debug.h:111
#define WARN(fmt,...)
Definition: debug.h:112
#define ERR(fmt,...)
Definition: debug.h:110
_Inout_ PIRP _In_ NTSTATUS ExceptionCode
Definition: cdprocs.h:1774
Definition: bufpool.h:45
Definition: Header.h:9
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define HeapAlloc
Definition: compat.h:733
#define HeapReAlloc
Definition: compat.h:734
#define HeapFree(x, y, z)
Definition: compat.h:735
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define CALLBACK
Definition: compat.h:35
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
DWORD WINAPI QueueUserAPC(IN PAPCFUNC pfnAPC, IN HANDLE hThread, IN ULONG_PTR dwData)
Definition: thread.c:959
BOOL WINAPI QueueUserWorkItem(IN LPTHREAD_START_ROUTINE Function, IN PVOID Context, IN ULONG Flags)
Definition: thread.c:1076
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
Status
Definition: gdiplustypes.h:25
GLuint start
Definition: gl.h:1545
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLsizeiptr size
Definition: glext.h:5919
GLuint in
Definition: glext.h:9616
GLbitfield flags
Definition: glext.h:7161
GLfloat GLfloat p
Definition: glext.h:8902
const GLuint * buffers
Definition: glext.h:5916
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static unsigned char * in_buffer
Definition: iccvid.c:87
#define FAILED(hr)
Definition: intsafe.h:51
BOOL WINAPI PostQueuedCompletionStatus(IN HANDLE CompletionHandle, IN DWORD dwNumberOfBytesTransferred, IN ULONG_PTR dwCompletionKey, IN LPOVERLAPPED lpOverlapped)
Definition: iocompl.c:192
char hdr[14]
Definition: iptest.cpp:33
#define LOBYTE(W)
Definition: jmemdos.c:487
#define HIBYTE(W)
Definition: jmemdos.c:486
if(dx< 0)
Definition: linetemp.h:194
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GUID UUID
Definition: module.h:1093
static HANDLE PIO_APC_ROUTINE PVOID PIO_STATUS_BLOCK ULONG PVOID ULONG PVOID ULONG out_size
Definition: file.c:100
static HANDLE PIO_APC_ROUTINE PVOID PIO_STATUS_BLOCK ULONG PVOID ULONG PVOID out_buffer
Definition: file.c:100
static HANDLE PIO_APC_ROUTINE PVOID PIO_STATUS_BLOCK ULONG PVOID ULONG in_size
Definition: file.c:100
DWORD exp
Definition: msg.c:16058
#define NCA_S_UNK_IF
Definition: ncastatus.h:25
#define NCA_S_FAULT_ILL_INST
Definition: ncastatus.h:47
#define NCA_S_MANAGER_NOT_ENTERED
Definition: ncastatus.h:45
#define NCA_S_FAULT_INT_DIV_BY_ZERO
Definition: ncastatus.h:34
#define NCA_S_UNSPEC_REJECT
Definition: ncastatus.h:42
#define NCA_S_FAULT_INT_OVERFLOW
Definition: ncastatus.h:49
#define NCA_S_FAULT_PIPE_MEMORY
Definition: ncastatus.h:57
#define NCA_S_FAULT_REMOTE_NO_MEMORY
Definition: ncastatus.h:59
#define NCA_S_RPC_VERSION_MISMATCH
Definition: ncastatus.h:41
#define NCA_S_COMM_FAILURE
Definition: ncastatus.h:23
#define NCA_S_SERVER_TOO_BUSY
Definition: ncastatus.h:30
#define NCA_S_FAULT_FP_OVERFLOW
Definition: ncastatus.h:38
#define NCA_S_FAULT_UNSPEC
Definition: ncastatus.h:50
#define NCA_S_BAD_ACTID
Definition: ncastatus.h:43
#define NCA_S_FAULT_FP_DIV_ZERO
Definition: ncastatus.h:36
#define NCA_S_FAULT_FP_ERROR
Definition: ncastatus.h:48
#define NCA_S_FAULT_PIPE_CLOSED
Definition: ncastatus.h:53
#define NCA_S_FAULT_CONTEXT_MISMATCH
Definition: ncastatus.h:58
#define NCA_S_UNSUPPORTED_TYPE
Definition: ncastatus.h:32
#define NCA_S_FAULT_ADDR_ERROR
Definition: ncastatus.h:35
#define NCA_S_WHO_ARE_YOU_FAILED
Definition: ncastatus.h:44
#define NCA_S_FAULT_PIPE_DISCIPLINE
Definition: ncastatus.h:55
#define NCA_S_FAULT_PIPE_EMPTY
Definition: ncastatus.h:52
#define NCA_S_FAULT_CANCEL
Definition: ncastatus.h:46
#define NCA_S_OUT_ARGS_TOO_BIG
Definition: ncastatus.h:29
#define NCA_S_OP_RNG_ERROR
Definition: ncastatus.h:24
#define NCA_S_FAULT_PIPE_COMM_ERROR
Definition: ncastatus.h:56
#define NCA_S_YOU_CRASHED
Definition: ncastatus.h:27
#define NCA_S_FAULT_FP_UNDERFLOW
Definition: ncastatus.h:37
#define NCA_S_FAULT_INVALID_TAG
Definition: ncastatus.h:39
#define NCA_S_FAULT_INVALID_BOUND
Definition: ncastatus.h:40
#define NCA_S_PROTO_ERROR
Definition: ncastatus.h:28
#define NCA_S_FAULT_PIPE_ORDER
Definition: ncastatus.h:54
#define STATUS_FLOAT_UNDERFLOW
Definition: ntstatus.h:383
#define STATUS_FLOAT_OVERFLOW
Definition: ntstatus.h:381
#define STATUS_FLOAT_DIVIDE_BY_ZERO
Definition: ntstatus.h:378
#define STATUS_FLOAT_INVALID_OPERATION
Definition: ntstatus.h:380
#define STATUS_INTEGER_OVERFLOW
Definition: ntstatus.h:385
#define STATUS_INTEGER_DIVIDE_BY_ZERO
Definition: ntstatus.h:384
#define LOWORD(l)
Definition: pedump.c:82
long LONG
Definition: pedump.c:60
#define ISC_REQ_CONFIDENTIALITY
Definition: sspi.h:366
LONG SECURITY_STATUS
Definition: sspi.h:34
#define SecIsValidHandle(x)
Definition: sspi.h:63
#define ASC_REQ_CONNECTION
Definition: sspi.h:435
#define ASC_REQ_DELEGATE
Definition: sspi.h:426
#define ASC_REQ_CONFIDENTIALITY
Definition: sspi.h:430
#define SECBUFFER_TOKEN
Definition: sspi.h:161
#define SECURITY_NETWORK_DREP
Definition: sspi.h:474
#define ISC_REQ_INTEGRITY
Definition: sspi.h:378
#define ISC_REQ_DELEGATE
Definition: sspi.h:362
#define SECBUFFER_DATA
Definition: sspi.h:160
#define SECBUFFER_READONLY_WITH_CHECKSUM
Definition: sspi.h:177
#define ASC_REQ_USE_DCE_STYLE
Definition: sspi.h:433
#define SECPKG_ATTR_SIZES
Definition: sspi.h:521
#define ISC_REQ_MUTUAL_AUTH
Definition: sspi.h:363
#define ASC_REQ_INTEGRITY
Definition: sspi.h:440
#define SecInvalidateHandle(x)
Definition: sspi.h:58
#define SECBUFFER_VERSION
Definition: sspi.h:187
#define ISC_REQ_CONNECTION
Definition: sspi.h:373
#define ISC_REQ_USE_DCE_STYLE
Definition: sspi.h:371
static FILE * out
Definition: regtests2xml.c:44
RPC_STATUS RpcAuthInfo_Create(ULONG AuthnLevel, ULONG AuthnSvc, CredHandle cred, TimeStamp exp, ULONG cbMaxToken, RPC_AUTH_IDENTITY_HANDLE identity, RpcAuthInfo **ret)
Definition: rpc_binding.c:1117
void RPCRT4_AddRefBinding(RpcBinding *Binding)
Definition: rpc_binding.c:249
RPC_STATUS RPCRT4_CloseBinding(RpcBinding *Binding, RpcConnection *Connection)
Definition: rpc_binding.c:293
ULONG RpcAuthInfo_Release(RpcAuthInfo *AuthInfo)
Definition: rpc_binding.c:1188
RPC_STATUS RPCRT4_ReleaseBinding(RpcBinding *Binding)
Definition: rpc_binding.c:254
RPC_STATUS RPCRT4_OpenBinding(RpcBinding *Binding, RpcConnection **Connection, const RPC_SYNTAX_IDENTIFIER *TransferSyntax, const RPC_SYNTAX_IDENTIFIER *InterfaceId, BOOL *from_cache)
Definition: rpc_binding.c:272
static RPC_STATUS rpcrt4_conn_secure_packet(RpcConnection *conn, enum secure_packet_direction dir, RpcPktHdr *hdr, unsigned int hdr_size, unsigned char *stub_data, unsigned int stub_data_size, RpcAuthVerifier *auth_hdr, unsigned char *auth_value, unsigned int auth_value_size)
Definition: rpc_binding.h:232
static int rpcrt4_conn_read(RpcConnection *Connection, void *buffer, unsigned int len)
Definition: rpc_binding.h:188
static int rpcrt4_conn_write(RpcConnection *Connection, const void *buffer, unsigned int len)
Definition: rpc_binding.h:194
secure_packet_direction
Definition: rpc_binding.h:31
@ SECURE_PACKET_SEND
Definition: rpc_binding.h:32
@ SECURE_PACKET_RECEIVE
Definition: rpc_binding.h:33
void RPCRT4_ReleaseConnection(RpcConnection *Connection) DECLSPEC_HIDDEN
static RPC_STATUS rpcrt4_conn_authorize(RpcConnection *conn, BOOL first_time, unsigned char *in_buffer, unsigned int in_len, unsigned char *out_buffer, unsigned int *out_len)
Definition: rpc_binding.h:225
#define RPCRT4_strdupW(x)
Definition: rpc_binding.h:152
static BOOL rpcrt4_conn_is_authorized(RpcConnection *Connection)
Definition: rpc_binding.h:220
void RPCRT4_SetThreadCurrentConnection(RpcConnection *Connection) DECLSPEC_HIDDEN
Definition: rpcrt4_main.c:954
#define RPC_VER_MAJOR
Definition: rpc_defs.h:176
#define RPC_FLG_LAST
Definition: rpc_defs.h:180
#define RPC_FLG_FIRST
Definition: rpc_defs.h:179
@ PKT_FAULT
Definition: rpc_defs.h:191
@ PKT_REQUEST
Definition: rpc_defs.h:188
@ PKT_RESPONSE
Definition: rpc_defs.h:190
@ PKT_BIND_NACK
Definition: rpc_defs.h:201
@ PKT_ALTER_CONTEXT
Definition: rpc_defs.h:202
@ PKT_BIND
Definition: rpc_defs.h:199
@ PKT_ALTER_CONTEXT_RESP
Definition: rpc_defs.h:203
@ PKT_SHUTDOWN
Definition: rpc_defs.h:205
@ PKT_AUTH3
Definition: rpc_defs.h:204
@ PKT_HTTP
Definition: rpc_defs.h:208
@ PKT_BIND_ACK
Definition: rpc_defs.h:200
#define RPC_AUTH_VERIFIER_LEN(common_hdr)
Definition: rpc_defs.h:173
#define RPC_VER_MINOR
Definition: rpc_defs.h:177
#define RPC_FLG_OBJECT_UUID
Definition: rpc_defs.h:181
RPC_STATUS WINAPI RpcEpResolveBinding(RPC_BINDING_HANDLE Binding, RPC_IF_HANDLE IfSpec)
Definition: rpc_epmap.c:431
RPC_STATUS WINAPI I_RpcGetBuffer(PRPC_MESSAGE pMsg)
Definition: rpc_message.c:1638
RPC_STATUS RPCRT4_ReceiveWithAuth(RpcConnection *Connection, RpcPktHdr **Header, PRPC_MESSAGE pMsg, unsigned char **auth_data_out, ULONG *auth_length_out)
Definition: rpc_message.c:1376
RPC_STATUS WINAPI I_RpcSend(PRPC_MESSAGE pMsg)
Definition: rpc_message.c:1790
#define WRITE_HTTP_PAYLOAD_FIELD_UUID(payload, type, uuid)
Definition: rpc_message.c:324
static RPC_STATUS RPCRT4_default_receive_fragment(RpcConnection *Connection, RpcPktHdr **Header, void **Payload)
Definition: rpc_message.c:1288
VOID RPCRT4_FreeHeader(RpcPktHdr *Header)
Definition: rpc_message.c:403
RpcPktHdr * RPCRT4_BuildFaultHeader(ULONG DataRepresentation, RPC_STATUS Status)
Definition: rpc_message.c:170
BOOL RPCRT4_IsValidHttpPacket(RpcPktHdr *hdr, unsigned char *data, unsigned short data_len)
Definition: rpc_message.c:483
RPC_STATUS RPCRT4_default_authorize(RpcConnection *conn, BOOL first_time, unsigned char *in_buffer, unsigned int in_size, unsigned char *out_buffer, unsigned int *out_size)
Definition: rpc_message.c:872
static unsigned char * RPCRT4_NextHttpHeaderField(unsigned char *data)
Definition: rpc_message.c:535
RpcPktHdr * RPCRT4_BuildHttpHeader(ULONG DataRepresentation, unsigned short flags, unsigned short num_data_items, unsigned int payload_size)
Definition: rpc_message.c:291
static BOOL packet_does_auth_negotiation(const RpcPktHdr *Header)
Definition: rpc_message.c:93
static RpcPktHdr * RPCRT4_BuildRequestHeader(ULONG DataRepresentation, ULONG BufferLength, unsigned short ProcNum, UUID *ObjectUuid)
Definition: rpc_message.c:124
BOOL RPCRT4_default_is_authorized(RpcConnection *Connection)
Definition: rpc_message.c:1122
RPC_STATUS WINAPI I_RpcAsyncSetHandle(PRPC_MESSAGE pMsg, PRPC_ASYNC_STATE pAsync)
Definition: rpc_message.c:1949
RPC_STATUS WINAPI I_RpcNegotiateTransferSyntax(PRPC_MESSAGE pMsg)
Definition: rpc_message.c:1574
#define GET_HTTP_PAYLOAD_FIELD_DATA(data)
Definition: rpc_message.c:563
RPC_STATUS WINAPI I_RpcAsyncAbortCall(PRPC_ASYNC_STATE pAsync, ULONG ExceptionCode)
Definition: rpc_message.c:1977
RpcPktHdr * RPCRT4_BuildBindHeader(ULONG DataRepresentation, unsigned short MaxTransmissionSize, unsigned short MaxReceiveSize, ULONG AssocGroupId, const RPC_SYNTAX_IDENTIFIER *AbstractId, const RPC_SYNTAX_IDENTIFIER *TransferId)
Definition: rpc_message.c:186
RPC_STATUS WINAPI I_RpcReceive(PRPC_MESSAGE pMsg)
Definition: rpc_message.c:1857
#define READ_HTTP_PAYLOAD_FIELD_TYPE(data)
Definition: rpc_message.c:562
RPC_STATUS RPCRT4_ValidateCommonHeader(const RpcPktCommonHdr *hdr)
Definition: rpc_message.c:1255
RpcPktHdr * RPCRT4_BuildBindAckHeader(ULONG DataRepresentation, unsigned short MaxTransmissionSize, unsigned short MaxReceiveSize, ULONG AssocGroupId, LPCSTR ServerAddress, unsigned char ResultCount, const RpcResult *Results)
Definition: rpc_message.c:253
RPC_STATUS RPCRT4_default_inquire_auth_client(RpcConnection *conn, RPC_AUTHZ_HANDLE *privs, RPC_WSTR *server_princ_name, ULONG *authn_level, ULONG *authn_svc, ULONG *authz_svc, ULONG flags)
Definition: rpc_message.c:1189
#define WRITE_HTTP_PAYLOAD_FIELD_FLOW_CONTROL(payload, bytes_transmitted, flow_control_increment, uuid)
Definition: rpc_message.c:332
NCA_STATUS RPC2NCA_STATUS(RPC_STATUS status)
Definition: rpc_message.c:408
RPC_STATUS RPCRT4_ParseHttpFlowControlHeader(RpcPktHdr *header, unsigned char *data, BOOL server, ULONG *bytes_transmitted, ULONG *flow_control_increment, UUID *pipe_uuid)
Definition: rpc_message.c:637
#define ROUND_UP(value, alignment)
Definition: rpc_message.c:53
static BOOL packet_has_auth_verifier(const RpcPktHdr *Header)
Definition: rpc_message.c:87
#define ROUND_UP_AMOUNT(value, alignment)
Definition: rpc_message.c:51
RPC_STATUS WINAPI I_RpcSendReceive(PRPC_MESSAGE pMsg)
Definition: rpc_message.c:1918
RpcPktHdr * RPCRT4_BuildBindNackHeader(ULONG DataRepresentation, unsigned char RpcVersion, unsigned char RpcVersionMinor, unsigned short RejectReason)
Definition: rpc_message.c:231
static DWORD WINAPI async_notifier_proc(LPVOID p)
Definition: rpc_message.c:1725
static RPC_STATUS I_RpcReAllocateBuffer(PRPC_MESSAGE pMsg)
Definition: rpc_message.c:1672
DWORD RPCRT4_GetHeaderSize(const RpcPktHdr *Header)
Definition: rpc_message.c:57
RPC_STATUS WINAPI I_RpcFreeBuffer(PRPC_MESSAGE pMsg)
Definition: rpc_message.c:1696
RPC_STATUS RPCRT4_default_revert_to_self(RpcConnection *conn)
Definition: rpc_message.c:1159
RPC_STATUS RPCRT4_ParseHttpPrepareHeader2(RpcPktHdr *header, unsigned char *data, ULONG *field1, ULONG *bytes_until_next_packet, ULONG *field3)
Definition: rpc_message.c:591
static void CALLBACK async_apc_notifier_proc(ULONG_PTR ulParam)
Definition: rpc_message.c:1719
#define WRITE_HTTP_PAYLOAD_FIELD_UINT32(payload, type, value)
Definition: rpc_message.c:316
static RPC_STATUS RPCRT4_receive_fragment(RpcConnection *Connection, RpcPktHdr **Header, void **Payload)
Definition: rpc_message.c:1362
RPC_STATUS RPCRT4_Send(RpcConnection *Connection, RpcPktHdr *Header, void *Buffer, unsigned int BufferLength)
Definition: rpc_message.c:1223
RPC_STATUS RPCRT4_ClientConnectionAuth(RpcConnection *conn, BYTE *challenge, ULONG count)
Definition: rpc_message.c:992
RpcPktHdr * RPCRT4_BuildResponseHeader(ULONG DataRepresentation, ULONG BufferLength)
Definition: rpc_message.c:154
RPC_STATUS RPCRT4_default_secure_packet(RpcConnection *Connection, enum secure_packet_direction dir, RpcPktHdr *hdr, unsigned int hdr_size, unsigned char *stub_data, unsigned int stub_data_size, RpcAuthVerifier *auth_hdr, unsigned char *auth_value, unsigned int auth_value_size)
Definition: rpc_message.c:682
RPC_STATUS RPCRT4_ServerConnectionAuth(RpcConnection *conn, BOOL start, RpcAuthVerifier *auth_data_in, ULONG auth_length_in, unsigned char **auth_data_out, ULONG *auth_length_out)
Definition: rpc_message.c:1025
static BOOL packet_has_body(const RpcPktHdr *Header)
Definition: rpc_message.c:80
RPC_STATUS RPCRT4_ParseHttpPrepareHeader1(RpcPktHdr *header, unsigned char *data, ULONG *field1)
Definition: rpc_message.c:566
static RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header, PRPC_MESSAGE pMsg)
Definition: rpc_message.c:1554
static RpcPktHdr * RPCRT4_BuildAuthHeader(ULONG DataRepresentation)
Definition: rpc_message.c:216
static VOID RPCRT4_BuildCommonHeader(RpcPktHdr *Header, unsigned char PacketType, ULONG DataRepresentation)
Definition: rpc_message.c:108
RpcPktHdr * RPCRT4_BuildHttpConnectHeader(int out_pipe, const UUID *connection_uuid, const UUID *pipe_uuid, const UUID *association_uuid)
Definition: rpc_message.c:344
RpcPktHdr * RPCRT4_BuildHttpFlowControlHeader(BOOL server, ULONG bytes_transmitted, ULONG flow_control_increment, const UUID *pipe_uuid)
Definition: rpc_message.c:384
static RPC_STATUS NCA2RPC_STATUS(NCA_STATUS status)
Definition: rpc_message.c:441
static BOOL is_hard_error(RPC_STATUS status)
Definition: rpc_message.c:1837
RPC_STATUS RPCRT4_SendWithAuth(RpcConnection *Connection, RpcPktHdr *Header, void *Buffer, unsigned int BufferLength, const void *Auth, unsigned int AuthLength)
Definition: rpc_message.c:761
RPC_STATUS RPCRT4_default_impersonate_client(RpcConnection *conn)
Definition: rpc_message.c:1131
#define AUTH_ALIGNMENT
Definition: rpc_message.c:48
unsigned int NCA_STATUS
Definition: rpc_message.h:26
RPC_STATUS RPCRT4_ServerGetRegisteredAuthInfo(USHORT auth_type, CredHandle *cred, TimeStamp *exp, ULONG *max_token) DECLSPEC_HIDDEN
Definition: rpc_server.c:1365
@ RpcNotificationTypeIoc
Definition: rpcasync.h:99
@ RpcNotificationTypeHwnd
Definition: rpcasync.h:100
@ RpcNotificationTypeApc
Definition: rpcasync.h:98
@ RpcNotificationTypeEvent
Definition: rpcasync.h:97
@ RpcNotificationTypeNone
Definition: rpcasync.h:96
@ RpcNotificationTypeCallback
Definition: rpcasync.h:101
@ RpcCallComplete
Definition: rpcasync.h:106
unsigned short * RPC_WSTR
Definition: rpcdce.h:46
#define RPC_C_AUTHZ_NONE
Definition: rpcdce.h:167
#define RPC_C_AUTHN_LEVEL_PKT_PRIVACY
Definition: rpcdce.h:151
#define RPC_C_AUTHN_LEVEL_NONE
Definition: rpcdce.h:146
#define RPC_C_AUTHN_LEVEL_PKT_INTEGRITY
Definition: rpcdce.h:150
#define RPC_BUFFER_ASYNC
Definition: rpcdcep.h:70
#define RPC_FLAGS_VALID_BIT
Definition: rpcdcep.h:52
#define NDR_LOCAL_DATA_REPRESENTATION
Definition: rpcndr.h:107
#define RPC_S_OK
Definition: rpcnterr.h:22
int WINAPI UuidIsNil(UUID *Uuid, RPC_STATUS *Status)
Definition: rpcrt4_main.c:268
void WINAPI I_RpcFree(void *Object)
Definition: rpcrt4_main.c:724
void *WINAPI I_RpcAllocate(unsigned int Size)
Definition: rpcrt4_main.c:716
long RPC_STATUS
Definition: rpc.h:52
INT WSAAPI bind(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen)
Definition: socklife.c:36
#define TRACE(s)
Definition: solgame.cpp:4
unsigned short length
Definition: rpc_defs.h:91
char string[ANYSIZE_ARRAY]
Definition: rpc_defs.h:92
unsigned char auth_type
Definition: rpc_defs.h:165
unsigned char auth_pad_length
Definition: rpc_defs.h:167
unsigned char auth_reserved
Definition: rpc_defs.h:168
unsigned char auth_level
Definition: rpc_defs.h:166
unsigned int auth_context_id
Definition: rpc_defs.h:169
RPC_SYNTAX_IDENTIFIER transfer_syntaxes[ANYSIZE_ARRAY]
Definition: rpc_defs.h:72
RPC_SYNTAX_IDENTIFIER abstract_syntax
Definition: rpc_defs.h:71
unsigned char num_syntaxes
Definition: rpc_defs.h:69
unsigned char flags
Definition: rpc_defs.h:31
unsigned short auth_len
Definition: rpc_defs.h:34
unsigned short frag_len
Definition: rpc_defs.h:33
RPC_SYNTAX_IDENTIFIER InterfaceId
Definition: rpcdcep.h:117
RPC_SYNTAX_IDENTIFIER TransferSyntax
Definition: rpcdcep.h:118
unsigned int BufferLength
Definition: rpcdcep.h:41
unsigned int ProcNum
Definition: rpcdcep.h:42
void * RpcInterfaceInformation
Definition: rpcdcep.h:44
void * Buffer
Definition: rpcdcep.h:40
ULONG DataRepresentation
Definition: rpcdcep.h:39
void * ReservedForRuntime
Definition: rpcdcep.h:45
RPC_BINDING_HANDLE Handle
Definition: rpcdcep.h:38
ULONG RpcFlags
Definition: rpcdcep.h:48
ULONG AuthnLevel
Definition: rpc_binding.h:40
ULONG AuthnSvc
Definition: rpc_binding.h:41
CredHandle cred
Definition: rpc_binding.h:42
ULONG cbMaxToken
Definition: rpc_binding.h:44
LPWSTR server_principal_name
Definition: rpc_binding.h:50
TimeStamp exp
Definition: rpc_binding.h:75
RpcAuthInfo * AuthInfo
Definition: rpc_binding.h:77
USHORT NextCallId
Definition: rpc_binding.h:93
USHORT MaxTransmissionSize
Definition: rpc_binding.h:71
ULONG signature_auth_len
Definition: rpc_binding.h:80
RPC_ASYNC_STATE * async_state
Definition: rpc_binding.h:87
const struct connection_ops * ops
Definition: rpc_binding.h:70
ULONG encryption_auth_len
Definition: rpc_binding.h:79
CtxtHandle ctx
Definition: rpc_binding.h:74
ULONG auth_context_id
Definition: rpc_binding.h:78
ULONG cBuffers
Definition: sspi.h:182
ULONG ulVersion
Definition: sspi.h:181
ULONG cbSecurityTrailer
Definition: sspi.h:564
ULONG cbMaxSignature
Definition: sspi.h:562
Definition: tftpd.h:60
Definition: ps.c:97
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
uint32_t ULONG_PTR
Definition: typedefs.h:65
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define HIWORD(l)
Definition: typedefs.h:247
RpcPktCommonHdr common
Definition: rpc_defs.h:152
static rfbScreenInfoPtr server
Definition: vnc.c:74
int ret
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3771
#define WINAPI
Definition: msvc.h:6
#define RPC_S_SERVER_TOO_BUSY
Definition: winerror.h:1034
#define SEC_E_OK
Definition: winerror.h:2356
#define RPC_S_OUT_OF_RESOURCES
Definition: winerror.h:1032
#define RPC_S_CALL_FAILED_DNE
Definition: winerror.h:1038
#define RPC_S_ADDRESS_ERROR
Definition: winerror.h:1076
#define RPC_X_SS_HANDLES_MISMATCH
Definition: winerror.h:1085
#define RPC_X_WRONG_PIPE_ORDER
Definition: winerror.h:1138
#define RPC_S_INVALID_BOUND
Definition: winerror.h:1043
#define RPC_S_CALL_FAILED
Definition: winerror.h:1037
#define RPC_S_INVALID_TAG
Definition: winerror.h:1042
#define RPC_S_FP_DIV_ZERO
Definition: winerror.h:1077
#define RPC_X_PIPE_DISCIPLINE_ERROR
Definition: winerror.h:1159
#define RPC_S_UNSUPPORTED_TYPE
Definition: winerror.h:1041
#define RPC_S_UNKNOWN_IF
Definition: winerror.h:1028
#define RPC_S_BINDING_HAS_NO_AUTH
Definition: winerror.h:1054
#define SEC_E_NO_IMPERSONATION
Definition: winerror.h:2920
#define RPC_S_CANNOT_SUPPORT
Definition: winerror.h:1072
#define RPC_S_INVALID_ASYNC_HANDLE
Definition: winerror.h:1156
#define RPC_S_FP_UNDERFLOW
Definition: winerror.h:1078
#define SEC_E_UNSUPPORTED_FUNCTION
Definition: winerror.h:2911
#define RPC_S_CALL_CANCELLED
Definition: winerror.h:1125
#define RPC_S_PROTOCOL_ERROR
Definition: winerror.h:1039
#define SEC_I_COMPLETE_NEEDED
Definition: winerror.h:2928
#define RPC_X_PIPE_CLOSED
Definition: winerror.h:1158
#define RPC_S_ZERO_DIVIDE
Definition: winerror.h:1075
#define RPC_X_PIPE_EMPTY
Definition: winerror.h:1160
#define RPC_S_NO_CONTEXT_AVAILABLE
Definition: winerror.h:1073
#define RPC_S_NOT_LISTENING
Definition: winerror.h:1026
#define SEC_I_CONTINUE_NEEDED
Definition: winerror.h:2927
#define SEC_I_COMPLETE_AND_CONTINUE
Definition: winerror.h:2929
#define RPC_S_SEC_PKG_ERROR
Definition: winerror.h:1132
#define RPC_S_INTERFACE_NOT_FOUND
Definition: winerror.h:1067
#define RPC_S_INVALID_BINDING
Definition: winerror.h:1013
#define RPC_S_COMM_FAILURE
Definition: winerror.h:1127
#define RPC_S_PROCNUM_OUT_OF_RANGE
Definition: winerror.h:1053
#define RPC_S_FP_OVERFLOW
Definition: winerror.h:1079
#define ERROR_NOT_ENOUGH_SERVER_MEMORY
Definition: winerror.h:666
#define WT_EXECUTELONGFUNCTION
Definition: winnt_old.h:1043
#define WT_EXECUTEDEFAULT
Definition: winnt_old.h:1038
BOOL WINAPI PostMessageW(_In_opt_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
SECURITY_STATUS WINAPI EncryptMessage(PCtxtHandle phContext, ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo)
Definition: wrapper.c:1006
SECURITY_STATUS WINAPI MakeSignature(PCtxtHandle phContext, ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo)
Definition: wrapper.c:623
SECURITY_STATUS WINAPI InitializeSecurityContextW(PCredHandle phCredential, PCtxtHandle phContext, SEC_WCHAR *pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext, PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
Definition: wrapper.c:301
SECURITY_STATUS WINAPI CompleteAuthToken(PCtxtHandle phContext, PSecBufferDesc pToken)
Definition: wrapper.c:420
SECURITY_STATUS WINAPI DecryptMessage(PCtxtHandle phContext, PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP)
Definition: wrapper.c:1036
SECURITY_STATUS WINAPI VerifySignature(PCtxtHandle phContext, PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP)
Definition: wrapper.c:653
SECURITY_STATUS WINAPI QueryContextAttributesA(PCtxtHandle phContext, ULONG ulAttribute, void *pBuffer)
Definition: wrapper.c:505
SECURITY_STATUS WINAPI AcceptSecurityContext(PCredHandle phCredential, PCtxtHandle phContext, PSecBufferDesc pInput, ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext, PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
Definition: wrapper.c:365
SECURITY_STATUS WINAPI DeleteSecurityContext(PCtxtHandle phContext)
Definition: wrapper.c:450
SECURITY_STATUS WINAPI ImpersonateSecurityContext(PCtxtHandle phContext)
Definition: wrapper.c:565
SECURITY_STATUS WINAPI FreeCredentialsHandle(PCredHandle phCredential)
Definition: wrapper.c:151
SECURITY_STATUS WINAPI RevertSecurityContext(PCtxtHandle phContext)
Definition: wrapper.c:594
const char * LPCSTR
Definition: xmlstorage.h:183
unsigned char BYTE
Definition: xxhash.c:193