1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
//! Corresponding header: `EndpointSecurity/ESMessage.h`
//!
//! Messages for an event are received when clients are subscribed to their related event, either
//! auth or notify.

// Types and methods should be added in the same order as they are in the original header to make
// maintenance easier.

use core::hash::Hash;
use core::mem::ManuallyDrop;
pub use std::os::raw::c_int;

#[cfg(feature = "macos_13_0_0")]
pub use libc::{cpu_subtype_t, cpu_type_t};
pub use libc::{dev_t, gid_t, mode_t, pid_t, stat, statfs, timespec, timeval, uid_t};
#[cfg(feature = "macos_14_0_0")]
use mach2::mach_types::uuid_t;
use objc2::{Encoding, RefEncode};

#[cfg(feature = "macos_10_15_4")]
use super::es_proc_check_type_t;
#[cfg(feature = "macos_10_15_1")]
use super::{acl_t, es_set_or_clear_t};
use super::{
    attrlist, audit_token_t, es_action_type_t, es_auth_result_t, es_event_id_t, es_event_type_t, es_result_type_t,
    es_string_token_t, es_token_t, user_addr_t, user_size_t, ShouldNotBeNull,
};
#[cfg(feature = "macos_13_0_0")]
use super::{es_address_type_t, es_authentication_type_t};
#[cfg(feature = "macos_14_0_0")]
use super::{
    es_authorization_rule_class_t, es_od_account_type_t, es_od_member_type_t, es_od_record_type_t, es_xpc_domain_type_t,
};

/// Provides the [`stat`][struct@stat] information and path to a file that relates to a security
/// event. The path may be truncated, which is indicated by the `path_truncated` flag.
///
/// For the FAT family of filesystems the `stat.st_ino` field is set to 999999999 for empty files.
///
/// For files with a link count greater than 1, the absolute path given may not be the only absolute
/// path that exists, and which hard link the emitted path points to is undefined.
///
/// Overlong paths are truncated at a maximum length that currently is 16K, though that number is
/// not considered API and may change at any time.
#[repr(C)]
pub struct es_file_t {
    /// Absolute path of the file
    pub path: es_string_token_t,
    /// Indicates if the `path` field was truncated
    pub path_truncated: bool,
    /// Informations about the file. See `man 2 stat` for details
    pub stat: stat,
}

/// Information related to a thread
#[cfg(feature = "macos_11_0_0")]
#[repr(C)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct es_thread_t {
    /// Unique of the thread
    pub thread_id: u64,
}

/// Information related to a process. This is used both for describing processes that performed an
/// action (e.g. in the case of the [`es_message_t.process`] field, or are targets of an action (e.g.
/// for exec events this describes the new process being executed, for signal events this describes
/// the process that will receive the signal).
///
/// Values such as `pid`, `pidversion`, `uid`, `gid`, etc. can be extracted from audit tokens using
/// API provided in `libbsm.h`.
///
/// ### Identifying unique process execution on a single machine
///
/// The tuple `(pid, pidversion)` identifies a specific process execution, and should be used to
/// link events to the process that emitted them. Executing an executable image in a process using
/// the `exec` or `posix_spawn` family of syscalls increments the `pidversion`. However, `(pid,
/// pidversion)` is not meant to be unique across reboots or across multiple systems.
///
/// ### Multiple ES clients
///
/// Clients should take caution when processing events where `is_es_client` is true. If multiple ES
/// clients exist, actions taken by one client could trigger additional actions by the other client,
/// causing a potentially infinite cycle.
///
/// ### Code signing
///
/// Fields related to code signing in the target `es_process_t` reflect the state of the process
/// at the time the message is generated. In the specific case of exec, this is after the exec
/// completed in the kernel, but before any code in the process has started executing. At that
/// point, XNU has validated the signature itself and has verified that the `CDHash` is correct
/// in that the hash of all the individual page hashes in the Code Directory matches the signed
/// `CDHash`, essentially verifying the signature was not tampered with. However, individual page
/// hashes are not verified by XNU until the corresponding pages are paged in once they are accessed
/// while the binary executes. It is not until the individual pages are paged in that XNU determines
/// if a binary has been tampered with and will update the code signing flags accordingly.
///
/// Endpoint Security provides clients the current state of the CS flags in the `codesigning_flags`
/// member of the `es_process_t` struct. The `CS_VALID` bit in the `codesigning_flags` means that
/// everything the kernel has validated **up to that point in time** was valid, but not that there
/// has been a full validation of all the pages in the executable file. If page content has been
/// tampered with in the executable, we won't know until that page is paged in. At that time, the
/// process will have its `CS_VALID` bit cleared and, if `CS_KILL` is set, the process will be
/// killed, preventing any tampered code from being executed.
///
/// `CS_KILL` is generally set for platform binaries and for binaries having opted into the hardened
/// runtime. An ES client wishing to detect tampered code before it is paged in, for example at
/// exec time, can use the Security framework to do so, but should be cautious of the potentially
/// significant performance cost. The Endpoint Security subsystem itself has no role in verifying
/// the validity of code signatures.
#[repr(C)]
pub struct es_process_t {
    /// Audit token of the process
    pub audit_token: audit_token_t,
    /// Parent pid of the process. It is recommended to instead use the `parent_audit_token` field.
    pub ppid: pid_t,
    /// Original ppid of the process. This field stays constant even in the event this process is
    /// reparented.
    pub original_ppid: pid_t,
    /// Process group id the process belongs to
    pub group_id: pid_t,
    /// Session id the process belongs to
    pub session_id: pid_t,
    /// Code signing flags of the process. The values for these flags can be found in the include
    /// file `cs_blobs.h` (`#include <kern/cs_blobs.h>`).
    pub codesigning_flags: u32,
    pub is_platform_binary: bool,
    /// Indicates this process has the Endpoint Security entitlement
    pub is_es_client: bool,
    /// The code directory hash of the code signature associated with this process
    pub cdhash: [u8; 20],
    /// The signing id of the code signature associated with this process
    pub signing_id: es_string_token_t,
    /// The team id of the code signature associated with this process
    pub team_id: es_string_token_t,
    /// The executable file that is executing in this process.
    pub executable: ShouldNotBeNull<es_file_t>,
    /// The TTY this process is associated with, or NULL if the process does not have an associated
    /// TTY. The TTY is a property of the POSIX session the process belongs to. A process' session
    /// may be associated with a TTY independently from whether its stdin or any other file
    /// descriptors point to a TTY device (as per `isatty(3)`, `tty(1)`).
    ///
    /// Field available only if message version >= 2.
    #[cfg(feature = "macos_10_15_1")]
    pub tty: *mut es_file_t,
    /// Process start time, i.e. time of fork creating this process.
    ///
    /// Field available only if message version >= 3.
    #[cfg(feature = "macos_10_15_4")]
    pub start_time: timeval,
    /// Audit token of the process responsible for this process, which may be the process itself in
    /// case there is no responsible process or the responsible process has already exited.
    ///
    /// Field available only if message version >= 4.
    #[cfg(feature = "macos_11_0_0")]
    pub responsible_audit_token: audit_token_t,
    /// Audit token of the parent process.
    ///
    /// Field available only if message version >= 4.
    #[cfg(feature = "macos_11_0_0")]
    pub parent_audit_token: audit_token_t,
}

should_not_be_null_fields!(es_process_t; executable -> es_file_t);
#[cfg(feature = "macos_10_15_1")]
null_fields!(es_process_t; tty -> es_file_t);

/// Machine-specific thread state as used by `thread_create_running` and other Mach API functions.
///
/// The `size` subfield of the `state` field is in bytes, NOT `natural_t` units. Definitions for
/// working with thread state can be found in the include file `mach/thread_status.h` and
/// corresponding machine-dependent headers.
#[cfg(feature = "macos_11_0_0")]
#[repr(C)]
pub struct es_thread_state_t {
    /// Representation of the machine-specific thread state
    pub flavor: c_int,
    /// Machine-specific thread state, equivalent to `thread_state_t` in Mach APIs
    pub state: es_token_t,
}

/// An open file descriptor
#[cfg(feature = "macos_11_0_0")]
#[repr(C)]
#[derive(Copy, Clone)]
pub struct es_fd_t {
    /// File descriptor number
    pub fd: i32,
    /// File descriptor type, as `libproc` fdtype
    pub fdtype: u32,
    /// Available if `fdtype` is [`Self::PROX_FDTYPE_PIPE`]
    pub anon_0: es_fd_t_anon_0,
}

#[cfg(feature = "macos_11_0_0")]
impl es_fd_t {
    /// Helper constant when checking if `anon_0` is valid by looking at `fdtype`
    pub const PROX_FDTYPE_PIPE: u32 = 6;

    /// Access the `pipe` member of [`es_fd_t_anon_0`] if `fdtype` is [`Self::PROX_FDTYPE_PIPE`].
    ///
    /// # Safety
    ///
    /// The `fdtype` and `anon_0` fields must be kept in sync.
    pub unsafe fn pipe(&self) -> Option<es_fd_t_anon_0_pipe> {
        if self.fdtype == Self::PROX_FDTYPE_PIPE {
            // Safety: we checked `fdtype` for the correct value just before and the caller
            // guarantees the fields are synced
            Some(unsafe { self.anon_0.pipe })
        } else {
            None
        }
    }
}

/// See [`es_fd_t_anon_0.anon_0`]
#[cfg(feature = "macos_11_0_0")]
#[repr(C)]
#[derive(Copy, Clone)]
pub union es_fd_t_anon_0 {
    pub pipe: es_fd_t_anon_0_pipe,
}

/// Pipe information available in [`es_fd_t`] if the `fdtype` field is `PROX_FDTYPE_PIPE`
///
/// See [`es_fd_t_anon_0_pipe.pipe`]
#[cfg(feature = "macos_11_0_0")]
#[repr(C)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct es_fd_t_anon_0_pipe {
    /// Unique id of the pipe for correlation with other file descriptors pointing to the same or
    /// other end of the same pipe
    pub pipe_id: u64,
}

#[cfg(feature = "macos_13_0_0")]
ffi_wrap_enum!(
    /// Type of launch item.
    ///
    /// See [`es_btm_launch_item_t`]
    es_btm_item_type_t(u32);

    == MACOS_13_0_0;
    ES_BTM_ITEM_TYPE_USER_ITEM = 0,
    ES_BTM_ITEM_TYPE_APP = 1,
    ES_BTM_ITEM_TYPE_LOGIN_ITEM = 2,
    ES_BTM_ITEM_TYPE_AGENT = 3,
    --
    ES_BTM_ITEM_TYPE_DAEMON = 4,
);

/// Structure describing a BTM launch item
#[cfg(feature = "macos_13_0_0")]
#[repr(C)]
pub struct es_btm_launch_item_t {
    /// Type of launch item.
    pub item_type: es_btm_item_type_t,
    /// True only if item is a legacy plist.
    pub legacy: bool,
    /// True only if item is managed by MDM.
    pub managed: bool,
    /// User ID for the item (may be user `nobody` (`-2`)).
    pub uid: uid_t,
    /// URL for item.
    ///
    /// If a file URL describing a relative path, it is relative to `app_url`.
    pub item_url: es_string_token_t,
    /// Optional. URL for app the item is attributed to.
    // NOTE: find out how optionality is modeled. Empty string ? Linked to an enum member ?
    pub app_url: es_string_token_t,
}

#[cfg(feature = "macos_14_0_0")]
ffi_wrap_enum!(
    /// Source of profile installation (MDM/Manual Install).
    ///
    /// See [`es_profile_t`]
    es_profile_source_t(u32);

    == MACOS_14_0_0;
    /// MDM (managed) installation
    ES_PROFILE_SOURCE_MANAGED = 0,
    --
    /// Manual installation
    ES_PROFILE_SOURCE_INSTALL = 1,
);

#[cfg(feature = "macos_14_0_0")]
#[repr(C)]
pub struct es_profile_t {
    /// Profile identifier
    pub identifier: es_string_token_t,
    /// Profile UUID
    pub uuid: es_string_token_t,
    /// Source of Profile installation (MDM/Manual Install)
    pub install_source: es_profile_source_t,
    /// Profile organization name
    pub organization: es_string_token_t,
    /// Profile display name
    pub display_name: es_string_token_t,
    /// Profile scope
    pub scope: es_string_token_t,
}

/// Execute a new process
///
/// Process arguments, environment variables and file descriptors are packed, use API functions
/// to access them: [`es_exec_arg()`], [`es_exec_arg_count()`], [`es_exec_env()`],
/// [`es_exec_env_count()`],
#[cfg_attr(feature = "macos_11_0_0", doc = "[`es_exec_fd()`] and [`es_exec_fd_count()`].")]
#[cfg_attr(not(feature = "macos_11_0_0"), doc = "`es_exec_fd()` and `es_exec_fd_count()`.")]
///
/// The API may only return descriptions for a subset of open file descriptors; how many and
/// which file descriptors are available as part of exec events is not considered API and can change
/// in future releases.
///
/// The CPU type and subtype correspond to `CPU_TYPE_*` and `CPU_SUBTYPE_*` macros defined in
/// `<mach/machine.h>`.
///
/// Fields related to code signing in `target` represent kernel state for the process at the
/// point in time the exec has completed, but the binary has not started running yet. Because code
/// pages are not validated until they are paged in, this means that modifications to code pages
/// would not have been detected yet at this point. For a more thorough explanation, please see the
/// documentation for [`es_process_t`].
///
/// There are two [`es_process_t`] fields that are represented in an [`es_message_t`] that
/// contains an `es_event_exec_t`. The `es_process_t` within the `es_message_t` struct (named
/// `process`) contains information about the program that calls `execve(2)` (or `posix_spawn(2)`).
/// This information is gathered prior to the program being replaced. The other `es_process_t`,
/// within the `es_event_exec_t` struct (named `target`), contains information about the program
/// after the image has been replaced by `execve(2)` (or `posix_spawn(2)`). This means that both
/// `es_process_t` structs refer to the same process (as identified by pid), but not necessarily the
/// same program, and definitely not the same program execution (as identified by pid, pidversion
/// tuple). The `audit_token_t` structs contained in the two different `es_process_t` structs will
/// not be identical: the `pidversion` field will be updated, and the UID/GID values may be
/// different if the new program had `setuid`/`setgid` permission bits set.
///
/// Cache key for this event type: `(process executable file, target executable file)`.
#[repr(C)]
// 10.15.0
pub struct es_event_exec_t {
    /// The new process that is being executed
    pub target: ShouldNotBeNull<es_process_t>,
    /// This field must not be accessed directly (see notes)
    #[cfg(not(feature = "macos_13_3_0"))]
    _reserved0: es_token_t,
    /// The exec path passed up to dyld, before symlink resolution. This is the path argument
    /// to `execve(2)` or `posix_spawn(2)`, or the interpreter from the shebang line for scripts run
    /// through the shell script image activator.
    ///
    /// Field available only if message version >= 7.
    #[cfg(feature = "macos_13_3_0")]
    pub dyld_exec_path: es_string_token_t,
    /// See variants of union
    pub anon_0: es_event_exec_t_anon_0,
}

should_not_be_null_fields!(es_event_exec_t; target -> es_process_t);

/// See [`es_event_exec_t.anon_0`]
#[repr(C)]
pub union es_event_exec_t_anon_0 {
    _reserved: [u8; 64],
    #[cfg(feature = "macos_10_15_1")]
    pub anon_0: ManuallyDrop<es_event_exec_t_anon_0_anon_0>,
}

/// See [`es_event_exec_t_anon_0.anon_0`]
#[repr(C)]
pub struct es_event_exec_t_anon_0_anon_0 {
    /// Script being executed by interpreter. This field is only valid if a script was executed
    /// directly and not as an argument to the interpreter (e.g. `./foo.sh` not `/bin/sh ./foo.sh`)
    ///
    /// Field available only if message version >= 2.
    #[cfg(feature = "macos_10_15_1")]
    pub script: *mut es_file_t,
    /// Current working directory at exec time.
    ///
    /// Field available only if message version >= 3.
    #[cfg(feature = "macos_10_15_4")]
    pub cwd: ShouldNotBeNull<es_file_t>,
    /// Highest open file descriptor after the exec completed. This number is equal to or
    /// larger than the highest number of file descriptors available via [`es_exec_fd_count()`] and
    /// [`es_exec_fd()`], in which case EndpointSecurity has capped the number of file descriptors
    /// available in the message. File descriptors for open files are not necessarily contiguous.
    /// The exact number of open file descriptors is not available.
    ///
    /// Field available only if message version >= 4.
    #[cfg(feature = "macos_11_0_0")]
    pub last_fd: c_int,

