1 /*-
2 * SPDX-License-Identifier: BSD-4-Clause
3 *
4 * Copyright (c) 2003
5 * Bill Paul <wpaul@windriver.com>. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Bill Paul.
18 * 4. Neither the name of the author nor the names of any co-contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32 * THE POSSIBILITY OF SUCH DAMAGE.
33 *
34 * $FreeBSD: releng/12.0/sys/compat/ndis/ntoskrnl_var.h 325966 2017-11-18 14:26:50Z pfg $
35 */
36
37 #ifndef _NTOSKRNL_VAR_H_
38 #define _NTOSKRNL_VAR_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_flag & P_KPROC == FALSE)
343
344 #define AT_DISPATCH_LEVEL(td) \
345 ((td)->td_base_pri == PI_REALTIME)
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 analogous
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 analogous 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 structure, 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 void *irp_ep;
1072 void *irp_dev;
1073 } irp_usb;
1074 } irp_misc;
1075 void *irp_compkey;
1076 } irp_tail;
1077 };
1078
1079 #define irp_csl s2.u2.irp_csl
1080 #define irp_pkttype s2.u2.irp_pkttype
1081
1082 #define IRP_NDIS_DEV(irp) (irp)->irp_tail.irp_misc.irp_usb.irp_dev
1083 #define IRP_NDISUSB_EP(irp) (irp)->irp_tail.irp_misc.irp_usb.irp_ep
1084
1085 typedef struct irp irp;
1086
1087 #define InterlockedExchangePointer(dst, val) \
1088 (void *)InterlockedExchange((uint32_t *)(dst), (uintptr_t)(val))
1089
1090 #define IoSizeOfIrp(ssize) \
1091 ((uint16_t) (sizeof(irp) + ((ssize) * (sizeof(io_stack_location)))))
1092
1093 #define IoSetCancelRoutine(irp, func) \
1094 (cancel_func)InterlockedExchangePointer( \
1095 (void *)&(ip)->irp_cancelfunc, (void *)(func))
1096
1097 #define IoSetCancelValue(irp, val) \
1098 (u_long)InterlockedExchangePointer( \
1099 (void *)&(ip)->irp_cancel, (void *)(val))
1100
1101 #define IoGetCurrentIrpStackLocation(irp) \
1102 (irp)->irp_tail.irp_overlay.irp_csl
1103
1104 #define IoGetNextIrpStackLocation(irp) \
1105 ((irp)->irp_tail.irp_overlay.irp_csl - 1)
1106
1107 #define IoSetNextIrpStackLocation(irp) \
1108 do { \
1109 irp->irp_currentstackloc--; \
1110 irp->irp_tail.irp_overlay.irp_csl--; \
1111 } while(0)
1112
1113 #define IoSetCompletionRoutine(irp, func, ctx, ok, err, cancel) \
1114 do { \
1115 io_stack_location *s; \
1116 s = IoGetNextIrpStackLocation((irp)); \
1117 s->isl_completionfunc = (func); \
1118 s->isl_completionctx = (ctx); \
1119 s->isl_ctl = 0; \
1120 if (ok) s->isl_ctl = SL_INVOKE_ON_SUCCESS; \
1121 if (err) s->isl_ctl |= SL_INVOKE_ON_ERROR; \
1122 if (cancel) s->isl_ctl |= SL_INVOKE_ON_CANCEL; \
1123 } while(0)
1124
1125 #define IoMarkIrpPending(irp) \
1126 IoGetCurrentIrpStackLocation(irp)->isl_ctl |= SL_PENDING_RETURNED
1127 #define IoUnmarkIrpPending(irp) \
1128 IoGetCurrentIrpStackLocation(irp)->isl_ctl &= ~SL_PENDING_RETURNED
1129
1130 #define IoCopyCurrentIrpStackLocationToNext(irp) \
1131 do { \
1132 io_stack_location *src, *dst; \
1133 src = IoGetCurrentIrpStackLocation(irp); \
1134 dst = IoGetNextIrpStackLocation(irp); \
1135 bcopy((char *)src, (char *)dst, \
1136 offsetof(io_stack_location, isl_completionfunc)); \
1137 } while(0)
1138
1139 #define IoSkipCurrentIrpStackLocation(irp) \
1140 do { \
1141 (irp)->irp_currentstackloc++; \
1142 (irp)->irp_tail.irp_overlay.irp_csl++; \
1143 } while(0)
1144
1145 #define IoInitializeDpcRequest(dobj, dpcfunc) \
1146 KeInitializeDpc(&(dobj)->do_dpc, dpcfunc, dobj)
1147
1148 #define IoRequestDpc(dobj, irp, ctx) \
1149 KeInsertQueueDpc(&(dobj)->do_dpc, irp, ctx)
1150
1151 typedef uint32_t (*driver_dispatch)(device_object *, irp *);
1152
1153 /*
1154 * The driver_object is allocated once for each driver that's loaded
1155 * into the system. A new one is allocated for each driver and
1156 * populated a bit via the driver's DriverEntry function.
1157 * In general, a Windows DriverEntry() function will provide a pointer
1158 * to its AddDevice() method and set up the dispatch table.
1159 * For NDIS drivers, this is all done behind the scenes in the
1160 * NdisInitializeWrapper() and/or NdisMRegisterMiniport() routines.
1161 */
1162
1163 struct driver_object {
1164 uint16_t dro_type;
1165 uint16_t dro_size;
1166 device_object *dro_devobj;
1167 uint32_t dro_flags;
1168 void *dro_driverstart;
1169 uint32_t dro_driversize;
1170 void *dro_driversection;
1171 driver_extension *dro_driverext;
1172 unicode_string dro_drivername;
1173 unicode_string *dro_hwdb;
1174 void *dro_pfastiodispatch;
1175 void *dro_driverinitfunc;
1176 void *dro_driverstartiofunc;
1177 void *dro_driverunloadfunc;
1178 driver_dispatch dro_dispatch[IRP_MJ_MAXIMUM_FUNCTION + 1];
1179 };
1180
1181 typedef struct driver_object driver_object;
1182
1183 #define DEVPROP_DEVICE_DESCRIPTION 0x00000000
1184 #define DEVPROP_HARDWARE_ID 0x00000001
1185 #define DEVPROP_COMPATIBLE_IDS 0x00000002
1186 #define DEVPROP_BOOTCONF 0x00000003
1187 #define DEVPROP_BOOTCONF_TRANSLATED 0x00000004
1188 #define DEVPROP_CLASS_NAME 0x00000005
1189 #define DEVPROP_CLASS_GUID 0x00000006
1190 #define DEVPROP_DRIVER_KEYNAME 0x00000007
1191 #define DEVPROP_MANUFACTURER 0x00000008
1192 #define DEVPROP_FRIENDLYNAME 0x00000009
1193 #define DEVPROP_LOCATION_INFO 0x0000000A
1194 #define DEVPROP_PHYSDEV_NAME 0x0000000B
1195 #define DEVPROP_BUSTYPE_GUID 0x0000000C
1196 #define DEVPROP_LEGACY_BUSTYPE 0x0000000D
1197 #define DEVPROP_BUS_NUMBER 0x0000000E
1198 #define DEVPROP_ENUMERATOR_NAME 0x0000000F
1199 #define DEVPROP_ADDRESS 0x00000010
1200 #define DEVPROP_UINUMBER 0x00000011
1201 #define DEVPROP_INSTALL_STATE 0x00000012
1202 #define DEVPROP_REMOVAL_POLICY 0x00000013
1203
1204 /* Various supported device types (used with IoCreateDevice()) */
1205
1206 #define FILE_DEVICE_BEEP 0x00000001
1207 #define FILE_DEVICE_CD_ROM 0x00000002
1208 #define FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003
1209 #define FILE_DEVICE_CONTROLLER 0x00000004
1210 #define FILE_DEVICE_DATALINK 0x00000005
1211 #define FILE_DEVICE_DFS 0x00000006
1212 #define FILE_DEVICE_DISK 0x00000007
1213 #define FILE_DEVICE_DISK_FILE_SYSTEM 0x00000008
1214 #define FILE_DEVICE_FILE_SYSTEM 0x00000009
1215 #define FILE_DEVICE_INPORT_PORT 0x0000000A
1216 #define FILE_DEVICE_KEYBOARD 0x0000000B
1217 #define FILE_DEVICE_MAILSLOT 0x0000000C
1218 #define FILE_DEVICE_MIDI_IN 0x0000000D
1219 #define FILE_DEVICE_MIDI_OUT 0x0000000E
1220 #define FILE_DEVICE_MOUSE 0x0000000F
1221 #define FILE_DEVICE_MULTI_UNC_PROVIDER 0x00000010
1222 #define FILE_DEVICE_NAMED_PIPE 0x00000011
1223 #define FILE_DEVICE_NETWORK 0x00000012
1224 #define FILE_DEVICE_NETWORK_BROWSER 0x00000013
1225 #define FILE_DEVICE_NETWORK_FILE_SYSTEM 0x00000014
1226 #define FILE_DEVICE_NULL 0x00000015
1227 #define FILE_DEVICE_PARALLEL_PORT 0x00000016
1228 #define FILE_DEVICE_PHYSICAL_NETCARD 0x00000017
1229 #define FILE_DEVICE_PRINTER 0x00000018
1230 #define FILE_DEVICE_SCANNER 0x00000019
1231 #define FILE_DEVICE_SERIAL_MOUSE_PORT 0x0000001A
1232 #define FILE_DEVICE_SERIAL_PORT 0x0000001B
1233 #define FILE_DEVICE_SCREEN 0x0000001C
1234 #define FILE_DEVICE_SOUND 0x0000001D
1235 #define FILE_DEVICE_STREAMS 0x0000001E
1236 #define FILE_DEVICE_TAPE 0x0000001F
1237 #define FILE_DEVICE_TAPE_FILE_SYSTEM 0x00000020
1238 #define FILE_DEVICE_TRANSPORT 0x00000021
1239 #define FILE_DEVICE_UNKNOWN 0x00000022
1240 #define FILE_DEVICE_VIDEO 0x00000023
1241 #define FILE_DEVICE_VIRTUAL_DISK 0x00000024
1242 #define FILE_DEVICE_WAVE_IN 0x00000025
1243 #define FILE_DEVICE_WAVE_OUT 0x00000026
1244 #define FILE_DEVICE_8042_PORT 0x00000027
1245 #define FILE_DEVICE_NETWORK_REDIRECTOR 0x00000028
1246 #define FILE_DEVICE_BATTERY 0x00000029
1247 #define FILE_DEVICE_BUS_EXTENDER 0x0000002A
1248 #define FILE_DEVICE_MODEM 0x0000002B
1249 #define FILE_DEVICE_VDM 0x0000002C
1250 #define FILE_DEVICE_MASS_STORAGE 0x0000002D
1251 #define FILE_DEVICE_SMB 0x0000002E
1252 #define FILE_DEVICE_KS 0x0000002F
1253 #define FILE_DEVICE_CHANGER 0x00000030
1254 #define FILE_DEVICE_SMARTCARD 0x00000031
1255 #define FILE_DEVICE_ACPI 0x00000032
1256 #define FILE_DEVICE_DVD 0x00000033
1257 #define FILE_DEVICE_FULLSCREEN_VIDEO 0x00000034
1258 #define FILE_DEVICE_DFS_FILE_SYSTEM 0x00000035
1259 #define FILE_DEVICE_DFS_VOLUME 0x00000036
1260 #define FILE_DEVICE_SERENUM 0x00000037
1261 #define FILE_DEVICE_TERMSRV 0x00000038
1262 #define FILE_DEVICE_KSEC 0x00000039
1263 #define FILE_DEVICE_FIPS 0x0000003A
1264
1265 /* Device characteristics */
1266
1267 #define FILE_REMOVABLE_MEDIA 0x00000001
1268 #define FILE_READ_ONLY_DEVICE 0x00000002
1269 #define FILE_FLOPPY_DISKETTE 0x00000004
1270 #define FILE_WRITE_ONCE_MEDIA 0x00000008
1271 #define FILE_REMOTE_DEVICE 0x00000010
1272 #define FILE_DEVICE_IS_MOUNTED 0x00000020
1273 #define FILE_VIRTUAL_VOLUME 0x00000040
1274 #define FILE_AUTOGENERATED_DEVICE_NAME 0x00000080
1275 #define FILE_DEVICE_SECURE_OPEN 0x00000100
1276
1277 /* Status codes */
1278
1279 #define STATUS_SUCCESS 0x00000000
1280 #define STATUS_USER_APC 0x000000C0
1281 #define STATUS_KERNEL_APC 0x00000100
1282 #define STATUS_ALERTED 0x00000101
1283 #define STATUS_TIMEOUT 0x00000102
1284 #define STATUS_PENDING 0x00000103
1285 #define STATUS_FAILURE 0xC0000001
1286 #define STATUS_NOT_IMPLEMENTED 0xC0000002
1287 #define STATUS_ACCESS_VIOLATION 0xC0000005
1288 #define STATUS_INVALID_PARAMETER 0xC000000D
1289 #define STATUS_INVALID_DEVICE_REQUEST 0xC0000010
1290 #define STATUS_MORE_PROCESSING_REQUIRED 0xC0000016
1291 #define STATUS_NO_MEMORY 0xC0000017
1292 #define STATUS_BUFFER_TOO_SMALL 0xC0000023
1293 #define STATUS_MUTANT_NOT_OWNED 0xC0000046
1294 #define STATUS_NOT_SUPPORTED 0xC00000BB
1295 #define STATUS_INVALID_PARAMETER_2 0xC00000F0
1296 #define STATUS_INSUFFICIENT_RESOURCES 0xC000009A
1297 #define STATUS_DEVICE_NOT_CONNECTED 0xC000009D
1298 #define STATUS_CANCELLED 0xC0000120
1299 #define STATUS_NOT_FOUND 0xC0000225
1300 #define STATUS_DEVICE_REMOVED 0xC00002B6
1301
1302 #define STATUS_WAIT_0 0x00000000
1303
1304 /* Memory pool types, for ExAllocatePoolWithTag() */
1305
1306 #define NonPagedPool 0x00000000
1307 #define PagedPool 0x00000001
1308 #define NonPagedPoolMustSucceed 0x00000002
1309 #define DontUseThisType 0x00000003
1310 #define NonPagedPoolCacheAligned 0x00000004
1311 #define PagedPoolCacheAligned 0x00000005
1312 #define NonPagedPoolCacheAlignedMustS 0x00000006
1313 #define MaxPoolType 0x00000007
1314
1315 /*
1316 * IO_WORKITEM is an opaque structures that must be allocated
1317 * via IoAllocateWorkItem() and released via IoFreeWorkItem().
1318 * Consequently, we can define it any way we want.
1319 */
1320 typedef void (*io_workitem_func)(device_object *, void *);
1321
1322 struct io_workitem {
1323 io_workitem_func iw_func;
1324 void *iw_ctx;
1325 list_entry iw_listentry;
1326 device_object *iw_dobj;
1327 int iw_idx;
1328 };
1329
1330 typedef struct io_workitem io_workitem;
1331
1332 #define WORKQUEUE_CRITICAL 0
1333 #define WORKQUEUE_DELAYED 1
1334 #define WORKQUEUE_HYPERCRITICAL 2
1335
1336 #define WORKITEM_THREADS 4
1337 #define WORKITEM_LEGACY_THREAD 3
1338 #define WORKIDX_INC(x) (x) = (x + 1) % WORKITEM_LEGACY_THREAD
1339
1340 /*
1341 * Older, deprecated work item API, needed to support NdisQueueWorkItem().
1342 */
1343
1344 struct work_queue_item;
1345
1346 typedef void (*work_item_func)(struct work_queue_item *, void *);
1347
1348 struct work_queue_item {
1349 list_entry wqi_entry;
1350 work_item_func wqi_func;
1351 void *wqi_ctx;
1352 };
1353
1354 typedef struct work_queue_item work_queue_item;
1355
1356 #define ExInitializeWorkItem(w, func, ctx) \
1357 do { \
1358 (w)->wqi_func = (func); \
1359 (w)->wqi_ctx = (ctx); \
1360 InitializeListHead(&((w)->wqi_entry)); \
1361 } while (0)
1362
1363 /*
1364 * FreeBSD's kernel stack is 2 pages in size by default. The
1365 * Windows stack is larger, so we need to give our threads more
1366 * stack pages. 4 should be enough, we use 8 just to extra safe.
1367 */
1368 #define NDIS_KSTACK_PAGES 8
1369
1370 /*
1371 * Different kinds of function wrapping we can do.
1372 */
1373
1374 #define WINDRV_WRAP_STDCALL 1
1375 #define WINDRV_WRAP_FASTCALL 2
1376 #define WINDRV_WRAP_REGPARM 3
1377 #define WINDRV_WRAP_CDECL 4
1378 #define WINDRV_WRAP_AMD64 5
1379
1380 struct drvdb_ent {
1381 driver_object *windrv_object;
1382 void *windrv_devlist;
1383 ndis_cfg *windrv_regvals;
1384 interface_type windrv_bustype;
1385 STAILQ_ENTRY(drvdb_ent) link;
1386 };
1387
1388 extern image_patch_table ntoskrnl_functbl[];
1389 #ifdef __amd64__
1390 extern struct kuser_shared_data kuser_shared_data;
1391 #endif
1392 typedef void (*funcptr)(void);
1393 typedef int (*matchfuncptr)(interface_type, void *, void *);
1394
1395 __BEGIN_DECLS
1396 extern int windrv_libinit(void);
1397 extern int windrv_libfini(void);
1398 extern driver_object *windrv_lookup(vm_offset_t, char *);
1399 extern struct drvdb_ent *windrv_match(matchfuncptr, void *);
1400 extern int windrv_load(module_t, vm_offset_t, int, interface_type,
1401 void *, ndis_cfg *);
1402 extern int windrv_unload(module_t, vm_offset_t, int);
1403 extern int windrv_create_pdo(driver_object *, device_t);
1404 extern void windrv_destroy_pdo(driver_object *, device_t);
1405 extern device_object *windrv_find_pdo(driver_object *, device_t);
1406 extern int windrv_bus_attach(driver_object *, char *);
1407 extern int windrv_wrap(funcptr, funcptr *, int, int);
1408 extern int windrv_unwrap(funcptr);
1409 extern void ctxsw_utow(void);
1410 extern void ctxsw_wtou(void);
1411
1412 extern int ntoskrnl_libinit(void);
1413 extern int ntoskrnl_libfini(void);
1414
1415 extern void ntoskrnl_intr(void *);
1416 extern void ntoskrnl_time(uint64_t *);
1417
1418 extern uint16_t ExQueryDepthSList(slist_header *);
1419 extern slist_entry
1420 *InterlockedPushEntrySList(slist_header *, slist_entry *);
1421 extern slist_entry *InterlockedPopEntrySList(slist_header *);
1422 extern uint32_t RtlUnicodeStringToAnsiString(ansi_string *,
1423 unicode_string *, uint8_t);
1424 extern uint32_t RtlAnsiStringToUnicodeString(unicode_string *,
1425 ansi_string *, uint8_t);
1426 extern void RtlInitAnsiString(ansi_string *, char *);
1427 extern void RtlInitUnicodeString(unicode_string *,
1428 uint16_t *);
1429 extern void RtlFreeUnicodeString(unicode_string *);
1430 extern void RtlFreeAnsiString(ansi_string *);
1431 extern void KeInitializeDpc(kdpc *, void *, void *);
1432 extern uint8_t KeInsertQueueDpc(kdpc *, void *, void *);
1433 extern uint8_t KeRemoveQueueDpc(kdpc *);
1434 extern void KeSetImportanceDpc(kdpc *, uint32_t);
1435 extern void KeSetTargetProcessorDpc(kdpc *, uint8_t);
1436 extern void KeFlushQueuedDpcs(void);
1437 extern uint32_t KeGetCurrentProcessorNumber(void);
1438 extern void KeInitializeTimer(ktimer *);
1439 extern void KeInitializeTimerEx(ktimer *, uint32_t);
1440 extern uint8_t KeSetTimer(ktimer *, int64_t, kdpc *);
1441 extern uint8_t KeSetTimerEx(ktimer *, int64_t, uint32_t, kdpc *);
1442 extern uint8_t KeCancelTimer(ktimer *);
1443 extern uint8_t KeReadStateTimer(ktimer *);
1444 extern uint32_t KeWaitForSingleObject(void *, uint32_t,
1445 uint32_t, uint8_t, int64_t *);
1446 extern void KeInitializeEvent(nt_kevent *, uint32_t, uint8_t);
1447 extern void KeClearEvent(nt_kevent *);
1448 extern uint32_t KeReadStateEvent(nt_kevent *);
1449 extern uint32_t KeSetEvent(nt_kevent *, uint32_t, uint8_t);
1450 extern uint32_t KeResetEvent(nt_kevent *);
1451 #ifdef __i386__
1452 extern void KefAcquireSpinLockAtDpcLevel(kspin_lock *);
1453 extern void KefReleaseSpinLockFromDpcLevel(kspin_lock *);
1454 extern uint8_t KeAcquireSpinLockRaiseToDpc(kspin_lock *);
1455 #else
1456 extern void KeAcquireSpinLockAtDpcLevel(kspin_lock *);
1457 extern void KeReleaseSpinLockFromDpcLevel(kspin_lock *);
1458 #endif
1459 extern void KeInitializeSpinLock(kspin_lock *);
1460 extern uint8_t KeAcquireInterruptSpinLock(kinterrupt *);
1461 extern void KeReleaseInterruptSpinLock(kinterrupt *, uint8_t);
1462 extern uint8_t KeSynchronizeExecution(kinterrupt *, void *, void *);
1463 extern uintptr_t InterlockedExchange(volatile uint32_t *,
1464 uintptr_t);
1465 extern void *ExAllocatePoolWithTag(uint32_t, size_t, uint32_t);
1466 extern void ExFreePool(void *);
1467 extern uint32_t IoConnectInterrupt(kinterrupt **, void *, void *,
1468 kspin_lock *, uint32_t, uint8_t, uint8_t, uint8_t, uint8_t,
1469 uint32_t, uint8_t);
1470 extern uint8_t MmIsAddressValid(void *);
1471 extern void *MmGetSystemRoutineAddress(unicode_string *);
1472 extern void *MmMapIoSpace(uint64_t, uint32_t, uint32_t);
1473 extern void MmUnmapIoSpace(void *, size_t);
1474 extern void MmBuildMdlForNonPagedPool(mdl *);
1475 extern void IoDisconnectInterrupt(kinterrupt *);
1476 extern uint32_t IoAllocateDriverObjectExtension(driver_object *,
1477 void *, uint32_t, void **);
1478 extern void *IoGetDriverObjectExtension(driver_object *, void *);
1479 extern uint32_t IoCreateDevice(driver_object *, uint32_t,
1480 unicode_string *, uint32_t, uint32_t, uint8_t, device_object **);
1481 extern void IoDeleteDevice(device_object *);
1482 extern device_object *IoGetAttachedDevice(device_object *);
1483 extern uint32_t IofCallDriver(device_object *, irp *);
1484 extern void IofCompleteRequest(irp *, uint8_t);
1485 extern void IoAcquireCancelSpinLock(uint8_t *);
1486 extern void IoReleaseCancelSpinLock(uint8_t);
1487 extern uint8_t IoCancelIrp(irp *);
1488 extern void IoDetachDevice(device_object *);
1489 extern device_object *IoAttachDeviceToDeviceStack(device_object *,
1490 device_object *);
1491 extern mdl *IoAllocateMdl(void *, uint32_t, uint8_t, uint8_t, irp *);
1492 extern void IoFreeMdl(mdl *);
1493 extern io_workitem *IoAllocateWorkItem(device_object *);
1494 extern void ExQueueWorkItem(work_queue_item *, u_int32_t);
1495 extern void IoFreeWorkItem(io_workitem *);
1496 extern void IoQueueWorkItem(io_workitem *, io_workitem_func,
1497 uint32_t, void *);
1498
1499 #define IoCallDriver(a, b) IofCallDriver(a, b)
1500 #define IoCompleteRequest(a, b) IofCompleteRequest(a, b)
1501
1502 /*
1503 * On the Windows x86 arch, KeAcquireSpinLock() and KeReleaseSpinLock()
1504 * routines live in the HAL. We try to imitate this behavior.
1505 */
1506 #ifdef __i386__
1507 #define KI_USER_SHARED_DATA 0xffdf0000
1508 #define KeAcquireSpinLock(a, b) *(b) = KfAcquireSpinLock(a)
1509 #define KeReleaseSpinLock(a, b) KfReleaseSpinLock(a, b)
1510 #define KeRaiseIrql(a, b) *(b) = KfRaiseIrql(a)
1511 #define KeLowerIrql(a) KfLowerIrql(a)
1512 #define KeAcquireSpinLockAtDpcLevel(a) KefAcquireSpinLockAtDpcLevel(a)
1513 #define KeReleaseSpinLockFromDpcLevel(a) KefReleaseSpinLockFromDpcLevel(a)
1514 #endif /* __i386__ */
1515
1516 #ifdef __amd64__
1517 #define KI_USER_SHARED_DATA 0xfffff78000000000UL
1518 #define KeAcquireSpinLock(a, b) *(b) = KfAcquireSpinLock(a)
1519 #define KeReleaseSpinLock(a, b) KfReleaseSpinLock(a, b)
1520
1521 /*
1522 * These may need to be redefined later;
1523 * not sure where they live on amd64 yet.
1524 */
1525 #define KeRaiseIrql(a, b) *(b) = KfRaiseIrql(a)
1526 #define KeLowerIrql(a) KfLowerIrql(a)
1527 #endif /* __amd64__ */
1528
1529 __END_DECLS
1530
1531 #endif /* _NTOSKRNL_VAR_H_ */
Cache object: 043a87b8eac4d6af09984cacc1b5164b
|