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