    /// The CPU type of the executable image which is being executed. In case of translation, this
    /// may be a different architecture than the one of the system.
    ///
    /// Field available only if message version >= 6.
    #[cfg(feature = "macos_13_0_0")]
    pub image_cputype: cpu_type_t,
    /// The CPU subtype of the executable image.
    ///
    /// Field available only if message version >= 6.
    #[cfg(feature = "macos_13_0_0")]
    pub image_cpusubtype: cpu_subtype_t,
}

#[cfg(feature = "macos_10_15_4")]
should_not_be_null_fields!(es_event_exec_t_anon_0_anon_0; cwd -> es_file_t);
#[cfg(feature = "macos_10_15_1")]
null_fields!(es_event_exec_t_anon_0_anon_0; script -> es_file_t);

/// Open a file system object.
///
/// The `fflag` field represents the mask as applied by the kernel, not as represented by
/// typical `open(2)` `oflag` values. When responding to `ES_EVENT_TYPE_AUTH_OPEN` events using
/// [`es_respond_flags_result()`][super::es_respond_flags_result], ensure that the same `FFLAG`
/// values are used (e.g. `FREAD`, `FWRITE` instead of `O_RDONLY`, `O_RDWR`, etc...).
///
/// Cache key for this event type: `(process executable file, file that will be opened)`.
///
/// See `fcntl.h`
#[repr(C)]
// 10.15.0
pub struct es_event_open_t {
    /// The desired flags to be used when opening `file` (see note)
    pub fflag: i32,
    /// The file that will be opened
    pub file: ShouldNotBeNull<es_file_t>,
    _reserved: [u8; 64],
}

should_not_be_null_fields!(es_event_open_t; file -> es_file_t);

/// Load a kernel extension
///
/// This event type does not support caching.
#[repr(C)]
// 10.15.0
pub struct es_event_kextload_t {
    /// The signing identifier of the kext being loaded
    pub identifier: es_string_token_t,
    _reserved: [u8; 64],
}

/// Unload a kernel extension
///
/// This event type does not support caching (notify-only).
#[repr(C)]
// 10.15.0
pub struct es_event_kextunload_t {
    /// The signing identifier of the kext being unloaded
    pub identifier: es_string_token_t,
    _reserved: [u8; 64],
}

/// Unlink a file system object.
///
/// This event can fire multiple times for a single syscall, for example when the syscall has to be
/// retried due to racing VFS operations.
///
/// This event type does not support caching.
#[repr(C)]
// 10.15.0
pub struct es_event_unlink_t {
    /// The object that will be removed
    pub target: ShouldNotBeNull<es_file_t>,
    /// The parent directory of the `target` file system object
    pub parent_dir: ShouldNotBeNull<es_file_t>,
    _reserved: [u8; 64],
}

should_not_be_null_fields!(es_event_unlink_t; target -> es_file_t, parent_dir -> es_file_t);

/// Memory map a file
///
/// Cache key for this event type: `(process executable file, source file)`.
#[repr(C)]
// 10.15.0
pub struct es_event_mmap_t {
    /// The protection (region accessibility) value
    pub protection: i32,
    /// The maximum allowed protection value the operating system will respect
    pub max_protection: i32,
    /// The type and attributes of the mapped file
    pub flags: i32,
    /// The offset into `source` that will be mapped
    pub file_pos: u64,
    /// The file system object being mapped
    pub source: ShouldNotBeNull<es_file_t>,
    _reserved: [u8; 64],
}

should_not_be_null_fields!(es_event_mmap_t; source -> es_file_t);

/// Link to a file
///
/// This event type does not support caching.
#[repr(C)]
// 10.15.0
pub struct es_event_link_t {
    /// The existing object to which a hard link will be created
    pub source: ShouldNotBeNull<es_file_t>,
    /// The directory in which the link will be created
    pub target_dir: ShouldNotBeNull<es_file_t>,
    /// The name of the new object linked to `source`
    pub target_filename: es_string_token_t,
    _reserved: [u8; 64],
}

should_not_be_null_fields!(es_event_link_t; source -> es_file_t, target_dir -> es_file_t);

/// Mount a file system
///
/// Cache key for this event type: `(process executable file, mount point)`.
#[repr(C)]
// 10.15.0
pub struct es_event_mount_t {
    /// The file system stats for the file system being mounted
    pub statfs: ShouldNotBeNull<statfs>,
    _reserved: [u8; 64],
}

should_not_be_null_fields!(es_event_mount_t; statfs -> statfs);

/// Unmount a file system
///
/// This event type does not support caching (notify-only).
#[repr(C)]
// 10.15.0
pub struct es_event_unmount_t {
    /// The file system stats for the file system being unmounted
    pub statfs: ShouldNotBeNull<statfs>,
    _reserved: [u8; 64],
}

should_not_be_null_fields!(es_event_unmount_t; statfs -> statfs);

/// Remount a file system
///
/// This event type does not support caching.
#[cfg(feature = "macos_10_15_1")]
#[repr(C)]
pub struct es_event_remount_t {
    /// The file system stats for the file system being remounted
    pub statfs: ShouldNotBeNull<statfs>,
    _reserved: [u8; 64],
}

#[cfg(feature = "macos_10_15_1")]
should_not_be_null_fields!(es_event_remount_t; statfs -> statfs);

/// Fork a new process
///
/// This event type does not support caching (notify-only).
#[repr(C)]
// 10.15.0
pub struct es_event_fork_t {
    /// The child process that was created
    pub child: ShouldNotBeNull<es_process_t>,
    _reserved: [u8; 64],
}

should_not_be_null_fields!(es_event_fork_t; child -> es_process_t);

/// Control protection of pages
///
/// This event type does not support caching.
#[repr(C)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
// 10.15.0
pub struct es_event_mprotect_t {
    /// The desired new protection value
    pub protection: i32,
    /// The base address to which the protection value will apply
    pub address: user_addr_t,
    /// The size of the memory region the protection value will apply
    pub size: user_size_t,
    _reserved: [u8; 64],
}

/// Send a signal to a process.
///
/// This event will not fire if a process sends a signal to itself.
///
/// Cache key for this event type: `(process executable file, target process executable file)`.
#[repr(C)]
// 10.15.0
pub struct es_event_signal_t {
    /// The signal number to be delivered
    pub sig: c_int,
    /// The process that will receive the signal
    pub target: ShouldNotBeNull<es_process_t>,
    _reserved: [u8; 64],
}

should_not_be_null_fields!(es_event_signal_t; target -> es_process_t);

ffi_wrap_enum!(
    es_destination_type_t(u32);

    == MACOS_10_15_0;
    ES_DESTINATION_TYPE_EXISTING_FILE = 0,
    --
    ES_DESTINATION_TYPE_NEW_PATH = 1,
);

/// Rename a file system object.
///
/// The `destination_type` field describes which member in the `destination` union should
/// accessed. `ES_DESTINATION_TYPE_EXISTING_FILE` means that `existing_file` should be used,
/// `ES_DESTINATION_TYPE_NEW_PATH` means that the `new_path` struct should be used.
///
/// This event can fire multiple times for a single syscall, for example when the syscall has to be
/// retried due to racing VFS operations.
///
/// This event type does not support caching.
#[repr(C)]
// 10.15.0
pub struct es_event_rename_t {
    /// The source file that is being renamed
    pub source: ShouldNotBeNull<es_file_t>,
    /// Whether or not the destination refers to an existing or new file
    pub destination_type: es_destination_type_t,
    /// Information about the destination of the renamed file (see note)
    pub destination: es_event_rename_t_anon_0,
    _reserved: [u8; 64],
}

should_not_be_null_fields!(es_event_rename_t; source -> es_file_t);

/// See [`es_event_rename_t`]
#[repr(C)]
pub union es_event_rename_t_anon_0 {
    /// The destination file that will be overwritten
    pub existing_file: ShouldNotBeNull<es_file_t>,
    /// Information regarding the destination of a newly created file
    pub new_path: ManuallyDrop<es_event_rename_t_anon_0_anon_0>,
}

/// See [`es_event_rename_t_anon_0`]
#[repr(C)]
pub struct es_event_rename_t_anon_0_anon_0 {
    /// The directory into which the file will be renamed
    pub dir: ShouldNotBeNull<es_file_t>,
    /// The name of the new file that will be created
    pub filename: es_string_token_t,
}

should_not_be_null_fields!(es_event_rename_t_anon_0_anon_0; dir -> es_file_t);

/// Set an extended attribute
///
/// This event type does not support caching.
#[repr(C)]
// 10.15.0
pub struct es_event_setextattr_t {
    /// The file for which the extended attribute will be set
    pub target: ShouldNotBeNull<es_file_t>,
    /// The extended attribute which will be set
    pub extattr: es_string_token_t,
    _reserved: [u8; 64],
}

should_not_be_null_fields!(es_event_setextattr_t; target -> es_file_t);

/// Retrieve an extended attribute
///
/// Cache key for this event type: `(process executable file, target file)`.
#[cfg(feature = "macos_10_15_1")]
#[repr(C)]
pub struct es_event_getextattr_t {
    /// The file for which the extended attribute will be retrieved
    pub target: ShouldNotBeNull<es_file_t>,
    /// The extended attribute which will be retrieved
    pub extattr: es_string_token_t,
    _reserved: [u8; 64],
}

#[cfg(feature = "macos_10_15_1")]
should_not_be_null_fields!(es_event_getextattr_t; target -> es_file_t);

/// Delete an extended attribute
///
/// This event type does not support caching.
#[cfg(feature = "macos_10_15_1")]
#[repr(C)]
pub struct es_event_deleteextattr_t {
    /// The file for which the extended attribute will be deleted
    pub target: ShouldNotBeNull<es_file_t>,
    /// The extended attribute which will be deleted
    pub extattr: es_string_token_t,
    _reserved: [u8; 64],
}

#[cfg(feature = "macos_10_15_1")]
should_not_be_null_fields!(es_event_deleteextattr_t; target -> es_file_t);

/// Modify file mode.
///
/// The `mode` member is the desired new mode. The `target` member's `stat` information contains the
/// current mode.
///
/// Cache key for this event type: `(process executable file, target file)`.
#[repr(C)]
// 10.15.0
pub struct es_event_setmode_t {
    /// The desired new mode
    pub mode: mode_t,
    /// The file for which mode information will be modified
    pub target: ShouldNotBeNull<es_file_t>,
    _reserved: [u8; 64],
}

should_not_be_null_fields!(es_event_setmode_t; target -> es_file_t);

/// Modify file flags information.
///
/// The `flags` member is the desired set of new flags. The `target` member's `stat` information
/// contains the current set of flags.
///
/// Cache key for this event type: `(process executable file, target file)`.
#[repr(C)]
// 10.15.0
pub struct es_event_setflags_t {
    /// The desired new flags
    pub flags: u32,
    /// The file for which flags information will be modified
    pub target: ShouldNotBeNull<es_file_t>,
    _reserved: [u8; 64],
}

should_not_be_null_fields!(es_event_setflags_t; target -> es_file_t);

/// Modify file owner information
///
/// The `uid` and `gid` members are the desired new values. The `target` member's `stat`
/// information contains the current uid and gid values.
///
/// Cache key for this event type: `(process executable file, target file)`.
#[repr(C)]
// 10.15.0
pub struct es_event_setowner_t {
    /// The desired new UID
    pub uid: uid_t,
    /// The desired new GID
    pub gid: gid_t,
    /// The file for which owner information will be modified
    pub target: ShouldNotBeNull<es_file_t>,
    _reserved: [u8; 64],
}

should_not_be_null_fields!(es_event_setowner_t; target -> es_file_t);

/// Close a file descriptor
///
/// This event type does not support caching (notify-only).
#[repr(C)]
// 10.15.0
pub struct es_event_close_t {
    /// Set to `true` if the target file being closed has been modified
    ///
    /// The `modified` flag only reflects that a file was or was not modified by filesystem syscall.
    /// If a file was only modifed though a memory mapping this flag will be `false`, but
    /// `was_mapped_writable` (message version >= 6) will be true.
    pub modified: bool,
    /// The file that is being closed
    pub target: ShouldNotBeNull<es_file_t>,
    pub anon0: es_event_close_t_anon_0,
}

should_not_be_null_fields!(es_event_close_t; target -> es_file_t);

/// See [`es_event_close_t`].
#[repr(C)]
pub union es_event_close_t_anon_0 {
    _reserved: [u8; 64],
    /// Indicates that at some point in the lifetime of the target file vnode it was mapped into a
    /// process as writable.
    ///
    /// `was_mapped_writable` only indicates whether the target file was mapped into writable memory
    /// or not for the lifetime of the vnode. It does not indicate whether the file has actually
    /// been written to by way of writing to mapped memory, and it does not indicate whether the
    /// file is currently still mapped writable. Correct interpretation requires consideration of
    /// vnode lifetimes in the kernel.
    ///
    /// Field available only if message version >= 6.
    #[cfg(feature = "macos_13_0_0")]
    pub was_mapped_writable: bool,
}

/// Create a file system object.
///
/// If an object is being created but has not yet been created, the `destination_type` will be
/// `ES_DESTINATION_TYPE_NEW_PATH`.
///
/// Typically `ES_EVENT_TYPE_NOTIFY_CREATE` events are fired after the object has been created and
/// the `destination_type` will be `ES_DESTINATION_TYPE_EXISTING_FILE`. The exception to this is
/// for notifications that occur if an ES client responds to an `ES_EVENT_TYPE_AUTH_CREATE` event
/// with `ES_AUTH_RESULT_DENY`.
///
/// This event can fire multiple times for a single syscall, for example when the syscall has to be
/// retried due to racing VFS operations.
///
/// This event type does not support caching.
#[repr(C)]
// 10.15.0
pub struct es_event_create_t {
    /// Whether or not the destination refers to an existing file (see note)
    pub destination_type: es_destination_type_t,
    /// Information about the destination of the new file (see note)
    pub destination: es_event_create_t_anon_0,
    _reserved2: [u8; 16],
    pub anon_1: es_event_create_t_anon_1,
}

/// See [`es_event_create_t`]
#[repr(C)]
pub union es_event_create_t_anon_0 {
    /// The file system object that was created
    pub existing_file: ShouldNotBeNull<es_file_t>,
    pub new_path: ManuallyDrop<es_event_create_t_anon_0_anon_0>,
}

/// See [`es_event_create_t_anon_0`]
#[repr(C)]
pub struct es_event_create_t_anon_0_anon_0 {
    /// The directory in which the new file system object will be created
    pub dir: ShouldNotBeNull<es_file_t>,
    /// The name of the new file system object to create
    pub filename: es_string_token_t,
    /// Mode of the file system object to create
    pub mode: mode_t,
}

should_not_be_null_fields!(es_event_create_t_anon_0_anon_0; dir -> es_file_t);

/// See [`es_event_create_t`]
#[repr(C)]
pub union es_event_create_t_anon_1 {
    _reserved: [u8; 48],
    #[cfg(feature = "macos_10_15_1")]
    pub anon_0: ManuallyDrop<es_event_create_t_anon_1_anon_0>,
}

/// See [`es_event_create_t_anon_1`]
#[repr(C)]
#[cfg(feature = "macos_10_15_1")]
pub struct es_event_create_t_anon_1_anon_0 {
    /// The ACL that the new file system object got or gets created with.
    ///
    /// May be `NULL` if the file system object gets created without ACL.
    ///
    /// See warning about usage on [`acl_t`].
    ///
    /// Field available only if message version >= 2.
    pub acl: acl_t,
}

/// Terminate a process
///
/// This event type does not support caching (notify-only).
#[repr(C)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
// 10.15.0
pub struct es_event_exit_t {
    /// The exit status of a process (same format as `wait(2)`)
    pub stat: c_int,
    _reserved: [u8; 64],
}

/// Exchange data atomically between two files
///
/// This event type does not support caching.
#[repr(C)]
// 10.15.0
pub struct es_event_exchangedata_t {
    /// The first file to be exchanged
    pub file1: ShouldNotBeNull<es_file_t>,
    /// The second file to be exchanged
    pub file2: ShouldNotBeNull<es_file_t>,
    _reserved: [u8; 64],
}

should_not_be_null_fields!(es_event_exchangedata_t; file1 -> es_file_t, file2 -> es_file_t);

