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
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_
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
{
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
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
83 void *mdl_mappedsystemva
;
85 uint32_t mdl_bytecount
;
86 uint32_t mdl_byteoffset
;
89 typedef struct mdl mdl
, ndis_buffer
;
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
119 #error PAGE_SHIFT undefined!
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)
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
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
;
181 struct slist_entry
*sl_next
;
184 typedef struct slist_entry slist_entry
;
189 struct slist_entry
*slh_next
;
195 typedef union slist_header slist_header
;
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) \
218 #define REMOVE_LIST_HEAD(l) \
229 #define REMOVE_LIST_TAIL(l) \
240 #define INSERT_LIST_TAIL(l, e) \
247 b->nle_flink = (e); \
248 l->nle_blink = (e); \
251 #define INSERT_LIST_HEAD(l, e) \
262 struct nt_dispatch_header
{
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
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
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)
299 #define AT_DISPATCH_LEVEL(td) \
300 ((td)->td_base_pri == PI_REALTIME)
303 /* TODO: What is the best way to do this? */
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) \
318 #define AT_DIRQL_LEVEL(td) \
319 ((td)->td_priority <= PI_NET)
321 #define AT_HIGH_LEVEL(td) \
322 ((td)->td_critnest != 0)
325 nt_dispatch_header no_dh
;
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
351 nt_dispatch_header k_header
;
354 list_entry k_timerlistentry
;
356 struct callout_handle k_handle
;
357 #else /* __NetBSD__ */
358 struct callout
*k_handle
;
365 #define k_timerlistentry u.k_timerlistentry
366 #define k_handle u.k_handle
368 typedef struct ktimer ktimer
;
371 nt_dispatch_header k_header
;
374 typedef struct nt_kevent nt_kevent
;
376 /* Kernel defered procedure call (i.e. timer callback) */
379 typedef __stdcall
void (*kdpc_func
)(struct kdpc
*, void *, void *, void *);
384 uint8_t k_importance
;
385 list_entry k_dpclistentry
;
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.
407 nt_dispatch_header km_header
;
409 list_entry km_listentry
;
410 uint32_t km_acquirecnt
;
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
;
427 uint16_t gl_maxdepth
;
428 uint32_t gl_totallocs
;
430 uint32_t gl_allocmisses
;
431 uint32_t gl_allochits
;
433 uint32_t gl_totalfrees
;
435 uint32_t gl_freemisses
;
436 uint32_t gl_freehits
;
443 list_entry gl_listent
;
444 uint32_t gl_lasttotallocs
;
446 uint32_t gl_lastallocmisses
;
447 uint32_t gl_lastallochits
;
452 typedef struct general_lookaside general_lookaside
;
454 struct npaged_lookaside_list
{
455 general_lookaside nll_l
;
457 kspin_lock nll_obsoletelock
;
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 *);
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
{
480 list_entry kq_devlisthead
;
485 typedef struct kdevice_queue kdevice_queue
;
487 struct wait_ctx_block
{
488 kdevice_qentry wcb_waitqueue
;
491 uint32_t wcb_mapregcnt
;
494 void *wcb_bufchaindpc
;
497 typedef struct wait_ctx_block wait_ctx_block
;
500 list_entry wb_waitlist
;
502 nt_dispatch_header
*wb_object
;
503 struct wait_block
*wb_next
;
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
{
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
{
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
{
571 struct driver_object
*do_drvobj
;
572 struct device_object
*do_nextdev
;
573 struct device_object
*do_attacheddev
;
574 struct irp
*do_currirp
;
577 uint32_t do_characteristics
;
581 uint8_t do_stacksize
;
583 list_entry do_listent
;
584 wait_ctx_block do_wcb
;
586 uint32_t do_alignreq
;
587 kdevice_queue do_devqueue
;
589 uint32_t do_activethreads
;
590 void *do_securitydesc
;
591 struct nt_kevent do_devlock
;
592 uint16_t do_sectorsz
;
594 struct devobj_extension
*do_devobj_ext
;
597 struct ndis_softc
*fdo_sc
;
598 struct ndis_softc
*pdo_sc
;
602 typedef struct device_object device_object
;
604 struct devobj_extension
{
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
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
{
816 #define isb_status u.isb_status
817 #define isb_ptr u.isb_ptr
819 typedef struct io_status_block io_status_block
;
828 void *apc_rundownfunc
;
829 void *apc_normalfunc
;
833 uint8_t apc_stateidx
;
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
*,
845 struct io_stack_location
{
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.
865 uint64_t isl_byteoff
;
870 uint64_t isl_byteoff
;
873 uint32_t isl_obuflen
;
874 uint32_t isl_ibuflen
;
884 } isl_parameters __packed
;
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
907 struct irp
*irp_master
;
911 list_entry irp_thlist
;
912 io_status_block irp_iostat
;
914 uint8_t irp_pendingreturned
;
915 uint8_t irp_stackcnt
;
916 uint8_t irp_currentstackloc
;
918 uint8_t irp_cancelirql
;
920 uint8_t irp_allocflags
;
921 io_status_block
*irp_usriostat
;
922 nt_kevent
*irp_usrevent
;
928 uint64_t irp_allocsz
;
930 cancel_func irp_cancelfunc
;
933 /* Windows kernel info */
938 kdevice_qentry irp_dqe
;
948 io_stack_location
*irp_csl
;
949 uint32_t irp_pkttype
;
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), \
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) \
983 irp->irp_currentstackloc--; \
984 irp->irp_tail.irp_overlay.irp_csl--; \
987 #define IoSetCompletionRoutine(irp, func, ctx, ok, err, cancel) \
989 io_stack_location *s; \
990 s = IoGetNextIrpStackLocation((irp)); \
991 s->isl_completionfunc = (func); \
992 s->isl_completionctx = (ctx); \
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; \
999 #define IoMarkIrpPending(irp) \
1000 IoGetCurrentIrpStackLocation(irp)->isl_ctl |= SL_PENDING_RETURNED
1002 #define IoCopyCurrentIrpStackLocationToNext(irp) \
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)); \
1011 #define IoSkipCurrentIrpStackLocation(irp) \
1013 (irp)->irp_currentstackloc++; \
1014 (irp)->irp_tail.irp_overlay.irp_csl++; \
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
{
1038 device_object
*dro_devobj
;
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
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);
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
*);
1221 __fastcall
extern void KefAcquireSpinLockAtDpcLevel(REGARGS1(kspin_lock
*));
1222 __fastcall
extern void KefReleaseSpinLockFromDpcLevel(REGARGS1(kspin_lock
*));
1223 __stdcall
extern uint8_t KeAcquireSpinLockRaiseToDpc(kspin_lock
*);
1225 __stdcall
extern void KeAcquireSpinLockAtDpcLevel(kspin_lock
*);
1226 __stdcall
extern void KeReleaseSpinLockFromDpcLevel(kspin_lock
*);
1228 __stdcall
extern void KeInitializeSpinLock(kspin_lock
*);
1229 __fastcall
extern uintptr_t InterlockedExchange(REGARGS2(volatile uint32_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
*,
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.
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__ */
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__ */
1283 #endif /* _NTOSKRNL_VAR_H_ */