Sync usage with man page.
[netbsd-mini2440.git] / sys / compat / ndis / ntoskrnl_var.h
blob4c7116be94e71b79eaf6d7ccb6f88170fdd9aa2b
1 /*-
2 * Copyright (c) 2003
3 * Bill Paul <wpaul@windriver.com>. All rights reserved.
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.
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.
32 * $FreeBSD: src/sys/compat/ndis/ntoskrnl_var.h,v 1.17.2.4 2005/03/31 04:24:35 wpaul Exp $
35 #ifndef _NTOSKRNL_VAR_H_
36 #define _NTOSKRNL_VAR_H_
38 #ifdef __NetBSD__
39 #include "nbcompat.h"
40 #endif
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 *.
47 struct unicode_string {
48 uint16_t us_len;
49 uint16_t us_maxlen;
50 uint16_t *us_buf;
53 typedef struct unicode_string unicode_string;
56 * Windows memory descriptor list. In Windows, it's possible for
57 * buffers to be passed between user and kernel contexts without
58 * copying. Buffers may also be allocated in either paged or
59 * non-paged memory regions. An MDL describes the pages of memory
60 * used to contain a particular buffer. Note that a single MDL
61 * may describe a buffer that spans multiple pages. An array of
62 * page addresses appears immediately after the MDL structure itself.
63 * MDLs are therefore implicitly variably sized, even though they
64 * don't look it.
66 * Note that in FreeBSD, we can take many shortcuts in the way
67 * we handle MDLs because:
69 * - We are only concerned with pages in kernel context. This means
70 * we will only ever use the kernel's memory map, and remapping
71 * of buffers is never needed.
73 * - Kernel pages can never be paged out, so we don't have to worry
74 * about whether or not a page is actually mapped before going to
75 * touch it.
78 struct mdl {
79 struct mdl *mdl_next;
80 uint16_t mdl_size;
81 uint16_t mdl_flags;
82 void *mdl_process;
83 void *mdl_mappedsystemva;
84 void *mdl_startva;
85 uint32_t mdl_bytecount;
86 uint32_t mdl_byteoffset;
89 typedef struct mdl mdl, ndis_buffer;
91 /* MDL flags */
93 #define MDL_MAPPED_TO_SYSTEM_VA 0x0001
94 #define MDL_PAGES_LOCKED 0x0002
95 #define MDL_SOURCE_IS_NONPAGED_POOL 0x0004
96 #define MDL_ALLOCATED_FIXED_SIZE 0x0008
97 #define MDL_PARTIAL 0x0010
98 #define MDL_PARTIAL_HAS_BEEN_MAPPED 0x0020
99 #define MDL_IO_PAGE_READ 0x0040
100 #define MDL_WRITE_OPERATION 0x0080
101 #define MDL_PARENT_MAPPED_SYSTEM_VA 0x0100
102 #define MDL_FREE_EXTRA_PTES 0x0200
103 #define MDL_IO_SPACE 0x0800
104 #define MDL_NETWORK_HEADER 0x1000
105 #define MDL_MAPPING_CAN_FAIL 0x2000
106 #define MDL_ALLOCATED_MUST_SUCCEED 0x4000
107 #define MDL_ZONE_ALLOCED 0x8000 /* BSD private */
109 #define MDL_ZONE_PAGES 16
110 #define MDL_ZONE_SIZE (sizeof(mdl) + (sizeof(vm_offset_t) * MDL_ZONE_PAGES))
112 /* Note: assumes x86 page size of 4K. */
114 #if PAGE_SIZE == 4096
115 #define PAGE_SHIFT 12
116 #elif PAGE_SIZE == 8192
117 #define PAGE_SHIFT 13
118 #else
119 #error PAGE_SHIFT undefined!
120 #endif
122 #define SPAN_PAGES(ptr, len) \
123 ((uint32_t)((((uintptr_t)(ptr) & (PAGE_SIZE - 1)) + \
124 (len) + (PAGE_SIZE - 1)) >> PAGE_SHIFT))
126 #define PAGE_ALIGN(ptr) \
127 ((void *)((uintptr_t)(ptr) & ~(PAGE_SIZE - 1)))
129 #define BYTE_OFFSET(ptr) \
130 ((uint32_t)((uintptr_t)(ptr) & (PAGE_SIZE - 1)))
132 #define MDL_PAGES(m) (vm_offset_t *)(m + 1)
134 #define MmInitializeMdl(b, baseva, len) \
135 (b)->mdl_next = NULL; \
136 (b)->mdl_size = (uint16_t)(sizeof(mdl) + \
137 (sizeof(vm_offset_t) * SPAN_PAGES((baseva), (len)))); \
138 (b)->mdl_flags = 0; \
139 (b)->mdl_startva = (void *)PAGE_ALIGN((baseva)); \
140 (b)->mdl_byteoffset = BYTE_OFFSET((baseva)); \
141 (b)->mdl_bytecount = (uint32_t)(len);
143 #define MmGetMdlByteOffset(mdl) ((mdl)->mdl_byteoffset)
144 #define MmGetMdlByteCount(mdl) ((mdl)->mdl_bytecount)
145 #define MmGetMdlVirtualAddress(mdl) \
146 ((void *)((char *)((mdl)->mdl_startva) + (mdl)->mdl_byteoffset))
147 #define MmGetMdlStartVa(mdl) ((mdl)->mdl_startva)
148 #define MmGetMdlPfnArray(mdl) MDL_PAGES(mdl)
150 #define WDM_MAJOR 1
151 #define WDM_MINOR_WIN98 0x00
152 #define WDM_MINOR_WINME 0x05
153 #define WDM_MINOR_WIN2000 0x10
154 #define WDM_MINOR_WINXP 0x20
155 #define WDM_MINOR_WIN2003 0x30
158 * The ndis_kspin_lock type is called KSPIN_LOCK in MS-Windows.
159 * According to the Windows DDK header files, KSPIN_LOCK is defined like this:
160 * typedef ULONG_PTR KSPIN_LOCK;
162 * From basetsd.h (SDK, Feb. 2003):
163 * typedef [public] unsigned __int3264 ULONG_PTR, *PULONG_PTR;
164 * typedef unsigned __int64 ULONG_PTR, *PULONG_PTR;
165 * typedef _W64 unsigned long ULONG_PTR, *PULONG_PTR;
167 * The keyword __int3264 specifies an integral type that has the following
168 * properties:
169 * + It is 32-bit on 32-bit platforms
170 * + It is 64-bit on 64-bit platforms
171 * + It is 32-bit on the wire for backward compatibility.
172 * It gets truncated on the sending side and extended appropriately
173 * (signed or unsigned) on the receiving side.
175 * Thus register_t seems the proper mapping onto FreeBSD for spin locks.
178 typedef register_t kspin_lock;
180 struct slist_entry {
181 struct slist_entry *sl_next;
184 typedef struct slist_entry slist_entry;
186 union slist_header {
187 uint64_t slh_align;
188 struct {
189 struct slist_entry *slh_next;
190 uint16_t slh_depth;
191 uint16_t slh_seq;
192 } slh_list;
195 typedef union slist_header slist_header;
197 struct list_entry {
198 struct list_entry *nle_flink;
199 struct list_entry *nle_blink;
202 typedef struct list_entry list_entry;
204 #define INIT_LIST_HEAD(l) \
205 (l)->nle_flink = (l)->nle_blink = (l)
207 #define REMOVE_LIST_ENTRY(e) \
208 do { \
209 list_entry *b; \
210 list_entry *f; \
212 f = e->nle_flink; \
213 b = e->nle_blink; \
214 b->nle_flink = f; \
215 f->nle_blink = b; \
216 } while (0)
218 #define REMOVE_LIST_HEAD(l) \
219 do { \
220 list_entry *f; \
221 list_entry *e; \
223 e = l->nle_flink; \
224 f = e->nle_flink; \
225 l->nle_flink = f; \
226 f->nle_blink = l; \
227 } while (0)
229 #define REMOVE_LIST_TAIL(l) \
230 do { \
231 list_entry *b; \
232 list_entry *e; \
234 e = l->nle_blink; \
235 b = e->nle_blink; \
236 l->nle_blink = b; \
237 b->nle_flink = l; \
238 } while (0)
240 #define INSERT_LIST_TAIL(l, e) \
241 do { \
242 list_entry *b; \
244 b = l->nle_blink; \
245 e->nle_flink = l; \
246 e->nle_blink = b; \
247 b->nle_flink = (e); \
248 l->nle_blink = (e); \
249 } while (0)
251 #define INSERT_LIST_HEAD(l, e) \
252 do { \
253 list_entry *f; \
255 f = l->nle_flink; \
256 e->nle_flink = f; \
257 e->nle_blink = l; \
258 f->nle_blink = e; \
259 l->nle_flink = e; \
260 } while (0)
262 struct nt_dispatch_header {
263 uint8_t dh_type;
264 uint8_t dh_abs;
265 uint8_t dh_size;
266 uint8_t dh_inserted;
267 uint32_t dh_sigstate;
268 list_entry dh_waitlisthead;
271 typedef struct nt_dispatch_header nt_dispatch_header;
273 #define OTYPE_EVENT 0
274 #define OTYPE_MUTEX 1
275 #define OTYPE_THREAD 2
276 #define OTYPE_TIMER 3
278 /* Windows dispatcher levels. */
280 #define PASSIVE_LEVEL 0
281 #define LOW_LEVEL 0
282 #define APC_LEVEL 1
283 #define DISPATCH_LEVEL 2
284 #define DEVICE_LEVEL (DISPATCH_LEVEL + 1)
285 #define PROFILE_LEVEL 27
286 #define CLOCK1_LEVEL 28
287 #define CLOCK2_LEVEL 28
288 #define IPI_LEVEL 29
289 #define POWER_LEVEL 30
290 #define HIGH_LEVEL 31
292 #define SYNC_LEVEL_UP DISPATCH_LEVEL
293 #define SYNC_LEVEL_MP (IPI_LEVEL - 1)
295 #define AT_PASSIVE_LEVEL(td) \
296 ((td)->td_proc->p_flag & P_KTHREAD == FALSE)
298 #ifdef __FreeBSD__
299 #define AT_DISPATCH_LEVEL(td) \
300 ((td)->td_base_pri == PI_REALTIME)
301 #else
303 /* TODO: What is the best way to do this? */
305 int win_irql;
306 #define AT_DISPATCH_LEVEL(useless) \
307 (win_irql == DISPATCH_LEVEL)
310 #define AT_DISPATCH_LEVEL(useless) \
311 curlwp->l_priority > IPL_NONE
313 #define AT_DISPATCH_LEVEL(useless) \
314 TRUE
316 #endif
318 #define AT_DIRQL_LEVEL(td) \
319 ((td)->td_priority <= PI_NET)
321 #define AT_HIGH_LEVEL(td) \
322 ((td)->td_critnest != 0)
324 struct nt_objref {
325 nt_dispatch_header no_dh;
326 void *no_obj;
327 TAILQ_ENTRY(nt_objref) link;
330 TAILQ_HEAD(nt_objref_head, nt_objref);
332 typedef struct nt_objref nt_objref;
334 #define EVENT_TYPE_NOTIFY 0
335 #define EVENT_TYPE_SYNC 1
338 * We need to use the timeout()/untimeout() API for ktimers
339 * since timers can be initialized, but not destroyed (so
340 * malloc()ing our own callout structures would mean a leak,
341 * since there'd be no way to free() them). This means we
342 * need to use struct callout_handle, which is really just a
343 * pointer. To make it easier to deal with, we use a union
344 * to overlay the callout_handle over the k_timerlistentry.
345 * The latter is a list_entry, which is two pointers, so
346 * there's enough space available to hide a callout_handle
347 * there.
350 struct ktimer {
351 nt_dispatch_header k_header;
352 uint64_t k_duetime;
353 union {
354 list_entry k_timerlistentry;
355 #ifdef __FreeBSD__
356 struct callout_handle k_handle;
357 #else /* __NetBSD__ */
358 struct callout *k_handle;
359 #endif
360 } u;
361 void *k_dpc;
362 uint32_t k_period;
365 #define k_timerlistentry u.k_timerlistentry
366 #define k_handle u.k_handle
368 typedef struct ktimer ktimer;
370 struct nt_kevent {
371 nt_dispatch_header k_header;
374 typedef struct nt_kevent nt_kevent;
376 /* Kernel defered procedure call (i.e. timer callback) */
378 struct kdpc;
379 typedef __stdcall void (*kdpc_func)(struct kdpc *, void *, void *, void *);
381 struct kdpc {
382 uint16_t k_type;
383 uint8_t k_num;
384 uint8_t k_importance;
385 list_entry k_dpclistentry;
386 void *k_deferedfunc;
387 void *k_deferredctx;
388 void *k_sysarg1;
389 void *k_sysarg2;
390 register_t k_lock;
393 typedef struct kdpc kdpc;
396 * Note: the acquisition count is BSD-specific. The Microsoft
397 * documentation says that mutexes can be acquired recursively
398 * by a given thread, but that you must release the mutex as
399 * many times as you acquired it before it will be set to the
400 * signalled state (i.e. before any other threads waiting on
401 * the object will be woken up). However the Windows KMUTANT
402 * structure has no field for keeping track of the number of
403 * acquisitions, so we need to add one ourselves. As long as
404 * driver code treats the mutex as opaque, we should be ok.
406 struct kmutant {
407 nt_dispatch_header km_header;
408 union {
409 list_entry km_listentry;
410 uint32_t km_acquirecnt;
411 } u;
412 void *km_ownerthread;
413 uint8_t km_abandoned;
414 uint8_t km_apcdisable;
417 #define km_listentry u.km_listentry
418 #define km_acquirecnt u.km_acquirecnt
420 typedef struct kmutant kmutant;
422 #define LOOKASIDE_DEPTH 256
424 struct general_lookaside {
425 slist_header gl_listhead;
426 uint16_t gl_depth;
427 uint16_t gl_maxdepth;
428 uint32_t gl_totallocs;
429 union {
430 uint32_t gl_allocmisses;
431 uint32_t gl_allochits;
432 } u_a;
433 uint32_t gl_totalfrees;
434 union {
435 uint32_t gl_freemisses;
436 uint32_t gl_freehits;
437 } u_m;
438 uint32_t gl_type;
439 uint32_t gl_tag;
440 uint32_t gl_size;
441 void *gl_allocfunc;
442 void *gl_freefunc;
443 list_entry gl_listent;
444 uint32_t gl_lasttotallocs;
445 union {
446 uint32_t gl_lastallocmisses;
447 uint32_t gl_lastallochits;
448 } u_l;
449 uint32_t gl_rsvd[2];
452 typedef struct general_lookaside general_lookaside;
454 struct npaged_lookaside_list {
455 general_lookaside nll_l;
456 #ifdef __i386__
457 kspin_lock nll_obsoletelock;
458 #endif
461 typedef struct npaged_lookaside_list npaged_lookaside_list;
462 typedef struct npaged_lookaside_list paged_lookaside_list;
464 typedef void *(*lookaside_alloc_func)(uint32_t, size_t, uint32_t);
465 typedef void (*lookaside_free_func)(void *);
467 struct irp;
469 struct kdevice_qentry {
470 list_entry kqe_devlistent;
471 uint32_t kqe_sortkey;
472 uint8_t kqe_inserted;
475 typedef struct kdevice_qentry kdevice_qentry;
477 struct kdevice_queue {
478 uint16_t kq_type;
479 uint16_t kq_size;
480 list_entry kq_devlisthead;
481 kspin_lock kq_lock;
482 uint8_t kq_busy;
485 typedef struct kdevice_queue kdevice_queue;
487 struct wait_ctx_block {
488 kdevice_qentry wcb_waitqueue;
489 void *wcb_devfunc;
490 void *wcb_devctx;
491 uint32_t wcb_mapregcnt;
492 void *wcb_devobj;
493 void *wcb_curirp;
494 void *wcb_bufchaindpc;
497 typedef struct wait_ctx_block wait_ctx_block;
499 struct wait_block {
500 list_entry wb_waitlist;
501 void *wb_kthread;
502 nt_dispatch_header *wb_object;
503 struct wait_block *wb_next;
504 uint16_t wb_waitkey;
505 uint16_t wb_waittype;
508 typedef struct wait_block wait_block;
510 #define THREAD_WAIT_OBJECTS 3
511 #define MAX_WAIT_OBJECTS 64
513 #define WAITTYPE_ALL 0
514 #define WAITTYPE_ANY 1
516 struct thread_context {
517 void *tc_thrctx;
518 void *tc_thrfunc;
521 typedef struct thread_context thread_context;
523 /* Forward declaration */
524 struct driver_object;
525 struct devobj_extension;
527 struct driver_extension {
528 struct driver_object *dre_driverobj;
529 void *dre_adddevicefunc;
530 uint32_t dre_reinitcnt;
531 unicode_string dre_srvname;
534 * Drivers are allowed to add one or more custom extensions
535 * to the driver object, but there's no special pointer
536 * for them. Hang them off here for now.
539 list_entry dre_usrext;
542 typedef struct driver_extension driver_extension;
544 struct custom_extension {
545 list_entry ce_list;
546 void *ce_clid;
549 typedef struct custom_extension custom_extension;
552 * In Windows, there are Physical Device Objects (PDOs) and
553 * Functional Device Objects (FDOs). Physical Device Objects are
554 * created and maintained by bus drivers. For example, the PCI
555 * bus driver might detect two PCI ethernet cards on a given
556 * bus. The PCI bus driver will then allocate two device_objects
557 * for its own internal bookeeping purposes. This is analagous
558 * to the device_t that the FreeBSD PCI code allocates and passes
559 * into each PCI driver's probe and attach routines.
561 * When an ethernet driver claims one of the ethernet cards
562 * on the bus, it will create its own device_object. This is
563 * the Functional Device Object. This object is analagous to the
564 * device-specific softc structure.
567 struct device_object {
568 uint16_t do_type;
569 uint16_t do_size;
570 uint32_t do_refcnt;
571 struct driver_object *do_drvobj;
572 struct device_object *do_nextdev;
573 struct device_object *do_attacheddev;
574 struct irp *do_currirp;
575 void *do_iotimer;
576 uint32_t do_flags;
577 uint32_t do_characteristics;
578 void *do_vpb;
579 void *do_devext;
580 uint32_t do_devtype;
581 uint8_t do_stacksize;
582 union {
583 list_entry do_listent;
584 wait_ctx_block do_wcb;
585 } queue;
586 uint32_t do_alignreq;
587 kdevice_queue do_devqueue;
588 struct kdpc do_dpc;
589 uint32_t do_activethreads;
590 void *do_securitydesc;
591 struct nt_kevent do_devlock;
592 uint16_t do_sectorsz;
593 uint16_t do_spare1;
594 struct devobj_extension *do_devobj_ext;
595 void *do_rsvd;
596 #ifdef __NetBSD__
597 struct ndis_softc *fdo_sc;
598 struct ndis_softc *pdo_sc;
599 #endif
602 typedef struct device_object device_object;
604 struct devobj_extension {
605 uint16_t dve_type;
606 uint16_t dve_size;
607 device_object *dve_devobj;
610 typedef struct devobj_extension devobj_extension;
612 /* Device object flags */
614 #define DO_VERIFY_VOLUME 0x00000002
615 #define DO_BUFFERED_IO 0x00000004
616 #define DO_EXCLUSIVE 0x00000008
617 #define DO_DIRECT_IO 0x00000010
618 #define DO_MAP_IO_BUFFER 0x00000020
619 #define DO_DEVICE_HAS_NAME 0x00000040
620 #define DO_DEVICE_INITIALIZING 0x00000080
621 #define DO_SYSTEM_BOOT_PARTITION 0x00000100
622 #define DO_LONG_TERM_REQUESTS 0x00000200
623 #define DO_NEVER_LAST_DEVICE 0x00000400
624 #define DO_SHUTDOWN_REGISTERED 0x00000800
625 #define DO_BUS_ENUMERATED_DEVICE 0x00001000
626 #define DO_POWER_PAGABLE 0x00002000
627 #define DO_POWER_INRUSH 0x00004000
628 #define DO_LOW_PRIORITY_FILESYSTEM 0x00010000
630 /* Priority boosts */
632 #define IO_NO_INCREMENT 0
633 #define IO_CD_ROM_INCREMENT 1
634 #define IO_DISK_INCREMENT 1
635 #define IO_KEYBOARD_INCREMENT 6
636 #define IO_MAILSLOT_INCREMENT 2
637 #define IO_MOUSE_INCREMENT 6
638 #define IO_NAMED_PIPE_INCREMENT 2
639 #define IO_NETWORK_INCREMENT 2
640 #define IO_PARALLEL_INCREMENT 1
641 #define IO_SERIAL_INCREMENT 2
642 #define IO_SOUND_INCREMENT 8
643 #define IO_VIDEO_INCREMENT 1
645 /* IRP major codes */
647 #define IRP_MJ_CREATE 0x00
648 #define IRP_MJ_CREATE_NAMED_PIPE 0x01
649 #define IRP_MJ_CLOSE 0x02
650 #define IRP_MJ_READ 0x03
651 #define IRP_MJ_WRITE 0x04
652 #define IRP_MJ_QUERY_INFORMATION 0x05
653 #define IRP_MJ_SET_INFORMATION 0x06
654 #define IRP_MJ_QUERY_EA 0x07
655 #define IRP_MJ_SET_EA 0x08
656 #define IRP_MJ_FLUSH_BUFFERS 0x09
657 #define IRP_MJ_QUERY_VOLUME_INFORMATION 0x0a
658 #define IRP_MJ_SET_VOLUME_INFORMATION 0x0b
659 #define IRP_MJ_DIRECTORY_CONTROL 0x0c
660 #define IRP_MJ_FILE_SYSTEM_CONTROL 0x0d
661 #define IRP_MJ_DEVICE_CONTROL 0x0e
662 #define IRP_MJ_INTERNAL_DEVICE_CONTROL 0x0f
663 #define IRP_MJ_SHUTDOWN 0x10
664 #define IRP_MJ_LOCK_CONTROL 0x11
665 #define IRP_MJ_CLEANUP 0x12
666 #define IRP_MJ_CREATE_MAILSLOT 0x13
667 #define IRP_MJ_QUERY_SECURITY 0x14
668 #define IRP_MJ_SET_SECURITY 0x15
669 #define IRP_MJ_POWER 0x16
670 #define IRP_MJ_SYSTEM_CONTROL 0x17
671 #define IRP_MJ_DEVICE_CHANGE 0x18
672 #define IRP_MJ_QUERY_QUOTA 0x19
673 #define IRP_MJ_SET_QUOTA 0x1a
674 #define IRP_MJ_PNP 0x1b
675 #define IRP_MJ_PNP_POWER IRP_MJ_PNP // Obsolete....
676 #define IRP_MJ_MAXIMUM_FUNCTION 0x1b
677 #define IRP_MJ_SCSI IRP_MJ_INTERNAL_DEVICE_CONTROL
679 /* IRP minor codes */
681 #define IRP_MN_QUERY_DIRECTORY 0x01
682 #define IRP_MN_NOTIFY_CHANGE_DIRECTORY 0x02
683 #define IRP_MN_USER_FS_REQUEST 0x00
685 #define IRP_MN_MOUNT_VOLUME 0x01
686 #define IRP_MN_VERIFY_VOLUME 0x02
687 #define IRP_MN_LOAD_FILE_SYSTEM 0x03
688 #define IRP_MN_TRACK_LINK 0x04
689 #define IRP_MN_KERNEL_CALL 0x04
691 #define IRP_MN_LOCK 0x01
692 #define IRP_MN_UNLOCK_SINGLE 0x02
693 #define IRP_MN_UNLOCK_ALL 0x03
694 #define IRP_MN_UNLOCK_ALL_BY_KEY 0x04
696 #define IRP_MN_NORMAL 0x00
697 #define IRP_MN_DPC 0x01
698 #define IRP_MN_MDL 0x02
699 #define IRP_MN_COMPLETE 0x04
700 #define IRP_MN_COMPRESSED 0x08
702 #define IRP_MN_MDL_DPC (IRP_MN_MDL | IRP_MN_DPC)
703 #define IRP_MN_COMPLETE_MDL (IRP_MN_COMPLETE | IRP_MN_MDL)
704 #define IRP_MN_COMPLETE_MDL_DPC (IRP_MN_COMPLETE_MDL | IRP_MN_DPC)
706 #define IRP_MN_SCSI_CLASS 0x01
708 #define IRP_MN_START_DEVICE 0x00
709 #define IRP_MN_QUERY_REMOVE_DEVICE 0x01
710 #define IRP_MN_REMOVE_DEVICE 0x02
711 #define IRP_MN_CANCEL_REMOVE_DEVICE 0x03
712 #define IRP_MN_STOP_DEVICE 0x04
713 #define IRP_MN_QUERY_STOP_DEVICE 0x05
714 #define IRP_MN_CANCEL_STOP_DEVICE 0x06
716 #define IRP_MN_QUERY_DEVICE_RELATIONS 0x07
717 #define IRP_MN_QUERY_INTERFACE 0x08
718 #define IRP_MN_QUERY_CAPABILITIES 0x09
719 #define IRP_MN_QUERY_RESOURCES 0x0A
720 #define IRP_MN_QUERY_RESOURCE_REQUIREMENTS 0x0B
721 #define IRP_MN_QUERY_DEVICE_TEXT 0x0C
722 #define IRP_MN_FILTER_RESOURCE_REQUIREMENTS 0x0D
724 #define IRP_MN_READ_CONFIG 0x0F
725 #define IRP_MN_WRITE_CONFIG 0x10
726 #define IRP_MN_EJECT 0x11
727 #define IRP_MN_SET_LOCK 0x12
728 #define IRP_MN_QUERY_ID 0x13
729 #define IRP_MN_QUERY_PNP_DEVICE_STATE 0x14
730 #define IRP_MN_QUERY_BUS_INFORMATION 0x15
731 #define IRP_MN_DEVICE_USAGE_NOTIFICATION 0x16
732 #define IRP_MN_SURPRISE_REMOVAL 0x17
733 #define IRP_MN_QUERY_LEGACY_BUS_INFORMATION 0x18
735 #define IRP_MN_WAIT_WAKE 0x00
736 #define IRP_MN_POWER_SEQUENCE 0x01
737 #define IRP_MN_SET_POWER 0x02
738 #define IRP_MN_QUERY_POWER 0x03
740 #define IRP_MN_QUERY_ALL_DATA 0x00
741 #define IRP_MN_QUERY_SINGLE_INSTANCE 0x01
742 #define IRP_MN_CHANGE_SINGLE_INSTANCE 0x02
743 #define IRP_MN_CHANGE_SINGLE_ITEM 0x03
744 #define IRP_MN_ENABLE_EVENTS 0x04
745 #define IRP_MN_DISABLE_EVENTS 0x05
746 #define IRP_MN_ENABLE_COLLECTION 0x06
747 #define IRP_MN_DISABLE_COLLECTION 0x07
748 #define IRP_MN_REGINFO 0x08
749 #define IRP_MN_EXECUTE_METHOD 0x09
750 #define IRP_MN_REGINFO_EX 0x0b
752 /* IRP flags */
754 #define IRP_NOCACHE 0x00000001
755 #define IRP_PAGING_IO 0x00000002
756 #define IRP_MOUNT_COMPLETION 0x00000002
757 #define IRP_SYNCHRONOUS_API 0x00000004
758 #define IRP_ASSOCIATED_IRP 0x00000008
759 #define IRP_BUFFERED_IO 0x00000010
760 #define IRP_DEALLOCATE_BUFFER 0x00000020
761 #define IRP_INPUT_OPERATION 0x00000040
762 #define IRP_SYNCHRONOUS_PAGING_IO 0x00000040
763 #define IRP_CREATE_OPERATION 0x00000080
764 #define IRP_READ_OPERATION 0x00000100
765 #define IRP_WRITE_OPERATION 0x00000200
766 #define IRP_CLOSE_OPERATION 0x00000400
767 #define IRP_DEFER_IO_COMPLETION 0x00000800
768 #define IRP_OB_QUERY_NAME 0x00001000
769 #define IRP_HOLD_DEVICE_QUEUE 0x00002000
770 #define IRP_RETRY_IO_COMPLETION 0x00004000
771 #define IRP_CLASS_CACHE_OPERATION 0x00008000
772 #define IRP_SET_USER_EVENT IRP_CLOSE_OPERATION
774 /* IRP I/O control flags */
776 #define IRP_QUOTA_CHARGED 0x01
777 #define IRP_ALLOCATED_MUST_SUCCEED 0x02
778 #define IRP_ALLOCATED_FIXED_SIZE 0x04
779 #define IRP_LOOKASIDE_ALLOCATION 0x08
781 /* I/O method types */
783 #define METHOD_BUFFERED 0
784 #define METHOD_IN_DIRECT 1
785 #define METHOD_OUT_DIRECT 2
786 #define METHOD_NEITHER 3
788 /* File access types */
790 #define FILE_ANY_ACCESS 0x0000
791 #define FILE_SPECIAL_ACCESS FILE_ANY_ACCESS
792 #define FILE_READ_ACCESS 0x0001
793 #define FILE_WRITE_ACCESS 0x0002
795 /* Recover I/O access method from IOCTL code. */
797 #define IO_METHOD(x) ((x) & 0xFFFFFFFC)
799 /* Recover function code from IOCTL code */
801 #define IO_FUNC(x) (((x) & 0x7FFC) >> 2)
803 /* Macro to construct an IOCTL code. */
805 #define IOCTL_CODE(dev, func, iomethod, acc) \
806 ((dev) << 16) | (acc << 14) | (func << 2) | (iomethod))
809 struct io_status_block {
810 union {
811 uint32_t isb_status;
812 void *isb_ptr;
813 } u;
814 register_t isb_info;
816 #define isb_status u.isb_status
817 #define isb_ptr u.isb_ptr
819 typedef struct io_status_block io_status_block;
821 struct kapc {
822 uint16_t apc_type;
823 uint16_t apc_size;
824 uint32_t apc_spare0;
825 void *apc_thread;
826 list_entry apc_list;
827 void *apc_kernfunc;
828 void *apc_rundownfunc;
829 void *apc_normalfunc;
830 void *apc_normctx;
831 void *apc_sysarg1;
832 void *apc_sysarg2;
833 uint8_t apc_stateidx;
834 uint8_t apc_cpumode;
835 uint8_t apc_inserted;
838 typedef struct kapc kapc;
840 typedef __stdcall uint32_t (*completion_func)(device_object *,
841 struct irp *, void *);
842 typedef __stdcall uint32_t (*cancel_func)(device_object *,
843 struct irp *);
845 struct io_stack_location {
846 uint8_t isl_major;
847 uint8_t isl_minor;
848 uint8_t isl_flags;
849 uint8_t isl_ctl;
852 * There's a big-ass union here in the actual Windows
853 * definition of the structure, but it contains stuff
854 * that doesn't really apply to BSD, and defining it
855 * all properly would require duplicating over a dozen
856 * other structures that we'll never use. Since the
857 * io_stack_location structure is opaque to drivers
858 * anyway, I'm not going to bother with the extra crap.
861 union {
862 struct {
863 uint32_t isl_len;
864 uint32_t *isl_key;
865 uint64_t isl_byteoff;
866 } isl_read;
867 struct {
868 uint32_t isl_len;
869 uint32_t *isl_key;
870 uint64_t isl_byteoff;
871 } isl_write;
872 struct {
873 uint32_t isl_obuflen;
874 uint32_t isl_ibuflen;
875 uint32_t isl_iocode;
876 void *isl_type3ibuf;
877 } isl_ioctl;
878 struct {
879 void *isl_arg1;
880 void *isl_arg2;
881 void *isl_arg3;
882 void *isl_arg4;
883 } isl_others;
884 } isl_parameters __packed;
886 void *isl_devobj;
887 void *isl_fileobj;
888 completion_func isl_completionfunc;
889 void *isl_completionctx;
892 typedef struct io_stack_location io_stack_location;
894 /* Stack location control flags */
896 #define SL_PENDING_RETURNED 0x01
897 #define SL_INVOKE_ON_CANCEL 0x20
898 #define SL_INVOKE_ON_SUCCESS 0x40
899 #define SL_INVOKE_ON_ERROR 0x80
901 struct irp {
902 uint16_t irp_type;
903 uint16_t irp_size;
904 mdl *irp_mdl;
905 uint32_t irp_flags;
906 union {
907 struct irp *irp_master;
908 uint32_t irp_irpcnt;
909 void *irp_sysbuf;
910 } irp_assoc;
911 list_entry irp_thlist;
912 io_status_block irp_iostat;
913 uint8_t irp_reqmode;
914 uint8_t irp_pendingreturned;
915 uint8_t irp_stackcnt;
916 uint8_t irp_currentstackloc;
917 uint8_t irp_cancel;
918 uint8_t irp_cancelirql;
919 uint8_t irp_apcenv;
920 uint8_t irp_allocflags;
921 io_status_block *irp_usriostat;
922 nt_kevent *irp_usrevent;
923 union {
924 struct {
925 void *irp_apcfunc;
926 void *irp_apcctx;
927 } irp_asyncparms;
928 uint64_t irp_allocsz;
929 } irp_overlay;
930 cancel_func irp_cancelfunc;
931 void *irp_userbuf;
933 /* Windows kernel info */
935 union {
936 struct {
937 union {
938 kdevice_qentry irp_dqe;
939 struct {
940 void *irp_drvctx[4];
941 } s1;
942 } u1;
943 void *irp_thread;
944 char *irp_auxbuf;
945 struct {
946 list_entry irp_list;
947 union {
948 io_stack_location *irp_csl;
949 uint32_t irp_pkttype;
950 } u2;
951 } s2;
952 void *irp_fileobj;
953 } irp_overlay;
954 kapc irp_apc;
955 void *irp_compkey;
956 } irp_tail;
959 #define irp_csl s2.u2.irp_csl
960 #define irp_pkttype s2.u2.irp_pkttype
962 typedef struct irp irp;
964 #define InterlockedExchangePointer(dst, val) \
965 (void *)FASTCALL2(InterlockedExchange, (uint32_t *)(dst), \
966 (uintptr_t)(val))
968 #define IoSizeOfIrp(ssize) \
969 ((uint16_t) (sizeof(irp) + ((ssize) * (sizeof(io_stack_location)))))
971 #define IoSetCancelRoutine(irp, func) \
972 (cancel_func)InterlockedExchangePointer( \
973 (void *)&(ip)->irp_cancelfunc, (void *)(func))
975 #define IoGetCurrentIrpStackLocation(irp) \
976 (irp)->irp_tail.irp_overlay.irp_csl
978 #define IoGetNextIrpStackLocation(irp) \
979 ((irp)->irp_tail.irp_overlay.irp_csl - 1)
981 #define IoSetNextIrpStackLocation(irp) \
982 do { \
983 irp->irp_currentstackloc--; \
984 irp->irp_tail.irp_overlay.irp_csl--; \
985 } while(0)
987 #define IoSetCompletionRoutine(irp, func, ctx, ok, err, cancel) \
988 do { \
989 io_stack_location *s; \
990 s = IoGetNextIrpStackLocation((irp)); \
991 s->isl_completionfunc = (func); \
992 s->isl_completionctx = (ctx); \
993 s->isl_ctl = 0; \
994 if (ok) s->isl_ctl = SL_INVOKE_ON_SUCCESS; \
995 if (err) s->isl_ctl |= SL_INVOKE_ON_ERROR; \
996 if (cancel) s->isl_ctl |= SL_INVOKE_ON_CANCEL; \
997 } while(0)
999 #define IoMarkIrpPending(irp) \
1000 IoGetCurrentIrpStackLocation(irp)->isl_ctl |= SL_PENDING_RETURNED
1002 #define IoCopyCurrentIrpStackLocationToNext(irp) \
1003 do { \
1004 io_stack_location *src, *dst; \
1005 src = IoGetCurrentIrpStackLocation(irp); \
1006 dst = IoGetNextIrpStackLocation(irp); \
1007 memcpy( (char *)dst, (char *)src, \
1008 offsetof(io_stack_location, isl_completionfunc)); \
1009 } while(0)
1011 #define IoSkipCurrentIrpStackLocation(irp) \
1012 do { \
1013 (irp)->irp_currentstackloc++; \
1014 (irp)->irp_tail.irp_overlay.irp_csl++; \
1015 } while(0)
1017 #define IoInitializeDpcRequest(dobj, dpcfunc) \
1018 KeInitializeDpc(&(dobj)->do_dpc, dpcfunc, dobj)
1020 #define IoRequestDpc(dobj, irp, ctx) \
1021 KeInsertQueueDpc(&(dobj)->do_dpc, irp, ctx)
1023 typedef __stdcall uint32_t (*driver_dispatch)(device_object *, irp *);
1026 * The driver_object is allocated once for each driver that's loaded
1027 * into the system. A new one is allocated for each driver and
1028 * populated a bit via the driver's DriverEntry function.
1029 * In general, a Windows DriverEntry() function will provide a pointer
1030 * to its AddDevice() method and set up the dispatch table.
1031 * For NDIS drivers, this is all done behind the scenes in the
1032 * NdisInitializeWrapper() and/or NdisMRegisterMiniport() routines.
1035 struct driver_object {
1036 uint16_t dro_type;
1037 uint16_t dro_size;
1038 device_object *dro_devobj;
1039 uint32_t dro_flags;
1040 void *dro_driverstart;
1041 uint32_t dro_driversize;
1042 void *dro_driversection;
1043 driver_extension *dro_driverext;
1044 unicode_string dro_drivername;
1045 unicode_string *dro_hwdb;
1046 void *dro_pfastiodispatch;
1047 void *dro_driverinitfunc;
1048 void *dro_driverstartiofunc;
1049 void *dro_driverunloadfunc;
1050 driver_dispatch dro_dispatch[IRP_MJ_MAXIMUM_FUNCTION + 1];
1053 typedef struct driver_object driver_object;
1055 #define DEVPROP_DEVICE_DESCRIPTION 0x00000000
1056 #define DEVPROP_HARDWARE_ID 0x00000001
1057 #define DEVPROP_COMPATIBLE_IDS 0x00000002
1058 #define DEVPROP_BOOTCONF 0x00000003
1059 #define DEVPROP_BOOTCONF_TRANSLATED 0x00000004
1060 #define DEVPROP_CLASS_NAME 0x00000005
1061 #define DEVPROP_CLASS_GUID 0x00000006
1062 #define DEVPROP_DRIVER_KEYNAME 0x00000007
1063 #define DEVPROP_MANUFACTURER 0x00000008
1064 #define DEVPROP_FRIENDLYNAME 0x00000009
1065 #define DEVPROP_LOCATION_INFO 0x0000000A
1066 #define DEVPROP_PHYSDEV_NAME 0x0000000B
1067 #define DEVPROP_BUSTYPE_GUID 0x0000000C
1068 #define DEVPROP_LEGACY_BUSTYPE 0x0000000D
1069 #define DEVPROP_BUS_NUMBER 0x0000000E
1070 #define DEVPROP_ENUMERATOR_NAME 0x0000000F
1071 #define DEVPROP_ADDRESS 0x00000010
1072 #define DEVPROP_UINUMBER 0x00000011
1073 #define DEVPROP_INSTALL_STATE 0x00000012
1074 #define DEVPROP_REMOVAL_POLICY 0x00000013
1076 /* Various supported device types (used with IoCreateDevice()) */
1078 #define FILE_DEVICE_BEEP 0x00000001
1079 #define FILE_DEVICE_CD_ROM 0x00000002
1080 #define FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003
1081 #define FILE_DEVICE_CONTROLLER 0x00000004
1082 #define FILE_DEVICE_DATALINK 0x00000005
1083 #define FILE_DEVICE_DFS 0x00000006
1084 #define FILE_DEVICE_DISK 0x00000007
1085 #define FILE_DEVICE_DISK_FILE_SYSTEM 0x00000008
1086 #define FILE_DEVICE_FILE_SYSTEM 0x00000009
1087 #define FILE_DEVICE_INPORT_PORT 0x0000000A
1088 #define FILE_DEVICE_KEYBOARD 0x0000000B
1089 #define FILE_DEVICE_MAILSLOT 0x0000000C
1090 #define FILE_DEVICE_MIDI_IN 0x0000000D
1091 #define FILE_DEVICE_MIDI_OUT 0x0000000E
1092 #define FILE_DEVICE_MOUSE 0x0000000F
1093 #define FILE_DEVICE_MULTI_UNC_PROVIDER 0x00000010
1094 #define FILE_DEVICE_NAMED_PIPE 0x00000011
1095 #define FILE_DEVICE_NETWORK 0x00000012
1096 #define FILE_DEVICE_NETWORK_BROWSER 0x00000013
1097 #define FILE_DEVICE_NETWORK_FILE_SYSTEM 0x00000014
1098 #define FILE_DEVICE_NULL 0x00000015
1099 #define FILE_DEVICE_PARALLEL_PORT 0x00000016
1100 #define FILE_DEVICE_PHYSICAL_NETCARD 0x00000017
1101 #define FILE_DEVICE_PRINTER 0x00000018
1102 #define FILE_DEVICE_SCANNER 0x00000019
1103 #define FILE_DEVICE_SERIAL_MOUSE_PORT 0x0000001A
1104 #define FILE_DEVICE_SERIAL_PORT 0x0000001B
1105 #define FILE_DEVICE_SCREEN 0x0000001C
1106 #define FILE_DEVICE_SOUND 0x0000001D
1107 #define FILE_DEVICE_STREAMS 0x0000001E
1108 #define FILE_DEVICE_TAPE 0x0000001F
1109 #define FILE_DEVICE_TAPE_FILE_SYSTEM 0x00000020
1110 #define FILE_DEVICE_TRANSPORT 0x00000021
1111 #define FILE_DEVICE_UNKNOWN 0x00000022
1112 #define FILE_DEVICE_VIDEO 0x00000023
1113 #define FILE_DEVICE_VIRTUAL_DISK 0x00000024
1114 #define FILE_DEVICE_WAVE_IN 0x00000025
1115 #define FILE_DEVICE_WAVE_OUT 0x00000026
1116 #define FILE_DEVICE_8042_PORT 0x00000027
1117 #define FILE_DEVICE_NETWORK_REDIRECTOR 0x00000028
1118 #define FILE_DEVICE_BATTERY 0x00000029
1119 #define FILE_DEVICE_BUS_EXTENDER 0x0000002A
1120 #define FILE_DEVICE_MODEM 0x0000002B
1121 #define FILE_DEVICE_VDM 0x0000002C
1122 #define FILE_DEVICE_MASS_STORAGE 0x0000002D
1123 #define FILE_DEVICE_SMB 0x0000002E
1124 #define FILE_DEVICE_KS 0x0000002F
1125 #define FILE_DEVICE_CHANGER 0x00000030
1126 #define FILE_DEVICE_SMARTCARD 0x00000031
1127 #define FILE_DEVICE_ACPI 0x00000032
1128 #define FILE_DEVICE_DVD 0x00000033
1129 #define FILE_DEVICE_FULLSCREEN_VIDEO 0x00000034
1130 #define FILE_DEVICE_DFS_FILE_SYSTEM 0x00000035
1131 #define FILE_DEVICE_DFS_VOLUME 0x00000036
1132 #define FILE_DEVICE_SERENUM 0x00000037
1133 #define FILE_DEVICE_TERMSRV 0x00000038
1134 #define FILE_DEVICE_KSEC 0x00000039
1135 #define FILE_DEVICE_FIPS 0x0000003A
1137 /* Device characteristics */
1139 #define FILE_REMOVABLE_MEDIA 0x00000001
1140 #define FILE_READ_ONLY_DEVICE 0x00000002
1141 #define FILE_FLOPPY_DISKETTE 0x00000004
1142 #define FILE_WRITE_ONCE_MEDIA 0x00000008
1143 #define FILE_REMOTE_DEVICE 0x00000010
1144 #define FILE_DEVICE_IS_MOUNTED 0x00000020
1145 #define FILE_VIRTUAL_VOLUME 0x00000040
1146 #define FILE_AUTOGENERATED_DEVICE_NAME 0x00000080
1147 #define FILE_DEVICE_SECURE_OPEN 0x00000100
1149 /* Status codes */
1151 #define STATUS_SUCCESS 0x00000000
1152 #define STATUS_USER_APC 0x000000C0
1153 #define STATUS_KERNEL_APC 0x00000100
1154 #define STATUS_ALERTED 0x00000101
1155 #define STATUS_TIMEOUT 0x00000102
1156 #define STATUS_PENDING 0x00000103
1157 #define STATUS_INVALID_PARAMETER 0xC000000D
1158 #define STATUS_INVALID_DEVICE_REQUEST 0xC0000010
1159 #define STATUS_MORE_PROCESSING_REQUIRED 0xC0000016
1160 #define STATUS_BUFFER_TOO_SMALL 0xC0000023
1161 #define STATUS_MUTANT_NOT_OWNED 0xC0000046
1162 #define STATUS_INVALID_PARAMETER_2 0xC00000F0
1163 #define STATUS_INSUFFICIENT_RESOURCES 0xC000009A
1165 #define STATUS_WAIT_0 0x00000000
1167 /* Memory pool types, for ExAllocatePoolWithTag() */
1169 #define NonPagedPool 0x00000000
1170 #define PagedPool 0x00000001
1171 #define NonPagedPoolMustSucceed 0x00000002
1172 #define DontUseThisType 0x00000003
1173 #define NonPagedPoolCacheAligned 0x00000004
1174 #define PagedPoolCacheAligned 0x00000005
1175 #define NonPagedPoolCacheAlignedMustS 0x00000006
1176 #define MaxPoolType 0x00000007
1179 * FreeBSD's kernel stack is 2 pages in size by default. The
1180 * Windows stack is larger, so we need to give our threads more
1181 * stack pages. 4 should be enough, we use 8 just to extra safe.
1183 /* This is also defined in nbcompat.c */
1184 #define NDIS_KSTACK_PAGES 8
1186 extern image_patch_table ntoskrnl_functbl[];
1187 typedef void (*funcptr)(void);
1189 __BEGIN_DECLS
1190 extern int windrv_libinit(void);
1191 extern int windrv_libfini(void);
1192 extern driver_object *windrv_lookup(vm_offset_t, const char *);
1193 extern int windrv_load(module_t, vm_offset_t, int);
1194 extern int windrv_unload(module_t, vm_offset_t, int);
1195 extern int windrv_create_pdo(driver_object *, device_t);
1196 extern void windrv_destroy_pdo(driver_object *, device_t);
1197 extern device_object *windrv_find_pdo(driver_object *, device_t);
1198 extern int windrv_bus_attach(driver_object *, const char *);
1199 extern int windrv_wrap(funcptr, funcptr *);
1200 extern int windrv_unwrap(funcptr);
1202 extern int ntoskrnl_libinit(void);
1203 extern int ntoskrnl_libfini(void);
1204 __stdcall extern void KeInitializeDpc(kdpc *, void *, void *);
1205 __stdcall extern uint8_t KeInsertQueueDpc(kdpc *, void *, void *);
1206 __stdcall extern uint8_t KeRemoveQueueDpc(kdpc *);
1207 __stdcall extern void KeInitializeTimer(ktimer *);
1208 __stdcall extern void KeInitializeTimerEx(ktimer *, uint32_t);
1209 __stdcall extern uint8_t KeSetTimer(ktimer *, int64_t, kdpc *);
1210 __stdcall extern uint8_t KeSetTimerEx(ktimer *, int64_t, uint32_t, kdpc *);
1211 __stdcall extern uint8_t KeCancelTimer(ktimer *);
1212 __stdcall extern uint8_t KeReadStateTimer(ktimer *);
1213 __stdcall extern uint32_t KeWaitForSingleObject(nt_dispatch_header *, uint32_t,
1214 uint32_t, uint8_t, int64_t *);
1215 __stdcall extern void KeInitializeEvent(nt_kevent *, uint32_t, uint8_t);
1216 __stdcall extern void KeClearEvent(nt_kevent *);
1217 __stdcall extern uint32_t KeReadStateEvent(nt_kevent *);
1218 __stdcall extern uint32_t KeSetEvent(nt_kevent *, uint32_t, uint8_t);
1219 __stdcall extern uint32_t KeResetEvent(nt_kevent *);
1220 #ifdef __i386__
1221 __fastcall extern void KefAcquireSpinLockAtDpcLevel(REGARGS1(kspin_lock *));
1222 __fastcall extern void KefReleaseSpinLockFromDpcLevel(REGARGS1(kspin_lock *));
1223 __stdcall extern uint8_t KeAcquireSpinLockRaiseToDpc(kspin_lock *);
1224 #else
1225 __stdcall extern void KeAcquireSpinLockAtDpcLevel(kspin_lock *);
1226 __stdcall extern void KeReleaseSpinLockFromDpcLevel(kspin_lock *);
1227 #endif
1228 __stdcall extern void KeInitializeSpinLock(kspin_lock *);
1229 __fastcall extern uintptr_t InterlockedExchange(REGARGS2(volatile uint32_t *,
1230 uintptr_t));
1231 __stdcall extern void *ExAllocatePoolWithTag(uint32_t, size_t, uint32_t);
1232 __stdcall extern void ExFreePool(void *);
1233 __stdcall extern uint32_t IoAllocateDriverObjectExtension(driver_object *,
1234 void *, uint32_t, void **);
1235 __stdcall extern void *IoGetDriverObjectExtension(driver_object *, void *);
1236 __stdcall extern uint32_t IoCreateDevice(driver_object *, uint32_t,
1237 unicode_string *, uint32_t, uint32_t, uint8_t, device_object **);
1238 __stdcall extern void IoDeleteDevice(device_object *);
1239 __stdcall extern device_object *IoGetAttachedDevice(device_object *);
1240 __fastcall extern uint32_t IofCallDriver(REGARGS2(device_object *, irp *));
1241 __fastcall extern void IofCompleteRequest(REGARGS2(irp *, uint8_t));
1242 __stdcall extern void IoAcquireCancelSpinLock(uint8_t *);
1243 __stdcall extern void IoReleaseCancelSpinLock(uint8_t);
1244 __stdcall extern uint8_t IoCancelIrp(irp *);
1245 __stdcall extern void IoDetachDevice(device_object *);
1246 __stdcall extern device_object *IoAttachDeviceToDeviceStack(device_object *,
1247 device_object *);
1248 __stdcall mdl *IoAllocateMdl(void *, uint32_t, uint8_t, uint8_t, irp *);
1249 __stdcall void IoFreeMdl(mdl *);
1251 #define IoCallDriver(a, b) FASTCALL2(IofCallDriver, a, b)
1252 #define IoCompleteRequest(a, b) FASTCALL2(IofCompleteRequest, a, b)
1255 * On the Windows x86 arch, KeAcquireSpinLock() and KeReleaseSpinLock()
1256 * routines live in the HAL. We try to imitate this behavior.
1258 #ifdef __i386__
1259 #define KeAcquireSpinLock(a, b) *(b) = FASTCALL1(KfAcquireSpinLock, a)
1260 #define KeReleaseSpinLock(a, b) FASTCALL2(KfReleaseSpinLock, a, b)
1261 #define KeRaiseIrql(a) FASTCALL1(KfRaiseIrql, a)
1262 #define KeLowerIrql(a) FASTCALL1(KfLowerIrql, a)
1263 #define KeAcquireSpinLockAtDpcLevel(a) \
1264 FASTCALL1(KefAcquireSpinLockAtDpcLevel, a)
1265 #define KeReleaseSpinLockFromDpcLevel(a) \
1266 FASTCALL1(KefReleaseSpinLockFromDpcLevel, a)
1267 #endif /* __i386__ */
1269 #ifdef __amd64__
1270 #define KeAcquireSpinLock(a, b) *(b) = KfAcquireSpinLock(a)
1271 #define KeReleaseSpinLock(a, b) KfReleaseSpinLock(a, b)
1274 * These may need to be redefined later;
1275 * not sure where they live on amd64 yet.
1277 #define KeRaiseIrql(a) KfRaiseIrql(a)
1278 #define KeLowerIrql(a) KfLowerIrql(a)
1279 #endif /* __amd64__ */
1281 __END_DECLS
1283 #endif /* _NTOSKRNL_VAR_H_ */