/// Write to a file
///
/// This event type does not support caching (notify-only).
#[repr(C)]
// 10.15.0
pub struct es_event_write_t {
    /// The file being written to
    pub target: ShouldNotBeNull<es_file_t>,
    _reserved: [u8; 64],
}

should_not_be_null_fields!(es_event_write_t; target -> es_file_t);

/// Truncate to a file
///
/// This event type does not support caching.
#[repr(C)]
// 10.15.0
pub struct es_event_truncate_t {
    /// The file being truncated
    pub target: ShouldNotBeNull<es_file_t>,
    _reserved: [u8; 64],
}

should_not_be_null_fields!(es_event_truncate_t; target -> es_file_t);

/// Changes directories
///
/// Cache key for this event type: `(process executable file, target directory)`.
#[cfg(feature = "macos_10_15_1")]
#[repr(C)]
pub struct es_event_chdir_t {
    /// The desired new current working directory
    pub target: ShouldNotBeNull<es_file_t>,
    _reserved: [u8; 64],
}

#[cfg(feature = "macos_10_15_1")]
should_not_be_null_fields!(es_event_chdir_t; target -> es_file_t);

/// View stat information of a file
///
/// This event type does not support caching (notify-only).
#[cfg(feature = "macos_10_15_1")]
#[repr(C)]
pub struct es_event_stat_t {
    /// The file for which stat information will be retrieved
    pub target: ShouldNotBeNull<es_file_t>,
    _reserved: [u8; 64],
}

#[cfg(feature = "macos_10_15_1")]
should_not_be_null_fields!(es_event_stat_t; target -> es_file_t);

/// Changes the root directory for a process
///
/// Cache key for this event type: `(process executable file, target directory)`.
#[cfg(feature = "macos_10_15_1")]
#[repr(C)]
pub struct es_event_chroot_t {
    /// The directory which will be the new root
    pub target: ShouldNotBeNull<es_file_t>,
    _reserved: [u8; 64],
}

#[cfg(feature = "macos_10_15_1")]
should_not_be_null_fields!(es_event_chroot_t; target -> es_file_t);

/// List extended attributes of a file
///
/// Cache key for this event type: `(process executable file, target file)`.
#[cfg(feature = "macos_10_15_1")]
#[repr(C)]
pub struct es_event_listextattr_t {
    /// The file for which extended attributes information are being retrieved
    pub target: ShouldNotBeNull<es_file_t>,
    _reserved: [u8; 64],
}

#[cfg(feature = "macos_10_15_1")]
should_not_be_null_fields!(es_event_listextattr_t; target -> es_file_t);

/// Open a connection to an I/O Kit IOService.
///
/// This event is fired when a process calls `IOServiceOpen()` in order to open a communications
/// channel with an I/O Kit driver.  The event does not correspond to driver <-> device
/// communication and is neither providing visibility nor access control into devices being
/// attached.
///
/// This event type does not support caching.
#[repr(C)]
// 10.15.0
pub struct es_event_iokit_open_t {
    /// A constant specifying the type of connection to be created, interpreted only by the
    /// IOService's family. This field corresponds to the type argument to `IOServiceOpen()`.
    pub user_client_type: u32,
    /// Meta class name of the user client instance
    pub user_client_class: es_string_token_t,
    _reserved: [u8; 64],
}

ffi_wrap_enum!(
    es_get_task_type_t(u32);

    == MACOS_10_15_0;
    /// Task port obtained by calling e.g. `task_for_pid()`, where the caller obtains a task port
    /// for a process identified by pid
    ES_GET_TASK_TYPE_TASK_FOR_PID = 0,
    /// Task port obtained by calling e.g. `processor_set_tasks()`, where the caller obtains a set
    /// of task ports
    ES_GET_TASK_TYPE_EXPOSE_TASK = 1,
    --
    /// Task port obtained by calling e.g. `task_identity_token_get_task_port()`, where the caller
    /// obtains a task port for a process identified by an identity token. Task identity tokens
    /// generally have to be given up by the target process voluntarily prior to the conversion
    /// into task ports.
    ES_GET_TASK_TYPE_IDENTITY_TOKEN = 2,
);

/// Get a process's task control port.
///
/// This event is fired when a process obtains a send right to a task control port (e.g.
/// `task_for_pid()`, `task_identity_token_get_task_port()`, `processor_set_tasks()` and other
/// means).
///
/// Task control ports were formerly known as simply "task ports".
///
/// There are many legitimate reasons why a process might need to obtain a send right to a task
/// control port of another process, not limited to intending to debug or suspend the target
/// process. For instance, frameworks and their daemons may need to obtain a task control port to
/// fulfill requests made by the target process. Obtaining a task control port is in itself not
/// indicative of malicious activity. Denying system processes acquiring task control ports may
/// result in breaking system functionality in potentially fatal ways.
///
/// Cache key for this event type: `(process executable file, target executable file)`.
#[repr(C)]
// 10.15.0
pub struct es_event_get_task_t {
    /// The process for which the task control port will be retrieved
    pub target: ShouldNotBeNull<es_process_t>,
    /// Type indicating how the process is obtaining the task port for the target process.
    ///
    /// Field available only if message version >= 5.
    pub type_: es_get_task_type_t,
    _reserved: [u8; 60],
}

should_not_be_null_fields!(es_event_get_task_t; target -> es_process_t);

/// Get a process's task read port.
///
/// This event is fired when a process obtains a send right to a task read port (e.g.
/// `task_read_for_pid()`, `task_identity_token_get_task_port()`).
///
/// Cache key for this event type: `(process executable file, target executable file)`.
#[cfg(feature = "macos_11_3_0")]
#[repr(C)]
pub struct es_event_get_task_read_t {
    /// The process for which the task read port will be retrieved
    pub target: ShouldNotBeNull<es_process_t>,
    /// Type indicating how the process is obtaining the task port for the target process.
    ///
    /// Field available only if message version >= 5.
    pub type_: es_get_task_type_t,
    _reserved: [u8; 60],
}

#[cfg(feature = "macos_11_3_0")]
should_not_be_null_fields!(es_event_get_task_read_t; target -> es_process_t);

/// Get a process's task inspect port.
///
/// This event is fired when a process obtains a send right to a task inspect port (e.g.
/// `task_inspect_for_pid()`, `task_identity_token_get_task_port()`).
///
/// This event type does not support caching.
#[cfg(feature = "macos_11_3_0")]
#[repr(C)]
pub struct es_event_get_task_inspect_t {
    /// The process for which the task inspect port will be retrieved
    pub target: ShouldNotBeNull<es_process_t>,
    /// Type indicating how the process is obtaining the task port for the target process.
    ///
    /// Field available only if message version >= 5.
    pub type_: es_get_task_type_t,
    _reserved: [u8; 60],
}

#[cfg(feature = "macos_11_3_0")]
should_not_be_null_fields!(es_event_get_task_inspect_t; target -> es_process_t);

/// Get a process's task name port.
///
/// This event is fired when a process obtains a send right to a task name port (e.g.
/// `task_name_for_pid()`, `task_identity_token_get_task_port()`).
///
/// This event type does not support caching.
#[cfg(feature = "macos_11_0_0")]
#[repr(C)]
pub struct es_event_get_task_name_t {
    /// The process for which the task name port will be retrieved
    pub target: ShouldNotBeNull<es_process_t>,
    /// Type indicating how the process is obtaining the task port for the target process.
    ///
    /// Field available only if message version >= 5.
    pub type_: es_get_task_type_t,
    _reserved: [u8; 60],
}

#[cfg(feature = "macos_11_0_0")]
should_not_be_null_fields!(es_event_get_task_name_t; target -> es_process_t);

/// Retrieve file system attributes
///
/// Cache key for this event type: `(process executable file, target file)`.
#[cfg(feature = "macos_10_15_1")]
#[repr(C)]
pub struct es_event_getattrlist_t {
    /// The attributes that will be retrieved
    pub attrlist: attrlist,
    /// The file for which attributes will be retrieved
    pub target: ShouldNotBeNull<es_file_t>,
    _reserved: [u8; 64],
}

#[cfg(feature = "macos_10_15_1")]
should_not_be_null_fields!(es_event_getattrlist_t; target -> es_file_t);

/// Modify file system attributes
///
/// This event type does not support caching.
#[repr(C)]
// 10.15.0
pub struct es_event_setattrlist_t {
    /// The attributes that will be modified
    pub attrlist: attrlist,
    /// The file for which attributes will be modified
    pub target: ShouldNotBeNull<es_file_t>,
    _reserved: [u8; 64],
}

should_not_be_null_fields!(es_event_setattrlist_t; target -> es_file_t);

/// Update file contents via the `FileProvider` framework
///
/// This event type does not support caching.
#[repr(C)]
// 10.15.0
pub struct es_event_file_provider_update_t {
    /// The staged file that has had its contents updated
    pub source: ShouldNotBeNull<es_file_t>,
    /// The destination that the staged `source` file will be moved to
    pub target_path: es_string_token_t,
    _reserved: [u8; 64],
}

should_not_be_null_fields!(es_event_file_provider_update_t; source -> es_file_t);

/// Materialize a file via the `FileProvider` framework
///
/// This event type does not support caching.
#[repr(C)]
// 10.15.0
pub struct es_event_file_provider_materialize_t {
    pub instigator: ShouldNotBeNull<es_process_t>,
    /// The staged file that has been materialized
    pub source: ShouldNotBeNull<es_file_t>,
    /// The destination of the staged `source` file
    pub target: ShouldNotBeNull<es_file_t>,
    _reserved: [u8; 64],
}

should_not_be_null_fields!(
    es_event_file_provider_materialize_t;
    instigator -> es_process_t,
    source -> es_file_t,
    target -> es_file_t
);

/// Resolve a symbolic link.
///
/// This is not limited only to `readlink(2)`. Other operations such as path lookups can also cause
/// this event to be fired.
///
/// *Caching support is undocumented for this event.*
#[repr(C)]
// 10.15.0
pub struct es_event_readlink_t {
    /// The symbolic link that is attempting to be resolved
    pub source: ShouldNotBeNull<es_file_t>,
    _reserved: [u8; 64],
}

should_not_be_null_fields!(es_event_readlink_t; source -> es_file_t);

/// Lookup a file system object.
///
/// The `relative_target` data may contain untrusted user input.
///
/// This event type does not support caching (notify-only).
#[repr(C)]
// 10.15.0
pub struct es_event_lookup_t {
    /// The current directory
    pub source_dir: ShouldNotBeNull<es_file_t>,
    /// The path to lookup relative to the `source_dir`
    pub relative_target: es_string_token_t,
    _reserved: [u8; 64],
}

should_not_be_null_fields!(es_event_lookup_t; source_dir -> es_file_t);

/// Test file access
///
/// This event type does not support caching (notify-only).
#[cfg(feature = "macos_10_15_1")]
#[repr(C)]
pub struct es_event_access_t {
    /// Access permission to check
    pub mode: i32,
    /// The file to check for access
    pub target: ShouldNotBeNull<es_file_t>,
    _reserved: [u8; 64],
}

#[cfg(feature = "macos_10_15_1")]
should_not_be_null_fields!(es_event_access_t; target -> es_file_t);

/// Change file access and modification times (e.g. via `utimes(2)`)
///
/// Cache key for this event type: `(process executable file, target file)`.
#[cfg(feature = "macos_10_15_1")]
#[repr(C)]
pub struct es_event_utimes_t {
    /// The path which will have its times modified
    pub target: ShouldNotBeNull<es_file_t>,
    /// The desired new access time
    pub atime: timespec,
    /// The desired new modification time
    pub mtime: timespec,
    _reserved: [u8; 64],
}

#[cfg(feature = "macos_10_15_1")]
should_not_be_null_fields!(es_event_utimes_t; target -> es_file_t);

/// Clone a file
///
/// This event type does not support caching.
#[cfg(feature = "macos_10_15_1")]
#[repr(C)]
pub struct es_event_clone_t {
    /// The file that will be cloned
    pub source: ShouldNotBeNull<es_file_t>,
    /// The directory into which the `source` file will be cloned
    pub target_dir: ShouldNotBeNull<es_file_t>,
    /// The name of the new file to which `source` will be cloned
    pub target_name: es_string_token_t,
    _reserved: [u8; 64],
}

#[cfg(feature = "macos_10_15_1")]
should_not_be_null_fields!(es_event_clone_t; source -> es_file_t, target_dir -> es_file_t);

/// Copy a file using the copyfile syscall.
///
/// Not to be confused with `copyfile(3)`.
///
/// Prior to macOS 12.0, the `copyfile` syscall fired `open`, `unlink` and `auth` create events, but
/// no notify `create`, nor `write` or `close` events.
///
/// This event type does not support caching.
#[cfg(feature = "macos_12_0_0")]
#[repr(C)]
pub struct es_event_copyfile_t {
    /// The file that will be cloned
    pub source: ShouldNotBeNull<es_file_t>,
    /// The file existing at the target path that will be overwritten by the copyfile operation.
    /// `NULL` if no such file exists.
    pub target_file: *mut es_file_t,
    /// The directory into which the `source` file will be copied
    pub target_dir: ShouldNotBeNull<es_file_t>,
    /// The name of the new file to which `source` will be copied
    pub target_name: es_string_token_t,
    /// Corresponds to mode argument of the copyfile syscall
    pub mode: mode_t,
    /// Corresponds to flags argument of the copyfile syscall
    pub flags: i32,
    _reserved: [u8; 56],
}

#[cfg(feature = "macos_12_0_0")]
should_not_be_null_fields!(es_event_copyfile_t; source -> es_file_t, target_dir -> es_file_t);
#[cfg(feature = "macos_12_0_0")]
null_fields!(es_event_copyfile_t; target_file -> es_file_t);

/// File control
///
/// This event type does not support caching.
#[cfg(feature = "macos_10_15_1")]
#[repr(C)]
pub struct es_event_fcntl_t {
    /// The target file on which the file control command will be performed
    pub target: ShouldNotBeNull<es_file_t>,
    /// The `cmd` argument given to `fcntl(2)`
    pub cmd: i32,
    _reserved: [u8; 64],
}

#[cfg(feature = "macos_10_15_1")]
should_not_be_null_fields!(es_event_fcntl_t; target -> es_file_t);

/// Read directory entries
///
/// Cache key for this event type: `(process executable file, target directory)`.
#[cfg(feature = "macos_10_15_1")]
#[repr(C)]
pub struct es_event_readdir_t {
    /// The directory whose contents will be read
    pub target: ShouldNotBeNull<es_file_t>,
    _reserved: [u8; 64],
}

#[cfg(feature = "macos_10_15_1")]
should_not_be_null_fields!(es_event_readdir_t; target -> es_file_t);

/// Retrieve file system path based on FSID.
///
/// This event can fire multiple times for a single syscall, for example when the syscall has to be
/// retried due to racing VFS operations.
///
/// Cache key for this event type: `(process executable file, target file)`.
#[cfg(feature = "macos_10_15_1")]
#[repr(C)]
pub struct es_event_fsgetpath_t {
    /// Describes the file system path that will be retrieved
    pub target: ShouldNotBeNull<es_file_t>,
    _reserved: [u8; 64],
}

#[cfg(feature = "macos_10_15_1")]
should_not_be_null_fields!(es_event_fsgetpath_t; target -> es_file_t);

/// Modify the system time
///
/// This event is not fired if the program contains the entitlement `com.apple.private.settime`.
/// Additionally, even if an ES client responds to `ES_EVENT_TYPE_AUTH_SETTIME` events with
/// `ES_AUTH_RESULT_ALLOW`, the operation may still fail for other reasons (e.g. unprivileged user).
///
/// This event type does not support caching.
#[cfg(feature = "macos_10_15_1")]
#[repr(C)]
#[derive(Copy, Clone)]
pub struct es_event_settime_t {
    _reserved: [u8; 64],
}

/// Duplicate a file descriptor
///
/// This event type does not support caching (notify-only).
#[cfg(feature = "macos_10_15_1")]
#[repr(C)]
pub struct es_event_dup_t {
    /// Describes the file the duplicated file descriptor points to
    pub target: ShouldNotBeNull<es_file_t>,
    _reserved: [u8; 64],
}

#[cfg(feature = "macos_10_15_1")]
should_not_be_null_fields!(es_event_dup_t; target -> es_file_t);

