The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/compat/ndis/ntoskrnl_var.h

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 043a87b8eac4d6af09984cacc1b5164b


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.