81fac33bb068c1e7267c3bb85f14c227c3e648ca
[dragonfly.git] / sys / emulation / ndis / ntoskrnl_var.h
1 /*-
2  * Copyright (c) 2003
3  *      Bill Paul <wpaul@windriver.com>.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *      This product includes software developed by Bill Paul.
16  * 4. Neither the name of the author nor the names of any co-contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30  * THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  * $FreeBSD: src/sys/compat/ndis/ntoskrnl_var.h,v 1.51 2010/12/06 20:54:53 bschmidt Exp $
33  */
34
35 #ifndef _NTOSKRNL_VAR_H_
36 #define _NTOSKRNL_VAR_H_
37
38 #include "use_usb4bsd.h"
39
40 #define MTX_NTOSKRNL_SPIN_LOCK "NDIS thread lock"
41
42 /*
43  * us_buf is really a wchar_t *, but it's inconvenient to include
44  * all the necessary header goop needed to define it, and it's a
45  * pointer anyway, so for now, just make it a uint16_t *.
46  */
47 struct unicode_string {
48         uint16_t                us_len;
49         uint16_t                us_maxlen;
50         uint16_t                *us_buf;
51 };
52
53 typedef struct unicode_string unicode_string;
54
55 struct ansi_string {
56         uint16_t                as_len;
57         uint16_t                as_maxlen;
58         char                    *as_buf;
59 };
60
61 typedef struct ansi_string ansi_string;
62
63 /*
64  * Windows memory descriptor list. In Windows, it's possible for
65  * buffers to be passed between user and kernel contexts without
66  * copying. Buffers may also be allocated in either paged or
67  * non-paged memory regions. An MDL describes the pages of memory
68  * used to contain a particular buffer. Note that a single MDL
69  * may describe a buffer that spans multiple pages. An array of
70  * page addresses appears immediately after the MDL structure itself.
71  * MDLs are therefore implicitly variably sized, even though they
72  * don't look it.
73  *
74  * Note that in FreeBSD, we can take many shortcuts in the way
75  * we handle MDLs because:
76  *
77  * - We are only concerned with pages in kernel context. This means
78  *   we will only ever use the kernel's memory map, and remapping
79  *   of buffers is never needed.
80  *
81  * - Kernel pages can never be paged out, so we don't have to worry
82  *   about whether or not a page is actually mapped before going to
83  *   touch it.
84  */
85
86 struct mdl {
87         struct mdl              *mdl_next;
88         uint16_t                mdl_size;
89         uint16_t                mdl_flags;
90         void                    *mdl_process;
91         void                    *mdl_mappedsystemva;
92         void                    *mdl_startva;
93         uint32_t                mdl_bytecount;
94         uint32_t                mdl_byteoffset;
95 };
96
97 typedef struct mdl mdl, ndis_buffer;
98
99 /* MDL flags */
100
101 #define MDL_MAPPED_TO_SYSTEM_VA         0x0001
102 #define MDL_PAGES_LOCKED                0x0002
103 #define MDL_SOURCE_IS_NONPAGED_POOL     0x0004
104 #define MDL_ALLOCATED_FIXED_SIZE        0x0008
105 #define MDL_PARTIAL                     0x0010
106 #define MDL_PARTIAL_HAS_BEEN_MAPPED     0x0020
107 #define MDL_IO_PAGE_READ                0x0040
108 #define MDL_WRITE_OPERATION             0x0080
109 #define MDL_PARENT_MAPPED_SYSTEM_VA     0x0100
110 #define MDL_FREE_EXTRA_PTES             0x0200
111 #define MDL_IO_SPACE                    0x0800
112 #define MDL_NETWORK_HEADER              0x1000
113 #define MDL_MAPPING_CAN_FAIL            0x2000
114 #define MDL_ALLOCATED_MUST_SUCCEED      0x4000
115 #define MDL_ZONE_ALLOCED                0x8000  /* BSD private */
116
117 #define MDL_ZONE_PAGES 16
118 #define MDL_ZONE_SIZE (sizeof(mdl) + (sizeof(vm_offset_t) * MDL_ZONE_PAGES))
119
120 /* Note: assumes x86 page size of 4K. */
121
122 #ifndef PAGE_SHIFT
123 #if PAGE_SIZE == 4096
124 #define PAGE_SHIFT      12
125 #elif PAGE_SIZE == 8192
126 #define PAGE_SHIFT      13
127 #else
128 #error PAGE_SHIFT undefined!
129 #endif
130 #endif
131
132 #define SPAN_PAGES(ptr, len)                                    \
133         ((uint32_t)((((uintptr_t)(ptr) & (PAGE_SIZE - 1)) +     \
134         (len) + (PAGE_SIZE - 1)) >> PAGE_SHIFT))
135
136 #define PAGE_ALIGN(ptr)                                         \
137         ((void *)((uintptr_t)(ptr) & ~(PAGE_SIZE - 1)))
138
139 #define BYTE_OFFSET(ptr)                                        \
140         ((uint32_t)((uintptr_t)(ptr) & (PAGE_SIZE - 1)))
141
142 #define MDL_PAGES(m)    (vm_offset_t *)(m + 1)
143
144 #define MmInitializeMdl(b, baseva, len)                                 \
145         (b)->mdl_next = NULL;                                           \
146         (b)->mdl_size = (uint16_t)(sizeof(mdl) +                        \
147                 (sizeof(vm_offset_t) * SPAN_PAGES((baseva), (len))));   \
148         (b)->mdl_flags = 0;                                             \
149         (b)->mdl_startva = (void *)PAGE_ALIGN((baseva));                \
150         (b)->mdl_byteoffset = BYTE_OFFSET((baseva));                    \
151         (b)->mdl_bytecount = (uint32_t)(len);
152
153 #define MmGetMdlByteOffset(mdl)         ((mdl)->mdl_byteoffset)
154 #define MmGetMdlByteCount(mdl)          ((mdl)->mdl_bytecount)
155 #define MmGetMdlVirtualAddress(mdl)                                     \
156         ((void *)((char *)((mdl)->mdl_startva) + (mdl)->mdl_byteoffset))
157 #define MmGetMdlStartVa(mdl)            ((mdl)->mdl_startva)
158 #define MmGetMdlPfnArray(mdl)           MDL_PAGES(mdl)
159
160 #define WDM_MAJOR               1
161 #define WDM_MINOR_WIN98         0x00
162 #define WDM_MINOR_WINME         0x05
163 #define WDM_MINOR_WIN2000       0x10
164 #define WDM_MINOR_WINXP         0x20
165 #define WDM_MINOR_WIN2003       0x30
166
167 enum nt_caching_type {
168         MmNonCached                     = 0,
169         MmCached                        = 1,
170         MmWriteCombined                 = 2,
171         MmHardwareCoherentCached        = 3,
172         MmNonCachedUnordered            = 4,
173         MmUSWCCached                    = 5,
174         MmMaximumCacheType              = 6
175 };
176
177 /*-
178  * The ndis_kspin_lock type is called KSPIN_LOCK in MS-Windows.
179  * According to the Windows DDK header files, KSPIN_LOCK is defined like this:
180  *      typedef ULONG_PTR KSPIN_LOCK;
181  *
182  * From basetsd.h (SDK, Feb. 2003):
183  *      typedef [public] unsigned __int3264 ULONG_PTR, *PULONG_PTR;
184  *      typedef unsigned __int64 ULONG_PTR, *PULONG_PTR;
185  *      typedef _W64 unsigned long ULONG_PTR, *PULONG_PTR;
186  *
187  * The keyword __int3264 specifies an integral type that has the following
188  * properties:
189  *      + It is 32-bit on 32-bit platforms
190  *      + It is 64-bit on 64-bit platforms
191  *      + It is 32-bit on the wire for backward compatibility.
192  *        It gets truncated on the sending side and extended appropriately
193  *        (signed or unsigned) on the receiving side.
194  *
195  * Thus register_t seems the proper mapping onto FreeBSD for spin locks.
196  */
197
198 typedef register_t kspin_lock;
199
200 struct slist_entry {
201         struct slist_entry      *sl_next;
202 };
203
204 typedef struct slist_entry slist_entry;
205
206 union slist_header {
207         uint64_t                slh_align;
208         struct {
209                 struct slist_entry      *slh_next;
210                 uint16_t                slh_depth;
211                 uint16_t                slh_seq;
212         } slh_list;
213 };
214
215 typedef union slist_header slist_header;
216
217 struct list_entry {
218         struct list_entry *nle_flink;
219         struct list_entry *nle_blink;
220 };
221
222 typedef struct list_entry list_entry;
223
224 #define InitializeListHead(l)                   \
225         (l)->nle_flink = (l)->nle_blink = (l)
226
227 #define IsListEmpty(h)                          \
228         ((h)->nle_flink == (h))
229
230 #define RemoveEntryList(e)                      \
231         do {                                    \
232                 list_entry              *b;     \
233                 list_entry              *f;     \
234                                                 \
235                 f = (e)->nle_flink;             \
236                 b = (e)->nle_blink;             \
237                 b->nle_flink = f;               \
238                 f->nle_blink = b;               \
239         } while (0)
240
241 /* These two have to be inlined since they return things. */
242
243 static __inline__ list_entry *
244 RemoveHeadList(list_entry *l)
245 {
246         list_entry              *f;
247         list_entry              *e;
248
249         e = l->nle_flink;
250         f = e->nle_flink;
251         l->nle_flink = f;
252         f->nle_blink = l;
253
254         return (e);
255 }
256
257 static __inline__ list_entry *
258 RemoveTailList(list_entry *l)
259 {
260         list_entry              *b;
261         list_entry              *e;
262
263         e = l->nle_blink;
264         b = e->nle_blink;
265         l->nle_blink = b;
266         b->nle_flink = l;
267
268         return (e);
269 }
270
271 #define InsertTailList(l, e)                    \
272         do {                                    \
273                 list_entry              *b;     \
274                                                 \
275                 b = l->nle_blink;               \
276                 e->nle_flink = l;               \
277                 e->nle_blink = b;               \
278                 b->nle_flink = (e);             \
279                 l->nle_blink = (e);             \
280         } while (0)
281
282 #define InsertHeadList(l, e)                    \
283         do {                                    \
284                 list_entry              *f;     \
285                                                 \
286                 f = l->nle_flink;               \
287                 e->nle_flink = f;               \
288                 e->nle_blink = l;               \
289                 f->nle_blink = e;               \
290                 l->nle_flink = e;               \
291         } while (0)
292
293 #define CONTAINING_RECORD(addr, type, field)    \
294         ((type *)((vm_offset_t)(addr) - (vm_offset_t)(&((type *)0)->field)))
295
296 struct nt_dispatch_header {
297         uint8_t                 dh_type;
298         uint8_t                 dh_abs;
299         uint8_t                 dh_size;
300         uint8_t                 dh_inserted;
301         int32_t                 dh_sigstate;
302         list_entry              dh_waitlisthead;
303 };
304
305 typedef struct nt_dispatch_header nt_dispatch_header;
306
307 /* Dispatcher object types */
308
309 #define DISP_TYPE_NOTIFICATION_EVENT    0       /* KEVENT */
310 #define DISP_TYPE_SYNCHRONIZATION_EVENT 1       /* KEVENT */
311 #define DISP_TYPE_MUTANT                2       /* KMUTANT/KMUTEX */
312 #define DISP_TYPE_PROCESS               3       /* KPROCESS */
313 #define DISP_TYPE_QUEUE                 4       /* KQUEUE */
314 #define DISP_TYPE_SEMAPHORE             5       /* KSEMAPHORE */
315 #define DISP_TYPE_THREAD                6       /* KTHREAD */
316 #define DISP_TYPE_NOTIFICATION_TIMER    8       /* KTIMER */
317 #define DISP_TYPE_SYNCHRONIZATION_TIMER 9       /* KTIMER */
318
319 #define OTYPE_EVENT             0
320 #define OTYPE_MUTEX             1
321 #define OTYPE_THREAD            2
322 #define OTYPE_TIMER             3
323
324 /* Windows dispatcher levels. */
325
326 #define PASSIVE_LEVEL           0
327 #define LOW_LEVEL               0
328 #define APC_LEVEL               1
329 #define DISPATCH_LEVEL          2
330 #define DEVICE_LEVEL            (DISPATCH_LEVEL + 1)
331 #define PROFILE_LEVEL           27
332 #define CLOCK1_LEVEL            28
333 #define CLOCK2_LEVEL            28
334 #define IPI_LEVEL               29
335 #define POWER_LEVEL             30
336 #define HIGH_LEVEL              31
337
338 #define SYNC_LEVEL_UP           DISPATCH_LEVEL
339 #define SYNC_LEVEL_MP           (IPI_LEVEL - 1)
340
341 #define AT_PASSIVE_LEVEL(td)            \
342         ((td)->td_proc->p_flags & P_KTHREAD == FALSE)
343
344 #define AT_DISPATCH_LEVEL(td)           \
345         (lwkt_getpri(td) == TDPRI_INT_HIGH)
346
347 #define AT_DIRQL_LEVEL(td)              \
348         ((td)->td_priority <= PI_NET)
349
350 #define AT_HIGH_LEVEL(td)               \
351         ((td)->td_critnest != 0)
352
353 struct nt_objref {
354         nt_dispatch_header      no_dh;
355         void                    *no_obj;
356         TAILQ_ENTRY(nt_objref)  link;
357 };
358
359 TAILQ_HEAD(nt_objref_head, nt_objref);
360
361 typedef struct nt_objref nt_objref;
362
363 #define EVENT_TYPE_NOTIFY       0
364 #define EVENT_TYPE_SYNC         1
365
366 /*
367  * We need to use the timeout()/untimeout() API for ktimers
368  * since timers can be initialized, but not destroyed (so
369  * malloc()ing our own callout structures would mean a leak,
370  * since there'd be no way to free() them). This means we
371  * need to use struct callout_handle, which is really just a
372  * pointer. To make it easier to deal with, we use a union
373  * to overlay the callout_handle over the k_timerlistentry.
374  * The latter is a list_entry, which is two pointers, so
375  * there's enough space available to hide a callout_handle
376  * there.
377  */
378
379 struct ktimer {
380         nt_dispatch_header      k_header;
381         uint64_t                k_duetime;
382         union {
383                 list_entry              k_timerlistentry;
384                 struct callout          *k_callout;
385         } u;
386         void                    *k_dpc;
387         uint32_t                k_period;
388 };
389
390 #define k_timerlistentry        u.k_timerlistentry
391 #define k_callout               u.k_callout
392
393 typedef struct ktimer ktimer;
394
395 struct nt_kevent {
396         nt_dispatch_header      k_header;
397 };
398
399 typedef struct nt_kevent nt_kevent;
400
401 /* Kernel defered procedure call (i.e. timer callback) */
402
403 struct kdpc;
404 typedef void (*kdpc_func)(struct kdpc *, void *, void *, void *);
405
406 struct kdpc {
407         uint16_t                k_type;
408         uint8_t                 k_num;          /* CPU number */
409         uint8_t                 k_importance;   /* priority */
410         list_entry              k_dpclistentry;
411         void                    *k_deferedfunc;
412         void                    *k_deferredctx;
413         void                    *k_sysarg1;
414         void                    *k_sysarg2;
415         void                    *k_lock;
416 };
417
418 #define KDPC_IMPORTANCE_LOW     0
419 #define KDPC_IMPORTANCE_MEDIUM  1
420 #define KDPC_IMPORTANCE_HIGH    2
421
422 #define KDPC_CPU_DEFAULT        255
423
424 typedef struct kdpc kdpc;
425
426 /*
427  * Note: the acquisition count is BSD-specific. The Microsoft
428  * documentation says that mutexes can be acquired recursively
429  * by a given thread, but that you must release the mutex as
430  * many times as you acquired it before it will be set to the
431  * signalled state (i.e. before any other threads waiting on
432  * the object will be woken up). However the Windows KMUTANT
433  * structure has no field for keeping track of the number of
434  * acquisitions, so we need to add one ourselves. As long as
435  * driver code treats the mutex as opaque, we should be ok.
436  */
437 struct kmutant {
438         nt_dispatch_header      km_header;
439         list_entry              km_listentry;
440         void                    *km_ownerthread;
441         uint8_t                 km_abandoned;
442         uint8_t                 km_apcdisable;
443 };
444
445 typedef struct kmutant kmutant;
446
447 #define LOOKASIDE_DEPTH 256
448
449 struct general_lookaside {
450         slist_header            gl_listhead;
451         uint16_t                gl_depth;
452         uint16_t                gl_maxdepth;
453         uint32_t                gl_totallocs;
454         union {
455                 uint32_t                gl_allocmisses;
456                 uint32_t                gl_allochits;
457         } u_a;
458         uint32_t                gl_totalfrees;
459         union {
460                 uint32_t                gl_freemisses;
461                 uint32_t                gl_freehits;
462         } u_m;
463         uint32_t                gl_type;
464         uint32_t                gl_tag;
465         uint32_t                gl_size;
466         void                    *gl_allocfunc;
467         void                    *gl_freefunc;
468         list_entry              gl_listent;
469         uint32_t                gl_lasttotallocs;
470         union {
471                 uint32_t                gl_lastallocmisses;
472                 uint32_t                gl_lastallochits;
473         } u_l;
474         uint32_t                gl_rsvd[2];
475 };
476
477 typedef struct general_lookaside general_lookaside;
478
479 struct npaged_lookaside_list {
480         general_lookaside       nll_l;
481 #ifdef __i386__
482         kspin_lock              nll_obsoletelock;
483 #endif
484 };
485
486 typedef struct npaged_lookaside_list npaged_lookaside_list;
487 typedef struct npaged_lookaside_list paged_lookaside_list;
488
489 typedef void * (*lookaside_alloc_func)(uint32_t, size_t, uint32_t);
490 typedef void (*lookaside_free_func)(void *);
491
492 struct irp;
493
494 struct kdevice_qentry {
495         list_entry              kqe_devlistent;
496         uint32_t                kqe_sortkey;
497         uint8_t                 kqe_inserted;
498 };
499
500 typedef struct kdevice_qentry kdevice_qentry;
501
502 struct kdevice_queue {
503         uint16_t                kq_type;
504         uint16_t                kq_size;
505         list_entry              kq_devlisthead;
506         kspin_lock              kq_lock;
507         uint8_t                 kq_busy;
508 };
509
510 typedef struct kdevice_queue kdevice_queue;
511
512 struct wait_ctx_block {
513         kdevice_qentry          wcb_waitqueue;
514         void                    *wcb_devfunc;
515         void                    *wcb_devctx;
516         uint32_t                wcb_mapregcnt;
517         void                    *wcb_devobj;
518         void                    *wcb_curirp;
519         void                    *wcb_bufchaindpc;
520 };
521
522 typedef struct wait_ctx_block wait_ctx_block;
523
524 struct wait_block {
525         list_entry              wb_waitlist;
526         void                    *wb_kthread;
527         nt_dispatch_header      *wb_object;
528         struct wait_block       *wb_next;
529 #ifdef notdef
530         uint16_t                wb_waitkey;
531         uint16_t                wb_waittype;
532 #endif
533         uint8_t                 wb_waitkey;
534         uint8_t                 wb_waittype;
535         uint8_t                 wb_awakened;
536         uint8_t                 wb_oldpri;
537 };
538
539 typedef struct wait_block wait_block;
540
541 #define wb_ext wb_kthread
542
543 #define THREAD_WAIT_OBJECTS     3
544 #define MAX_WAIT_OBJECTS        64
545
546 #define WAITTYPE_ALL            0
547 #define WAITTYPE_ANY            1
548
549 #define WAITKEY_VALID           0x8000
550
551 /* kthread priority  */
552 #define LOW_PRIORITY            0
553 #define LOW_REALTIME_PRIORITY   16
554 #define HIGH_PRIORITY           31
555
556 struct thread_context {
557         void                    *tc_thrctx;
558         void                    *tc_thrfunc;
559 };
560
561 typedef struct thread_context thread_context;
562
563 /* Forward declaration */
564 struct driver_object;
565 struct devobj_extension;
566
567 struct driver_extension {
568         struct driver_object    *dre_driverobj;
569         void                    *dre_adddevicefunc;
570         uint32_t                dre_reinitcnt;
571         unicode_string          dre_srvname;
572
573         /*
574          * Drivers are allowed to add one or more custom extensions
575          * to the driver object, but there's no special pointer
576          * for them. Hang them off here for now.
577          */
578
579         list_entry              dre_usrext;
580 };
581
582 typedef struct driver_extension driver_extension;
583
584 struct custom_extension {
585         list_entry              ce_list;
586         void                    *ce_clid;
587 };
588
589 typedef struct custom_extension custom_extension;
590
591 /*
592  * The KINTERRUPT structure in Windows is opaque to drivers.
593  * We define our own custom version with things we need.
594  */
595
596 struct kinterrupt {
597         list_entry              ki_list;
598         device_t                ki_dev;
599         int                     ki_rid;
600         void                    *ki_cookie;
601         struct resource         *ki_irq;
602         kspin_lock              ki_lock_priv;
603         kspin_lock              *ki_lock;
604         void                    *ki_svcfunc;
605         void                    *ki_svcctx;
606 };
607
608 typedef struct kinterrupt kinterrupt;
609
610 struct ksystem_time {
611         uint32_t        low_part;
612         int32_t         high1_time;
613         int32_t         high2_time;
614 };
615
616 enum nt_product_type {
617         NT_PRODUCT_WIN_NT = 1,
618         NT_PRODUCT_LAN_MAN_NT,
619         NT_PRODUCT_SERVER
620 };
621
622 enum alt_arch_type {
623         STANDARD_DESIGN,
624         NEC98x86,
625         END_ALTERNATIVES
626 };
627
628 struct kuser_shared_data {
629         uint32_t                tick_count;
630         uint32_t                tick_count_multiplier;
631         volatile struct         ksystem_time interrupt_time;
632         volatile struct         ksystem_time system_time;
633         volatile struct         ksystem_time time_zone_bias;
634         uint16_t                image_number_low;
635         uint16_t                image_number_high;
636         int16_t                 nt_system_root[260];
637         uint32_t                max_stack_trace_depth;
638         uint32_t                crypto_exponent;
639         uint32_t                time_zone_id;
640         uint32_t                large_page_min;
641         uint32_t                reserved2[7];
642         enum nt_product_type    nt_product_type;
643         uint8_t                 product_type_is_valid;
644         uint32_t                nt_major_version;
645         uint32_t                nt_minor_version;
646         uint8_t                 processor_features[64];
647         uint32_t                reserved1;
648         uint32_t                reserved3;
649         volatile uint32_t       time_slip;
650         enum alt_arch_type      alt_arch_type;
651         int64_t                 system_expiration_date;
652         uint32_t                suite_mask;
653         uint8_t                 kdbg_enabled;
654         volatile uint32_t       active_console;
655         volatile uint32_t       dismount_count;
656         uint32_t                com_plus_package;
657         uint32_t                last_system_rit_event_tick_count;
658         uint32_t                num_phys_pages;
659         uint8_t                 safe_boot_mode;
660         uint32_t                trace_log;
661         uint64_t                fill0;
662         uint64_t                sys_call[4];
663         union {
664                 volatile struct ksystem_time    tick_count;
665                 volatile uint64_t               tick_count_quad;
666         } tick;
667 };
668
669 /*
670  * In Windows, there are Physical Device Objects (PDOs) and
671  * Functional Device Objects (FDOs). Physical Device Objects are
672  * created and maintained by bus drivers. For example, the PCI
673  * bus driver might detect two PCI ethernet cards on a given
674  * bus. The PCI bus driver will then allocate two device_objects
675  * for its own internal bookeeping purposes. This is analagous
676  * to the device_t that the FreeBSD PCI code allocates and passes
677  * into each PCI driver's probe and attach routines.
678  *
679  * When an ethernet driver claims one of the ethernet cards
680  * on the bus, it will create its own device_object. This is
681  * the Functional Device Object. This object is analagous to the
682  * device-specific softc structure.
683  */
684
685 struct device_object {
686         uint16_t                do_type;
687         uint16_t                do_size;
688         uint32_t                do_refcnt;
689         struct driver_object    *do_drvobj;
690         struct device_object    *do_nextdev;
691         struct device_object    *do_attacheddev;
692         struct irp              *do_currirp;
693         void                    *do_iotimer;
694         uint32_t                do_flags;
695         uint32_t                do_characteristics;
696         void                    *do_vpb;
697         void                    *do_devext;
698         uint32_t                do_devtype;
699         uint8_t                 do_stacksize;
700         union {
701                 list_entry              do_listent;
702                 wait_ctx_block          do_wcb;
703         } queue;
704         uint32_t                do_alignreq;
705         kdevice_queue           do_devqueue;
706         struct kdpc             do_dpc;
707         uint32_t                do_activethreads;
708         void                    *do_securitydesc;
709         struct nt_kevent        do_devlock;
710         uint16_t                do_sectorsz;
711         uint16_t                do_spare1;
712         struct devobj_extension *do_devobj_ext;
713         void                    *do_rsvd;
714 };
715
716 typedef struct device_object device_object;
717
718 struct devobj_extension {
719         uint16_t                dve_type;
720         uint16_t                dve_size;
721         device_object           *dve_devobj;
722 };
723
724 typedef struct devobj_extension devobj_extension;
725
726 /* Device object flags */
727
728 #define DO_VERIFY_VOLUME                0x00000002
729 #define DO_BUFFERED_IO                  0x00000004
730 #define DO_EXCLUSIVE                    0x00000008
731 #define DO_DIRECT_IO                    0x00000010
732 #define DO_MAP_IO_BUFFER                0x00000020
733 #define DO_DEVICE_HAS_NAME              0x00000040
734 #define DO_DEVICE_INITIALIZING          0x00000080
735 #define DO_SYSTEM_BOOT_PARTITION        0x00000100
736 #define DO_LONG_TERM_REQUESTS           0x00000200
737 #define DO_NEVER_LAST_DEVICE            0x00000400
738 #define DO_SHUTDOWN_REGISTERED          0x00000800
739 #define DO_BUS_ENUMERATED_DEVICE        0x00001000
740 #define DO_POWER_PAGABLE                0x00002000
741 #define DO_POWER_INRUSH                 0x00004000
742 #define DO_LOW_PRIORITY_FILESYSTEM      0x00010000
743
744 /* Priority boosts */
745
746 #define IO_NO_INCREMENT                 0
747 #define IO_CD_ROM_INCREMENT             1
748 #define IO_DISK_INCREMENT               1
749 #define IO_KEYBOARD_INCREMENT           6
750 #define IO_MAILSLOT_INCREMENT           2
751 #define IO_MOUSE_INCREMENT              6
752 #define IO_NAMED_PIPE_INCREMENT         2
753 #define IO_NETWORK_INCREMENT            2
754 #define IO_PARALLEL_INCREMENT           1
755 #define IO_SERIAL_INCREMENT             2
756 #define IO_SOUND_INCREMENT              8
757 #define IO_VIDEO_INCREMENT              1
758
759 /* IRP major codes */
760
761 #define IRP_MJ_CREATE                   0x00
762 #define IRP_MJ_CREATE_NAMED_PIPE        0x01
763 #define IRP_MJ_CLOSE                    0x02
764 #define IRP_MJ_READ                     0x03
765 #define IRP_MJ_WRITE                    0x04
766 #define IRP_MJ_QUERY_INFORMATION        0x05
767 #define IRP_MJ_SET_INFORMATION          0x06
768 #define IRP_MJ_QUERY_EA                 0x07
769 #define IRP_MJ_SET_EA                   0x08
770 #define IRP_MJ_FLUSH_BUFFERS            0x09
771 #define IRP_MJ_QUERY_VOLUME_INFORMATION 0x0a
772 #define IRP_MJ_SET_VOLUME_INFORMATION   0x0b
773 #define IRP_MJ_DIRECTORY_CONTROL        0x0c
774 #define IRP_MJ_FILE_SYSTEM_CONTROL      0x0d
775 #define IRP_MJ_DEVICE_CONTROL           0x0e
776 #define IRP_MJ_INTERNAL_DEVICE_CONTROL  0x0f
777 #define IRP_MJ_SHUTDOWN                 0x10
778 #define IRP_MJ_LOCK_CONTROL             0x11
779 #define IRP_MJ_CLEANUP                  0x12
780 #define IRP_MJ_CREATE_MAILSLOT          0x13
781 #define IRP_MJ_QUERY_SECURITY           0x14
782 #define IRP_MJ_SET_SECURITY             0x15
783 #define IRP_MJ_POWER                    0x16
784 #define IRP_MJ_SYSTEM_CONTROL           0x17
785 #define IRP_MJ_DEVICE_CHANGE            0x18
786 #define IRP_MJ_QUERY_QUOTA              0x19
787 #define IRP_MJ_SET_QUOTA                0x1a
788 #define IRP_MJ_PNP                      0x1b
789 #define IRP_MJ_PNP_POWER                IRP_MJ_PNP      // Obsolete....
790 #define IRP_MJ_MAXIMUM_FUNCTION         0x1b
791 #define IRP_MJ_SCSI                     IRP_MJ_INTERNAL_DEVICE_CONTROL
792
793 /* IRP minor codes */
794
795 #define IRP_MN_QUERY_DIRECTORY          0x01
796 #define IRP_MN_NOTIFY_CHANGE_DIRECTORY  0x02
797 #define IRP_MN_USER_FS_REQUEST          0x00
798
799 #define IRP_MN_MOUNT_VOLUME             0x01
800 #define IRP_MN_VERIFY_VOLUME            0x02
801 #define IRP_MN_LOAD_FILE_SYSTEM         0x03
802 #define IRP_MN_TRACK_LINK               0x04
803 #define IRP_MN_KERNEL_CALL              0x04
804
805 #define IRP_MN_LOCK                     0x01
806 #define IRP_MN_UNLOCK_SINGLE            0x02
807 #define IRP_MN_UNLOCK_ALL               0x03
808 #define IRP_MN_UNLOCK_ALL_BY_KEY        0x04
809
810 #define IRP_MN_NORMAL                   0x00
811 #define IRP_MN_DPC                      0x01
812 #define IRP_MN_MDL                      0x02
813 #define IRP_MN_COMPLETE                 0x04
814 #define IRP_MN_COMPRESSED               0x08
815
816 #define IRP_MN_MDL_DPC                  (IRP_MN_MDL | IRP_MN_DPC)
817 #define IRP_MN_COMPLETE_MDL             (IRP_MN_COMPLETE | IRP_MN_MDL)
818 #define IRP_MN_COMPLETE_MDL_DPC         (IRP_MN_COMPLETE_MDL | IRP_MN_DPC)
819
820 #define IRP_MN_SCSI_CLASS               0x01
821
822 #define IRP_MN_START_DEVICE                 0x00
823 #define IRP_MN_QUERY_REMOVE_DEVICE          0x01
824 #define IRP_MN_REMOVE_DEVICE                0x02
825 #define IRP_MN_CANCEL_REMOVE_DEVICE         0x03
826 #define IRP_MN_STOP_DEVICE                  0x04
827 #define IRP_MN_QUERY_STOP_DEVICE            0x05
828 #define IRP_MN_CANCEL_STOP_DEVICE           0x06
829
830 #define IRP_MN_QUERY_DEVICE_RELATIONS       0x07
831 #define IRP_MN_QUERY_INTERFACE              0x08
832 #define IRP_MN_QUERY_CAPABILITIES           0x09
833 #define IRP_MN_QUERY_RESOURCES              0x0A
834 #define IRP_MN_QUERY_RESOURCE_REQUIREMENTS  0x0B
835 #define IRP_MN_QUERY_DEVICE_TEXT            0x0C
836 #define IRP_MN_FILTER_RESOURCE_REQUIREMENTS 0x0D
837
838 #define IRP_MN_READ_CONFIG                  0x0F
839 #define IRP_MN_WRITE_CONFIG                 0x10
840 #define IRP_MN_EJECT                        0x11
841 #define IRP_MN_SET_LOCK                     0x12
842 #define IRP_MN_QUERY_ID                     0x13
843 #define IRP_MN_QUERY_PNP_DEVICE_STATE       0x14
844 #define IRP_MN_QUERY_BUS_INFORMATION        0x15
845 #define IRP_MN_DEVICE_USAGE_NOTIFICATION    0x16
846 #define IRP_MN_SURPRISE_REMOVAL             0x17
847 #define IRP_MN_QUERY_LEGACY_BUS_INFORMATION 0x18
848
849 #define IRP_MN_WAIT_WAKE                    0x00
850 #define IRP_MN_POWER_SEQUENCE               0x01
851 #define IRP_MN_SET_POWER                    0x02
852 #define IRP_MN_QUERY_POWER                  0x03
853
854 #define IRP_MN_QUERY_ALL_DATA               0x00
855 #define IRP_MN_QUERY_SINGLE_INSTANCE        0x01
856 #define IRP_MN_CHANGE_SINGLE_INSTANCE       0x02
857 #define IRP_MN_CHANGE_SINGLE_ITEM           0x03
858 #define IRP_MN_ENABLE_EVENTS                0x04
859 #define IRP_MN_DISABLE_EVENTS               0x05
860 #define IRP_MN_ENABLE_COLLECTION            0x06
861 #define IRP_MN_DISABLE_COLLECTION           0x07
862 #define IRP_MN_REGINFO                      0x08
863 #define IRP_MN_EXECUTE_METHOD               0x09
864 #define IRP_MN_REGINFO_EX                   0x0b
865
866 /* IRP flags */
867
868 #define IRP_NOCACHE                     0x00000001
869 #define IRP_PAGING_IO                   0x00000002
870 #define IRP_MOUNT_COMPLETION            0x00000002
871 #define IRP_SYNCHRONOUS_API             0x00000004
872 #define IRP_ASSOCIATED_IRP              0x00000008
873 #define IRP_BUFFERED_IO                 0x00000010
874 #define IRP_DEALLOCATE_BUFFER           0x00000020
875 #define IRP_INPUT_OPERATION             0x00000040
876 #define IRP_SYNCHRONOUS_PAGING_IO       0x00000040
877 #define IRP_CREATE_OPERATION            0x00000080
878 #define IRP_READ_OPERATION              0x00000100
879 #define IRP_WRITE_OPERATION             0x00000200
880 #define IRP_CLOSE_OPERATION             0x00000400
881 #define IRP_DEFER_IO_COMPLETION         0x00000800
882 #define IRP_OB_QUERY_NAME               0x00001000
883 #define IRP_HOLD_DEVICE_QUEUE           0x00002000
884 #define IRP_RETRY_IO_COMPLETION         0x00004000
885 #define IRP_CLASS_CACHE_OPERATION       0x00008000
886 #define IRP_SET_USER_EVENT              IRP_CLOSE_OPERATION
887
888 /* IRP I/O control flags */
889
890 #define IRP_QUOTA_CHARGED               0x01
891 #define IRP_ALLOCATED_MUST_SUCCEED      0x02
892 #define IRP_ALLOCATED_FIXED_SIZE        0x04
893 #define IRP_LOOKASIDE_ALLOCATION        0x08
894
895 /* I/O method types */
896
897 #define METHOD_BUFFERED                 0
898 #define METHOD_IN_DIRECT                1
899 #define METHOD_OUT_DIRECT               2
900 #define METHOD_NEITHER                  3
901
902 /* File access types */
903
904 #define FILE_ANY_ACCESS                 0x0000
905 #define FILE_SPECIAL_ACCESS             FILE_ANY_ACCESS
906 #define FILE_READ_ACCESS                0x0001
907 #define FILE_WRITE_ACCESS               0x0002
908
909 /* Recover I/O access method from IOCTL code. */
910
911 #define IO_METHOD(x)                    ((x) & 0xFFFFFFFC)
912
913 /* Recover function code from IOCTL code */
914
915 #define IO_FUNC(x)                      (((x) & 0x7FFC) >> 2)
916
917 /* Macro to construct an IOCTL code. */
918
919 #define IOCTL_CODE(dev, func, iomethod, acc)    \
920         ((dev) << 16) | (acc << 14) | (func << 2) | (iomethod))
921
922
923 struct io_status_block {
924         union {
925                 uint32_t                isb_status;
926                 void                    *isb_ptr;
927         } u;
928         register_t              isb_info;
929 };
930 #define isb_status              u.isb_status
931 #define isb_ptr                 u.isb_ptr
932
933 typedef struct io_status_block io_status_block;
934
935 struct kapc {
936         uint16_t                apc_type;
937         uint16_t                apc_size;
938         uint32_t                apc_spare0;
939         void                    *apc_thread;
940         list_entry              apc_list;
941         void                    *apc_kernfunc;
942         void                    *apc_rundownfunc;
943         void                    *apc_normalfunc;
944         void                    *apc_normctx;
945         void                    *apc_sysarg1;
946         void                    *apc_sysarg2;
947         uint8_t                 apc_stateidx;
948         uint8_t                 apc_cpumode;
949         uint8_t                 apc_inserted;
950 };
951
952 typedef struct kapc kapc;
953
954 typedef uint32_t (*completion_func)(device_object *,
955         struct irp *, void *);
956 typedef uint32_t (*cancel_func)(device_object *,
957         struct irp *);
958
959 struct io_stack_location {
960         uint8_t                 isl_major;
961         uint8_t                 isl_minor;
962         uint8_t                 isl_flags;
963         uint8_t                 isl_ctl;
964
965         /*
966          * There's a big-ass union here in the actual Windows
967          * definition of the stucture, but it contains stuff
968          * that doesn't really apply to BSD, and defining it
969          * all properly would require duplicating over a dozen
970          * other structures that we'll never use. Since the
971          * io_stack_location structure is opaque to drivers
972          * anyway, I'm not going to bother with the extra crap.
973          */
974
975         union {
976                 struct {
977                         uint32_t                isl_len;
978                         uint32_t                *isl_key;
979                         uint64_t                isl_byteoff;
980                 } isl_read;
981                 struct {
982                         uint32_t                isl_len;
983                         uint32_t                *isl_key;
984                         uint64_t                isl_byteoff;
985                 } isl_write;
986                 struct {
987                         uint32_t                isl_obuflen;
988                         uint32_t                isl_ibuflen;
989                         uint32_t                isl_iocode;
990                         void                    *isl_type3ibuf;
991                 } isl_ioctl;
992                 struct {
993                         void                    *isl_arg1;
994                         void                    *isl_arg2;
995                         void                    *isl_arg3;
996                         void                    *isl_arg4;
997                 } isl_others;
998         } isl_parameters __attribute__((packed));
999
1000         void                    *isl_devobj;
1001         void                    *isl_fileobj;
1002         completion_func         isl_completionfunc;
1003         void                    *isl_completionctx;
1004 };
1005
1006 typedef struct io_stack_location io_stack_location;
1007
1008 /* Stack location control flags */
1009
1010 #define SL_PENDING_RETURNED             0x01
1011 #define SL_INVOKE_ON_CANCEL             0x20
1012 #define SL_INVOKE_ON_SUCCESS            0x40
1013 #define SL_INVOKE_ON_ERROR              0x80
1014
1015 struct irp {
1016         uint16_t                irp_type;
1017         uint16_t                irp_size;
1018         mdl                     *irp_mdl;
1019         uint32_t                irp_flags;
1020         union {
1021                 struct irp              *irp_master;
1022                 uint32_t                irp_irpcnt;
1023                 void                    *irp_sysbuf;
1024         } irp_assoc;
1025         list_entry              irp_thlist;
1026         io_status_block         irp_iostat;
1027         uint8_t                 irp_reqmode;
1028         uint8_t                 irp_pendingreturned;
1029         uint8_t                 irp_stackcnt;
1030         uint8_t                 irp_currentstackloc;
1031         uint8_t                 irp_cancel;
1032         uint8_t                 irp_cancelirql;
1033         uint8_t                 irp_apcenv;
1034         uint8_t                 irp_allocflags;
1035         io_status_block         *irp_usriostat;
1036         nt_kevent               *irp_usrevent;
1037         union {
1038                 struct {
1039                         void                    *irp_apcfunc;
1040                         void                    *irp_apcctx;
1041                 } irp_asyncparms;
1042                 uint64_t                        irp_allocsz;
1043         } irp_overlay;
1044         cancel_func             irp_cancelfunc;
1045         void                    *irp_userbuf;
1046
1047         /* Windows kernel info */
1048
1049         union {
1050                 struct {
1051                         union {
1052                                 kdevice_qentry                  irp_dqe;
1053                                 struct {
1054                                         void                    *irp_drvctx[4];
1055                                 } s1;
1056                         } u1;
1057                         void                    *irp_thread;
1058                         char                    *irp_auxbuf;
1059                         struct {
1060                                 list_entry                      irp_list;
1061                                 union {
1062                                         io_stack_location       *irp_csl;
1063                                         uint32_t                irp_pkttype;
1064                                 } u2;
1065                         } s2;
1066                         void                    *irp_fileobj;
1067                 } irp_overlay;
1068                 union {
1069                         kapc                    irp_apc;
1070                         struct {
1071 #if NUSB4BSD > 0
1072                                 void            *irp_ep;
1073 #else
1074                                 void            *irp_xfer;
1075 #endif
1076                                 void            *irp_dev;
1077                         } irp_usb;
1078                 } irp_misc;
1079                 void                    *irp_compkey;
1080         } irp_tail;
1081 };
1082
1083 #define irp_csl                 s2.u2.irp_csl
1084 #define irp_pkttype             s2.u2.irp_pkttype
1085
1086 #define IRP_NDIS_DEV(irp)       (irp)->irp_tail.irp_misc.irp_usb.irp_dev
1087 #if NUSB4BSD > 0
1088 #define IRP_NDISUSB_EP(irp)     (irp)->irp_tail.irp_misc.irp_usb.irp_ep
1089 #else
1090 #define IRP_NDISUSB_XFER(irp)   (irp)->irp_tail.irp_misc.irp_usb.irp_xfer
1091 #endif
1092
1093 typedef struct irp irp;
1094
1095 #define InterlockedExchangePointer(dst, val)                            \
1096         (void *)InterlockedExchange((uint32_t *)(dst), (uintptr_t)(val))
1097
1098 #define IoSizeOfIrp(ssize)                                              \
1099         ((uint16_t) (sizeof(irp) + ((ssize) * (sizeof(io_stack_location)))))
1100
1101 #define IoSetCancelRoutine(irp, func)                                   \
1102         (cancel_func)InterlockedExchangePointer(                        \
1103         (void *)&(ip)->irp_cancelfunc, (void *)(func))
1104
1105 #define IoSetCancelValue(irp, val)                                      \
1106         (u_long)InterlockedExchangePointer(                             \
1107         (void *)&(ip)->irp_cancel, (void *)(val))
1108
1109 #define IoGetCurrentIrpStackLocation(irp)                               \
1110         (irp)->irp_tail.irp_overlay.irp_csl
1111
1112 #define IoGetNextIrpStackLocation(irp)                                  \
1113         ((irp)->irp_tail.irp_overlay.irp_csl - 1)
1114
1115 #define IoSetNextIrpStackLocation(irp)                                  \
1116         do {                                                            \
1117                 irp->irp_currentstackloc--;                             \
1118                 irp->irp_tail.irp_overlay.irp_csl--;                    \
1119         } while(0)
1120
1121 #define IoSetCompletionRoutine(irp, func, ctx, ok, err, cancel)         \
1122         do {                                                            \
1123                 io_stack_location               *s;                     \
1124                 s = IoGetNextIrpStackLocation((irp));                   \
1125                 s->isl_completionfunc = (func);                         \
1126                 s->isl_completionctx = (ctx);                           \
1127                 s->isl_ctl = 0;                                         \
1128                 if (ok) s->isl_ctl = SL_INVOKE_ON_SUCCESS;              \
1129                 if (err) s->isl_ctl |= SL_INVOKE_ON_ERROR;              \
1130                 if (cancel) s->isl_ctl |= SL_INVOKE_ON_CANCEL;          \
1131         } while(0)
1132
1133 #define IoMarkIrpPending(irp)                                           \
1134         IoGetCurrentIrpStackLocation(irp)->isl_ctl |= SL_PENDING_RETURNED
1135 #define IoUnmarkIrpPending(irp)                                         \
1136         IoGetCurrentIrpStackLocation(irp)->isl_ctl &= ~SL_PENDING_RETURNED
1137
1138 #define IoCopyCurrentIrpStackLocationToNext(irp)                        \
1139         do {                                                            \
1140                 io_stack_location *src, *dst;                           \
1141                 src = IoGetCurrentIrpStackLocation(irp);                \
1142                 dst = IoGetNextIrpStackLocation(irp);                   \
1143                 bcopy((char *)src, (char *)dst,                         \
1144                     offsetof(io_stack_location, isl_completionfunc));   \
1145         } while(0)
1146
1147 #define IoSkipCurrentIrpStackLocation(irp)                              \
1148         do {                                                            \
1149                 (irp)->irp_currentstackloc++;                           \
1150                 (irp)->irp_tail.irp_overlay.irp_csl++;                  \
1151         } while(0)
1152
1153 #define IoInitializeDpcRequest(dobj, dpcfunc)                           \
1154         KeInitializeDpc(&(dobj)->do_dpc, dpcfunc, dobj)
1155
1156 #define IoRequestDpc(dobj, irp, ctx)                                    \
1157         KeInsertQueueDpc(&(dobj)->do_dpc, irp, ctx)
1158
1159 typedef uint32_t (*driver_dispatch)(device_object *, irp *);
1160
1161 /*
1162  * The driver_object is allocated once for each driver that's loaded
1163  * into the system. A new one is allocated for each driver and
1164  * populated a bit via the driver's DriverEntry function.
1165  * In general, a Windows DriverEntry() function will provide a pointer
1166  * to its AddDevice() method and set up the dispatch table.
1167  * For NDIS drivers, this is all done behind the scenes in the
1168  * NdisInitializeWrapper() and/or NdisMRegisterMiniport() routines.
1169  */
1170
1171 struct driver_object {
1172         uint16_t                dro_type;
1173         uint16_t                dro_size;
1174         device_object           *dro_devobj;
1175         uint32_t                dro_flags;
1176         void                    *dro_driverstart;
1177         uint32_t                dro_driversize;
1178         void                    *dro_driversection;
1179         driver_extension        *dro_driverext;
1180         unicode_string          dro_drivername;
1181         unicode_string          *dro_hwdb;
1182         void                    *dro_pfastiodispatch;
1183         void                    *dro_driverinitfunc;
1184         void                    *dro_driverstartiofunc;
1185         void                    *dro_driverunloadfunc;
1186         driver_dispatch         dro_dispatch[IRP_MJ_MAXIMUM_FUNCTION + 1];
1187 };
1188
1189 typedef struct driver_object driver_object;
1190
1191 #define DEVPROP_DEVICE_DESCRIPTION      0x00000000
1192 #define DEVPROP_HARDWARE_ID             0x00000001
1193 #define DEVPROP_COMPATIBLE_IDS          0x00000002
1194 #define DEVPROP_BOOTCONF                0x00000003
1195 #define DEVPROP_BOOTCONF_TRANSLATED     0x00000004
1196 #define DEVPROP_CLASS_NAME              0x00000005
1197 #define DEVPROP_CLASS_GUID              0x00000006
1198 #define DEVPROP_DRIVER_KEYNAME          0x00000007
1199 #define DEVPROP_MANUFACTURER            0x00000008
1200 #define DEVPROP_FRIENDLYNAME            0x00000009
1201 #define DEVPROP_LOCATION_INFO           0x0000000A
1202 #define DEVPROP_PHYSDEV_NAME            0x0000000B
1203 #define DEVPROP_BUSTYPE_GUID            0x0000000C
1204 #define DEVPROP_LEGACY_BUSTYPE          0x0000000D
1205 #define DEVPROP_BUS_NUMBER              0x0000000E
1206 #define DEVPROP_ENUMERATOR_NAME         0x0000000F
1207 #define DEVPROP_ADDRESS                 0x00000010
1208 #define DEVPROP_UINUMBER                0x00000011
1209 #define DEVPROP_INSTALL_STATE           0x00000012
1210 #define DEVPROP_REMOVAL_POLICY          0x00000013
1211
1212 /* Various supported device types (used with IoCreateDevice()) */
1213
1214 #define FILE_DEVICE_BEEP                0x00000001
1215 #define FILE_DEVICE_CD_ROM              0x00000002
1216 #define FILE_DEVICE_CD_ROM_FILE_SYSTEM  0x00000003
1217 #define FILE_DEVICE_CONTROLLER          0x00000004
1218 #define FILE_DEVICE_DATALINK            0x00000005
1219 #define FILE_DEVICE_DFS                 0x00000006
1220 #define FILE_DEVICE_DISK                0x00000007
1221 #define FILE_DEVICE_DISK_FILE_SYSTEM    0x00000008
1222 #define FILE_DEVICE_FILE_SYSTEM         0x00000009
1223 #define FILE_DEVICE_INPORT_PORT         0x0000000A
1224 #define FILE_DEVICE_KEYBOARD            0x0000000B
1225 #define FILE_DEVICE_MAILSLOT            0x0000000C
1226 #define FILE_DEVICE_MIDI_IN             0x0000000D
1227 #define FILE_DEVICE_MIDI_OUT            0x0000000E
1228 #define FILE_DEVICE_MOUSE               0x0000000F
1229 #define FILE_DEVICE_MULTI_UNC_PROVIDER  0x00000010
1230 #define FILE_DEVICE_NAMED_PIPE          0x00000011
1231 #define FILE_DEVICE_NETWORK             0x00000012
1232 #define FILE_DEVICE_NETWORK_BROWSER     0x00000013
1233 #define FILE_DEVICE_NETWORK_FILE_SYSTEM 0x00000014
1234 #define FILE_DEVICE_NULL                0x00000015
1235 #define FILE_DEVICE_PARALLEL_PORT       0x00000016
1236 #define FILE_DEVICE_PHYSICAL_NETCARD    0x00000017
1237 #define FILE_DEVICE_PRINTER             0x00000018
1238 #define FILE_DEVICE_SCANNER             0x00000019
1239 #define FILE_DEVICE_SERIAL_MOUSE_PORT   0x0000001A
1240 #define FILE_DEVICE_SERIAL_PORT         0x0000001B
1241 #define FILE_DEVICE_SCREEN              0x0000001C
1242 #define FILE_DEVICE_SOUND               0x0000001D
1243 #define FILE_DEVICE_STREAMS             0x0000001E
1244 #define FILE_DEVICE_TAPE                0x0000001F
1245 #define FILE_DEVICE_TAPE_FILE_SYSTEM    0x00000020
1246 #define FILE_DEVICE_TRANSPORT           0x00000021
1247 #define FILE_DEVICE_UNKNOWN             0x00000022
1248 #define FILE_DEVICE_VIDEO               0x00000023
1249 #define FILE_DEVICE_VIRTUAL_DISK        0x00000024
1250 #define FILE_DEVICE_WAVE_IN             0x00000025
1251 #define FILE_DEVICE_WAVE_OUT            0x00000026
1252 #define FILE_DEVICE_8042_PORT           0x00000027
1253 #define FILE_DEVICE_NETWORK_REDIRECTOR  0x00000028
1254 #define FILE_DEVICE_BATTERY             0x00000029
1255 #define FILE_DEVICE_BUS_EXTENDER        0x0000002A
1256 #define FILE_DEVICE_MODEM               0x0000002B
1257 #define FILE_DEVICE_VDM                 0x0000002C
1258 #define FILE_DEVICE_MASS_STORAGE        0x0000002D
1259 #define FILE_DEVICE_SMB                 0x0000002E
1260 #define FILE_DEVICE_KS                  0x0000002F
1261 #define FILE_DEVICE_CHANGER             0x00000030
1262 #define FILE_DEVICE_SMARTCARD           0x00000031
1263 #define FILE_DEVICE_ACPI                0x00000032
1264 #define FILE_DEVICE_DVD                 0x00000033
1265 #define FILE_DEVICE_FULLSCREEN_VIDEO    0x00000034
1266 #define FILE_DEVICE_DFS_FILE_SYSTEM     0x00000035
1267 #define FILE_DEVICE_DFS_VOLUME          0x00000036
1268 #define FILE_DEVICE_SERENUM             0x00000037
1269 #define FILE_DEVICE_TERMSRV             0x00000038
1270 #define FILE_DEVICE_KSEC                0x00000039
1271 #define FILE_DEVICE_FIPS                0x0000003A
1272
1273 /* Device characteristics */
1274
1275 #define FILE_REMOVABLE_MEDIA            0x00000001
1276 #define FILE_READ_ONLY_DEVICE           0x00000002
1277 #define FILE_FLOPPY_DISKETTE            0x00000004
1278 #define FILE_WRITE_ONCE_MEDIA           0x00000008
1279 #define FILE_REMOTE_DEVICE              0x00000010
1280 #define FILE_DEVICE_IS_MOUNTED          0x00000020
1281 #define FILE_VIRTUAL_VOLUME             0x00000040
1282 #define FILE_AUTOGENERATED_DEVICE_NAME  0x00000080
1283 #define FILE_DEVICE_SECURE_OPEN         0x00000100
1284
1285 /* Status codes */
1286
1287 #define STATUS_SUCCESS                  0x00000000
1288 #define STATUS_USER_APC                 0x000000C0
1289 #define STATUS_KERNEL_APC               0x00000100
1290 #define STATUS_ALERTED                  0x00000101
1291 #define STATUS_TIMEOUT                  0x00000102
1292 #define STATUS_PENDING                  0x00000103
1293 #define STATUS_FAILURE                  0xC0000001
1294 #define STATUS_NOT_IMPLEMENTED          0xC0000002
1295 #define STATUS_ACCESS_VIOLATION         0xC0000005
1296 #define STATUS_INVALID_PARAMETER        0xC000000D
1297 #define STATUS_INVALID_DEVICE_REQUEST   0xC0000010
1298 #define STATUS_MORE_PROCESSING_REQUIRED 0xC0000016
1299 #define STATUS_NO_MEMORY                0xC0000017
1300 #define STATUS_BUFFER_TOO_SMALL         0xC0000023
1301 #define STATUS_MUTANT_NOT_OWNED         0xC0000046
1302 #define STATUS_NOT_SUPPORTED            0xC00000BB
1303 #define STATUS_INVALID_PARAMETER_2      0xC00000F0
1304 #define STATUS_INSUFFICIENT_RESOURCES   0xC000009A
1305 #define STATUS_DEVICE_NOT_CONNECTED     0xC000009D
1306 #define STATUS_CANCELLED                0xC0000120
1307 #define STATUS_NOT_FOUND                0xC0000225
1308 #define STATUS_DEVICE_REMOVED           0xC00002B6
1309
1310 #define STATUS_WAIT_0                   0x00000000
1311
1312 /* Memory pool types, for ExAllocatePoolWithTag() */
1313
1314 #define NonPagedPool                    0x00000000
1315 #define PagedPool                       0x00000001
1316 #define NonPagedPoolMustSucceed         0x00000002
1317 #define DontUseThisType                 0x00000003
1318 #define NonPagedPoolCacheAligned        0x00000004
1319 #define PagedPoolCacheAligned           0x00000005
1320 #define NonPagedPoolCacheAlignedMustS   0x00000006
1321 #define MaxPoolType                     0x00000007
1322
1323 /*
1324  * IO_WORKITEM is an opaque structures that must be allocated
1325  * via IoAllocateWorkItem() and released via IoFreeWorkItem().
1326  * Consequently, we can define it any way we want.
1327  */
1328 typedef void (*io_workitem_func)(device_object *, void *);
1329
1330 struct io_workitem {
1331         io_workitem_func        iw_func;
1332         void                    *iw_ctx;
1333         list_entry              iw_listentry;
1334         device_object           *iw_dobj;
1335         int                     iw_idx;
1336 };
1337
1338 typedef struct io_workitem io_workitem;
1339
1340 #define WORKQUEUE_CRITICAL      0
1341 #define WORKQUEUE_DELAYED       1
1342 #define WORKQUEUE_HYPERCRITICAL 2
1343
1344 #define WORKITEM_THREADS        4
1345 #define WORKITEM_LEGACY_THREAD  3
1346 #define WORKIDX_INC(x)          (x) = (x + 1) % WORKITEM_LEGACY_THREAD
1347
1348 /*
1349  * Older, deprecated work item API, needed to support NdisQueueWorkItem().
1350  */
1351
1352 struct work_queue_item;
1353
1354 typedef void (*work_item_func)(struct work_queue_item *, void *);
1355
1356 struct work_queue_item {
1357         list_entry              wqi_entry;
1358         work_item_func          wqi_func;
1359         void                    *wqi_ctx;
1360 };
1361
1362 typedef struct work_queue_item work_queue_item;
1363
1364 #define ExInitializeWorkItem(w, func, ctx)              \
1365         do {                                            \
1366                 (w)->wqi_func = (func);                 \
1367                 (w)->wqi_ctx = (ctx);                   \
1368                 InitializeListHead(&((w)->wqi_entry));  \
1369         } while (0)
1370
1371 /*
1372  * FreeBSD's kernel stack is 2 pages in size by default. The
1373  * Windows stack is larger, so we need to give our threads more
1374  * stack pages. 4 should be enough, we use 8 just to extra safe.
1375  */
1376 #define NDIS_KSTACK_PAGES       8
1377
1378 /*
1379  * Different kinds of function wrapping we can do.
1380  */
1381
1382 #define WINDRV_WRAP_STDCALL     1
1383 #define WINDRV_WRAP_FASTCALL    2
1384 #define WINDRV_WRAP_REGPARM     3
1385 #define WINDRV_WRAP_CDECL       4
1386 #define WINDRV_WRAP_AMD64       5
1387
1388 struct drvdb_ent {
1389         driver_object           *windrv_object;
1390         void                    *windrv_devlist;
1391         ndis_cfg                *windrv_regvals;
1392         interface_type          windrv_bustype;
1393         STAILQ_ENTRY(drvdb_ent) link;
1394 };
1395
1396 extern image_patch_table ntoskrnl_functbl[];
1397 #ifdef __amd64__
1398 extern struct kuser_shared_data kuser_shared_data;
1399 #endif
1400 typedef void (*funcptr)(void);
1401 typedef int (*matchfuncptr)(interface_type, void *, void *);
1402
1403 __BEGIN_DECLS
1404 extern int windrv_libinit(void);
1405 extern int windrv_libfini(void);
1406 extern driver_object *windrv_lookup(vm_offset_t, char *);
1407 extern struct drvdb_ent *windrv_match(matchfuncptr, void *);
1408 extern int windrv_load(module_t, vm_offset_t, int, interface_type,
1409         void *, ndis_cfg *);
1410 extern int windrv_unload(module_t, vm_offset_t, int);
1411 extern int windrv_create_pdo(driver_object *, device_t);
1412 extern void windrv_destroy_pdo(driver_object *, device_t);
1413 extern device_object *windrv_find_pdo(driver_object *, device_t);
1414 extern int windrv_bus_attach(driver_object *, char *);
1415 extern int windrv_wrap(funcptr, funcptr *, int, int);
1416 extern int windrv_unwrap(funcptr);
1417 extern void ctxsw_utow(void);
1418 extern void ctxsw_wtou(void);
1419
1420 extern int ntoskrnl_libinit(void);
1421 extern int ntoskrnl_libfini(void);
1422
1423 extern void ntoskrnl_intr(void *);
1424 extern void ntoskrnl_time(uint64_t *);
1425
1426 extern uint16_t ExQueryDepthSList(slist_header *);
1427 extern slist_entry
1428         *InterlockedPushEntrySList(slist_header *, slist_entry *);
1429 extern slist_entry *InterlockedPopEntrySList(slist_header *);
1430 extern uint32_t RtlUnicodeStringToAnsiString(ansi_string *,
1431         unicode_string *, uint8_t);
1432 extern uint32_t RtlAnsiStringToUnicodeString(unicode_string *,
1433         ansi_string *, uint8_t);
1434 extern void RtlInitAnsiString(ansi_string *, char *);
1435 extern void RtlInitUnicodeString(unicode_string *,
1436         uint16_t *);
1437 extern void RtlFreeUnicodeString(unicode_string *);
1438 extern void RtlFreeAnsiString(ansi_string *);
1439 extern void KeInitializeDpc(kdpc *, void *, void *);
1440 extern uint8_t KeInsertQueueDpc(kdpc *, void *, void *);
1441 extern uint8_t KeRemoveQueueDpc(kdpc *);
1442 extern void KeSetImportanceDpc(kdpc *, uint32_t);
1443 extern void KeSetTargetProcessorDpc(kdpc *, uint8_t);
1444 extern void KeFlushQueuedDpcs(void);
1445 extern uint32_t KeGetCurrentProcessorNumber(void);
1446 extern void KeInitializeTimer(ktimer *);
1447 extern void KeInitializeTimerEx(ktimer *, uint32_t);
1448 extern uint8_t KeSetTimer(ktimer *, int64_t, kdpc *);
1449 extern uint8_t KeSetTimerEx(ktimer *, int64_t, uint32_t, kdpc *);
1450 extern uint8_t KeCancelTimer(ktimer *);
1451 extern uint8_t KeReadStateTimer(ktimer *);
1452 extern uint32_t KeWaitForSingleObject(void *, uint32_t,
1453         uint32_t, uint8_t, int64_t *);
1454 extern void KeInitializeEvent(nt_kevent *, uint32_t, uint8_t);
1455 extern void KeClearEvent(nt_kevent *);
1456 extern uint32_t KeReadStateEvent(nt_kevent *);
1457 extern uint32_t KeSetEvent(nt_kevent *, uint32_t, uint8_t);
1458 extern uint32_t KeResetEvent(nt_kevent *);
1459 #ifdef __i386__
1460 extern void KefAcquireSpinLockAtDpcLevel(kspin_lock *);
1461 extern void KefReleaseSpinLockFromDpcLevel(kspin_lock *);
1462 extern uint8_t KeAcquireSpinLockRaiseToDpc(kspin_lock *);
1463 #else
1464 extern void KeAcquireSpinLockAtDpcLevel(kspin_lock *);
1465 extern void KeReleaseSpinLockFromDpcLevel(kspin_lock *);
1466 #endif
1467 extern void KeInitializeSpinLock(kspin_lock *);
1468 extern uint8_t KeAcquireInterruptSpinLock(kinterrupt *);
1469 extern void KeReleaseInterruptSpinLock(kinterrupt *, uint8_t);
1470 extern uint8_t KeSynchronizeExecution(kinterrupt *, void *, void *);
1471 extern uintptr_t InterlockedExchange(volatile uint32_t *,
1472         uintptr_t);
1473 extern void *ExAllocatePoolWithTag(uint32_t, size_t, uint32_t);
1474 extern void ExFreePool(void *);
1475 extern uint32_t IoConnectInterrupt(kinterrupt **, void *, void *,
1476         kspin_lock *, uint32_t, uint8_t, uint8_t, uint8_t, uint8_t,
1477         uint32_t, uint8_t);
1478 extern uint8_t MmIsAddressValid(void *);
1479 extern void *MmGetSystemRoutineAddress(unicode_string *);
1480 extern void *MmMapIoSpace(uint64_t, uint32_t, uint32_t);
1481 extern void MmUnmapIoSpace(void *, size_t);
1482 extern void MmBuildMdlForNonPagedPool(mdl *);
1483 extern void IoDisconnectInterrupt(kinterrupt *);
1484 extern uint32_t IoAllocateDriverObjectExtension(driver_object *,
1485         void *, uint32_t, void **);
1486 extern void *IoGetDriverObjectExtension(driver_object *, void *);
1487 extern uint32_t IoCreateDevice(driver_object *, uint32_t,
1488         unicode_string *, uint32_t, uint32_t, uint8_t, device_object **);
1489 extern void IoDeleteDevice(device_object *);
1490 extern device_object *IoGetAttachedDevice(device_object *);
1491 extern uint32_t IofCallDriver(device_object *, irp *);
1492 extern void IofCompleteRequest(irp *, uint8_t);
1493 extern void IoAcquireCancelSpinLock(uint8_t *);
1494 extern void IoReleaseCancelSpinLock(uint8_t);
1495 extern uint8_t IoCancelIrp(irp *);
1496 extern void IoDetachDevice(device_object *);
1497 extern device_object *IoAttachDeviceToDeviceStack(device_object *,
1498         device_object *);
1499 extern mdl *IoAllocateMdl(void *, uint32_t, uint8_t, uint8_t, irp *);
1500 extern void IoFreeMdl(mdl *);
1501 extern io_workitem *IoAllocateWorkItem(device_object *);
1502 extern void ExQueueWorkItem(work_queue_item *, u_int32_t);
1503 extern void IoFreeWorkItem(io_workitem *);
1504 extern void IoQueueWorkItem(io_workitem *, io_workitem_func,
1505         uint32_t, void *);
1506
1507 #define IoCallDriver(a, b)              IofCallDriver(a, b)
1508 #define IoCompleteRequest(a, b)         IofCompleteRequest(a, b)
1509
1510 /*
1511  * On the Windows x86 arch, KeAcquireSpinLock() and KeReleaseSpinLock()
1512  * routines live in the HAL. We try to imitate this behavior.
1513  */
1514 #ifdef __i386__
1515 #define KI_USER_SHARED_DATA 0xffdf0000
1516 #define KeAcquireSpinLock(a, b) *(b) = KfAcquireSpinLock(a)
1517 #define KeReleaseSpinLock(a, b) KfReleaseSpinLock(a, b)
1518 #define KeRaiseIrql(a, b)       *(b) = KfRaiseIrql(a)
1519 #define KeLowerIrql(a)          KfLowerIrql(a)
1520 #define KeAcquireSpinLockAtDpcLevel(a)  KefAcquireSpinLockAtDpcLevel(a)
1521 #define KeReleaseSpinLockFromDpcLevel(a)  KefReleaseSpinLockFromDpcLevel(a)
1522 #endif /* __i386__ */
1523
1524 #ifdef __x86_64__
1525 #define KI_USER_SHARED_DATA 0xfffff78000000000UL
1526 #define KeAcquireSpinLock(a, b) *(b) = KfAcquireSpinLock(a)
1527 #define KeReleaseSpinLock(a, b) KfReleaseSpinLock(a, b)
1528
1529 /*
1530  * These may need to be redefined later;
1531  * not sure where they live on amd64 yet.
1532  */
1533 #define KeRaiseIrql(a, b)       *(b) = KfRaiseIrql(a)
1534 #define KeLowerIrql(a)          KfLowerIrql(a)
1535 #endif /* __x86_64__ */
1536
1537 __END_DECLS
1538
1539 #endif /* _NTOSKRNL_VAR_H_ */