/// Fired when a UNIX-domain socket is about to be bound to a path
///
/// This event type does not support caching.
#[cfg(feature = "macos_10_15_1")]
#[repr(C)]
pub struct es_event_uipc_bind_t {
    /// Describes the directory the socket file is created in
    pub dir: ShouldNotBeNull<es_file_t>,
    /// The filename of the socket file
    pub filename: es_string_token_t,
    /// The mode of the socket file
    pub mode: mode_t,
    _reserved: [u8; 64],
}

#[cfg(feature = "macos_10_15_1")]
should_not_be_null_fields!(es_event_uipc_bind_t; dir -> es_file_t);

/// Fired when a UNIX-domain socket is about to be connected.
///
/// Cache key for this event type: `(process executable file, socket file)`.
#[cfg(feature = "macos_10_15_1")]
#[repr(C)]
pub struct es_event_uipc_connect_t {
    /// Describes the socket file that the socket is bound to
    pub file: ShouldNotBeNull<es_file_t>,
    /// The communications domain of the socket (see `socket(2)`)
    pub domain: c_int,
    /// The type of the socket (see `socket(2)`)
    pub type_: c_int,
    /// The protocol of the socket (see `socket(2)`)
    pub protocol: c_int,
    _reserved: [u8; 64],
}

#[cfg(feature = "macos_10_15_1")]
should_not_be_null_fields!(es_event_uipc_connect_t; file -> es_file_t);

/// Set a file ACL.
///
/// This event type does not support caching.
#[cfg(feature = "macos_10_15_1")]
#[repr(C)]
pub struct es_event_setacl_t {
    /// Describes the file whose ACL is being set.
    pub target: ShouldNotBeNull<es_file_t>,
    /// Describes whether or not the ACL on the `target` is being set or cleared
    pub set_or_clear: es_set_or_clear_t,
    /// Union that is valid when `set_or_clear` is set to `ES_SET`
    pub acl: es_event_setacl_t_anon_0,
    _reserved: [u8; 64],
}

#[cfg(feature = "macos_10_15_1")]
should_not_be_null_fields!(es_event_setacl_t; target -> es_file_t);

#[cfg(feature = "macos_10_15_1")]
impl es_event_setacl_t {
    /// `Some` if `set_or_clear` is `ES_SET`
    ///
    /// # Safety
    ///
    /// `acl_t` is a pointer to the opaque ACL, be careful not to extend it's lifetime past that
    /// of `self`. The `acl` and `set_or_clear` fields must be synced.
    pub unsafe fn acl(&self) -> Option<&acl_t> {
        if self.set_or_clear == es_set_or_clear_t::ES_SET {
            // Safety: we checked `set_or_clear` for the correct value just before and the field
            // are guaranteed to be in sync by the caller.
            Some(unsafe { &self.acl.set })
        } else {
            None
        }
    }
}

/// See [`es_event_setacl_t`]
#[cfg(feature = "macos_10_15_1")]
#[repr(C)]
pub union es_event_setacl_t_anon_0 {
    /// The [`acl_t`] structure to be used by various `acl(3)` functions.
    ///
    /// See the warning on the type to learn how to use it safely.
    ///
    /// This is theoretically `ShouldNotBeNull` but since it can be absent depending on
    /// [`es_event_setacl_t::set_or_clear`], this is not represented in the type here
    pub set: acl_t,
}

/// Fired when a pseudoterminal control device is granted
///
/// This event type does not support caching (notify-only).
#[cfg(feature = "macos_10_15_4")]
#[repr(C)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct es_event_pty_grant_t {
    /// Major and minor numbers of device
    pub dev: dev_t,
    _reserved: [u8; 64],
}

/// Fired when a pseudoterminal control device is closed
///
/// This event type does not support caching (notify-only).
#[cfg(feature = "macos_10_15_4")]
#[repr(C)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct es_event_pty_close_t {
    /// Major and minor numbers of device
    pub dev: dev_t,
    _reserved: [u8; 64],
}

/// Access control check for retrieving process information
///
/// Cache key for this event type: `(process executable file, target process executable file, type)`.
#[cfg(feature = "macos_10_15_4")]
#[repr(C)]
pub struct es_event_proc_check_t {
    /// The process for which the access will be checked
    pub target: *mut es_process_t,
    /// The type of call number used to check the access on the target process
    pub type_: es_proc_check_type_t,
    /// The flavor used to check the access on the target process
    pub flavor: c_int,
    _reserved: [u8; 64],
}

#[cfg(feature = "macos_10_15_4")]
null_fields!(es_event_proc_check_t; target -> es_process_t);

/// Access control check for searching a volume or a mounted file system
///
/// Cache key for this event type: `(process executable file, target file)`.
#[cfg(feature = "macos_11_0_0")]
#[repr(C)]
pub struct es_event_searchfs_t {
    /// The attributes that will be used to do the search
    pub attrlist: attrlist,
    /// The volume whose contents will be searched
    pub target: ShouldNotBeNull<es_file_t>,
    _reserved: [u8; 64],
}

#[cfg(feature = "macos_11_0_0")]
should_not_be_null_fields!(es_event_searchfs_t; target -> es_file_t);

ffi_wrap_enum!(
    /// This enum describes the type of suspend/resume operations that are currently used
    es_proc_suspend_resume_type_t(u32);

    == MACOS_10_15_0;
    ES_PROC_SUSPEND_RESUME_TYPE_SUSPEND = 0,
    ES_PROC_SUSPEND_RESUME_TYPE_RESUME = 1,
    --
    ES_PROC_SUSPEND_RESUME_TYPE_SHUTDOWN_SOCKETS = 3,
);

/// Fired when one of pid_suspend, pid_resume or pid_shutdown_sockets is called on a process
///
/// This event type does not support caching.
#[cfg(feature = "macos_11_0_0")]
#[repr(C)]
pub struct es_event_proc_suspend_resume_t {
    /// The process that is being suspended, resumed, or is the object of a pid_shutdown_sockets call
    pub target: *mut es_process_t,
    /// The type of operation that was called on the target process
    pub type_: es_proc_suspend_resume_type_t,
    _reserved: [u8; 64],
}

#[cfg(feature = "macos_11_0_0")]
null_fields!(es_event_proc_suspend_resume_t; target -> es_process_t);

/// Code signing status for process was invalidated.
///
/// This event fires when the `CS_VALID` bit is removed from a process' CS flags, that is, when the
/// first invalid page is paged in for a process with an otherwise valid code signature, or when a
/// process is explicitly invalidated by a `csops(CS_OPS_MARKINVALID)` syscall. This event does not
/// fire if `CS_HARD` was set, since `CS_HARD` by design prevents the process from going invalid.
///
/// This event type does not support caching (notify-only).
#[cfg(feature = "macos_11_0_0")]
#[repr(C)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct es_event_cs_invalidated_t {
    _reserved: [u8; 64],
}

/// Fired when one process attempts to attach to another process
///
/// This event can fire multiple times for a single trace attempt, for example when the processes to
/// which is being attached is reparented during the operation
///
/// This event type does not support caching (notify-only).
#[cfg(feature = "macos_11_0_0")]
#[repr(C)]
pub struct es_event_trace_t {
    /// The process that will be attached to by the process that instigated the event
    pub target: ShouldNotBeNull<es_process_t>,
    _reserved: [u8; 64],
}

#[cfg(feature = "macos_11_0_0")]
should_not_be_null_fields!(es_event_trace_t; target -> es_process_t);

/// Notification that a process has attempted to create a thread in another process by calling one
/// of the `thread_create` or `thread_create_running` MIG routines
///
/// This event type does not support caching (notify-only).
#[cfg(feature = "macos_11_0_0")]
#[repr(C)]
pub struct es_event_remote_thread_create_t {
    /// The process in which a new thread was created
    pub target: ShouldNotBeNull<es_process_t>,
    /// The new thread state in case of `thread_create_running`, `NULL` in case of `thread_create`
    pub thread_state: *mut es_thread_state_t,
    _reserved: [u8; 64],
}

#[cfg(feature = "macos_11_0_0")]
should_not_be_null_fields!(es_event_remote_thread_create_t; target -> es_process_t);
#[cfg(feature = "macos_11_0_0")]
null_fields!(es_event_remote_thread_create_t; thread_state -> es_thread_state_t);

/// Notification that a process has called `setuid()`
///
/// This event type does not support caching (notify-only).
#[cfg(feature = "macos_12_0_0")]
#[repr(C)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct es_event_setuid_t {
    /// The `uid` argument to the `setuid()` syscall
    pub uid: uid_t,
    _reserved: [u8; 64],
}

/// Notification that a process has called `setgid()`
///
/// This event type does not support caching (notify-only).
#[cfg(feature = "macos_12_0_0")]
#[repr(C)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct es_event_setgid_t {
    /// The `gid` argument to the `setgid()` syscall
    pub gid: uid_t,
    _reserved: [u8; 64],
}

/// Notification that a process has called `seteuid()`
///
/// This event type does not support caching (notify-only).
#[cfg(feature = "macos_12_0_0")]
#[repr(C)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct es_event_seteuid_t {
    /// The `euid` argument to the `seteuid()` syscall
    pub euid: uid_t,
    _reserved: [u8; 64],
}

/// Notification that a process has called `setegid()`
///
/// This event type does not support caching (notify-only).
#[cfg(feature = "macos_12_0_0")]
#[repr(C)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct es_event_setegid_t {
    /// The `egid` argument to the `setegid()` syscall
    pub egid: uid_t,
    _reserved: [u8; 64],
}

/// Notification that a process has called `setreuid()`
///
/// This event type does not support caching (notify-only).
#[cfg(feature = "macos_12_0_0")]
#[repr(C)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct es_event_setreuid_t {
    /// The `ruid` argument to the `setreuid()` syscall
    pub ruid: uid_t,
    /// The `euid` argument to the `setreuid()` syscall
    pub euid: uid_t,
    _reserved: [u8; 64],
}

/// Notification that a process has called `setregid()`
///
/// This event type does not support caching (notify-only).
#[cfg(feature = "macos_12_0_0")]
#[repr(C)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct es_event_setregid_t {
    /// The `rgid` argument to the `setregid()` syscall
    pub rgid: uid_t,
    /// The `egid` argument to the `setregid()` syscall
    pub egid: uid_t,
    _reserved: [u8; 64],
}

/// OpenDirectory authentication data for type
/// [`ES_AUTHENTICATION_TYPE_OD`][crate::es_authentication_type_t].
#[cfg(feature = "macos_13_0_0")]
#[repr(C)]
pub struct es_event_authentication_od_t {
    /// Process that instigated the authentication (XPC caller that asked for authentication).
    pub instigator: ShouldNotBeNull<es_process_t>,
    /// OD record type against which OD is authenticating. Typically `Users`, but other record types
    /// can auth too.
    pub record_type: es_string_token_t,
    /// OD record name against which OD is authenticating. For record type `Users`, this is the
    /// username.
    pub record_name: es_string_token_t,
    /// OD node against which OD is authenticating. Typically one of `/Local/Default`, `/LDAPv3/
    /// <server>` or `/Active Directory/<domain>`.
    pub node_name: es_string_token_t,
    /// Optional. If node_name is "/Local/Default", this is the path of the database against which
    /// OD is authenticating.
    pub db_path: es_string_token_t,
}

#[cfg(feature = "macos_13_0_0")]
should_not_be_null_fields!(es_event_authentication_od_t; instigator -> es_process_t);

#[cfg(feature = "macos_13_0_0")]
ffi_wrap_enum!(
    /// See [`es_event_authentication_touchid_t`]
    es_touchid_mode_t(u32);

    == MACOS_13_0_0;
    ES_TOUCHID_MODE_VERIFICATION = 0,
    --
    ES_TOUCHID_MODE_IDENTIFICATION = 1,
);

/// TouchID authentication data for type
/// [`ES_AUTHENTICATION_TYPE_TOUCHID`][crate::es_authentication_type_t].
#[cfg(feature = "macos_13_0_0")]
#[repr(C)]
pub struct es_event_authentication_touchid_t {
    /// Process that instigated the authentication (XPC caller that asked for authentication).
    pub instigator: ShouldNotBeNull<es_process_t>,
    /// TouchID authentication type
    pub touchid_mode: es_touchid_mode_t,
    /// Describes whether or not the uid of the user authenticated is available
    pub has_uid: bool,
    /// Union that is valid when `has_uid` is set to `true`
    pub anon0: es_event_authentication_touchid_t_anon0,
}

#[cfg(feature = "macos_13_0_0")]
should_not_be_null_fields!(es_event_authentication_touchid_t; instigator -> es_process_t);

/// See [`es_event_authentication_touchid_t`]
#[cfg(feature = "macos_13_0_0")]
#[repr(C)]
pub union es_event_authentication_touchid_t_anon0 {
    /// Uid of user that was authenticated. This will be set when `success` is true and
    /// `touchid_mode` is of verification type i.e.
    /// [`ES_TOUCHID_MODE_VERIFICATION`][crate::es_authentication_type_t].
    pub uid: uid_t,
}

/// Token authentication data for type
/// [`ES_AUTHENTICATION_TYPE_TOKEN`][crate::es_authentication_type_t].
#[cfg(feature = "macos_13_0_0")]
#[repr(C)]
pub struct es_event_authentication_token_t {
    /// Process that instigated the authentication (XPC caller that asked for authentication).
    pub instigator: ShouldNotBeNull<es_process_t>,
    /// Hash of the public key which CryptoTokenKit is authenticating.
    pub pubkey_hash: es_string_token_t,
    /// Token identifier of the event which CryptoTokenKit is authenticating.
    pub token_id: es_string_token_t,
    /// Optional. This will be available if token is used for GSS PKINIT authentication for
    /// obtaining a kerberos TGT. `NULL` in all other cases.
    pub kerberos_principal: es_string_token_t,
}

#[cfg(feature = "macos_13_0_0")]
should_not_be_null_fields!(es_event_authentication_token_t; instigator -> es_process_t);

#[cfg(feature = "macos_13_0_0")]
ffi_wrap_enum!(
    /// See [`es_event_authentication_auto_unlock_t`].
    es_auto_unlock_type_t(u32);

    == MACOS_13_0_0;
    /// Unlock the machine using Apple Watch.
    ES_AUTO_UNLOCK_MACHINE_UNLOCK = 1,
    --
    /// Approve an authorization prompt using Apple Watch.
    ES_AUTO_UNLOCK_AUTH_PROMPT = 2,
);

/// Auto Unlock authentication data for type
/// [`ES_AUTHENTICATION_TYPE_TOKEN`][crate::es_authentication_type_t].
///
/// This kind of authentication is performed when authenticating to the local Mac using an Apple
/// Watch for the purpose of unlocking the machine or confirming an authorization prompt. Auto
/// Unlock is part of Continuity.
///
/// This event type does not support caching (notify-only).
#[cfg(feature = "macos_13_0_0")]
#[repr(C)]
pub struct es_event_authentication_auto_unlock_t {
    /// Username for which the authentication was attempted.
    pub username: es_string_token_t,
    /// Purpose of the authentication.
    pub type_: es_auto_unlock_type_t,
}

/// Notification that an authentication was performed.
///
/// This event type does not support caching (notify-only).
#[cfg(feature = "macos_13_0_0")]
#[repr(C)]
pub struct es_event_authentication_t {
    /// True iff authentication was successful.
    pub success: bool,
    /// The type of authentication.
    pub type_: es_authentication_type_t,
    /// Type-specific data describing the authentication.
    pub data: es_event_authentication_t_anon0,
}

/// See [`es_event_authentication_t`]
#[cfg(feature = "macos_13_0_0")]
#[repr(C)]
#[derive(Copy, Clone)]
pub union es_event_authentication_t_anon0 {
    pub od: ShouldNotBeNull<es_event_authentication_od_t>,
    pub touchid: ShouldNotBeNull<es_event_authentication_touchid_t>,
    pub token: ShouldNotBeNull<es_event_authentication_token_t>,
    pub auto_unlock: ShouldNotBeNull<es_event_authentication_auto_unlock_t>,
}

#[cfg(feature = "macos_13_0_0")]
should_not_be_null_fields!(
    es_event_authentication_t_anon0;
    od -> es_event_authentication_od_t,
    touchid -> es_event_authentication_touchid_t,
    token -> es_event_authentication_token_t,
    auto_unlock -> es_event_authentication_auto_unlock_t,
);

