1 use core::mem::size_of;
2 use crate::ntapi_base::{CLIENT_ID, CLIENT_ID64};
3 use winapi::ctypes::c_double;
4 use winapi::shared::basetsd::{PSIZE_T, SIZE_T, ULONG64, ULONG_PTR};
5 use winapi::shared::ntdef::{
6     BOOLEAN, CSHORT, HANDLE, LARGE_INTEGER, NTSTATUS, OBJ_CASE_INSENSITIVE, PHANDLE,
7     PLARGE_INTEGER, POBJECT_ATTRIBUTES, PULONG, PUNICODE_STRING, PVOID, ULONG, ULONGLONG,
8     UNICODE_STRING,
9 };
10 use winapi::um::winnt::{
11     ACCESS_MASK, PSECURITY_DESCRIPTOR, PSECURITY_QUALITY_OF_SERVICE, PSID, RTL_SRWLOCK,
12     SECURITY_QUALITY_OF_SERVICE, STANDARD_RIGHTS_REQUIRED, SYNCHRONIZE,
13 };
14 pub const PORT_CONNECT: u32 = 0x0001;
15 pub const PORT_ALL_ACCESS: u32 = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1;
16 STRUCT!{struct PORT_MESSAGE_u1_s {
17     DataLength: CSHORT,
18     TotalLength: CSHORT,
19 }}
20 STRUCT!{struct PORT_MESSAGE_u2_s {
21     Type: CSHORT,
22     DataInfoOffset: CSHORT,
23 }}
24 UNION!{union PORT_MESSAGE_u1 {
25     s: PORT_MESSAGE_u1_s,
26     Length: ULONG,
27 }}
28 UNION!{union PORT_MESSAGE_u2 {
29     s: PORT_MESSAGE_u2_s,
30     ZeroInit: ULONG,
31 }}
32 UNION!{union PORT_MESSAGE_u3 {
33     ClientId: CLIENT_ID,
34     DoNotUseThisField: c_double,
35 }}
36 UNION!{union PORT_MESSAGE_u4 {
37     ClientViewSize: SIZE_T,
38     CallbackId: ULONG,
39 }}
40 STRUCT!{struct PORT_MESSAGE {
41     u1: PORT_MESSAGE_u1,
42     u2: PORT_MESSAGE_u2,
43     u3: PORT_MESSAGE_u3,
44     MessageId: ULONG,
45     u4: PORT_MESSAGE_u4,
46 }}
47 pub type PPORT_MESSAGE = *mut PORT_MESSAGE;
48 STRUCT!{struct PORT_DATA_ENTRY {
49     Base: PVOID,
50     Size: ULONG,
51 }}
52 pub type PPORT_DATA_ENTRY = *mut PORT_DATA_ENTRY;
53 STRUCT!{struct PORT_DATA_INFORMATION {
54     CountDataEntries: ULONG,
55     DataEntries: [PORT_DATA_ENTRY; 1],
56 }}
57 pub type PPORT_DATA_INFORMATION = *mut PORT_DATA_INFORMATION;
58 pub const LPC_REQUEST: ULONG = 1;
59 pub const LPC_REPLY: ULONG = 2;
60 pub const LPC_DATAGRAM: ULONG = 3;
61 pub const LPC_LOST_REPLY: ULONG = 4;
62 pub const LPC_PORT_CLOSED: ULONG = 5;
63 pub const LPC_CLIENT_DIED: ULONG = 6;
64 pub const LPC_EXCEPTION: ULONG = 7;
65 pub const LPC_DEBUG_EVENT: ULONG = 8;
66 pub const LPC_ERROR_EVENT: ULONG = 9;
67 pub const LPC_CONNECTION_REQUEST: ULONG = 10;
68 pub const LPC_KERNELMODE_MESSAGE: CSHORT = 0x8000;
69 pub const LPC_NO_IMPERSONATE: CSHORT = 0x4000;
70 pub const PORT_VALID_OBJECT_ATTRIBUTES: u32 = OBJ_CASE_INSENSITIVE;
71 #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
72 pub const PORT_MAXIMUM_MESSAGE_LENGTH: u32 = 512;
73 #[cfg(target_arch = "x86")]
74 pub const PORT_MAXIMUM_MESSAGE_LENGTH: u32 = 256;
75 pub const LPC_MAX_CONNECTION_INFO_SIZE: u32 = 16 * size_of::<ULONG_PTR>() as u32;
76 pub const PORT_TOTAL_MAXIMUM_MESSAGE_LENGTH: u32 = (PORT_MAXIMUM_MESSAGE_LENGTH
77     + size_of::<PORT_MESSAGE>() as u32
78     + LPC_MAX_CONNECTION_INFO_SIZE
79     + 0xf) & !0xf;
80 STRUCT!{struct LPC_CLIENT_DIED_MSG {
81     PortMsg: PORT_MESSAGE,
82     CreateTime: LARGE_INTEGER,
83 }}
84 pub type PLPC_CLIENT_DIED_MSG = *mut LPC_CLIENT_DIED_MSG;
85 STRUCT!{struct PORT_VIEW {
86     Length: ULONG,
87     SectionHandle: HANDLE,
88     SectionOffset: ULONG,
89     ViewSize: SIZE_T,
90     ViewBase: PVOID,
91     ViewRemoteBase: PVOID,
92 }}
93 pub type PPORT_VIEW = *mut PORT_VIEW;
94 STRUCT!{struct REMOTE_PORT_VIEW {
95     Length: ULONG,
96     ViewSize: SIZE_T,
97     ViewBase: PVOID,
98 }}
99 pub type PREMOTE_PORT_VIEW = *mut REMOTE_PORT_VIEW;
100 STRUCT!{struct PORT_MESSAGE64_u1_s {
101     DataLength: CSHORT,
102     TotalLength: CSHORT,
103 }}
104 STRUCT!{struct PORT_MESSAGE64_u2_s {
105     Type: CSHORT,
106     DataInfoOffset: CSHORT,
107 }}
108 UNION!{union PORT_MESSAGE64_u1 {
109     s: PORT_MESSAGE64_u1_s,
110     Length: ULONG,
111 }}
112 UNION!{union PORT_MESSAGE64_u2 {
113     s: PORT_MESSAGE64_u2_s,
114     ZeroInit: ULONG,
115 }}
116 UNION!{union PORT_MESSAGE64_u3 {
117     ClientId: CLIENT_ID64,
118     DoNotUseThisField: c_double,
119 }}
120 UNION!{union PORT_MESSAGE64_u4 {
121     ClientViewSize: ULONGLONG,
122     CallbackId: ULONG,
123 }}
124 STRUCT!{struct PORT_MESSAGE64 {
125     u1: PORT_MESSAGE64_u1,
126     u2: PORT_MESSAGE64_u2,
127     u3: PORT_MESSAGE64_u3,
128     MessageId: ULONG,
129     u4: PORT_MESSAGE64_u4,
130 }}
131 pub type PPORT_MESSAGE64 = *mut PORT_MESSAGE64;
132 STRUCT!{struct LPC_CLIENT_DIED_MSG64 {
133     PortMsg: PORT_MESSAGE64,
134     CreateTime: LARGE_INTEGER,
135 }}
136 pub type PLPC_CLIENT_DIED_MSG64 = *mut LPC_CLIENT_DIED_MSG64;
137 STRUCT!{struct PORT_VIEW64 {
138     Length: ULONG,
139     SectionHandle: ULONGLONG,
140     SectionOffset: ULONG,
141     ViewSize: ULONGLONG,
142     ViewBase: ULONGLONG,
143     ViewRemoteBase: ULONGLONG,
144 }}
145 pub type PPORT_VIEW64 = *mut PORT_VIEW64;
146 STRUCT!{struct REMOTE_PORT_VIEW64 {
147     Length: ULONG,
148     ViewSize: ULONGLONG,
149     ViewBase: ULONGLONG,
150 }}
151 pub type PREMOTE_PORT_VIEW64 = *mut REMOTE_PORT_VIEW64;
152 EXTERN!{extern "system" {
153     fn NtCreatePort(
154         PortHandle: PHANDLE,
155         ObjectAttributes: POBJECT_ATTRIBUTES,
156         MaxConnectionInfoLength: ULONG,
157         MaxMessageLength: ULONG,
158         MaxPoolUsage: ULONG,
159     ) -> NTSTATUS;
160     fn NtCreateWaitablePort(
161         PortHandle: PHANDLE,
162         ObjectAttributes: POBJECT_ATTRIBUTES,
163         MaxConnectionInfoLength: ULONG,
164         MaxMessageLength: ULONG,
165         MaxPoolUsage: ULONG,
166     ) -> NTSTATUS;
167     fn NtConnectPort(
168         PortHandle: PHANDLE,
169         PortName: PUNICODE_STRING,
170         SecurityQos: PSECURITY_QUALITY_OF_SERVICE,
171         ClientView: PPORT_VIEW,
172         ServerView: PREMOTE_PORT_VIEW,
173         MaxMessageLength: PULONG,
174         ConnectionInformation: PVOID,
175         ConnectionInformationLength: PULONG,
176     ) -> NTSTATUS;
177     fn NtSecureConnectPort(
178         PortHandle: PHANDLE,
179         PortName: PUNICODE_STRING,
180         SecurityQos: PSECURITY_QUALITY_OF_SERVICE,
181         ClientView: PPORT_VIEW,
182         RequiredServerSid: PSID,
183         ServerView: PREMOTE_PORT_VIEW,
184         MaxMessageLength: PULONG,
185         ConnectionInformation: PVOID,
186         ConnectionInformationLength: PULONG,
187     ) -> NTSTATUS;
188     fn NtListenPort(
189         PortHandle: HANDLE,
190         ConnectionRequest: PPORT_MESSAGE,
191     ) -> NTSTATUS;
192     fn NtAcceptConnectPort(
193         PortHandle: PHANDLE,
194         PortContext: PVOID,
195         ConnectionRequest: PPORT_MESSAGE,
196         AcceptConnection: BOOLEAN,
197         ServerView: PPORT_VIEW,
198         ClientView: PREMOTE_PORT_VIEW,
199     ) -> NTSTATUS;
200     fn NtCompleteConnectPort(
201         PortHandle: HANDLE,
202     ) -> NTSTATUS;
203     fn NtRequestPort(
204         PortHandle: HANDLE,
205         RequestMessage: PPORT_MESSAGE,
206     ) -> NTSTATUS;
207     fn NtRequestWaitReplyPort(
208         PortHandle: HANDLE,
209         RequestMessage: PPORT_MESSAGE,
210         ReplyMessage: PPORT_MESSAGE,
211     ) -> NTSTATUS;
212     fn NtReplyPort(
213         PortHandle: HANDLE,
214         ReplyMessage: PPORT_MESSAGE,
215     ) -> NTSTATUS;
216     fn NtReplyWaitReplyPort(
217         PortHandle: HANDLE,
218         ReplyMessage: PPORT_MESSAGE,
219     ) -> NTSTATUS;
220     fn NtReplyWaitReceivePort(
221         PortHandle: HANDLE,
222         PortContext: *mut PVOID,
223         ReplyMessage: PPORT_MESSAGE,
224         ReceiveMessage: PPORT_MESSAGE,
225     ) -> NTSTATUS;
226     fn NtReplyWaitReceivePortEx(
227         PortHandle: HANDLE,
228         PortContext: *mut PVOID,
229         ReplyMessage: PPORT_MESSAGE,
230         ReceiveMessage: PPORT_MESSAGE,
231         Timeout: PLARGE_INTEGER,
232     ) -> NTSTATUS;
233     fn NtImpersonateClientOfPort(
234         PortHandle: HANDLE,
235         Message: PPORT_MESSAGE,
236     ) -> NTSTATUS;
237     fn NtReadRequestData(
238         PortHandle: HANDLE,
239         Message: PPORT_MESSAGE,
240         DataEntryIndex: ULONG,
241         Buffer: PVOID,
242         BufferSize: SIZE_T,
243         NumberOfBytesRead: PSIZE_T,
244     ) -> NTSTATUS;
245     fn NtWriteRequestData(
246         PortHandle: HANDLE,
247         Message: PPORT_MESSAGE,
248         DataEntryIndex: ULONG,
249         Buffer: PVOID,
250         BufferSize: SIZE_T,
251         NumberOfBytesWritten: PSIZE_T,
252     ) -> NTSTATUS;
253 }}
254 ENUM!{enum PORT_INFORMATION_CLASS {
255     PortBasicInformation = 0,
256     PortDumpInformation = 1,
257 }}
258 EXTERN!{extern "system" {
259     fn NtQueryInformationPort(
260         PortHandle: HANDLE,
261         PortInformationClass: PORT_INFORMATION_CLASS,
262         PortInformation: PVOID,
263         Length: ULONG,
264         ReturnLength: PULONG,
265     ) -> NTSTATUS;
266 }}
267 pub type PALPC_HANDLE = *mut HANDLE;
268 pub type ALPC_HANDLE = HANDLE;
269 pub const ALPC_PORFLG_ALLOW_LPC_REQUESTS: ULONG = 0x20000;
270 pub const ALPC_PORFLG_WAITABLE_PORT: ULONG = 0x40000;
271 pub const ALPC_PORFLG_SYSTEM_PROCESS: ULONG = 0x100000;
272 #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
273 STRUCT!{struct ALPC_PORT_ATTRIBUTES {
274     Flags: ULONG,
275     SecurityQos: SECURITY_QUALITY_OF_SERVICE,
276     MaxMessageLength: SIZE_T,
277     MemoryBandwidth: SIZE_T,
278     MaxPoolUsage: SIZE_T,
279     MaxSectionSize: SIZE_T,
280     MaxViewSize: SIZE_T,
281     MaxTotalSectionSize: SIZE_T,
282     DupObjectTypes: ULONG,
283     Reserved: ULONG,
284 }}
285 #[cfg(target_arch = "x86")]
286 STRUCT!{struct ALPC_PORT_ATTRIBUTES {
287     Flags: ULONG,
288     SecurityQos: SECURITY_QUALITY_OF_SERVICE,
289     MaxMessageLength: SIZE_T,
290     MemoryBandwidth: SIZE_T,
291     MaxPoolUsage: SIZE_T,
292     MaxSectionSize: SIZE_T,
293     MaxViewSize: SIZE_T,
294     MaxTotalSectionSize: SIZE_T,
295     DupObjectTypes: ULONG,
296 }}
297 pub type PALPC_PORT_ATTRIBUTES = *mut ALPC_PORT_ATTRIBUTES;
298 pub const ALPC_MESSAGE_SECURITY_ATTRIBUTE: ULONG = 0x80000000;
299 pub const ALPC_MESSAGE_VIEW_ATTRIBUTE: ULONG = 0x40000000;
300 pub const ALPC_MESSAGE_CONTEXT_ATTRIBUTE: ULONG = 0x20000000;
301 pub const ALPC_MESSAGE_HANDLE_ATTRIBUTE: ULONG = 0x10000000;
302 STRUCT!{struct ALPC_MESSAGE_ATTRIBUTES {
303     AllocatedAttributes: ULONG,
304     ValidAttributes: ULONG,
305 }}
306 pub type PALPC_MESSAGE_ATTRIBUTES = *mut ALPC_MESSAGE_ATTRIBUTES;
307 STRUCT!{struct ALPC_COMPLETION_LIST_STATE {
308     Value: ULONG64,
309 }}
310 BITFIELD!{ALPC_COMPLETION_LIST_STATE Value: ULONG64 [
311     Head set_Head[0..24],
312     Tail set_Tail[24..48],
313     ActiveThreadCount set_ActiveThreadCount[48..64],
314 ]}
315 pub type PALPC_COMPLETION_LIST_STATE = *mut ALPC_COMPLETION_LIST_STATE;
316 pub const ALPC_COMPLETION_LIST_BUFFER_GRANULARITY_MASK: ULONG = 0x3f;
317 STRUCT!{#[repr(align(128))] struct ALPC_COMPLETION_LIST_HEADER {
318     StartMagic: ULONG64,
319     TotalSize: ULONG,
320     ListOffset: ULONG,
321     ListSize: ULONG,
322     BitmapOffset: ULONG,
323     BitmapSize: ULONG,
324     DataOffset: ULONG,
325     DataSize: ULONG,
326     AttributeFlags: ULONG,
327     AttributeSize: ULONG,
328     __padding0: [u64; 10],
329     State: ALPC_COMPLETION_LIST_STATE,
330     LastMessageId: ULONG,
331     LastCallbackId: ULONG,
332     __padding1: [u32; 28],
333     PostCount: ULONG,
334     __padding2: [u32; 31],
335     ReturnCount: ULONG,
336     __padding3: [u32; 31],
337     LogSequenceNumber: ULONG,
338     __padding4: [u64; 15],
339     UserLock: RTL_SRWLOCK,
340     EndMagic: ULONG64,
341     __padding5: [u64; 14],
342 }}
343 pub type PALPC_COMPLETION_LIST_HEADER = *mut ALPC_COMPLETION_LIST_HEADER;
344 STRUCT!{struct ALPC_CONTEXT_ATTR {
345     PortContext: PVOID,
346     MessageContext: PVOID,
347     Sequence: ULONG,
348     MessageId: ULONG,
349     CallbackId: ULONG,
350 }}
351 pub type PALPC_CONTEXT_ATTR = *mut ALPC_CONTEXT_ATTR;
352 pub const ALPC_HANDLEFLG_DUPLICATE_SAME_ACCESS: ULONG = 0x10000;
353 pub const ALPC_HANDLEFLG_DUPLICATE_SAME_ATTRIBUTES: ULONG = 0x20000;
354 pub const ALPC_HANDLEFLG_DUPLICATE_INHERIT: ULONG = 0x80000;
355 STRUCT!{struct ALPC_HANDLE_ATTR32 {
356     Flags: ULONG,
357     Reserved0: ULONG,
358     SameAccess: ULONG,
359     SameAttributes: ULONG,
360     Indirect: ULONG,
361     Inherit: ULONG,
362     Reserved1: ULONG,
363     Handle: ULONG,
364     ObjectType: ULONG,
365     DesiredAccess: ULONG,
366     GrantedAccess: ULONG,
367 }}
368 pub type PALPC_HANDLE_ATTR32 = *mut ALPC_HANDLE_ATTR32;
369 STRUCT!{struct ALPC_HANDLE_ATTR {
370     Flags: ULONG,
371     Reserved0: ULONG,
372     SameAccess: ULONG,
373     SameAttributes: ULONG,
374     Indirect: ULONG,
375     Inherit: ULONG,
376     Reserved1: ULONG,
377     Handle: HANDLE,
378     HandleAttrArray: PALPC_HANDLE_ATTR32,
379     ObjectType: ULONG,
380     HandleCount: ULONG,
381     DesiredAccess: ACCESS_MASK,
382     GrantedAccess: ACCESS_MASK,
383 }}
384 pub type PALPC_HANDLE_ATTR = *mut ALPC_HANDLE_ATTR;
385 pub const ALPC_SECFLG_CREATE_HANDLE: ULONG = 0x20000;
386 STRUCT!{struct ALPC_SECURITY_ATTR {
387     Flags: ULONG,
388     QoS: PSECURITY_QUALITY_OF_SERVICE,
389     ContextHandle: ALPC_HANDLE,
390 }}
391 pub type PALPC_SECURITY_ATTR = *mut ALPC_SECURITY_ATTR;
392 pub const ALPC_VIEWFLG_NOT_SECURE: ULONG = 0x40000;
393 STRUCT!{struct ALPC_DATA_VIEW_ATTR {
394     Flags: ULONG,
395     SectionHandle: ALPC_HANDLE,
396     ViewBase: PVOID,
397     ViewSize: SIZE_T,
398 }}
399 pub type PALPC_DATA_VIEW_ATTR = *mut ALPC_DATA_VIEW_ATTR;
400 ENUM!{enum ALPC_PORT_INFORMATION_CLASS {
401     AlpcBasicInformation = 0,
402     AlpcPortInformation = 1,
403     AlpcAssociateCompletionPortInformation = 2,
404     AlpcConnectedSIDInformation = 3,
405     AlpcServerInformation = 4,
406     AlpcMessageZoneInformation = 5,
407     AlpcRegisterCompletionListInformation = 6,
408     AlpcUnregisterCompletionListInformation = 7,
409     AlpcAdjustCompletionListConcurrencyCountInformation = 8,
410     AlpcRegisterCallbackInformation = 9,
411     AlpcCompletionListRundownInformation = 10,
412     AlpcWaitForPortReferences = 11,
413 }}
414 STRUCT!{struct ALPC_BASIC_INFORMATION {
415     Flags: ULONG,
416     SequenceNo: ULONG,
417     PortContext: PVOID,
418 }}
419 pub type PALPC_BASIC_INFORMATION = *mut ALPC_BASIC_INFORMATION;
420 STRUCT!{struct ALPC_PORT_ASSOCIATE_COMPLETION_PORT {
421     CompletionKey: PVOID,
422     CompletionPort: HANDLE,
423 }}
424 pub type PALPC_PORT_ASSOCIATE_COMPLETION_PORT = *mut ALPC_PORT_ASSOCIATE_COMPLETION_PORT;
425 STRUCT!{struct ALPC_SERVER_INFORMATION_Out {
426     ThreadBlocked: BOOLEAN,
427     ConnectedProcessId: HANDLE,
428     ConnectionPortName: UNICODE_STRING,
429 }}
430 UNION!{union ALPC_SERVER_INFORMATION {
431     ThreadHandle: HANDLE,
432     Out: ALPC_SERVER_INFORMATION_Out,
433 }}
434 pub type PALPC_SERVER_INFORMATION = *mut ALPC_SERVER_INFORMATION;
435 STRUCT!{struct ALPC_PORT_MESSAGE_ZONE_INFORMATION {
436     Buffer: PVOID,
437     Size: ULONG,
438 }}
439 pub type PALPC_PORT_MESSAGE_ZONE_INFORMATION = *mut ALPC_PORT_MESSAGE_ZONE_INFORMATION;
440 STRUCT!{struct ALPC_PORT_COMPLETION_LIST_INFORMATION {
441     Buffer: PVOID,
442     Size: ULONG,
443     ConcurrencyCount: ULONG,
444     AttributeFlags: ULONG,
445 }}
446 pub type PALPC_PORT_COMPLETION_LIST_INFORMATION = *mut ALPC_PORT_COMPLETION_LIST_INFORMATION;
447 ENUM!{enum ALPC_MESSAGE_INFORMATION_CLASS {
448     AlpcMessageSidInformation = 0,
449     AlpcMessageTokenModifiedIdInformation = 1,
450     AlpcMessageDirectStatusInformation = 2,
451     AlpcMessageHandleInformation = 3,
452     MaxAlpcMessageInfoClass = 4,
453 }}
454 pub type PALPC_MESSAGE_INFORMATION_CLASS = *mut ALPC_MESSAGE_INFORMATION_CLASS;
455 STRUCT!{struct ALPC_MESSAGE_HANDLE_INFORMATION {
456     Index: ULONG,
457     Flags: ULONG,
458     Handle: ULONG,
459     ObjectType: ULONG,
460     GrantedAccess: ACCESS_MASK,
461 }}
462 pub type PALPC_MESSAGE_HANDLE_INFORMATION = *mut ALPC_MESSAGE_HANDLE_INFORMATION;
463 EXTERN!{extern "system" {
464     fn NtAlpcCreatePort(
465         PortHandle: PHANDLE,
466         ObjectAttributes: POBJECT_ATTRIBUTES,
467         PortAttributes: PALPC_PORT_ATTRIBUTES,
468     ) -> NTSTATUS;
469     fn NtAlpcDisconnectPort(
470         PortHandle: HANDLE,
471         Flags: ULONG,
472     ) -> NTSTATUS;
473     fn NtAlpcQueryInformation(
474         PortHandle: HANDLE,
475         PortInformationClass: ALPC_PORT_INFORMATION_CLASS,
476         PortInformation: PVOID,
477         Length: ULONG,
478         ReturnLength: PULONG,
479     ) -> NTSTATUS;
480     fn NtAlpcSetInformation(
481         PortHandle: HANDLE,
482         PortInformationClass: ALPC_PORT_INFORMATION_CLASS,
483         PortInformation: PVOID,
484         Length: ULONG,
485     ) -> NTSTATUS;
486     fn NtAlpcCreatePortSection(
487         PortHandle: HANDLE,
488         Flags: ULONG,
489         SectionHandle: HANDLE,
490         SectionSize: SIZE_T,
491         AlpcSectionHandle: PALPC_HANDLE,
492         ActualSectionSize: PSIZE_T,
493     ) -> NTSTATUS;
494     fn NtAlpcDeletePortSection(
495         PortHandle: HANDLE,
496         Flags: ULONG,
497         SectionHandle: ALPC_HANDLE,
498     ) -> NTSTATUS;
499     fn NtAlpcCreateResourceReserve(
500         PortHandle: HANDLE,
501         Flags: ULONG,
502         MessageSize: SIZE_T,
503         ResourceId: PALPC_HANDLE,
504     ) -> NTSTATUS;
505     fn NtAlpcDeleteResourceReserve(
506         PortHandle: HANDLE,
507         Flags: ULONG,
508         ResourceId: ALPC_HANDLE,
509     ) -> NTSTATUS;
510     fn NtAlpcCreateSectionView(
511         PortHandle: HANDLE,
512         Flags: ULONG,
513         ViewAttributes: PALPC_DATA_VIEW_ATTR,
514     ) -> NTSTATUS;
515     fn NtAlpcDeleteSectionView(
516         PortHandle: HANDLE,
517         Flags: ULONG,
518         ViewBase: PVOID,
519     ) -> NTSTATUS;
520     fn NtAlpcCreateSecurityContext(
521         PortHandle: HANDLE,
522         Flags: ULONG,
523         SecurityAttribute: PALPC_SECURITY_ATTR,
524     ) -> NTSTATUS;
525     fn NtAlpcDeleteSecurityContext(
526         PortHandle: HANDLE,
527         Flags: ULONG,
528         ContextHandle: ALPC_HANDLE,
529     ) -> NTSTATUS;
530     fn NtAlpcRevokeSecurityContext(
531         PortHandle: HANDLE,
532         Flags: ULONG,
533         ContextHandle: ALPC_HANDLE,
534     ) -> NTSTATUS;
535     fn NtAlpcQueryInformationMessage(
536         PortHandle: HANDLE,
537         PortMessage: PPORT_MESSAGE,
538         MessageInformationClass: ALPC_MESSAGE_INFORMATION_CLASS,
539         MessageInformation: PVOID,
540         Length: ULONG,
541         ReturnLength: PULONG,
542     ) -> NTSTATUS;
543 }}
544 pub const ALPC_MSGFLG_REPLY_MESSAGE: ULONG = 0x1;
545 pub const ALPC_MSGFLG_LPC_MODE: ULONG = 0x2;
546 pub const ALPC_MSGFLG_RELEASE_MESSAGE: ULONG = 0x10000;
547 pub const ALPC_MSGFLG_SYNC_REQUEST: ULONG = 0x20000;
548 pub const ALPC_MSGFLG_WAIT_USER_MODE: ULONG = 0x100000;
549 pub const ALPC_MSGFLG_WAIT_ALERTABLE: ULONG = 0x200000;
550 pub const ALPC_MSGFLG_WOW64_CALL: ULONG = 0x80000000;
551 EXTERN!{extern "system" {
552     fn NtAlpcConnectPort(
553         PortHandle: PHANDLE,
554         PortName: PUNICODE_STRING,
555         ObjectAttributes: POBJECT_ATTRIBUTES,
556         PortAttributes: PALPC_PORT_ATTRIBUTES,
557         Flags: ULONG,
558         RequiredServerSid: PSID,
559         ConnectionMessage: PPORT_MESSAGE,
560         BufferLength: PULONG,
561         OutMessageAttributes: PALPC_MESSAGE_ATTRIBUTES,
562         InMessageAttributes: PALPC_MESSAGE_ATTRIBUTES,
563         Timeout: PLARGE_INTEGER,
564     ) -> NTSTATUS;
565     fn NtAlpcConnectPortEx(
566         PortHandle: PHANDLE,
567         ConnectionPortObjectAttributes: POBJECT_ATTRIBUTES,
568         ClientPortObjectAttributes: POBJECT_ATTRIBUTES,
569         PortAttributes: PALPC_PORT_ATTRIBUTES,
570         Flags: ULONG,
571         ServerSecurityRequirements: PSECURITY_DESCRIPTOR,
572         ConnectionMessage: PPORT_MESSAGE,
573         BufferLength: PSIZE_T,
574         OutMessageAttributes: PALPC_MESSAGE_ATTRIBUTES,
575         InMessageAttributes: PALPC_MESSAGE_ATTRIBUTES,
576         Timeout: PLARGE_INTEGER,
577     ) -> NTSTATUS;
578     fn NtAlpcAcceptConnectPort(
579         PortHandle: PHANDLE,
580         ConnectionPortHandle: HANDLE,
581         Flags: ULONG,
582         ObjectAttributes: POBJECT_ATTRIBUTES,
583         PortAttributes: PALPC_PORT_ATTRIBUTES,
584         PortContext: PVOID,
585         ConnectionRequest: PPORT_MESSAGE,
586         ConnectionMessageAttributes: PALPC_MESSAGE_ATTRIBUTES,
587         AcceptConnection: BOOLEAN,
588     ) -> NTSTATUS;
589     fn NtAlpcSendWaitReceivePort(
590         PortHandle: HANDLE,
591         Flags: ULONG,
592         SendMessageA: PPORT_MESSAGE,
593         SendMessageAttributes: PALPC_MESSAGE_ATTRIBUTES,
594         ReceiveMessage: PPORT_MESSAGE,
595         BufferLength: PSIZE_T,
596         ReceiveMessageAttributes: PALPC_MESSAGE_ATTRIBUTES,
597         Timeout: PLARGE_INTEGER,
598     ) -> NTSTATUS;
599 }}
600 pub const ALPC_CANCELFLG_TRY_CANCEL: ULONG = 0x1;
601 pub const ALPC_CANCELFLG_NO_CONTEXT_CHECK: ULONG = 0x8;
602 pub const ALPC_CANCELFLGP_FLUSH: ULONG = 0x10000;
603 EXTERN!{extern "system" {
604     fn NtAlpcCancelMessage(
605         PortHandle: HANDLE,
606         Flags: ULONG,
607         MessageContext: PALPC_CONTEXT_ATTR,
608     ) -> NTSTATUS;
609     fn NtAlpcImpersonateClientOfPort(
610         PortHandle: HANDLE,
611         Message: PPORT_MESSAGE,
612         Flags: PVOID,
613     ) -> NTSTATUS;
614     fn NtAlpcImpersonateClientContainerOfPort(
615         PortHandle: HANDLE,
616         Message: PPORT_MESSAGE,
617         Flags: ULONG,
618     ) -> NTSTATUS;
619     fn NtAlpcOpenSenderProcess(
620         ProcessHandle: PHANDLE,
621         PortHandle: HANDLE,
622         PortMessage: PPORT_MESSAGE,
623         Flags: ULONG,
624         DesiredAccess: ACCESS_MASK,
625         ObjectAttributes: POBJECT_ATTRIBUTES,
626     ) -> NTSTATUS;
627     fn NtAlpcOpenSenderThread(
628         ThreadHandle: PHANDLE,
629         PortHandle: HANDLE,
630         PortMessage: PPORT_MESSAGE,
631         Flags: ULONG,
632         DesiredAccess: ACCESS_MASK,
633         ObjectAttributes: POBJECT_ATTRIBUTES,
634     ) -> NTSTATUS;
635     fn AlpcMaxAllowedMessageLength() -> ULONG;
636     fn AlpcGetHeaderSize(
637         Flags: ULONG,
638     ) -> ULONG;
639     fn AlpcInitializeMessageAttribute(
640         AttributeFlags: ULONG,
641         Buffer: PALPC_MESSAGE_ATTRIBUTES,
642         BufferSize: ULONG,
643         RequiredBufferSize: PULONG,
644     ) -> NTSTATUS;
645     fn AlpcGetMessageAttribute(
646         Buffer: PALPC_MESSAGE_ATTRIBUTES,
647         AttributeFlag: ULONG,
648     ) -> PVOID;
649     fn AlpcRegisterCompletionList(
650         PortHandle: HANDLE,
651         Buffer: PALPC_COMPLETION_LIST_HEADER,
652         Size: ULONG,
653         ConcurrencyCount: ULONG,
654         AttributeFlags: ULONG,
655     ) -> NTSTATUS;
656     fn AlpcUnregisterCompletionList(
657         PortHandle: HANDLE,
658     ) -> NTSTATUS;
659     fn AlpcRundownCompletionList(
660         PortHandle: HANDLE,
661     ) -> NTSTATUS;
662     fn AlpcAdjustCompletionListConcurrencyCount(
663         PortHandle: HANDLE,
664         ConcurrencyCount: ULONG,
665     ) -> NTSTATUS;
666     fn AlpcRegisterCompletionListWorkerThread(
667         CompletionList: PVOID,
668     ) -> BOOLEAN;
669     fn AlpcUnregisterCompletionListWorkerThread(
670         CompletionList: PVOID,
671     ) -> BOOLEAN;
672     fn AlpcGetCompletionListLastMessageInformation(
673         CompletionList: PVOID,
674         LastMessageId: PULONG,
675         LastCallbackId: PULONG,
676     );
677     fn AlpcGetOutstandingCompletionListMessageCount(
678         CompletionList: PVOID,
679     ) -> ULONG;
680     fn AlpcGetMessageFromCompletionList(
681         CompletionList: PVOID,
682         MessageAttributes: *mut PALPC_MESSAGE_ATTRIBUTES,
683     ) -> PPORT_MESSAGE;
684     fn AlpcFreeCompletionListMessage(
685         CompletionList: PVOID,
686         Message: PPORT_MESSAGE,
687     );
688     fn AlpcGetCompletionListMessageAttributes(
689         CompletionList: PVOID,
690         Message: PPORT_MESSAGE,
691     ) -> PALPC_MESSAGE_ATTRIBUTES;
692 }}
693