/// Notification that XProtect detected malware.
///
/// For any given malware incident, XProtect may emit zero or more `xp_malware_detected` events, and
/// zero or more `xp_malware_remediated` events.
///
/// This event type does not support caching (notify-only).
#[cfg(feature = "macos_13_0_0")]
#[repr(C)]
pub struct es_event_xp_malware_detected_t {
    /// Version of the signatures used for detection. Currently corresponds to XProtect version.
    pub signature_version: es_string_token_t,
    /// String identifying the malware that was detected.
    pub malware_identifier: es_string_token_t,
    /// String identifying the incident, intended for linking multiple malware detected and
    /// remediated events.
    pub incident_identifier: es_string_token_t,
    /// Path where malware was detected. This path is not necessarily a malicious binary, it can
    /// also be a legitimate file containing a malicious portion.
    pub detected_path: es_string_token_t,
}

/// Notification that XProtect remediated malware.
///
/// For any given malware incident, XProtect may emit zero or more `xp_malware_detected` events, and
/// zero or more `xp_malware_remediated` events.
///
/// This event type does not support caching (notify-only).
#[cfg(feature = "macos_13_0_0")]
#[repr(C)]
pub struct es_event_xp_malware_remediated_t {
    /// Version of the signatures used for remediation. Currently corresponds to XProtect version.
    pub signature_version: es_string_token_t,
    /// String identifying the malware that was detected.
    pub malware_identifier: es_string_token_t,
    /// String identifying the incident, intended for linking multiple malware detected and
    /// remediated events.
    pub incident_identifier: es_string_token_t,
    /// String indicating the type of action that was taken, e.g. "path_delete".
    pub action_type: es_string_token_t,
    /// True only if remediation was successful.
    pub success: bool,
    /// String describing specific reasons for failure or success.
    pub result_description: es_string_token_t,
    /// Optional. Path that was subject to remediation, if any. This path is not necessarily
    /// a malicious binary, it can also be a legitimate file containing a malicious portion.
    /// Specifically, the file at this path may still exist after successful remediation.
    pub remediated_path: es_string_token_t,
    /// Audit token of process that was subject to remediation, if any.
    pub remediated_process_audit_token: *mut audit_token_t,
}

#[cfg(feature = "macos_13_0_0")]
null_fields!(es_event_xp_malware_remediated_t; remediated_process_audit_token -> audit_token_t);

/// A session identifier identifying a on-console or off-console graphical session.
///
/// A graphical session exists and can potentially be attached to via Screen Sharing before a user
/// is logged in. EndpointSecurity clients should treat the `graphical_session_id` as an opaque
/// identifier and not assign special meaning to it beyond correlating events pertaining to the same
/// graphical session. Not to be confused with the audit session ID.
#[cfg(feature = "macos_13_0_0")]
pub type es_graphical_session_id_t = u32;

/// Notification that LoginWindow has logged in a user.
///
/// This event type does not support caching (notify-only).
#[cfg(feature = "macos_13_0_0")]
#[repr(C)]
pub struct es_event_lw_session_login_t {
    /// Short username of the user.
    pub username: es_string_token_t,
    /// Graphical session id of the session.
    pub graphical_session_id: es_graphical_session_id_t,
}

/// Notification that LoginWindow has logged out a user.
///
/// This event type does not support caching (notify-only).
#[cfg(feature = "macos_13_0_0")]
#[repr(C)]
pub struct es_event_lw_session_logout_t {
    /// Short username of the user.
    pub username: es_string_token_t,
    /// Graphical session id of the session.
    pub graphical_session_id: es_graphical_session_id_t,
}

/// Notification that LoginWindow locked the screen of a session.
///
///
/// This event type does not support caching (notify-only).
#[cfg(feature = "macos_13_0_0")]
#[repr(C)]
pub struct es_event_lw_session_lock_t {
    /// Short username of the user.
    pub username: es_string_token_t,
    /// Graphical session id of the session.
    pub graphical_session_id: es_graphical_session_id_t,
}

/// Notification that LoginWindow unlocked the screen of a session.
///
/// This event type does not support caching (notify-only).
#[cfg(feature = "macos_13_0_0")]
#[repr(C)]
pub struct es_event_lw_session_unlock_t {
    /// Short username of the user.
    pub username: es_string_token_t,
    /// Graphical session id of the session.
    pub graphical_session_id: es_graphical_session_id_t,
}

/// Notification that Screen Sharing has attached to a graphical session.
///
/// This event type does not support caching (notify-only).
///
/// This event is not emitted when a screensharing session has the same source and destination
/// address. For example if device A is acting as a NAT gateway for device B, then a screensharing
/// session from B -> A would not emit an event.
#[cfg(feature = "macos_13_0_0")]
#[repr(C)]
pub struct es_event_screensharing_attach_t {
    /// True iff Screen Sharing successfully attached.
    pub success: bool,
    /// Type of source address.
    pub source_address_type: es_address_type_t,
    /// Optional. Source address of connection, or `NULL`. Depending on the transport used, the
    /// source address may or may not be available.
    pub source_address: es_string_token_t,
    /// Optional. For screen sharing initiated using an Apple ID (e.g., from Messages or FaceTime),
    /// this is the viewer's (client's) Apple ID. It is not necessarily the Apple ID that invited
    /// the screen sharing. `NULL` if unavailable.
    pub viewer_appleid: es_string_token_t,
    /// Type of authentication.
    pub authentication_type: es_string_token_t,
    /// Optional. Username used for authentication to Screen Sharing. `NULL` if authentication type
    /// doesn't use an username (e.g. simple VNC password).
    pub authentication_username: es_string_token_t,
    /// Optional. Username of the loginwindow session if available, `NULL` otherwise.
    pub session_username: es_string_token_t,
    /// True iff there was an existing user session.
    pub existing_session: bool,
    /// Graphical session id of the screen shared.
    pub graphical_session_id: es_graphical_session_id_t,
}

/// Notification that Screen Sharing has detached from a graphical session.
///
/// This event type does not support caching (notify-only).
///
/// This event is not emitted when a screensharing session has the same source and destination
/// address.
#[cfg(feature = "macos_13_0_0")]
#[repr(C)]
pub struct es_event_screensharing_detach_t {
    /// Type of source address.
    pub source_address_type: es_address_type_t,
    /// Optional. Source address of connection, or `NULL`. Depending on the transport used, the
    /// source address may or may not be available.
    pub source_address: es_string_token_t,
    /// Optional. For screen sharing initiated using an Apple ID (e.g., from Messages or FaceTime),
    /// this is the viewer's (client's) Apple ID. It is not necessarily the Apple ID that invited
    /// the screen sharing. `NULL` if unavailable.
    pub viewer_appleid: es_string_token_t,
    /// Graphical session id of the screen shared.
    pub graphical_session_id: es_graphical_session_id_t,
}

#[cfg(feature = "macos_13_0_0")]
ffi_wrap_enum!(
    /// See [`es_event_openssh_login_t`]
    es_openssh_login_result_type_t(u32);

    == MACOS_13_0_0;
    ES_OPENSSH_LOGIN_EXCEED_MAXTRIES = 0,
    ES_OPENSSH_LOGIN_ROOT_DENIED = 1,
    ES_OPENSSH_AUTH_SUCCESS = 2,
    ES_OPENSSH_AUTH_FAIL_NONE = 3,
    ES_OPENSSH_AUTH_FAIL_PASSWD = 4,
    ES_OPENSSH_AUTH_FAIL_KBDINT = 5,
    ES_OPENSSH_AUTH_FAIL_PUBKEY = 6,
    ES_OPENSSH_AUTH_FAIL_HOSTBASED = 7,
    ES_OPENSSH_AUTH_FAIL_GSSAPI = 8,
    --
    ES_OPENSSH_INVALID_USER = 9,
);

/// Notification for OpenSSH login event.
///
/// This is a connection-level event. An SSH connection that is used for multiple interactive
/// sessions and/or non-interactive commands will emit only a single successful login event.
///
/// This event type does not support caching (notify-only).
#[cfg(feature = "macos_13_0_0")]
#[repr(C)]
pub struct es_event_openssh_login_t {
    /// True iff login was successful.
    pub success: bool,
    /// Result type for the login attempt.
    pub result_type: es_openssh_login_result_type_t,
    /// Type of source address.
    pub source_address_type: es_address_type_t,
    /// Source address of connection.
    pub source_address: es_string_token_t,
    /// Username used for login.
    pub username: es_string_token_t,
    /// Describes whether or not the uid of the user logged in is available
    pub has_uid: bool,
    /// Uid of user that was logged in.
    pub anon0: es_event_openssh_login_t_anon0,
}

/// See [`es_event_openssh_login_t`]
#[cfg(feature = "macos_13_0_0")]
#[repr(C)]
pub union es_event_openssh_login_t_anon0 {
    /// Uid of user that was logged in.
    pub uid: uid_t,
}

/// Notification for OpenSSH logout event.
///
/// This is a connection-level event. An SSH connection that is used for multiple interactive
/// sessions and/or non-interactive commands will emit only a single logout event.
///
/// This event type does not support caching (notify-only).
#[cfg(feature = "macos_13_0_0")]
#[repr(C)]
pub struct es_event_openssh_logout_t {
    /// Type of address used in the connection.
    pub source_address_type: es_address_type_t,
    /// Source address of the connection.
    pub source_address: es_string_token_t,
    /// Username which got logged out.
    pub username: es_string_token_t,
    /// uid of user that was logged out.
    pub uid: uid_t,
}

/// Notification for authenticated login event from `/usr/bin/login`.
///
/// This event type does not support caching (notify-only).
#[cfg(feature = "macos_13_0_0")]
#[repr(C)]
pub struct es_event_login_login_t {
    /// True iff login was successful.
    pub success: bool,
    /// Optional. Failure message generated.
    pub failure_message: es_string_token_t,
    /// Username used for login.
    pub username: es_string_token_t,
    /// Describes whether or not the uid of the user logged in is available or not.
    pub has_uid: bool,
    /// Union that is valid when `has_uid` is set to `true`
    pub anon0: es_event_login_login_t_anon0,
}

/// See [`es_event_login_login_t`]
#[cfg(feature = "macos_13_0_0")]
#[repr(C)]
pub union es_event_login_login_t_anon0 {
    /// Uid of user that was logged in.
    pub uid: uid_t,
}

/// Notification for authenticated logout event from `/usr/bin/login`.
///
/// This event type does not support caching (notify-only).
#[cfg(feature = "macos_13_0_0")]
#[repr(C)]
pub struct es_event_login_logout_t {
    /// Username used for login.
    pub username: es_string_token_t,
    /// uid of user that was logged in.
    pub uid: uid_t,
}

/// Notification for launch item being made known to background task management. This includes
/// launch agents and daemons as well as login items added by the user, via MDM or by an app.
///
/// May be emitted for items where an add was already seen previously, with or without the item
/// having changed.
///
/// This event type does not support caching (notify-only).
#[cfg(feature = "macos_13_0_0")]
#[repr(C)]
pub struct es_event_btm_launch_item_add_t {
    /// Optional. Process that instigated the BTM operation (XPC caller that asked for the item to
    /// be added).
    pub instigator: *mut es_process_t,
    /// Optional. App process that registered the item.
    pub app: *mut es_process_t,
    /// BTM launch item.
    pub item: ShouldNotBeNull<es_btm_launch_item_t>,
    /// Optional. If available and applicable, the POSIX executable path from the launchd plist. If
    /// the path is relative, it is relative to `item.app_url`.
    pub executable_path: es_string_token_t,
}

#[cfg(feature = "macos_13_0_0")]
should_not_be_null_fields!(es_event_btm_launch_item_add_t; item -> es_btm_launch_item_t);
#[cfg(feature = "macos_13_0_0")]
null_fields!(es_event_btm_launch_item_add_t; instigator -> es_process_t, app -> es_process_t);

/// Notification for launch item being removed from background
///        task management.  This includes launch agents and daemons as
///        well as login items added by the user, via MDM or by an app.
///
/// This event type does not support caching (notify-only).
#[cfg(feature = "macos_13_0_0")]
#[repr(C)]
pub struct es_event_btm_launch_item_remove_t {
    /// Optional. Process that instigated the BTM operation (XPC caller that asked for the item to
    /// be added).
    pub instigator: *mut es_process_t,
    /// Optional. App process that registered the item.
    pub app: *mut es_process_t,
    /// BTM launch item.
    pub item: ShouldNotBeNull<es_btm_launch_item_t>,
}

#[cfg(feature = "macos_13_0_0")]
should_not_be_null_fields!(es_event_btm_launch_item_remove_t; item -> es_btm_launch_item_t);
#[cfg(feature = "macos_13_0_0")]
null_fields!(es_event_btm_launch_item_remove_t; instigator -> es_process_t, app -> es_process_t);

/// Notification for a su policy decisions events.
///
/// This event type does not support caching (notify-only). Should always
/// emit on success but will only emit on security relevant failures. For example,
/// Endpoint Security clients will not get an event for `su` being passed invalid
/// command line arguments.
#[cfg(feature = "macos_14_0_0")]
#[repr(C)]
pub struct es_event_su_t {
    /// True iff su was successful.
    pub success: bool,
    /// Optional. If success is false, a failure message is contained in this field
    pub failure_message: es_string_token_t,
    /// The uid of the user who initiated the su
    pub from_uid: uid_t,
    /// The name of the user who initiated the su
    pub from_username: es_string_token_t,
    /// True iff su was successful, Describes whether or not the to_uid is interpretable
    pub has_to_uid: bool,
    /// Optional. If success, the user ID that is going to be substituted
    pub to_uid: es_event_su_t_anon0,
    /// Optional. If success, the user name that is going to be substituted
    pub to_username: es_string_token_t,
    /// Optional. If success, the shell is going to execute
    pub shell: es_string_token_t,
    /// The length of argv
    pub argc: usize,
    /// If success, the arguments are passed into to the shell
    pub argv: *mut es_string_token_t,
    /// The length of env
    pub env_count: usize,
    /// If success, list of environment variables that is going to be substituted
    pub env: *mut es_string_token_t,
}

/// See [`es_event_su_t`]
#[cfg(feature = "macos_14_0_0")]
#[repr(C)]
pub union es_event_su_t_anon0 {
    pub uid: uid_t,
}

#[cfg(feature = "macos_14_0_0")]
ffi_wrap_enum!(
    /// Describes the type of plugin types in sudo.
    es_sudo_plugin_type_t(u32);

    == MACOS_14_0_0;
    ES_SUDO_PLUGIN_TYPE_UNKNOWN = 0,
    ES_SUDO_PLUGIN_TYPE_FRONT_END = 1,
    ES_SUDO_PLUGIN_TYPE_POLICY = 2,
    ES_SUDO_PLUGIN_TYPE_IO = 3,
    ES_SUDO_PLUGIN_TYPE_AUDIT = 4,
    --
    ES_SUDO_PLUGIN_TYPE_APPROVAL = 5,
);

/// Provides context about failures in [`es_event_sudo_t`].
#[cfg(feature = "macos_14_0_0")]
#[repr(C)]
pub struct es_sudo_reject_info_t {
    /// The sudo plugin that initiated the reject
    pub plugin_name: es_string_token_t,
    /// The sudo plugin type that initiated the reject
    pub plugin_type: es_sudo_plugin_type_t,
    /// A reason represented by a string for the failure
    pub failure_message: es_string_token_t,
}

/// Notification for a sudo event.
///
/// This event type does not support caching (notify-only).
#[cfg(feature = "macos_14_0_0")]
#[repr(C)]
pub struct es_event_sudo_t {
    /// True iff sudo was successful
    pub success: bool,
    /// Optional. When success is false, describes why sudo was rejected
    pub reject_info: *mut es_sudo_reject_info_t,
    /// Describes whether or not the from_uid is interpretable
    pub has_from_uid: bool,
    /// Optional. The uid of the user who initiated the su
    pub from_uid: es_event_sudo_t_anon0,
    /// Optional. The name of the user who initiated the su
    pub from_username: es_string_token_t,
    /// Describes whether or not the to_uid is interpretable
    pub has_to_uid: bool,
    /// Optional. If success, the user ID that is going to be substituted
    pub to_uid: es_event_sudo_t_anon0,
    /// Optional. If success, the user name that is going to be substituted
    pub to_username: es_string_token_t,
    /// Optional. The command to be run
    pub command: es_string_token_t,
}

#[cfg(feature = "macos_14_0_0")]
null_fields!(es_event_sudo_t; reject_info -> es_sudo_reject_info_t);

/// [`es_event_sudo_t`]
#[cfg(feature = "macos_14_0_0")]
#[repr(C)]
pub union es_event_sudo_t_anon0 {
    pub uid: uid_t,
}

/// Notification for Profiles installed on the system.
///
/// This event type does not support caching (notify-only).
#[cfg(feature = "macos_14_0_0")]
#[repr(C)]
pub struct es_event_profile_add_t {
    /// Process that instigated the Profile install or update.
    pub instigator: ShouldNotBeNull<es_process_t>,
    /// Indicates if the profile is an update to an already installed profile.
    pub is_update: bool,
    /// Profile install item.
    pub profile: ShouldNotBeNull<es_profile_t>,
}

#[cfg(feature = "macos_14_0_0")]
should_not_be_null_fields!(es_event_profile_add_t; instigator -> es_process_t, profile -> es_profile_t);

/// Notification for Profiles removed on the system.
///
/// This event type does not support caching (notify-only).
#[cfg(feature = "macos_14_0_0")]
#[repr(C)]
pub struct es_event_profile_remove_t {
    /// Process that instigated the Profile removal.
    pub instigator: ShouldNotBeNull<es_process_t>,
    /// Profile being removed.
    pub profile: ShouldNotBeNull<es_profile_t>,
}

#[cfg(feature = "macos_14_0_0")]
should_not_be_null_fields!(es_event_profile_remove_t; instigator -> es_process_t, profile -> es_profile_t);

/// Notification that a process petitioned for certain authorization rights
///
/// This event type does not support caching (notify-only).
#[cfg(feature = "macos_14_0_0")]
#[repr(C)]
pub struct es_event_authorization_petition_t {
    /// Process that submitted the petition (XPC caller)
    pub instigator: ShouldNotBeNull<es_process_t>,
    /// Process that created the petition
    pub petitioner: *mut es_process_t,
    /// Flags associated with the petition. Defined in Security framework "Authorization/Authorization.h"
    pub flags: u32,
    /// The number of elements in `rights`
    pub right_count: usize,
    /// Array of string tokens, each token is the name of a right being requested
    pub rights: *mut es_string_token_t,
}

#[cfg(feature = "macos_14_0_0")]
should_not_be_null_fields!(es_event_authorization_petition_t; instigator -> es_process_t);
#[cfg(feature = "macos_14_0_0")]
null_fields!(es_event_authorization_petition_t; petitioner -> es_process_t);

/// Describes, for a single right, the class of that right and if it was granted
#[cfg(feature = "macos_14_0_0")]
#[repr(C)]
pub struct es_authorization_result_t {
    /// The name of the right being considered
    pub right_name: es_string_token_t,
    /// The class of the right being considered
    ///
    /// The rule class determines how the operating system determines if it should be granted or not
    pub rule_class: es_authorization_rule_class_t,
    /// Indicates if the right was granted or not
    pub granted: bool,
}

/// Notification that a process had it's right petition judged
///
/// This event type does not support caching (notify-only).
#[cfg(feature = "macos_14_0_0")]
#[repr(C)]
pub struct es_event_authorization_judgement_t {
    /// Process that submitted the petition (XPC caller)
    pub instigator: ShouldNotBeNull<es_process_t>,
    /// Process that created the petition
    pub petitioner: *mut es_process_t,
    /// The overall result of the petition. 0 indicates success.
    ///
    /// Possible return codes are defined in Security framework "Authorization/Authorization.h"
    pub return_code: i32,
    /// The number of elements in `results`
    pub result_count: usize,
    /// Array of results. One for each right that was petitioned
    pub results: *mut es_authorization_result_t,
}

#[cfg(feature = "macos_14_0_0")]
should_not_be_null_fields!(es_event_authorization_judgement_t; instigator -> es_process_t);
#[cfg(feature = "macos_14_0_0")]
null_fields!(es_event_authorization_judgement_t; petitioner -> es_process_t);

/// The identity of a group member
#[cfg(feature = "macos_14_0_0")]
#[repr(C)]
pub struct es_od_member_id_t {
    /// Indicates the type of the member, and how it is identified.
    ///
    /// Note that member_type indicates which field of member_value is initialised.
    pub member_type: es_od_member_type_t,
    /// The member identity.
    pub member_value: es_od_member_id_t_anon0,
}

/// See [`es_od_member_id_t`]
#[cfg(feature = "macos_14_0_0")]
#[repr(C)]
pub union es_od_member_id_t_anon0 {
    pub uuid: uuid_t,
    pub name: ManuallyDrop<es_string_token_t>,
}

/// Notification that a member was added to a group.
///
/// This event type does not support caching (notify-only).
///
/// This event does not indicate that a member was actually added. For example when adding a user
/// to a group they are already a member of.
#[cfg(feature = "macos_14_0_0")]
#[repr(C)]
pub struct es_event_od_group_add_t {
    /// Process that instigated operation (XPC caller).
    pub instigator: ShouldNotBeNull<es_process_t>,
    /// Result code for the operation.
    pub error_code: i32,
    /// The group to which the member was added.
    pub group_name: es_string_token_t,
    /// The identity of the member added.
    pub member: ShouldNotBeNull<es_od_member_id_t>,
    /// OD node being mutated.
    ///
    /// Typically one of "/Local/Default", "/LDAPv3/<server>" or "/Active Directory/<domain>".
    pub node_name: es_string_token_t,
    /// Optional. If node_name is "/Local/Default", this is, the path of the database against which
    /// OD is authenticating.
    pub db_path: es_string_token_t,
}

#[cfg(feature = "macos_14_0_0")]
should_not_be_null_fields!(es_event_od_group_add_t; instigator -> es_process_t);

/// Notification that a member was removed to a group.
///
/// This event type does not support caching (notify-only).
///
/// This event does not indicate that a member was actually removed. For example when removing a
/// user from a group they are not a member of.
#[cfg(feature = "macos_14_0_0")]
#[repr(C)]
pub struct es_event_od_group_remove_t {
    /// Process that instigated operation (XPC caller).
    pub instigator: ShouldNotBeNull<es_process_t>,
    /// Result code for the operation.
    pub error_code: i32,
    /// The group to which the member was removed.
    pub group_name: es_string_token_t,
    /// The identity of the member removed.
    pub member: ShouldNotBeNull<es_od_member_id_t>,
    /// OD node being mutated.
    ///
    /// Typically one of "/Local/Default", "/LDAPv3/<server>" or "/Active Directory/<domain>".
    pub node_name: es_string_token_t,
    /// Optional. If node_name is "/Local/Default", this is, the path of the database against which
    /// OD is authenticating.
    pub db_path: es_string_token_t,
}

#[cfg(feature = "macos_14_0_0")]
should_not_be_null_fields!(es_event_od_group_remove_t; instigator -> es_process_t);

/// An array of group member identities.
#[cfg(feature = "macos_14_0_0")]
#[repr(C)]
pub struct es_od_member_id_array_t {
    /// Indicates the type of the members, and how they are identified.
    ///
    /// Note that `member_type` indicates which field of member_array is initialised.
    pub member_type: es_od_member_type_t,
    /// The number of elements in `member_array`.
    pub member_count: usize,
    /// A union of pointers.
    ///
    /// The initialised member points to the first element of an array of member values.
    pub member_array: es_od_member_id_array_t_anon0,
}

/// See [`es_od_member_id_array_t`]
#[cfg(feature = "macos_14_0_0")]
#[repr(C)]
pub union es_od_member_id_array_t_anon0 {
    pub uuids: ShouldNotBeNull<uuid_t>,
    pub names: ShouldNotBeNull<es_string_token_t>,
}

/// Notification that a group had it's members initialised or replaced.
///
/// This event type does not support caching (notify-only).
#[cfg(feature = "macos_14_0_0")]
#[repr(C)]
pub struct es_event_od_group_set_t {
    /// Process that instigated operation (XPC caller).
    pub instigator: ShouldNotBeNull<es_process_t>,
    /// Result code for the operation.
    ///
    /// Values indicating specific failure reasons are defined in odconstants.h.
    pub error_code: i32,
    /// The group to which members were set.
    pub group_name: es_string_token_t,
    /// Array of new members.
    pub members: ShouldNotBeNull<es_od_member_id_array_t>,
    /// OD node being mutated.
    ///
    /// Typically one of "/Local/Default", "/LDAPv3/<server>" or "/Active Directory/<domain>".
    pub node_name: es_string_token_t,
    /// Optional. If node_name is "/Local/Default", this is, the path of the database against which
    /// OD is authenticating.
    pub db_path: es_string_token_t,
}

#[cfg(feature = "macos_14_0_0")]
should_not_be_null_fields!(es_event_od_group_set_t; instigator -> es_process_t);

/// Notification that an account had its password modified.
///
/// This event type does not support caching (notify-only).
#[cfg(feature = "macos_14_0_0")]
#[repr(C)]
pub struct es_event_od_modify_password_t {
    /// Process that instigated operation (XPC caller).
    pub instigator: ShouldNotBeNull<es_process_t>,
    /// Result code for the operation.
    ///
    /// Values indicating specific failure reasons are defined in odconstants.h.
    pub error_code: i32,
    /// The type of the account for which the password was modified.
    pub account_type: es_od_account_type_t,
    /// The name of the account for which the password was modified.
    pub account_name: es_string_token_t,
    /// OD node being mutated.
    ///
    /// Typically one of "/Local/Default", "/LDAPv3/<server>" or "/Active Directory/<domain>".
    pub node_name: es_string_token_t,
    /// Optional. If node_name is "/Local/Default", this is, the path of the database against which
    /// OD is authenticating.
    pub db_path: es_string_token_t,
}

#[cfg(feature = "macos_14_0_0")]
should_not_be_null_fields!(es_event_od_modify_password_t; instigator -> es_process_t);

/// Notification that a user account was disabled.
///
/// This event type does not support caching (notify-only).
#[cfg(feature = "macos_14_0_0")]
#[repr(C)]
pub struct es_event_od_disable_user_t {
    /// Process that instigated operation (XPC caller).
    pub instigator: ShouldNotBeNull<es_process_t>,
    /// Result code for the operation.
    ///
    /// Values indicating specific failure reasons are defined in odconstants.h.
    pub error_code: i32,
    /// The name of the user account that was disabled.
    pub user_name: es_string_token_t,
    /// OD node being mutated.
    ///
    /// Typically one of "/Local/Default", "/LDAPv3/<server>" or "/Active Directory/<domain>".
    pub node_name: es_string_token_t,
    /// Optional. If node_name is "/Local/Default", this is, the path of the database against which
    /// OD is authenticating.
    pub db_path: es_string_token_t,
}

#[cfg(feature = "macos_14_0_0")]
should_not_be_null_fields!(es_event_od_disable_user_t; instigator -> es_process_t);

/// Notification that a user account was enabled.
///
/// This event type does not support caching (notify-only).
#[cfg(feature = "macos_14_0_0")]
#[repr(C)]
pub struct es_event_od_enable_user_t {
    /// Process that instigated operation (XPC caller).
    pub instigator: ShouldNotBeNull<es_process_t>,
    /// Result code for the operation.
    ///
    /// Values indicating specific failure reasons are defined in odconstants.h.
    pub error_code: i32,
    /// The name of the user account that was enabled.
    pub user_name: es_string_token_t,
    /// OD node being mutated.
    ///
    /// Typically one of "/Local/Default", "/LDAPv3/<server>" or "/Active Directory/<domain>".
    pub node_name: es_string_token_t,
    /// Optional. If node_name is "/Local/Default", this is, the path of the database against which
    /// OD is authenticating.
    pub db_path: es_string_token_t,
}

#[cfg(feature = "macos_14_0_0")]
should_not_be_null_fields!(es_event_od_enable_user_t; instigator -> es_process_t);

/// Notification that an attribute value was added to a record.
///
/// This event type does not support caching (notify-only).
///
/// Attributes conceptually have the type `Map String (Set String)`.
/// Each OD record has a Map of attribute name to Set of attribute value.
/// When an attribute value is added, it is inserted into the set of values for that name.
#[cfg(feature = "macos_14_0_0")]
#[repr(C)]
pub struct es_event_od_attribute_value_add_t {
    /// Process that instigated operation (XPC caller).
    pub instigator: ShouldNotBeNull<es_process_t>,
    /// Result code for the operation.
    ///
    /// Values indicating specific failure reasons are defined in odconstants.h.
    pub error_code: i32,
    /// The type of the record to which the attribute value was added.
    pub record_type: es_od_record_type_t,
    /// The name of the record to which the attribute value was added.
    pub record_name: es_string_token_t,
    /// The name of the attribute to which the value was added.
    pub attribute_name: es_string_token_t,
    /// The value that was added.
    pub attribute_value: es_string_token_t,
    /// OD node being mutated.
    ///
    /// Typically one of "/Local/Default", "/LDAPv3/<server>" or "/Active Directory/<domain>".
    pub node_name: es_string_token_t,
    /// Optional. If node_name is "/Local/Default", this is, the path of the database against which
    /// OD is authenticating.
    pub db_path: es_string_token_t,
}

#[cfg(feature = "macos_14_0_0")]
should_not_be_null_fields!(es_event_od_attribute_value_add_t; instigator -> es_process_t);

/// Notification that an attribute value was removed to a record.
///
/// This event type does not support caching (notify-only).
///
/// Attributes conceptually have the type `Map String (Set String)`.
/// Each OD record has a Map of attribute name to Set of attribute value.
/// When an attribute value is removed, it is inserted into the set of values for that name.
///
/// Removing a value that was never added is a no-op.
#[cfg(feature = "macos_14_0_0")]
#[repr(C)]
pub struct es_event_od_attribute_value_remove_t {
    /// Process that instigated operation (XPC caller).
    pub instigator: ShouldNotBeNull<es_process_t>,
    /// Result code for the operation.
    ///
    /// Values indicating specific failure reasons are defined in odconstants.h.
    pub error_code: i32,
    /// The type of the record to which the attribute value was removed.
    pub record_type: es_od_record_type_t,
    /// The name of the record to which the attribute value was removed.
    pub record_name: es_string_token_t,
    /// The name of the attribute to which the value was removed.
    pub attribute_name: es_string_token_t,
    /// The value that was removed.
    pub attribute_value: es_string_token_t,
    /// OD node being mutated.
    ///
    /// Typically one of "/Local/Default", "/LDAPv3/<server>" or "/Active Directory/<domain>".
    pub node_name: es_string_token_t,
    /// Optional. If node_name is "/Local/Default", this is, the path of the database against which
    /// OD is authenticating.
    pub db_path: es_string_token_t,
}

/// Notification that an attribute is being set.
///
/// This event type does not support caching (notify-only).
///
/// Attributes conceptually have the type `Map String (Set String)`.
/// Each OD record has a Map of attribute name to Set of attribute value.
/// When an attribute value is added, it is inserted into the set of values for that name.
///
/// The new set of attribute values may be empty.
#[cfg(feature = "macos_14_0_0")]
#[repr(C)]
pub struct es_event_od_attribute_set_t {
    /// Process that instigated operation (XPC caller).
    pub instigator: ShouldNotBeNull<es_process_t>,
    /// Result code for the operation.
    ///
    /// Values indicating specific failure reasons are defined in odconstants.h.
    pub error_code: i32,
    /// The type of the record for which the attribute is being set.
    pub record_type: es_od_record_type_t,
    /// The name of the record for which the attribute is being set.
    pub record_name: es_string_token_t,
    /// The name of the attribute that was set.
    pub attribute_name: es_string_token_t,
    /// The size of attribute_value_array.
    pub attribute_value_count: usize,
    /// Array of attribute values that were set.
    pub attribute_value_array: *mut es_string_token_t,
    /// OD node being mutated.
    ///
    /// Typically one of "/Local/Default", "/LDAPv3/<server>" or "/Active Directory/<domain>".
    pub node_name: es_string_token_t,
    /// Optional. If node_name is "/Local/Default", this is, the path of the database against which
    /// OD is authenticating.
    pub db_path: es_string_token_t,
}

#[cfg(feature = "macos_14_0_0")]
should_not_be_null_fields!(es_event_od_attribute_set_t; instigator -> es_process_t);

/// Notification that a user account was created.
///
/// This event type does not support caching (notify-only).
#[cfg(feature = "macos_14_0_0")]
#[repr(C)]
pub struct es_event_od_create_user_t {
    /// Process that instigated operation (XPC caller).
    pub instigator: ShouldNotBeNull<es_process_t>,
    /// Result code for the operation.
    ///
    /// Values indicating specific failure reasons are defined in odconstants.h.
    pub error_code: i32,
    /// The name of the user account that was created.
    pub user_name: es_string_token_t,
    /// OD node being mutated.
    ///
    /// Typically one of "/Local/Default", "/LDAPv3/<server>" or "/Active Directory/<domain>".
    pub node_name: es_string_token_t,
    /// Optional. If node_name is "/Local/Default", this is, the path of the database against which
    /// OD is authenticating.
    pub db_path: es_string_token_t,
}

#[cfg(feature = "macos_14_0_0")]
should_not_be_null_fields!(es_event_od_create_user_t; instigator -> es_process_t);

/// Notification that a group was created.
///
/// This event type does not support caching (notify-only).
#[cfg(feature = "macos_14_0_0")]
#[repr(C)]
pub struct es_event_od_create_group_t {
    /// Process that instigated operation (XPC caller).
    pub instigator: ShouldNotBeNull<es_process_t>,
    /// Result code for the operation.
    ///
    /// Values indicating specific failure reasons are defined in odconstants.h.
    pub error_code: i32,
    /// The name of the group account that was created.
    pub group_name: es_string_token_t,
    /// OD node being mutated.
    ///
    /// Typically one of "/Local/Default", "/LDAPv3/<server>" or "/Active Directory/<domain>".
    pub node_name: es_string_token_t,
    /// Optional. If node_name is "/Local/Default", this is, the path of the database against which
    /// OD is authenticating.
    pub db_path: es_string_token_t,
}

#[cfg(feature = "macos_14_0_0")]
should_not_be_null_fields!(es_event_od_create_group_t; instigator -> es_process_t);

/// Notification that a user account was deleted.
///
/// This event type does not support caching (notify-only).
#[cfg(feature = "macos_14_0_0")]
#[repr(C)]
pub struct es_event_od_delete_user_t {
    /// Process that instigated operation (XPC caller).
    pub instigator: ShouldNotBeNull<es_process_t>,
    /// Result code for the operation.
    ///
    /// Values indicating specific failure reasons are defined in odconstants.h.
    pub error_code: i32,
    /// The name of the user account that was deleted.
    pub user_name: es_string_token_t,
    /// OD node being mutated.
    ///
    /// Typically one of "/Local/Default", "/LDAPv3/<server>" or "/Active Directory/<domain>".
    pub node_name: es_string_token_t,
    /// Optional. If node_name is "/Local/Default", this is, the path of the database against which
    /// OD is authenticating.
    pub db_path: es_string_token_t,
}

#[cfg(feature = "macos_14_0_0")]
should_not_be_null_fields!(es_event_od_delete_user_t; instigator -> es_process_t);

/// Notification that a group was deleted.
///
/// This event type does not support caching (notify-only).
#[cfg(feature = "macos_14_0_0")]
#[repr(C)]
pub struct es_event_od_delete_group_t {
    /// Process that instigated operation (XPC caller).
    pub instigator: ShouldNotBeNull<es_process_t>,
    /// Result code for the operation.
    ///
    /// Values indicating specific failure reasons are defined in odconstants.h.
    pub error_code: i32,
    /// The name of the group account that was deleted.
    pub group_name: es_string_token_t,
    /// OD node being mutated.
    ///
    /// Typically one of "/Local/Default", "/LDAPv3/<server>" or "/Active Directory/<domain>".
    pub node_name: es_string_token_t,
    /// Optional. If node_name is "/Local/Default", this is, the path of the database against which
    /// OD is authenticating.
    pub db_path: es_string_token_t,
}

#[cfg(feature = "macos_14_0_0")]
should_not_be_null_fields!(es_event_od_delete_group_t; instigator -> es_process_t);

/// Notification for an XPC connection being established to a named service.
#[cfg(feature = "macos_14_0_0")]
#[repr(C)]
pub struct es_event_xpc_connect_t {
    /// Service name of the named service.
    pub service_name: es_string_token_t,
    /// The type of XPC domain in which the service resides in.
    pub service_domain_type: es_xpc_domain_type_t,
}

/// Union of all possible events that can appear in an [`es_message_t`]
#[repr(C)]
pub union es_events_t {
    // Events added before macOS 13.0.0 use structs directly.
    //
    // Originally this union is sorted according to the members' names. Here we first sort it by
    // version to make it easy to track what was first added when. Note that events can be added
    // as AUTH in a version and NOTIFY in another. The first appeareance is the one used for the
    // sorting here.

    // 10.15.0
    pub close: ManuallyDrop<es_event_close_t>,
    pub create: ManuallyDrop<es_event_create_t>,
    pub exchangedata: ManuallyDrop<es_event_exchangedata_t>,
    pub exec: ManuallyDrop<es_event_exec_t>,
    pub exit: ManuallyDrop<es_event_exit_t>,
    pub file_provider_materialize: ManuallyDrop<es_event_file_provider_materialize_t>,
    pub file_provider_update: ManuallyDrop<es_event_file_provider_update_t>,
    pub fork: ManuallyDrop<es_event_fork_t>,
    pub get_task: ManuallyDrop<es_event_get_task_t>,
    pub iokit_open: ManuallyDrop<es_event_iokit_open_t>,
    pub kextload: ManuallyDrop<es_event_kextload_t>,
    pub kextunload: ManuallyDrop<es_event_kextunload_t>,
    pub link: ManuallyDrop<es_event_link_t>,
    pub lookup: ManuallyDrop<es_event_lookup_t>,
    pub mmap: ManuallyDrop<es_event_mmap_t>,
    pub mount: ManuallyDrop<es_event_mount_t>,
    pub mprotect: ManuallyDrop<es_event_mprotect_t>,
    pub open: ManuallyDrop<es_event_open_t>,
    pub readlink: ManuallyDrop<es_event_readlink_t>,
    pub rename: ManuallyDrop<es_event_rename_t>,
    pub setattrlist: ManuallyDrop<es_event_setattrlist_t>,
    pub setextattr: ManuallyDrop<es_event_setextattr_t>,
    pub setflags: ManuallyDrop<es_event_setflags_t>,
    pub setmode: ManuallyDrop<es_event_setmode_t>,
    pub setowner: ManuallyDrop<es_event_setowner_t>,
    pub signal: ManuallyDrop<es_event_signal_t>,
    pub truncate: ManuallyDrop<es_event_truncate_t>,
    pub unlink: ManuallyDrop<es_event_unlink_t>,
    pub unmount: ManuallyDrop<es_event_unmount_t>,
    pub write: ManuallyDrop<es_event_write_t>,

    // 10.15.1
    #[cfg(feature = "macos_10_15_1")]
    pub access: ManuallyDrop<es_event_access_t>,
    #[cfg(feature = "macos_10_15_1")]
    pub chdir: ManuallyDrop<es_event_chdir_t>,
    #[cfg(feature = "macos_10_15_1")]
    pub chroot: ManuallyDrop<es_event_chroot_t>,
    #[cfg(feature = "macos_10_15_1")]
    pub clone: ManuallyDrop<es_event_clone_t>,
    #[cfg(feature = "macos_10_15_1")]
    pub deleteextattr: ManuallyDrop<es_event_deleteextattr_t>,
    #[cfg(feature = "macos_10_15_1")]
    pub dup: ManuallyDrop<es_event_dup_t>,
    #[cfg(feature = "macos_10_15_1")]
    pub fcntl: ManuallyDrop<es_event_fcntl_t>,
    #[cfg(feature = "macos_10_15_1")]
    pub fsgetpath: ManuallyDrop<es_event_fsgetpath_t>,
    #[cfg(feature = "macos_10_15_1")]
    pub getattrlist: ManuallyDrop<es_event_getattrlist_t>,
    #[cfg(feature = "macos_10_15_1")]
    pub getextattr: ManuallyDrop<es_event_getextattr_t>,
    #[cfg(feature = "macos_10_15_1")]
    pub listextattr: ManuallyDrop<es_event_listextattr_t>,
    #[cfg(feature = "macos_10_15_1")]
    pub readdir: ManuallyDrop<es_event_readdir_t>,
    #[cfg(feature = "macos_10_15_1")]
    pub remount: ManuallyDrop<es_event_remount_t>,
    #[cfg(feature = "macos_10_15_1")]
    pub setacl: ManuallyDrop<es_event_setacl_t>,
    #[cfg(feature = "macos_10_15_1")]
    pub settime: ManuallyDrop<es_event_settime_t>,
    #[cfg(feature = "macos_10_15_1")]
    pub stat: ManuallyDrop<es_event_stat_t>,
    #[cfg(feature = "macos_10_15_1")]
    pub uipc_bind: ManuallyDrop<es_event_uipc_bind_t>,
    #[cfg(feature = "macos_10_15_1")]
    pub uipc_connect: ManuallyDrop<es_event_uipc_connect_t>,
    #[cfg(feature = "macos_10_15_1")]
    pub utimes: ManuallyDrop<es_event_utimes_t>,

    // 10.15.4
    #[cfg(feature = "macos_10_15_4")]
    pub proc_check: ManuallyDrop<es_event_proc_check_t>,
    #[cfg(feature = "macos_10_15_4")]
    pub pty_close: ManuallyDrop<es_event_pty_close_t>,
    #[cfg(feature = "macos_10_15_4")]
    pub pty_grant: ManuallyDrop<es_event_pty_grant_t>,

    // 11.0.0
    #[cfg(feature = "macos_11_0_0")]
    pub cs_invalidated: ManuallyDrop<es_event_cs_invalidated_t>,
    #[cfg(feature = "macos_11_0_0")]
    pub get_task_name: ManuallyDrop<es_event_get_task_name_t>,
    #[cfg(feature = "macos_11_0_0")]
    pub proc_suspend_resume: ManuallyDrop<es_event_proc_suspend_resume_t>,
    #[cfg(feature = "macos_11_0_0")]
    pub remote_thread_create: ManuallyDrop<es_event_remote_thread_create_t>,
    #[cfg(feature = "macos_11_0_0")]
    pub searchfs: ManuallyDrop<es_event_searchfs_t>,
    #[cfg(feature = "macos_11_0_0")]
    pub trace: ManuallyDrop<es_event_trace_t>,

    // 11.3.0
    #[cfg(feature = "macos_11_3_0")]
    pub get_task_read: ManuallyDrop<es_event_get_task_read_t>,
    #[cfg(feature = "macos_11_3_0")]
    pub get_task_inspect: ManuallyDrop<es_event_get_task_inspect_t>,

    // 12.0.0
    #[cfg(feature = "macos_12_0_0")]
    pub copyfile: ManuallyDrop<es_event_copyfile_t>,
    #[cfg(feature = "macos_12_0_0")]
    pub setgid: ManuallyDrop<es_event_setgid_t>,
    #[cfg(feature = "macos_12_0_0")]
    pub setuid: ManuallyDrop<es_event_setuid_t>,
    #[cfg(feature = "macos_12_0_0")]
    pub setegid: ManuallyDrop<es_event_setegid_t>,
    #[cfg(feature = "macos_12_0_0")]
    pub seteuid: ManuallyDrop<es_event_seteuid_t>,
    #[cfg(feature = "macos_12_0_0")]
    pub setregid: ManuallyDrop<es_event_setregid_t>,
    #[cfg(feature = "macos_12_0_0")]
    pub setreuid: ManuallyDrop<es_event_setreuid_t>,
    // Events added in macOS 13.0 or later use nonnull pointers.
    //
    // 13.0.0
    #[cfg(feature = "macos_13_0_0")]
    pub authentication: ShouldNotBeNull<es_event_authentication_t>,
    #[cfg(feature = "macos_13_0_0")]
    pub xp_malware_detected: ShouldNotBeNull<es_event_xp_malware_detected_t>,
    #[cfg(feature = "macos_13_0_0")]
    pub xp_malware_remediated: ShouldNotBeNull<es_event_xp_malware_remediated_t>,
    #[cfg(feature = "macos_13_0_0")]
    pub lw_session_login: ShouldNotBeNull<es_event_lw_session_login_t>,
    #[cfg(feature = "macos_13_0_0")]
    pub lw_session_logout: ShouldNotBeNull<es_event_lw_session_logout_t>,
    #[cfg(feature = "macos_13_0_0")]
    pub lw_session_lock: ShouldNotBeNull<es_event_lw_session_lock_t>,
    #[cfg(feature = "macos_13_0_0")]
    pub lw_session_unlock: ShouldNotBeNull<es_event_lw_session_unlock_t>,
    #[cfg(feature = "macos_13_0_0")]
    pub screensharing_attach: ShouldNotBeNull<es_event_screensharing_attach_t>,
    #[cfg(feature = "macos_13_0_0")]
    pub screensharing_detach: ShouldNotBeNull<es_event_screensharing_detach_t>,
    #[cfg(feature = "macos_13_0_0")]
    pub openssh_login: ShouldNotBeNull<es_event_openssh_login_t>,
    #[cfg(feature = "macos_13_0_0")]
    pub openssh_logout: ShouldNotBeNull<es_event_openssh_logout_t>,
    #[cfg(feature = "macos_13_0_0")]
    pub login_login: ShouldNotBeNull<es_event_login_login_t>,
    #[cfg(feature = "macos_13_0_0")]
    pub login_logout: ShouldNotBeNull<es_event_login_logout_t>,
    #[cfg(feature = "macos_13_0_0")]
    pub btm_launch_item_add: ShouldNotBeNull<es_event_btm_launch_item_add_t>,
    #[cfg(feature = "macos_13_0_0")]
    pub btm_launch_item_remove: ShouldNotBeNull<es_event_btm_launch_item_remove_t>,

    // 14.0.0
    #[cfg(feature = "macos_14_0_0")]
    pub profile_add: ShouldNotBeNull<es_event_profile_add_t>,
    #[cfg(feature = "macos_14_0_0")]
    pub profile_remove: ShouldNotBeNull<es_event_profile_remove_t>,
    #[cfg(feature = "macos_14_0_0")]
    pub su: ShouldNotBeNull<es_event_su_t>,
    #[cfg(feature = "macos_14_0_0")]
    pub authorization_petition: ShouldNotBeNull<es_event_authorization_petition_t>,
    #[cfg(feature = "macos_14_0_0")]
    pub authorization_judgement: ShouldNotBeNull<es_event_authorization_judgement_t>,
    #[cfg(feature = "macos_14_0_0")]
    pub sudo: ShouldNotBeNull<es_event_sudo_t>,
    #[cfg(feature = "macos_14_0_0")]
    pub od_group_add: ShouldNotBeNull<es_event_od_group_add_t>,
    #[cfg(feature = "macos_14_0_0")]
    pub od_group_remove: ShouldNotBeNull<es_event_od_group_remove_t>,
    #[cfg(feature = "macos_14_0_0")]
    pub od_group_set: ShouldNotBeNull<es_event_od_group_set_t>,
    #[cfg(feature = "macos_14_0_0")]
    pub od_modify_password: ShouldNotBeNull<es_event_od_modify_password_t>,
    #[cfg(feature = "macos_14_0_0")]
    pub od_disable_user: ShouldNotBeNull<es_event_od_disable_user_t>,
    #[cfg(feature = "macos_14_0_0")]
    pub od_enable_user: ShouldNotBeNull<es_event_od_enable_user_t>,
    #[cfg(feature = "macos_14_0_0")]
    pub od_attribute_value_add: ShouldNotBeNull<es_event_od_attribute_value_add_t>,
    #[cfg(feature = "macos_14_0_0")]
    pub od_attribute_value_remove: ShouldNotBeNull<es_event_od_attribute_value_remove_t>,
    #[cfg(feature = "macos_14_0_0")]
    pub od_attribute_set: ShouldNotBeNull<es_event_od_attribute_set_t>,
    #[cfg(feature = "macos_14_0_0")]
    pub od_create_user: ShouldNotBeNull<es_event_od_create_user_t>,
    #[cfg(feature = "macos_14_0_0")]
    pub od_create_group: ShouldNotBeNull<es_event_od_create_group_t>,
    #[cfg(feature = "macos_14_0_0")]
    pub od_delete_user: ShouldNotBeNull<es_event_od_delete_user_t>,
    #[cfg(feature = "macos_14_0_0")]
    pub od_delete_group: ShouldNotBeNull<es_event_od_delete_group_t>,
    #[cfg(feature = "macos_14_0_0")]
    pub xpc_connect: ShouldNotBeNull<es_event_xpc_connect_t>,
}

/// Indicates the result of the ES subsystem authorization process
#[repr(C)]
#[must_use]
#[derive(Copy, Clone)]
pub struct es_result_t {
    pub result_type: es_result_type_t,
    pub result: es_result_t_anon_0,
}

/// See [`es_result_t`]
#[repr(C)]
#[derive(Copy, Clone)]
pub union es_result_t_anon_0 {
    pub auth: es_auth_result_t,
    pub flags: u32,
    _reserved: [u8; 32],
}

/// This is the top level datatype that encodes information sent from the ES subsystem to its
/// clients. Each security event being processed by the ES subsystem will be encoded in an
/// `es_message_t`. A message can be an authorization request or a notification of an event that has
/// already taken place.
///
/// For events that can be authorized there are unique `NOTIFY` and `AUTH` event types for the same
/// event data, eg: `event.exec` is the correct union label for both `ES_EVENT_TYPE_AUTH_EXEC` and
/// `ES_EVENT_TYPE_NOTIFY_EXEC` event types.
///
/// For fields marked only available in specific message versions, all access must be guarded at
/// runtime by checking the value of the message version field, e.g.
///
/// ```ignore
/// if msg.version >= 2 {
///     acl = unsafe { msg.event.create.acl };
/// }
/// ```
///
/// Fields using Mach time are in the resolution matching the ES client's architecture. This means
/// they can be compared to `mach_absolute_time()` and converted to nanoseconds with the help of
/// mach_timebase_info(). Further note that on Apple silicon, x86_64 clients running under Rosetta 2
/// will see Mach times in a different resolution than native arm64 clients. For more information on
/// differences regarding Mach time on Apple silicon and Intel-based Mac computers, see "Addressing
/// Architectural Differences in Your macOS Code":
/// <https://developer.apple.com/documentation/apple_silicon/addressing_architectural_differences_in_your_macos_code>
///
/// ## Rust implementation notes
///
/// [`RefEncode`] is currently implemented with the encoding left unknown explicitly. If
/// `es_message_t` needs to be encoded for Objective C messages, this will require changes.
///
/// ## A note on userspace events
///
/// Before macOS 13.0 almost all ES events were created by `xnu` (the macOS kernel).
/// Such events are *mandatory*.
/// If no `es_event_setuid_t` event is emitted then no `setuid` took place. This is a security guarantee.
/// Most events added in macOS 13 and 14 are emitted by userspace binaries and frameworks.
/// ES still guarantees that if an event was not emitted *by that binary or framework* then it did not happen, but this is not quite the same guarantee.
///
/// Consider `es_event_su_t`:
/// This event is created by the `su` binary first shipped in macOS 14.0, but it's entirely possible for a user to install (or compile) a different `su`!
/// ES only guarantees that the platform binary shipped with macOS emits `es_event_su_t` events.
/// As such `es_event_su_t` does not provide the same security guarantee that `es_event_setuid_t` does.
///
/// When a user invokes the platform `su` binary ES will emit both `es_event_su_t` and `es_event_setuid_t` events.
/// When a user compiles their own `su` binary from source and executes it:
///
/// - ES will emit an `es_event_setuid_t` event.
/// - ES will NOT emit an `es_event_su_t`.
///
/// Userspace events are inherently discretionary.
/// It is at the users discretion as to whether they use the builtin binaries/frameworks or not.
/// Kernel events are mandatory. There is no `setuid` syscall that ES does not interdict.
///
/// The following events are created by userspace binaries or frameworks:
///
/// - [`ES_EVENT_TYPE_AUTH_FILE_PROVIDER_MATERIALIZE`]
/// - [`ES_EVENT_TYPE_NOTIFY_FILE_PROVIDER_MATERIALIZE`]
/// - [`ES_EVENT_TYPE_AUTH_FILE_PROVIDER_UPDATE`]
/// - [`ES_EVENT_TYPE_NOTIFY_FILE_PROVIDER_UPDATE`]
/// - [`ES_EVENT_TYPE_NOTIFY_AUTHENTICATION`]
/// - [`ES_EVENT_TYPE_NOTIFY_XP_MALWARE_DETECTED`]
/// - [`ES_EVENT_TYPE_NOTIFY_XP_MALWARE_REMEDIATED`]
/// - [`ES_EVENT_TYPE_NOTIFY_LW_SESSION_LOGIN`]
/// - [`ES_EVENT_TYPE_NOTIFY_LW_SESSION_LOGOUT`]
/// - [`ES_EVENT_TYPE_NOTIFY_LW_SESSION_LOCK`]
/// - [`ES_EVENT_TYPE_NOTIFY_LW_SESSION_UNLOCK`]
/// - [`ES_EVENT_TYPE_NOTIFY_SCREENSHARING_ATTACH`]
/// - [`ES_EVENT_TYPE_NOTIFY_SCREENSHARING_DETACH`]
/// - [`ES_EVENT_TYPE_NOTIFY_OPENSSH_LOGIN`]
/// - [`ES_EVENT_TYPE_NOTIFY_OPENSSH_LOGOUT`]
/// - [`ES_EVENT_TYPE_NOTIFY_LOGIN_LOGIN`]
/// - [`ES_EVENT_TYPE_NOTIFY_LOGIN_LOGOUT`]
/// - [`ES_EVENT_TYPE_NOTIFY_BTM_LAUNCH_ITEM_ADD`]
/// - [`ES_EVENT_TYPE_NOTIFY_BTM_LAUNCH_ITEM_REMOVE`]
/// - [`ES_EVENT_TYPE_NOTIFY_PROFILE_ADD`]
/// - [`ES_EVENT_TYPE_NOTIFY_PROFILE_REMOVE`]
/// - [`ES_EVENT_TYPE_NOTIFY_SU`]
/// - [`ES_EVENT_TYPE_NOTIFY_AUTHORIZATION_PETITION`]
/// - [`ES_EVENT_TYPE_NOTIFY_AUTHORIZATION_JUDGEMENT`]
/// - [`ES_EVENT_TYPE_NOTIFY_SUDO`]
/// - [`ES_EVENT_TYPE_NOTIFY_OD_GROUP_ADD`]
/// - [`ES_EVENT_TYPE_NOTIFY_OD_GROUP_REMOVE`]
/// - [`ES_EVENT_TYPE_NOTIFY_OD_GROUP_SET`]
/// - [`ES_EVENT_TYPE_NOTIFY_OD_MODIFY_PASSWORD`]
/// - [`ES_EVENT_TYPE_NOTIFY_OD_DISABLE_USER`]
/// - [`ES_EVENT_TYPE_NOTIFY_OD_ENABLE_USER`]
/// - [`ES_EVENT_TYPE_NOTIFY_OD_ATTRIBUTE_VALUE_ADD`]
/// - [`ES_EVENT_TYPE_NOTIFY_OD_ATTRIBUTE_VALUE_REMOVE`]
/// - [`ES_EVENT_TYPE_NOTIFY_OD_ATTRIBUTE_SET`]
/// - [`ES_EVENT_TYPE_NOTIFY_OD_CREATE_USER`]
/// - [`ES_EVENT_TYPE_NOTIFY_OD_CREATE_GROUP`]
/// - [`ES_EVENT_TYPE_NOTIFY_OD_DELETE_USER`]
/// - [`ES_EVENT_TYPE_NOTIFY_OD_DELETE_GROUP`]
#[repr(C)]
pub struct es_message_t {
    /// Indicates the message version; some fields are not available and must not be accessed unless
    /// the message version is equal to or higher than the message version at which the field was
    /// introduced.
    pub version: u32,
    /// The time at which the event was generated
    pub time: timespec,
    /// The Mach absolute time at which the event was generated
    pub mach_time: u64,
    /// The Mach absolute time before which an auth event must be responded to. If a client fails
    /// to respond to auth events prior to the `deadline`, the client will be killed. Each message
    /// can contain its own unique deadline, and some deadlines can vary substantially. Clients must
    /// take care to inspect the deadline value of each message to know how much time is allotted
    /// for processing.
    pub deadline: u64,
    /// Describes the process that took the action
    pub process: ShouldNotBeNull<es_process_t>,
    /// Per-client, per-event-type sequence number that can be inspected to detect whether the
    /// kernel had to drop events for this client. When no events are dropped for this client,
    /// `seq_num` increments by 1 for every message of that event type. When events have been
    /// dropped, the difference between the last seen sequence number of that event type plus 1 and
    /// `seq_num` of the received message indicates the number of events that had to be dropped.
    /// Dropped events generally indicate that more events were generated in the kernel than the
    /// client was able to handle.
    ///
    /// See `global_seq_num`.
    ///
    /// Field available only if message version >= 2.
    pub seq_num: u64,
    /// Indicates if the action field is an auth or notify action
    pub action_type: es_action_type_t,
    /// For auth events, contains the opaque auth ID that must be supplied when responding to the
    /// event. For notify events, describes the result of the action.
    pub action: es_message_t_anon_0,
    /// Indicates which event struct is defined in the event union
    pub event_type: es_event_type_t,
    /// Contains data specific to the event type
    pub event: es_events_t,
    /// Describes the thread that took the action. May be `NULL` when thread is not applicable,
    /// for example for trace events that describe the traced process calling `ptrace(PT_TRACE_ME)`
    /// or for cs invalidated events that are a result of another process calling
    /// `csops(CS_OPS_MARKINVALID)`.
    ///
    /// Field available only if message version >= 4.
    #[cfg(feature = "macos_11_0_0")]
    pub thread: *mut es_thread_t,
    /// Per-client sequence number that can be inspected to detect whether the kernel had to
    /// drop events for this client. When no events are dropped for this client, `global_seq_num`
    /// increments by 1 for every message. When events have been dropped, the difference between the
    /// last seen global sequence number and the `global_seq_num` of the received message indicates
    /// the number of events that had to be dropped. Dropped events generally indicate that more
    /// events were generated in the kernel than the client was able to handle.
    ///
    /// See also: `seq_num`.
    ///
    /// Field available only if message version >= 4.
    #[cfg(feature = "macos_11_0_0")]
    pub global_seq_num: u64,
    /// Opaque data that must not be accessed directly
    _opaque: [u64; 0],
}

should_not_be_null_fields!(es_message_t; process -> es_process_t);
#[cfg(feature = "macos_11_0_0")]
null_fields!(es_message_t; thread -> es_thread_t);

unsafe impl RefEncode for es_message_t {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Encoding::Unknown);
}

#[repr(C)]
#[derive(Copy, Clone)]
pub union es_message_t_anon_0 {
    pub auth: es_event_id_t,
    pub notify: es_result_t,
}

#[link(name = "EndpointSecurity", kind = "dylib")]
extern "C" {
    /// Calculate the size of an [`es_message_t`].
    ///
    /// This function **MUST NOT** be used in conjunction with attempting to copy an `es_message_t`
    /// (e.g. by using the reported size in order to `malloc(3)` a buffer, and `memcpy(3)` an
    /// existing `es_message_t` into that buffer). Doing so will result in use-after-free bugs.
    ///
    ///
    #[cfg_attr(
        feature = "macos_11_0_0",
        doc = "**Deprecated in macOS 11+**: Please use [`es_retain_message()`] to retain an `es_message_t`."
    )]
    #[cfg_attr(
        not(feature = "macos_11_0_0"),
        doc = "**Deprecated in macOS 11+**: Please use `es_retain_message()` to retain an `es_message_t`."
    )]
    ///
    /// - `msg`: The message for which the size will be calculated
    /// - Returns the size of the message
    pub fn es_message_size(msg: &es_message_t) -> usize;

    /// Retains an [`es_message_t`], returning a non-const pointer to the given `es_message_t` for
    /// compatibility with existing code.
    ///
    /// It is invalid to attempt to write to the returned `es_message_t`, despite being non-`const`,
    /// and doing so will result in a crash.
    ///
    #[cfg_attr(
        feature = "macos_11_0_0",
        doc = "**Deprecated in macOS 11+**: Please use [`es_retain_message()`] to retain an `es_message_t`."
    )]
    #[cfg_attr(
        not(feature = "macos_11_0_0"),
        doc = "**Deprecated in macOS 11+**: Please use `es_retain_message()` to retain an `es_message_t`."
    )]
    ///
    /// - `msg`: The message to be retained
    /// - Returns a non-const pointer to the retained `es_message_t`
    ///
    /// The caller must release the memory with [`es_free_message()`]
    pub fn es_copy_message(msg: &es_message_t) -> *mut es_message_t;

    /// Releases the memory associated with the given [`es_message_t`] that was retained via
    /// [`es_copy_message()`]
    ///
    #[cfg_attr(
        feature = "macos_11_0_0",
        doc = "**Deprecated in macOS 11+**: Please use [`es_retain_message()`] to retain an `es_message_t`."
    )]
    #[cfg_attr(
        not(feature = "macos_11_0_0"),
        doc = "**Deprecated in macOS 11+**: Please use `es_retain_message()` to retain an `es_message_t`."
    )]
    ///
    /// - `msg`: The message to be released
    pub fn es_free_message(msg: &es_message_t);

    /// Retains the given [`es_message_t`], extending its lifetime until released with [`es_release_message()`].
    ///
    /// - `msg`: The message to be retained
    ///
    /// It is necessary to retain a message when the `es_message_t` provided in the event handler block of
    /// [`es_new_client()`][super::es_new_client] will be processed asynchronously.
    ///
    /// Available for macos 11+
    #[cfg(feature = "macos_11_0_0")]
    pub fn es_retain_message(msg: &es_message_t);

    /// Releases the given [`es_message_t`] that was previously retained with [`es_retain_message()`]
    ///
    /// - `msg`: The message to be released
    ///
    /// Available for macos 11+
    #[cfg(feature = "macos_11_0_0")]
    pub fn es_release_message(msg: &es_message_t);

    /// Get the number of arguments in a message containing an [`es_event_exec_t`]
    ///
    /// - `event`: The `es_event_exec_t` being inspected
    /// - Returns the number of arguments
    pub fn es_exec_arg_count(event: &es_event_exec_t) -> u32;

    /// Get the number of environment variables in a message containing an [`es_event_exec_t`]
    ///
    /// - `event`: The `es_event_exec_t` being inspected
    /// - Returns The number of environment variables
    pub fn es_exec_env_count(event: &es_event_exec_t) -> u32;

    /// Get the number of file descriptors in a message containing an [`es_event_exec_t`]
    ///
    /// - `event`: The `es_event_exec_t` being inspected
    /// - Returns The number of file descriptors
    ///
    /// Available for macos 11+
    #[cfg(feature = "macos_11_0_0")]
    pub fn es_exec_fd_count(event: &es_event_exec_t) -> u32;

    /// Get the argument at the specified position in the message containing an [`es_event_exec_t`]
    ///
    /// - `event`: The `es_event_exec_t` being inspected
    /// - `index`: Index of the argument to retrieve (starts from 0)
    /// - Returns an `es_string_token_t` containing a pointer to the argument and its length.
    ///   This is a zero-allocation operation. The returned pointer **must not** outlive `exec_event`.
    ///
    /// Reading an an argument where `index` >= [`es_exec_arg_count()`] is undefined
    pub fn es_exec_arg(event: &es_event_exec_t, index: u32) -> es_string_token_t;

    /// Get the environment variable at the specified position in the message containing an
    /// [`es_event_exec_t`]
    ///
    /// - `event`: The `es_event_exec_t` being inspected
    /// - `index`: Index of the environment variable to retrieve (starts from 0)
    /// - Returns an `es_string_token_t` containing a pointer to the environment variable and its length.
    ///   This is zero-allocation operation. The returned pointer **must not** outlive `exec_event`.
    ///
    /// Reading an an env where `index` >= [`es_exec_env_count()`] is undefined.
    pub fn es_exec_env(event: &es_event_exec_t, index: u32) -> es_string_token_t;

    /// Get the file descriptor at the specified position in the message containing an
    /// [`es_event_exec_t`]
    ///
    /// - `event`: The `es_event_exec_t` being inspected
    /// - `index`: Index of the file descriptor to retrieve (starts from 0)
    /// - Returns a pointer to an `es_fd_t` describing the file descriptor.
    ///   This is zero-allocation operation. The returned pointer **must not** outlive `exec_event`.
    ///
    /// Reading an fd where `index` >= [`es_exec_fd_count()`] is undefined
    ///
    /// Available for macos 11+
    #[cfg(feature = "macos_11_0_0")]
    pub fn es_exec_fd(event: &es_event_exec_t, index: u32) -> ShouldNotBeNull<es_fd_t>;
}