ntoskrnl_var.h revision 145485
1139743Simp/*- 2123474Swpaul * Copyright (c) 2003 3123474Swpaul * Bill Paul <wpaul@windriver.com>. All rights reserved. 4123474Swpaul * 5123474Swpaul * Redistribution and use in source and binary forms, with or without 6123474Swpaul * modification, are permitted provided that the following conditions 7123474Swpaul * are met: 8123474Swpaul * 1. Redistributions of source code must retain the above copyright 9123474Swpaul * notice, this list of conditions and the following disclaimer. 10123474Swpaul * 2. Redistributions in binary form must reproduce the above copyright 11123474Swpaul * notice, this list of conditions and the following disclaimer in the 12123474Swpaul * documentation and/or other materials provided with the distribution. 13123474Swpaul * 3. All advertising materials mentioning features or use of this software 14123474Swpaul * must display the following acknowledgement: 15123474Swpaul * This product includes software developed by Bill Paul. 16123474Swpaul * 4. Neither the name of the author nor the names of any co-contributors 17123474Swpaul * may be used to endorse or promote products derived from this software 18123474Swpaul * without specific prior written permission. 19123474Swpaul * 20123474Swpaul * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 21123474Swpaul * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22123474Swpaul * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23123474Swpaul * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD 24123474Swpaul * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25123474Swpaul * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26123474Swpaul * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27123474Swpaul * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28123474Swpaul * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29123474Swpaul * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 30123474Swpaul * THE POSSIBILITY OF SUCH DAMAGE. 31123474Swpaul * 32123474Swpaul * $FreeBSD: head/sys/compat/ndis/ntoskrnl_var.h 145485 2005-04-24 20:21:22Z wpaul $ 33123474Swpaul */ 34123474Swpaul 35123474Swpaul#ifndef _NTOSKRNL_VAR_H_ 36123474Swpaul#define _NTOSKRNL_VAR_H_ 37123474Swpaul 38140751Swpaul/* 39140751Swpaul * us_buf is really a wchar_t *, but it's inconvenient to include 40140751Swpaul * all the necessary header goop needed to define it, and it's a 41140751Swpaul * pointer anyway, so for now, just make it a uint16_t *. 42140751Swpaul */ 43140751Swpaulstruct unicode_string { 44140751Swpaul uint16_t us_len; 45140751Swpaul uint16_t us_maxlen; 46140751Swpaul uint16_t *us_buf; 47140751Swpaul}; 48140751Swpaul 49140751Swpaultypedef struct unicode_string unicode_string; 50140751Swpaul 51140751Swpaul/* 52140751Swpaul * Windows memory descriptor list. In Windows, it's possible for 53140751Swpaul * buffers to be passed between user and kernel contexts without 54140751Swpaul * copying. Buffers may also be allocated in either paged or 55140751Swpaul * non-paged memory regions. An MDL describes the pages of memory 56140751Swpaul * used to contain a particular buffer. Note that a single MDL 57140751Swpaul * may describe a buffer that spans multiple pages. An array of 58140751Swpaul * page addresses appears immediately after the MDL structure itself. 59140751Swpaul * MDLs are therefore implicitly variably sized, even though they 60140751Swpaul * don't look it. 61140751Swpaul * 62140751Swpaul * Note that in FreeBSD, we can take many shortcuts in the way 63140751Swpaul * we handle MDLs because: 64140751Swpaul * 65140751Swpaul * - We are only concerned with pages in kernel context. This means 66140751Swpaul * we will only ever use the kernel's memory map, and remapping 67140751Swpaul * of buffers is never needed. 68140751Swpaul * 69140751Swpaul * - Kernel pages can never be paged out, so we don't have to worry 70140751Swpaul * about whether or not a page is actually mapped before going to 71140751Swpaul * touch it. 72140751Swpaul */ 73140751Swpaul 74140751Swpaulstruct mdl { 75140751Swpaul struct mdl *mdl_next; 76140751Swpaul uint16_t mdl_size; 77140751Swpaul uint16_t mdl_flags; 78140751Swpaul void *mdl_process; 79140751Swpaul void *mdl_mappedsystemva; 80140751Swpaul void *mdl_startva; 81140751Swpaul uint32_t mdl_bytecount; 82140751Swpaul uint32_t mdl_byteoffset; 83140751Swpaul}; 84140751Swpaul 85140751Swpaultypedef struct mdl mdl, ndis_buffer; 86140751Swpaul 87140751Swpaul/* MDL flags */ 88140751Swpaul 89140751Swpaul#define MDL_MAPPED_TO_SYSTEM_VA 0x0001 90140751Swpaul#define MDL_PAGES_LOCKED 0x0002 91140751Swpaul#define MDL_SOURCE_IS_NONPAGED_POOL 0x0004 92140751Swpaul#define MDL_ALLOCATED_FIXED_SIZE 0x0008 93140751Swpaul#define MDL_PARTIAL 0x0010 94140751Swpaul#define MDL_PARTIAL_HAS_BEEN_MAPPED 0x0020 95140751Swpaul#define MDL_IO_PAGE_READ 0x0040 96140751Swpaul#define MDL_WRITE_OPERATION 0x0080 97140751Swpaul#define MDL_PARENT_MAPPED_SYSTEM_VA 0x0100 98140751Swpaul#define MDL_FREE_EXTRA_PTES 0x0200 99140751Swpaul#define MDL_IO_SPACE 0x0800 100140751Swpaul#define MDL_NETWORK_HEADER 0x1000 101140751Swpaul#define MDL_MAPPING_CAN_FAIL 0x2000 102140751Swpaul#define MDL_ALLOCATED_MUST_SUCCEED 0x4000 103142530Swpaul#define MDL_ZONE_ALLOCED 0x8000 /* BSD private */ 104140751Swpaul 105142530Swpaul#define MDL_ZONE_PAGES 16 106142530Swpaul#define MDL_ZONE_SIZE (sizeof(mdl) + (sizeof(vm_offset_t) * MDL_ZONE_PAGES)) 107142530Swpaul 108123512Swpaul/* Note: assumes x86 page size of 4K. */ 109140751Swpaul 110140751Swpaul#if PAGE_SIZE == 4096 111123512Swpaul#define PAGE_SHIFT 12 112140751Swpaul#elif PAGE_SIZE == 8192 113140751Swpaul#define PAGE_SHIFT 13 114140751Swpaul#else 115140751Swpaul#error PAGE_SHIFT undefined! 116140751Swpaul#endif 117140751Swpaul 118123512Swpaul#define SPAN_PAGES(ptr, len) \ 119140751Swpaul ((uint32_t)((((uintptr_t)(ptr) & (PAGE_SIZE - 1)) + \ 120123512Swpaul (len) + (PAGE_SIZE - 1)) >> PAGE_SHIFT)) 121140751Swpaul 122123757Swpaul#define PAGE_ALIGN(ptr) \ 123123757Swpaul ((void *)((uintptr_t)(ptr) & ~(PAGE_SIZE - 1))) 124140751Swpaul 125123757Swpaul#define BYTE_OFFSET(ptr) \ 126123757Swpaul ((uint32_t)((uintptr_t)(ptr) & (PAGE_SIZE - 1))) 127140751Swpaul 128140751Swpaul#define MDL_PAGES(m) (vm_offset_t *)(m + 1) 129140751Swpaul 130140751Swpaul#define MmInitializeMdl(b, baseva, len) \ 131140751Swpaul (b)->mdl_next = NULL; \ 132140751Swpaul (b)->mdl_size = (uint16_t)(sizeof(mdl) + \ 133144175Swpaul (sizeof(vm_offset_t) * SPAN_PAGES((baseva), (len)))); \ 134140751Swpaul (b)->mdl_flags = 0; \ 135140751Swpaul (b)->mdl_startva = (void *)PAGE_ALIGN((baseva)); \ 136140751Swpaul (b)->mdl_byteoffset = BYTE_OFFSET((baseva)); \ 137140751Swpaul (b)->mdl_bytecount = (uint32_t)(len); 138123512Swpaul 139140751Swpaul#define MmGetMdlByteOffset(mdl) ((mdl)->mdl_byteoffset) 140140751Swpaul#define MmGetMdlByteCount(mdl) ((mdl)->mdl_bytecount) 141140751Swpaul#define MmGetMdlVirtualAddress(mdl) \ 142140751Swpaul ((void *)((char *)((mdl)->mdl_startva) + (mdl)->mdl_byteoffset)) 143140751Swpaul#define MmGetMdlStartVa(mdl) ((mdl)->mdl_startva) 144140751Swpaul#define MmGetMdlPfnArray(mdl) MDL_PAGES(mdl) 145140751Swpaul 146124729Swpaul#define WDM_MAJOR 1 147124729Swpaul#define WDM_MINOR_WIN98 0x00 148124729Swpaul#define WDM_MINOR_WINME 0x05 149124729Swpaul#define WDM_MINOR_WIN2000 0x10 150124729Swpaul#define WDM_MINOR_WINXP 0x20 151124729Swpaul#define WDM_MINOR_WIN2003 0x30 152124729Swpaul 153124582Sobrien/*- 154124582Sobrien * The ndis_kspin_lock type is called KSPIN_LOCK in MS-Windows. 155124582Sobrien * According to the Windows DDK header files, KSPIN_LOCK is defined like this: 156124582Sobrien * typedef ULONG_PTR KSPIN_LOCK; 157124582Sobrien * 158124582Sobrien * From basetsd.h (SDK, Feb. 2003): 159124582Sobrien * typedef [public] unsigned __int3264 ULONG_PTR, *PULONG_PTR; 160124582Sobrien * typedef unsigned __int64 ULONG_PTR, *PULONG_PTR; 161124582Sobrien * typedef _W64 unsigned long ULONG_PTR, *PULONG_PTR; 162124582Sobrien * 163124582Sobrien * The keyword __int3264 specifies an integral type that has the following 164124582Sobrien * properties: 165124582Sobrien * + It is 32-bit on 32-bit platforms 166124582Sobrien * + It is 64-bit on 64-bit platforms 167124582Sobrien * + It is 32-bit on the wire for backward compatibility. 168124582Sobrien * It gets truncated on the sending side and extended appropriately 169124582Sobrien * (signed or unsigned) on the receiving side. 170124582Sobrien * 171124582Sobrien * Thus register_t seems the proper mapping onto FreeBSD for spin locks. 172124582Sobrien */ 173123474Swpaul 174124582Sobrientypedef register_t kspin_lock; 175124582Sobrien 176123474Swpaulstruct slist_entry { 177123474Swpaul struct slist_entry *sl_next; 178123474Swpaul}; 179123474Swpaul 180123474Swpaultypedef struct slist_entry slist_entry; 181123474Swpaul 182123474Swpaulunion slist_header { 183123474Swpaul uint64_t slh_align; 184123474Swpaul struct { 185123474Swpaul struct slist_entry *slh_next; 186123474Swpaul uint16_t slh_depth; 187123474Swpaul uint16_t slh_seq; 188123474Swpaul } slh_list; 189123474Swpaul}; 190123474Swpaul 191123474Swpaultypedef union slist_header slist_header; 192123474Swpaul 193123507Swpaulstruct list_entry { 194123507Swpaul struct list_entry *nle_flink; 195123507Swpaul struct list_entry *nle_blink; 196123507Swpaul}; 197123507Swpaul 198123507Swpaultypedef struct list_entry list_entry; 199123507Swpaul 200125551Swpaul#define INIT_LIST_HEAD(l) \ 201141524Swpaul (l)->nle_flink = (l)->nle_blink = (l) 202125551Swpaul 203125551Swpaul#define REMOVE_LIST_ENTRY(e) \ 204125551Swpaul do { \ 205125551Swpaul list_entry *b; \ 206125551Swpaul list_entry *f; \ 207125551Swpaul \ 208125551Swpaul f = e->nle_flink; \ 209125551Swpaul b = e->nle_blink; \ 210125551Swpaul b->nle_flink = f; \ 211125551Swpaul f->nle_blink = b; \ 212125551Swpaul } while (0) 213125551Swpaul 214125551Swpaul#define REMOVE_LIST_HEAD(l) \ 215125551Swpaul do { \ 216125551Swpaul list_entry *f; \ 217125551Swpaul list_entry *e; \ 218125551Swpaul \ 219125551Swpaul e = l->nle_flink; \ 220125551Swpaul f = e->nle_flink; \ 221125551Swpaul l->nle_flink = f; \ 222125551Swpaul f->nle_blink = l; \ 223125551Swpaul } while (0) 224125551Swpaul 225125551Swpaul#define REMOVE_LIST_TAIL(l) \ 226125551Swpaul do { \ 227125551Swpaul list_entry *b; \ 228125551Swpaul list_entry *e; \ 229125551Swpaul \ 230125551Swpaul e = l->nle_blink; \ 231125551Swpaul b = e->nle_blink; \ 232125551Swpaul l->nle_blink = b; \ 233125551Swpaul b->nle_flink = l; \ 234125551Swpaul } while (0) 235125551Swpaul 236125551Swpaul#define INSERT_LIST_TAIL(l, e) \ 237125551Swpaul do { \ 238125551Swpaul list_entry *b; \ 239125551Swpaul \ 240125551Swpaul b = l->nle_blink; \ 241125860Swpaul e->nle_flink = l; \ 242125551Swpaul e->nle_blink = b; \ 243141524Swpaul b->nle_flink = (e); \ 244141524Swpaul l->nle_blink = (e); \ 245125551Swpaul } while (0) 246125551Swpaul 247125551Swpaul#define INSERT_LIST_HEAD(l, e) \ 248125551Swpaul do { \ 249125551Swpaul list_entry *f; \ 250125551Swpaul \ 251125551Swpaul f = l->nle_flink; \ 252125551Swpaul e->nle_flink = f; \ 253125551Swpaul e->nle_blink = l; \ 254125551Swpaul f->nle_blink = e; \ 255125551Swpaul l->nle_flink = e; \ 256125551Swpaul } while (0) 257125551Swpaul 258125551Swpaulstruct nt_dispatch_header { 259125551Swpaul uint8_t dh_type; 260125551Swpaul uint8_t dh_abs; 261125551Swpaul uint8_t dh_size; 262125551Swpaul uint8_t dh_inserted; 263125551Swpaul uint32_t dh_sigstate; 264125551Swpaul list_entry dh_waitlisthead; 265125551Swpaul}; 266125551Swpaul 267125551Swpaultypedef struct nt_dispatch_header nt_dispatch_header; 268125551Swpaul 269125551Swpaul#define OTYPE_EVENT 0 270125551Swpaul#define OTYPE_MUTEX 1 271125551Swpaul#define OTYPE_THREAD 2 272125551Swpaul#define OTYPE_TIMER 3 273125551Swpaul 274125551Swpaul/* Windows dispatcher levels. */ 275125551Swpaul 276125551Swpaul#define PASSIVE_LEVEL 0 277125551Swpaul#define LOW_LEVEL 0 278125551Swpaul#define APC_LEVEL 1 279125551Swpaul#define DISPATCH_LEVEL 2 280128229Swpaul#define DEVICE_LEVEL (DISPATCH_LEVEL + 1) 281125551Swpaul#define PROFILE_LEVEL 27 282125551Swpaul#define CLOCK1_LEVEL 28 283125551Swpaul#define CLOCK2_LEVEL 28 284125551Swpaul#define IPI_LEVEL 29 285125551Swpaul#define POWER_LEVEL 30 286125551Swpaul#define HIGH_LEVEL 31 287125551Swpaul 288125551Swpaul#define SYNC_LEVEL_UP DISPATCH_LEVEL 289125551Swpaul#define SYNC_LEVEL_MP (IPI_LEVEL - 1) 290125551Swpaul 291128229Swpaul#define AT_PASSIVE_LEVEL(td) \ 292128229Swpaul ((td)->td_proc->p_flag & P_KTHREAD == FALSE) 293128229Swpaul 294128229Swpaul#define AT_DISPATCH_LEVEL(td) \ 295128449Swpaul ((td)->td_base_pri == PI_REALTIME) 296128229Swpaul 297128229Swpaul#define AT_DIRQL_LEVEL(td) \ 298128295Swpaul ((td)->td_priority <= PI_NET) 299128229Swpaul 300128229Swpaul#define AT_HIGH_LEVEL(td) \ 301128229Swpaul ((td)->td_critnest != 0) 302128229Swpaul 303125551Swpaulstruct nt_objref { 304125551Swpaul nt_dispatch_header no_dh; 305125551Swpaul void *no_obj; 306125551Swpaul TAILQ_ENTRY(nt_objref) link; 307125551Swpaul}; 308125551Swpaul 309125551SwpaulTAILQ_HEAD(nt_objref_head, nt_objref); 310125551Swpaul 311125551Swpaultypedef struct nt_objref nt_objref; 312125551Swpaul 313125551Swpaul#define EVENT_TYPE_NOTIFY 0 314125551Swpaul#define EVENT_TYPE_SYNC 1 315125551Swpaul 316126620Swpaul/* 317126620Swpaul * We need to use the timeout()/untimeout() API for ktimers 318126620Swpaul * since timers can be initialized, but not destroyed (so 319126620Swpaul * malloc()ing our own callout structures would mean a leak, 320126620Swpaul * since there'd be no way to free() them). This means we 321126620Swpaul * need to use struct callout_handle, which is really just a 322126620Swpaul * pointer. To make it easier to deal with, we use a union 323126620Swpaul * to overlay the callout_handle over the k_timerlistentry. 324126620Swpaul * The latter is a list_entry, which is two pointers, so 325126620Swpaul * there's enough space available to hide a callout_handle 326126620Swpaul * there. 327126620Swpaul */ 328126620Swpaul 329125551Swpaulstruct ktimer { 330125551Swpaul nt_dispatch_header k_header; 331125551Swpaul uint64_t k_duetime; 332126620Swpaul union { 333126620Swpaul list_entry k_timerlistentry; 334126620Swpaul struct callout_handle k_handle; 335126620Swpaul } u; 336125551Swpaul void *k_dpc; 337125551Swpaul uint32_t k_period; 338125551Swpaul}; 339125551Swpaul 340126620Swpaul#define k_timerlistentry u.k_timerlistentry 341126620Swpaul#define k_handle u.k_handle 342126620Swpaul 343126620Swpaultypedef struct ktimer ktimer; 344126620Swpaul 345125551Swpaulstruct nt_kevent { 346125551Swpaul nt_dispatch_header k_header; 347125551Swpaul}; 348125551Swpaul 349125551Swpaultypedef struct nt_kevent nt_kevent; 350125551Swpaul 351125551Swpaul/* Kernel defered procedure call (i.e. timer callback) */ 352125551Swpaul 353125551Swpaulstruct kdpc; 354144888Swpaultypedef void (*kdpc_func)(struct kdpc *, void *, void *, void *); 355125551Swpaul 356125551Swpaulstruct kdpc { 357125551Swpaul uint16_t k_type; 358125551Swpaul uint8_t k_num; 359125551Swpaul uint8_t k_importance; 360125551Swpaul list_entry k_dpclistentry; 361140827Swpaul void *k_deferedfunc; 362125551Swpaul void *k_deferredctx; 363125551Swpaul void *k_sysarg1; 364125551Swpaul void *k_sysarg2; 365127552Swpaul register_t k_lock; 366125551Swpaul}; 367125551Swpaul 368126620Swpaultypedef struct kdpc kdpc; 369126620Swpaul 370125551Swpaul/* 371125551Swpaul * Note: the acquisition count is BSD-specific. The Microsoft 372125551Swpaul * documentation says that mutexes can be acquired recursively 373125551Swpaul * by a given thread, but that you must release the mutex as 374125551Swpaul * many times as you acquired it before it will be set to the 375125551Swpaul * signalled state (i.e. before any other threads waiting on 376125551Swpaul * the object will be woken up). However the Windows KMUTANT 377125551Swpaul * structure has no field for keeping track of the number of 378125551Swpaul * acquisitions, so we need to add one ourselves. As long as 379125551Swpaul * driver code treats the mutex as opaque, we should be ok. 380125551Swpaul */ 381125551Swpaulstruct kmutant { 382125551Swpaul nt_dispatch_header km_header; 383126620Swpaul union { 384126620Swpaul list_entry km_listentry; 385126620Swpaul uint32_t km_acquirecnt; 386126620Swpaul } u; 387125551Swpaul void *km_ownerthread; 388125551Swpaul uint8_t km_abandoned; 389125551Swpaul uint8_t km_apcdisable; 390125551Swpaul}; 391125551Swpaul 392126620Swpaul#define km_listentry u.km_listentry 393126620Swpaul#define km_acquirecnt u.km_acquirecnt 394126620Swpaul 395125551Swpaultypedef struct kmutant kmutant; 396125551Swpaul 397125860Swpaul#define LOOKASIDE_DEPTH 256 398125860Swpaul 399123474Swpaulstruct general_lookaside { 400123474Swpaul slist_header gl_listhead; 401123474Swpaul uint16_t gl_depth; 402123474Swpaul uint16_t gl_maxdepth; 403123474Swpaul uint32_t gl_totallocs; 404123474Swpaul union { 405123474Swpaul uint32_t gl_allocmisses; 406123474Swpaul uint32_t gl_allochits; 407123474Swpaul } u_a; 408123474Swpaul uint32_t gl_totalfrees; 409123474Swpaul union { 410123474Swpaul uint32_t gl_freemisses; 411123474Swpaul uint32_t gl_freehits; 412123474Swpaul } u_m; 413123474Swpaul uint32_t gl_type; 414123474Swpaul uint32_t gl_tag; 415123474Swpaul uint32_t gl_size; 416123474Swpaul void *gl_allocfunc; 417123474Swpaul void *gl_freefunc; 418123507Swpaul list_entry gl_listent; 419123474Swpaul uint32_t gl_lasttotallocs; 420123474Swpaul union { 421123474Swpaul uint32_t gl_lastallocmisses; 422123474Swpaul uint32_t gl_lastallochits; 423123474Swpaul } u_l; 424123474Swpaul uint32_t gl_rsvd[2]; 425123474Swpaul}; 426123474Swpaul 427123474Swpaultypedef struct general_lookaside general_lookaside; 428123474Swpaul 429123474Swpaulstruct npaged_lookaside_list { 430123474Swpaul general_lookaside nll_l; 431144240Swpaul#ifdef __i386__ 432123474Swpaul kspin_lock nll_obsoletelock; 433144240Swpaul#endif 434123474Swpaul}; 435123474Swpaul 436123474Swpaultypedef struct npaged_lookaside_list npaged_lookaside_list; 437123474Swpaultypedef struct npaged_lookaside_list paged_lookaside_list; 438123474Swpaul 439123474Swpaultypedef void * (*lookaside_alloc_func)(uint32_t, size_t, uint32_t); 440123474Swpaultypedef void (*lookaside_free_func)(void *); 441123474Swpaul 442125551Swpaulstruct irp; 443123474Swpaul 444125551Swpaulstruct kdevice_qentry { 445125551Swpaul list_entry kqe_devlistent; 446125551Swpaul uint32_t kqe_sortkey; 447125551Swpaul uint8_t kqe_inserted; 448125551Swpaul}; 449125551Swpaul 450125551Swpaultypedef struct kdevice_qentry kdevice_qentry; 451125551Swpaul 452125551Swpaulstruct kdevice_queue { 453125551Swpaul uint16_t kq_type; 454125551Swpaul uint16_t kq_size; 455125551Swpaul list_entry kq_devlisthead; 456125551Swpaul kspin_lock kq_lock; 457125551Swpaul uint8_t kq_busy; 458125551Swpaul}; 459125551Swpaul 460125551Swpaultypedef struct kdevice_queue kdevice_queue; 461125551Swpaul 462125551Swpaulstruct wait_ctx_block { 463125551Swpaul kdevice_qentry wcb_waitqueue; 464125551Swpaul void *wcb_devfunc; 465125551Swpaul void *wcb_devctx; 466125551Swpaul uint32_t wcb_mapregcnt; 467125551Swpaul void *wcb_devobj; 468125551Swpaul void *wcb_curirp; 469125551Swpaul void *wcb_bufchaindpc; 470125551Swpaul}; 471125551Swpaul 472125551Swpaultypedef struct wait_ctx_block wait_ctx_block; 473125551Swpaul 474125551Swpaulstruct wait_block { 475125551Swpaul list_entry wb_waitlist; 476125551Swpaul void *wb_kthread; 477125551Swpaul nt_dispatch_header *wb_object; 478125551Swpaul struct wait_block *wb_next; 479125551Swpaul uint16_t wb_waitkey; 480125551Swpaul uint16_t wb_waittype; 481125551Swpaul}; 482125551Swpaul 483125551Swpaultypedef struct wait_block wait_block; 484125551Swpaul 485125551Swpaul#define THREAD_WAIT_OBJECTS 3 486125551Swpaul#define MAX_WAIT_OBJECTS 64 487125551Swpaul 488125551Swpaul#define WAITTYPE_ALL 0 489125551Swpaul#define WAITTYPE_ANY 1 490125551Swpaul 491125551Swpaulstruct thread_context { 492125551Swpaul void *tc_thrctx; 493125551Swpaul void *tc_thrfunc; 494125551Swpaul}; 495125551Swpaul 496125551Swpaultypedef struct thread_context thread_context; 497125551Swpaul 498140751Swpaul/* Forward declaration */ 499140751Swpaulstruct driver_object; 500140751Swpaulstruct devobj_extension; 501140751Swpaul 502140751Swpaulstruct driver_extension { 503140751Swpaul struct driver_object *dre_driverobj; 504140751Swpaul void *dre_adddevicefunc; 505140751Swpaul uint32_t dre_reinitcnt; 506140751Swpaul unicode_string dre_srvname; 507141524Swpaul 508141524Swpaul /* 509141524Swpaul * Drivers are allowed to add one or more custom extensions 510141524Swpaul * to the driver object, but there's no special pointer 511141524Swpaul * for them. Hang them off here for now. 512141524Swpaul */ 513141524Swpaul 514141524Swpaul list_entry dre_usrext; 515140751Swpaul}; 516140751Swpaul 517140751Swpaultypedef struct driver_extension driver_extension; 518140751Swpaul 519141524Swpaulstruct custom_extension { 520141524Swpaul list_entry ce_list; 521141524Swpaul void *ce_clid; 522141524Swpaul}; 523141524Swpaul 524141524Swpaultypedef struct custom_extension custom_extension; 525141524Swpaul 526140751Swpaul/* 527140751Swpaul * In Windows, there are Physical Device Objects (PDOs) and 528140751Swpaul * Functional Device Objects (FDOs). Physical Device Objects are 529140751Swpaul * created and maintained by bus drivers. For example, the PCI 530140751Swpaul * bus driver might detect two PCI ethernet cards on a given 531140751Swpaul * bus. The PCI bus driver will then allocate two device_objects 532140751Swpaul * for its own internal bookeeping purposes. This is analagous 533140751Swpaul * to the device_t that the FreeBSD PCI code allocates and passes 534140751Swpaul * into each PCI driver's probe and attach routines. 535140751Swpaul * 536140751Swpaul * When an ethernet driver claims one of the ethernet cards 537140751Swpaul * on the bus, it will create its own device_object. This is 538140751Swpaul * the Functional Device Object. This object is analagous to the 539140751Swpaul * device-specific softc structure. 540140751Swpaul */ 541140751Swpaul 542125551Swpaulstruct device_object { 543125551Swpaul uint16_t do_type; 544125551Swpaul uint16_t do_size; 545125551Swpaul uint32_t do_refcnt; 546141524Swpaul struct driver_object *do_drvobj; 547125551Swpaul struct device_object *do_nextdev; 548125551Swpaul struct device_object *do_attacheddev; 549125551Swpaul struct irp *do_currirp; 550125551Swpaul void *do_iotimer; 551125551Swpaul uint32_t do_flags; 552125551Swpaul uint32_t do_characteristics; 553125551Swpaul void *do_vpb; 554125551Swpaul void *do_devext; 555141524Swpaul uint32_t do_devtype; 556125551Swpaul uint8_t do_stacksize; 557125551Swpaul union { 558125551Swpaul list_entry do_listent; 559125551Swpaul wait_ctx_block do_wcb; 560125551Swpaul } queue; 561125551Swpaul uint32_t do_alignreq; 562125551Swpaul kdevice_queue do_devqueue; 563125551Swpaul struct kdpc do_dpc; 564125551Swpaul uint32_t do_activethreads; 565125551Swpaul void *do_securitydesc; 566125551Swpaul struct nt_kevent do_devlock; 567125551Swpaul uint16_t do_sectorsz; 568125551Swpaul uint16_t do_spare1; 569140751Swpaul struct devobj_extension *do_devobj_ext; 570125551Swpaul void *do_rsvd; 571125551Swpaul}; 572125551Swpaul 573125551Swpaultypedef struct device_object device_object; 574125551Swpaul 575140751Swpaulstruct devobj_extension { 576140751Swpaul uint16_t dve_type; 577140751Swpaul uint16_t dve_size; 578140751Swpaul device_object *dve_devobj; 579140751Swpaul}; 580140751Swpaul 581140751Swpaultypedef struct devobj_extension devobj_extension; 582140751Swpaul 583142311Swpaul/* Device object flags */ 584142311Swpaul 585142311Swpaul#define DO_VERIFY_VOLUME 0x00000002 586142311Swpaul#define DO_BUFFERED_IO 0x00000004 587142311Swpaul#define DO_EXCLUSIVE 0x00000008 588142311Swpaul#define DO_DIRECT_IO 0x00000010 589142311Swpaul#define DO_MAP_IO_BUFFER 0x00000020 590142311Swpaul#define DO_DEVICE_HAS_NAME 0x00000040 591142311Swpaul#define DO_DEVICE_INITIALIZING 0x00000080 592142311Swpaul#define DO_SYSTEM_BOOT_PARTITION 0x00000100 593142311Swpaul#define DO_LONG_TERM_REQUESTS 0x00000200 594142311Swpaul#define DO_NEVER_LAST_DEVICE 0x00000400 595142311Swpaul#define DO_SHUTDOWN_REGISTERED 0x00000800 596142311Swpaul#define DO_BUS_ENUMERATED_DEVICE 0x00001000 597142311Swpaul#define DO_POWER_PAGABLE 0x00002000 598142311Swpaul#define DO_POWER_INRUSH 0x00004000 599142311Swpaul#define DO_LOW_PRIORITY_FILESYSTEM 0x00010000 600142311Swpaul 601142311Swpaul/* Priority boosts */ 602142311Swpaul 603140751Swpaul#define IO_NO_INCREMENT 0 604140751Swpaul#define IO_CD_ROM_INCREMENT 1 605140751Swpaul#define IO_DISK_INCREMENT 1 606140751Swpaul#define IO_KEYBOARD_INCREMENT 6 607140751Swpaul#define IO_MAILSLOT_INCREMENT 2 608140751Swpaul#define IO_MOUSE_INCREMENT 6 609140751Swpaul#define IO_NAMED_PIPE_INCREMENT 2 610140751Swpaul#define IO_NETWORK_INCREMENT 2 611140751Swpaul#define IO_PARALLEL_INCREMENT 1 612140751Swpaul#define IO_SERIAL_INCREMENT 2 613140751Swpaul#define IO_SOUND_INCREMENT 8 614140751Swpaul#define IO_VIDEO_INCREMENT 1 615140751Swpaul 616140751Swpaul/* IRP major codes */ 617140751Swpaul 618140751Swpaul#define IRP_MJ_CREATE 0x00 619140751Swpaul#define IRP_MJ_CREATE_NAMED_PIPE 0x01 620140751Swpaul#define IRP_MJ_CLOSE 0x02 621140751Swpaul#define IRP_MJ_READ 0x03 622140751Swpaul#define IRP_MJ_WRITE 0x04 623140751Swpaul#define IRP_MJ_QUERY_INFORMATION 0x05 624140751Swpaul#define IRP_MJ_SET_INFORMATION 0x06 625140751Swpaul#define IRP_MJ_QUERY_EA 0x07 626140751Swpaul#define IRP_MJ_SET_EA 0x08 627140751Swpaul#define IRP_MJ_FLUSH_BUFFERS 0x09 628140751Swpaul#define IRP_MJ_QUERY_VOLUME_INFORMATION 0x0a 629140751Swpaul#define IRP_MJ_SET_VOLUME_INFORMATION 0x0b 630140751Swpaul#define IRP_MJ_DIRECTORY_CONTROL 0x0c 631140751Swpaul#define IRP_MJ_FILE_SYSTEM_CONTROL 0x0d 632140751Swpaul#define IRP_MJ_DEVICE_CONTROL 0x0e 633140751Swpaul#define IRP_MJ_INTERNAL_DEVICE_CONTROL 0x0f 634140751Swpaul#define IRP_MJ_SHUTDOWN 0x10 635140751Swpaul#define IRP_MJ_LOCK_CONTROL 0x11 636140751Swpaul#define IRP_MJ_CLEANUP 0x12 637140751Swpaul#define IRP_MJ_CREATE_MAILSLOT 0x13 638140751Swpaul#define IRP_MJ_QUERY_SECURITY 0x14 639140751Swpaul#define IRP_MJ_SET_SECURITY 0x15 640140751Swpaul#define IRP_MJ_POWER 0x16 641140751Swpaul#define IRP_MJ_SYSTEM_CONTROL 0x17 642140751Swpaul#define IRP_MJ_DEVICE_CHANGE 0x18 643140751Swpaul#define IRP_MJ_QUERY_QUOTA 0x19 644140751Swpaul#define IRP_MJ_SET_QUOTA 0x1a 645140751Swpaul#define IRP_MJ_PNP 0x1b 646140751Swpaul#define IRP_MJ_PNP_POWER IRP_MJ_PNP // Obsolete.... 647140751Swpaul#define IRP_MJ_MAXIMUM_FUNCTION 0x1b 648140751Swpaul#define IRP_MJ_SCSI IRP_MJ_INTERNAL_DEVICE_CONTROL 649140751Swpaul 650140751Swpaul/* IRP minor codes */ 651140751Swpaul 652140751Swpaul#define IRP_MN_QUERY_DIRECTORY 0x01 653140751Swpaul#define IRP_MN_NOTIFY_CHANGE_DIRECTORY 0x02 654140751Swpaul#define IRP_MN_USER_FS_REQUEST 0x00 655140751Swpaul 656140751Swpaul#define IRP_MN_MOUNT_VOLUME 0x01 657140751Swpaul#define IRP_MN_VERIFY_VOLUME 0x02 658140751Swpaul#define IRP_MN_LOAD_FILE_SYSTEM 0x03 659144240Swpaul#define IRP_MN_TRACK_LINK 0x04 660140751Swpaul#define IRP_MN_KERNEL_CALL 0x04 661140751Swpaul 662140751Swpaul#define IRP_MN_LOCK 0x01 663140751Swpaul#define IRP_MN_UNLOCK_SINGLE 0x02 664140751Swpaul#define IRP_MN_UNLOCK_ALL 0x03 665140751Swpaul#define IRP_MN_UNLOCK_ALL_BY_KEY 0x04 666140751Swpaul 667140751Swpaul#define IRP_MN_NORMAL 0x00 668140751Swpaul#define IRP_MN_DPC 0x01 669140751Swpaul#define IRP_MN_MDL 0x02 670140751Swpaul#define IRP_MN_COMPLETE 0x04 671140751Swpaul#define IRP_MN_COMPRESSED 0x08 672140751Swpaul 673140751Swpaul#define IRP_MN_MDL_DPC (IRP_MN_MDL | IRP_MN_DPC) 674140751Swpaul#define IRP_MN_COMPLETE_MDL (IRP_MN_COMPLETE | IRP_MN_MDL) 675140751Swpaul#define IRP_MN_COMPLETE_MDL_DPC (IRP_MN_COMPLETE_MDL | IRP_MN_DPC) 676140751Swpaul 677140751Swpaul#define IRP_MN_SCSI_CLASS 0x01 678140751Swpaul 679140751Swpaul#define IRP_MN_START_DEVICE 0x00 680140751Swpaul#define IRP_MN_QUERY_REMOVE_DEVICE 0x01 681140751Swpaul#define IRP_MN_REMOVE_DEVICE 0x02 682140751Swpaul#define IRP_MN_CANCEL_REMOVE_DEVICE 0x03 683140751Swpaul#define IRP_MN_STOP_DEVICE 0x04 684140751Swpaul#define IRP_MN_QUERY_STOP_DEVICE 0x05 685140751Swpaul#define IRP_MN_CANCEL_STOP_DEVICE 0x06 686140751Swpaul 687140751Swpaul#define IRP_MN_QUERY_DEVICE_RELATIONS 0x07 688140751Swpaul#define IRP_MN_QUERY_INTERFACE 0x08 689140751Swpaul#define IRP_MN_QUERY_CAPABILITIES 0x09 690140751Swpaul#define IRP_MN_QUERY_RESOURCES 0x0A 691140751Swpaul#define IRP_MN_QUERY_RESOURCE_REQUIREMENTS 0x0B 692140751Swpaul#define IRP_MN_QUERY_DEVICE_TEXT 0x0C 693140751Swpaul#define IRP_MN_FILTER_RESOURCE_REQUIREMENTS 0x0D 694140751Swpaul 695140751Swpaul#define IRP_MN_READ_CONFIG 0x0F 696140751Swpaul#define IRP_MN_WRITE_CONFIG 0x10 697140751Swpaul#define IRP_MN_EJECT 0x11 698140751Swpaul#define IRP_MN_SET_LOCK 0x12 699140751Swpaul#define IRP_MN_QUERY_ID 0x13 700140751Swpaul#define IRP_MN_QUERY_PNP_DEVICE_STATE 0x14 701140751Swpaul#define IRP_MN_QUERY_BUS_INFORMATION 0x15 702140751Swpaul#define IRP_MN_DEVICE_USAGE_NOTIFICATION 0x16 703140751Swpaul#define IRP_MN_SURPRISE_REMOVAL 0x17 704140751Swpaul#define IRP_MN_QUERY_LEGACY_BUS_INFORMATION 0x18 705140751Swpaul 706140751Swpaul#define IRP_MN_WAIT_WAKE 0x00 707140751Swpaul#define IRP_MN_POWER_SEQUENCE 0x01 708140751Swpaul#define IRP_MN_SET_POWER 0x02 709140751Swpaul#define IRP_MN_QUERY_POWER 0x03 710140751Swpaul 711140751Swpaul#define IRP_MN_QUERY_ALL_DATA 0x00 712140751Swpaul#define IRP_MN_QUERY_SINGLE_INSTANCE 0x01 713140751Swpaul#define IRP_MN_CHANGE_SINGLE_INSTANCE 0x02 714140751Swpaul#define IRP_MN_CHANGE_SINGLE_ITEM 0x03 715140751Swpaul#define IRP_MN_ENABLE_EVENTS 0x04 716140751Swpaul#define IRP_MN_DISABLE_EVENTS 0x05 717140751Swpaul#define IRP_MN_ENABLE_COLLECTION 0x06 718140751Swpaul#define IRP_MN_DISABLE_COLLECTION 0x07 719140751Swpaul#define IRP_MN_REGINFO 0x08 720140751Swpaul#define IRP_MN_EXECUTE_METHOD 0x09 721140751Swpaul#define IRP_MN_REGINFO_EX 0x0b 722140751Swpaul 723140751Swpaul/* IRP flags */ 724140751Swpaul 725140751Swpaul#define IRP_NOCACHE 0x00000001 726140751Swpaul#define IRP_PAGING_IO 0x00000002 727140751Swpaul#define IRP_MOUNT_COMPLETION 0x00000002 728140751Swpaul#define IRP_SYNCHRONOUS_API 0x00000004 729140751Swpaul#define IRP_ASSOCIATED_IRP 0x00000008 730140751Swpaul#define IRP_BUFFERED_IO 0x00000010 731140751Swpaul#define IRP_DEALLOCATE_BUFFER 0x00000020 732140751Swpaul#define IRP_INPUT_OPERATION 0x00000040 733140751Swpaul#define IRP_SYNCHRONOUS_PAGING_IO 0x00000040 734140751Swpaul#define IRP_CREATE_OPERATION 0x00000080 735140751Swpaul#define IRP_READ_OPERATION 0x00000100 736140751Swpaul#define IRP_WRITE_OPERATION 0x00000200 737140751Swpaul#define IRP_CLOSE_OPERATION 0x00000400 738140751Swpaul#define IRP_DEFER_IO_COMPLETION 0x00000800 739140751Swpaul#define IRP_OB_QUERY_NAME 0x00001000 740140751Swpaul#define IRP_HOLD_DEVICE_QUEUE 0x00002000 741140751Swpaul#define IRP_RETRY_IO_COMPLETION 0x00004000 742140751Swpaul#define IRP_CLASS_CACHE_OPERATION 0x00008000 743140751Swpaul#define IRP_SET_USER_EVENT IRP_CLOSE_OPERATION 744140751Swpaul 745140751Swpaul/* IRP I/O control flags */ 746140751Swpaul 747140751Swpaul#define IRP_QUOTA_CHARGED 0x01 748140751Swpaul#define IRP_ALLOCATED_MUST_SUCCEED 0x02 749140751Swpaul#define IRP_ALLOCATED_FIXED_SIZE 0x04 750140751Swpaul#define IRP_LOOKASIDE_ALLOCATION 0x08 751140751Swpaul 752142311Swpaul/* I/O method types */ 753142311Swpaul 754142311Swpaul#define METHOD_BUFFERED 0 755142311Swpaul#define METHOD_IN_DIRECT 1 756142311Swpaul#define METHOD_OUT_DIRECT 2 757142311Swpaul#define METHOD_NEITHER 3 758142311Swpaul 759142497Swpaul/* File access types */ 760142497Swpaul 761142497Swpaul#define FILE_ANY_ACCESS 0x0000 762142497Swpaul#define FILE_SPECIAL_ACCESS FILE_ANY_ACCESS 763142497Swpaul#define FILE_READ_ACCESS 0x0001 764142497Swpaul#define FILE_WRITE_ACCESS 0x0002 765142497Swpaul 766142497Swpaul/* Recover I/O access method from IOCTL code. */ 767142497Swpaul 768142311Swpaul#define IO_METHOD(x) ((x) & 0xFFFFFFFC) 769142311Swpaul 770142497Swpaul/* Recover function code from IOCTL code */ 771142497Swpaul 772142497Swpaul#define IO_FUNC(x) (((x) & 0x7FFC) >> 2) 773142497Swpaul 774142497Swpaul/* Macro to construct an IOCTL code. */ 775142497Swpaul 776142497Swpaul#define IOCTL_CODE(dev, func, iomethod, acc) \ 777142497Swpaul ((dev) << 16) | (acc << 14) | (func << 2) | (iomethod)) 778142497Swpaul 779142497Swpaul 780140751Swpaulstruct io_status_block { 781140751Swpaul union { 782140751Swpaul uint32_t isb_status; 783140751Swpaul void *isb_ptr; 784140751Swpaul } u; 785140751Swpaul register_t isb_info; 786140751Swpaul}; 787141524Swpaul#define isb_status u.isb_status 788141524Swpaul#define isb_ptr u.isb_ptr 789140751Swpaul 790140751Swpaultypedef struct io_status_block io_status_block; 791140751Swpaul 792140751Swpaulstruct kapc { 793140751Swpaul uint16_t apc_type; 794140751Swpaul uint16_t apc_size; 795140751Swpaul uint32_t apc_spare0; 796140751Swpaul void *apc_thread; 797140751Swpaul list_entry apc_list; 798140751Swpaul void *apc_kernfunc; 799140751Swpaul void *apc_rundownfunc; 800140751Swpaul void *apc_normalfunc; 801140751Swpaul void *apc_normctx; 802140751Swpaul void *apc_sysarg1; 803140751Swpaul void *apc_sysarg2; 804140751Swpaul uint8_t apc_stateidx; 805140751Swpaul uint8_t apc_cpumode; 806140751Swpaul uint8_t apc_inserted; 807140751Swpaul}; 808140751Swpaul 809140751Swpaultypedef struct kapc kapc; 810140751Swpaul 811144888Swpaultypedef uint32_t (*completion_func)(device_object *, 812141524Swpaul struct irp *, void *); 813144888Swpaultypedef uint32_t (*cancel_func)(device_object *, 814142311Swpaul struct irp *); 815141524Swpaul 816140751Swpaulstruct io_stack_location { 817140751Swpaul uint8_t isl_major; 818140751Swpaul uint8_t isl_minor; 819140751Swpaul uint8_t isl_flags; 820140751Swpaul uint8_t isl_ctl; 821140751Swpaul 822140751Swpaul /* 823140751Swpaul * There's a big-ass union here in the actual Windows 824140751Swpaul * definition of the stucture, but it contains stuff 825140751Swpaul * that doesn't really apply to BSD, and defining it 826140751Swpaul * all properly would require duplicating over a dozen 827140751Swpaul * other structures that we'll never use. Since the 828140751Swpaul * io_stack_location structure is opaque to drivers 829140751Swpaul * anyway, I'm not going to bother with the extra crap. 830140751Swpaul */ 831140751Swpaul 832140751Swpaul union { 833140751Swpaul struct { 834142311Swpaul uint32_t isl_len; 835142311Swpaul uint32_t *isl_key; 836142311Swpaul uint64_t isl_byteoff; 837142311Swpaul } isl_read; 838142311Swpaul struct { 839142311Swpaul uint32_t isl_len; 840142311Swpaul uint32_t *isl_key; 841142311Swpaul uint64_t isl_byteoff; 842142311Swpaul } isl_write; 843142311Swpaul struct { 844142311Swpaul uint32_t isl_obuflen; 845142311Swpaul uint32_t isl_ibuflen; 846142311Swpaul uint32_t isl_iocode; 847142311Swpaul void *isl_type3ibuf; 848142311Swpaul } isl_ioctl; 849142311Swpaul struct { 850140751Swpaul void *isl_arg1; 851140751Swpaul void *isl_arg2; 852140751Swpaul void *isl_arg3; 853140751Swpaul void *isl_arg4; 854140751Swpaul } isl_others; 855142311Swpaul } isl_parameters __attribute__((packed)); 856140751Swpaul 857140751Swpaul void *isl_devobj; 858140751Swpaul void *isl_fileobj; 859141524Swpaul completion_func isl_completionfunc; 860140751Swpaul void *isl_completionctx; 861140751Swpaul}; 862140751Swpaul 863140751Swpaultypedef struct io_stack_location io_stack_location; 864140751Swpaul 865140751Swpaul/* Stack location control flags */ 866140751Swpaul 867140751Swpaul#define SL_PENDING_RETURNED 0x01 868140751Swpaul#define SL_INVOKE_ON_CANCEL 0x20 869140751Swpaul#define SL_INVOKE_ON_SUCCESS 0x40 870140751Swpaul#define SL_INVOKE_ON_ERROR 0x80 871140751Swpaul 872125551Swpaulstruct irp { 873140751Swpaul uint16_t irp_type; 874140751Swpaul uint16_t irp_size; 875140751Swpaul mdl *irp_mdl; 876140751Swpaul uint32_t irp_flags; 877140751Swpaul union { 878140751Swpaul struct irp *irp_master; 879140751Swpaul uint32_t irp_irpcnt; 880140751Swpaul void *irp_sysbuf; 881140751Swpaul } irp_assoc; 882140751Swpaul list_entry irp_thlist; 883140751Swpaul io_status_block irp_iostat; 884140751Swpaul uint8_t irp_reqmode; 885140751Swpaul uint8_t irp_pendingreturned; 886140751Swpaul uint8_t irp_stackcnt; 887140751Swpaul uint8_t irp_currentstackloc; 888140751Swpaul uint8_t irp_cancel; 889140751Swpaul uint8_t irp_cancelirql; 890140751Swpaul uint8_t irp_apcenv; 891140751Swpaul uint8_t irp_allocflags; 892140751Swpaul io_status_block *irp_usriostat; 893141524Swpaul nt_kevent *irp_usrevent; 894140751Swpaul union { 895140751Swpaul struct { 896140751Swpaul void *irp_apcfunc; 897140751Swpaul void *irp_apcctx; 898140751Swpaul } irp_asyncparms; 899140751Swpaul uint64_t irp_allocsz; 900140751Swpaul } irp_overlay; 901142311Swpaul cancel_func irp_cancelfunc; 902140751Swpaul void *irp_userbuf; 903140751Swpaul 904140751Swpaul /* Windows kernel info */ 905140751Swpaul 906140751Swpaul union { 907140751Swpaul struct { 908140751Swpaul union { 909140751Swpaul kdevice_qentry irp_dqe; 910140751Swpaul struct { 911140751Swpaul void *irp_drvctx[4]; 912140751Swpaul } s1; 913140751Swpaul } u1; 914140751Swpaul void *irp_thread; 915140751Swpaul char *irp_auxbuf; 916140751Swpaul struct { 917140751Swpaul list_entry irp_list; 918140751Swpaul union { 919140751Swpaul io_stack_location *irp_csl; 920140751Swpaul uint32_t irp_pkttype; 921140751Swpaul } u2; 922140751Swpaul } s2; 923140751Swpaul void *irp_fileobj; 924140751Swpaul } irp_overlay; 925140751Swpaul kapc irp_apc; 926140751Swpaul void *irp_compkey; 927140751Swpaul } irp_tail; 928125551Swpaul}; 929125551Swpaul 930140751Swpaul#define irp_csl s2.u2.irp_csl 931140751Swpaul#define irp_pkttype s2.u2.irp_pkttype 932140751Swpaul 933125551Swpaultypedef struct irp irp; 934125551Swpaul 935142311Swpaul#define InterlockedExchangePointer(dst, val) \ 936144888Swpaul (void *)InterlockedExchange((uint32_t *)(dst), (uintptr_t)(val)) 937142311Swpaul 938141524Swpaul#define IoSizeOfIrp(ssize) \ 939141524Swpaul ((uint16_t) (sizeof(irp) + ((ssize) * (sizeof(io_stack_location))))) 940141524Swpaul 941142311Swpaul#define IoSetCancelRoutine(irp, func) \ 942142311Swpaul (cancel_func)InterlockedExchangePointer( \ 943142311Swpaul (void *)&(ip)->irp_cancelfunc, (void *)(func)) 944141524Swpaul 945140751Swpaul#define IoGetCurrentIrpStackLocation(irp) \ 946140751Swpaul (irp)->irp_tail.irp_overlay.irp_csl 947140751Swpaul 948140751Swpaul#define IoGetNextIrpStackLocation(irp) \ 949140751Swpaul ((irp)->irp_tail.irp_overlay.irp_csl - 1) 950140751Swpaul 951141524Swpaul#define IoSetNextIrpStackLocation(irp) \ 952141524Swpaul do { \ 953141524Swpaul irp->irp_currentstackloc--; \ 954141524Swpaul irp->irp_tail.irp_overlay.irp_csl--; \ 955141524Swpaul } while(0) 956141524Swpaul 957140751Swpaul#define IoSetCompletionRoutine(irp, func, ctx, ok, err, cancel) \ 958140751Swpaul do { \ 959140751Swpaul io_stack_location *s; \ 960140751Swpaul s = IoGetNextIrpStackLocation((irp)); \ 961140751Swpaul s->isl_completionfunc = (func); \ 962140751Swpaul s->isl_completionctx = (ctx); \ 963140751Swpaul s->isl_ctl = 0; \ 964141524Swpaul if (ok) s->isl_ctl = SL_INVOKE_ON_SUCCESS; \ 965141524Swpaul if (err) s->isl_ctl |= SL_INVOKE_ON_ERROR; \ 966141524Swpaul if (cancel) s->isl_ctl |= SL_INVOKE_ON_CANCEL; \ 967140751Swpaul } while(0) 968140751Swpaul 969140751Swpaul#define IoMarkIrpPending(irp) \ 970140751Swpaul IoGetCurrentIrpStackLocation(irp)->isl_ctl |= SL_PENDING_RETURNED 971140751Swpaul 972140751Swpaul#define IoCopyCurrentIrpStackLocationToNext(irp) \ 973140751Swpaul do { \ 974140751Swpaul io_stack_location *src, *dst; \ 975140751Swpaul src = IoGetCurrentIrpStackLocation(irp); \ 976140751Swpaul dst = IoGetNextIrpStackLocation(irp); \ 977140751Swpaul bcopy((char *)src, (char *)dst, \ 978140751Swpaul offsetof(io_stack_location, isl_completionfunc)); \ 979140751Swpaul } while(0) 980140751Swpaul 981140751Swpaul#define IoSkipCurrentIrpStackLocation(irp) \ 982140751Swpaul do { \ 983140751Swpaul (irp)->irp_currentstackloc++; \ 984140751Swpaul (irp)->irp_tail.irp_overlay.irp_csl++; \ 985140751Swpaul } while(0) 986140751Swpaul 987144175Swpaul#define IoInitializeDpcRequest(dobj, dpcfunc) \ 988144175Swpaul KeInitializeDpc(&(dobj)->do_dpc, dpcfunc, dobj) 989144175Swpaul 990144175Swpaul#define IoRequestDpc(dobj, irp, ctx) \ 991144175Swpaul KeInsertQueueDpc(&(dobj)->do_dpc, irp, ctx) 992144175Swpaul 993144888Swpaultypedef uint32_t (*driver_dispatch)(device_object *, irp *); 994125551Swpaul 995140751Swpaul/* 996140751Swpaul * The driver_object is allocated once for each driver that's loaded 997140751Swpaul * into the system. A new one is allocated for each driver and 998140751Swpaul * populated a bit via the driver's DriverEntry function. 999140751Swpaul * In general, a Windows DriverEntry() function will provide a pointer 1000140751Swpaul * to its AddDevice() method and set up the dispatch table. 1001140751Swpaul * For NDIS drivers, this is all done behind the scenes in the 1002140751Swpaul * NdisInitializeWrapper() and/or NdisMRegisterMiniport() routines. 1003140751Swpaul */ 1004140751Swpaul 1005140751Swpaulstruct driver_object { 1006140751Swpaul uint16_t dro_type; 1007140751Swpaul uint16_t dro_size; 1008140751Swpaul device_object *dro_devobj; 1009140751Swpaul uint32_t dro_flags; 1010140751Swpaul void *dro_driverstart; 1011140751Swpaul uint32_t dro_driversize; 1012140751Swpaul void *dro_driversection; 1013141524Swpaul driver_extension *dro_driverext; 1014140751Swpaul unicode_string dro_drivername; 1015140751Swpaul unicode_string *dro_hwdb; 1016140751Swpaul void *dro_pfastiodispatch; 1017140751Swpaul void *dro_driverinitfunc; 1018140751Swpaul void *dro_driverstartiofunc; 1019140751Swpaul void *dro_driverunloadfunc; 1020141524Swpaul driver_dispatch dro_dispatch[IRP_MJ_MAXIMUM_FUNCTION + 1]; 1021140751Swpaul}; 1022140751Swpaul 1023140751Swpaultypedef struct driver_object driver_object; 1024140751Swpaul 1025125551Swpaul#define DEVPROP_DEVICE_DESCRIPTION 0x00000000 1026125551Swpaul#define DEVPROP_HARDWARE_ID 0x00000001 1027125551Swpaul#define DEVPROP_COMPATIBLE_IDS 0x00000002 1028125551Swpaul#define DEVPROP_BOOTCONF 0x00000003 1029125551Swpaul#define DEVPROP_BOOTCONF_TRANSLATED 0x00000004 1030125551Swpaul#define DEVPROP_CLASS_NAME 0x00000005 1031125551Swpaul#define DEVPROP_CLASS_GUID 0x00000006 1032125551Swpaul#define DEVPROP_DRIVER_KEYNAME 0x00000007 1033125551Swpaul#define DEVPROP_MANUFACTURER 0x00000008 1034125551Swpaul#define DEVPROP_FRIENDLYNAME 0x00000009 1035125551Swpaul#define DEVPROP_LOCATION_INFO 0x0000000A 1036125551Swpaul#define DEVPROP_PHYSDEV_NAME 0x0000000B 1037125551Swpaul#define DEVPROP_BUSTYPE_GUID 0x0000000C 1038125551Swpaul#define DEVPROP_LEGACY_BUSTYPE 0x0000000D 1039125551Swpaul#define DEVPROP_BUS_NUMBER 0x0000000E 1040125551Swpaul#define DEVPROP_ENUMERATOR_NAME 0x0000000F 1041125551Swpaul#define DEVPROP_ADDRESS 0x00000010 1042125551Swpaul#define DEVPROP_UINUMBER 0x00000011 1043125551Swpaul#define DEVPROP_INSTALL_STATE 0x00000012 1044125551Swpaul#define DEVPROP_REMOVAL_POLICY 0x00000013 1045125551Swpaul 1046141524Swpaul/* Various supported device types (used with IoCreateDevice()) */ 1047141524Swpaul 1048141524Swpaul#define FILE_DEVICE_BEEP 0x00000001 1049141524Swpaul#define FILE_DEVICE_CD_ROM 0x00000002 1050141524Swpaul#define FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003 1051141524Swpaul#define FILE_DEVICE_CONTROLLER 0x00000004 1052141524Swpaul#define FILE_DEVICE_DATALINK 0x00000005 1053141524Swpaul#define FILE_DEVICE_DFS 0x00000006 1054141524Swpaul#define FILE_DEVICE_DISK 0x00000007 1055141524Swpaul#define FILE_DEVICE_DISK_FILE_SYSTEM 0x00000008 1056141524Swpaul#define FILE_DEVICE_FILE_SYSTEM 0x00000009 1057141524Swpaul#define FILE_DEVICE_INPORT_PORT 0x0000000A 1058141524Swpaul#define FILE_DEVICE_KEYBOARD 0x0000000B 1059141524Swpaul#define FILE_DEVICE_MAILSLOT 0x0000000C 1060141524Swpaul#define FILE_DEVICE_MIDI_IN 0x0000000D 1061141524Swpaul#define FILE_DEVICE_MIDI_OUT 0x0000000E 1062141524Swpaul#define FILE_DEVICE_MOUSE 0x0000000F 1063141524Swpaul#define FILE_DEVICE_MULTI_UNC_PROVIDER 0x00000010 1064141524Swpaul#define FILE_DEVICE_NAMED_PIPE 0x00000011 1065141524Swpaul#define FILE_DEVICE_NETWORK 0x00000012 1066141524Swpaul#define FILE_DEVICE_NETWORK_BROWSER 0x00000013 1067141524Swpaul#define FILE_DEVICE_NETWORK_FILE_SYSTEM 0x00000014 1068141524Swpaul#define FILE_DEVICE_NULL 0x00000015 1069141524Swpaul#define FILE_DEVICE_PARALLEL_PORT 0x00000016 1070141524Swpaul#define FILE_DEVICE_PHYSICAL_NETCARD 0x00000017 1071141524Swpaul#define FILE_DEVICE_PRINTER 0x00000018 1072141524Swpaul#define FILE_DEVICE_SCANNER 0x00000019 1073141524Swpaul#define FILE_DEVICE_SERIAL_MOUSE_PORT 0x0000001A 1074141524Swpaul#define FILE_DEVICE_SERIAL_PORT 0x0000001B 1075141524Swpaul#define FILE_DEVICE_SCREEN 0x0000001C 1076141524Swpaul#define FILE_DEVICE_SOUND 0x0000001D 1077141524Swpaul#define FILE_DEVICE_STREAMS 0x0000001E 1078141524Swpaul#define FILE_DEVICE_TAPE 0x0000001F 1079141524Swpaul#define FILE_DEVICE_TAPE_FILE_SYSTEM 0x00000020 1080141524Swpaul#define FILE_DEVICE_TRANSPORT 0x00000021 1081141524Swpaul#define FILE_DEVICE_UNKNOWN 0x00000022 1082141524Swpaul#define FILE_DEVICE_VIDEO 0x00000023 1083141524Swpaul#define FILE_DEVICE_VIRTUAL_DISK 0x00000024 1084141524Swpaul#define FILE_DEVICE_WAVE_IN 0x00000025 1085141524Swpaul#define FILE_DEVICE_WAVE_OUT 0x00000026 1086141524Swpaul#define FILE_DEVICE_8042_PORT 0x00000027 1087141524Swpaul#define FILE_DEVICE_NETWORK_REDIRECTOR 0x00000028 1088141524Swpaul#define FILE_DEVICE_BATTERY 0x00000029 1089141524Swpaul#define FILE_DEVICE_BUS_EXTENDER 0x0000002A 1090141524Swpaul#define FILE_DEVICE_MODEM 0x0000002B 1091141524Swpaul#define FILE_DEVICE_VDM 0x0000002C 1092141524Swpaul#define FILE_DEVICE_MASS_STORAGE 0x0000002D 1093141524Swpaul#define FILE_DEVICE_SMB 0x0000002E 1094141524Swpaul#define FILE_DEVICE_KS 0x0000002F 1095141524Swpaul#define FILE_DEVICE_CHANGER 0x00000030 1096141524Swpaul#define FILE_DEVICE_SMARTCARD 0x00000031 1097141524Swpaul#define FILE_DEVICE_ACPI 0x00000032 1098141524Swpaul#define FILE_DEVICE_DVD 0x00000033 1099141524Swpaul#define FILE_DEVICE_FULLSCREEN_VIDEO 0x00000034 1100141524Swpaul#define FILE_DEVICE_DFS_FILE_SYSTEM 0x00000035 1101141524Swpaul#define FILE_DEVICE_DFS_VOLUME 0x00000036 1102141524Swpaul#define FILE_DEVICE_SERENUM 0x00000037 1103141524Swpaul#define FILE_DEVICE_TERMSRV 0x00000038 1104141524Swpaul#define FILE_DEVICE_KSEC 0x00000039 1105141524Swpaul#define FILE_DEVICE_FIPS 0x0000003A 1106141524Swpaul 1107141524Swpaul/* Device characteristics */ 1108141524Swpaul 1109141524Swpaul#define FILE_REMOVABLE_MEDIA 0x00000001 1110141524Swpaul#define FILE_READ_ONLY_DEVICE 0x00000002 1111141524Swpaul#define FILE_FLOPPY_DISKETTE 0x00000004 1112141524Swpaul#define FILE_WRITE_ONCE_MEDIA 0x00000008 1113141524Swpaul#define FILE_REMOTE_DEVICE 0x00000010 1114141524Swpaul#define FILE_DEVICE_IS_MOUNTED 0x00000020 1115141524Swpaul#define FILE_VIRTUAL_VOLUME 0x00000040 1116141524Swpaul#define FILE_AUTOGENERATED_DEVICE_NAME 0x00000080 1117141524Swpaul#define FILE_DEVICE_SECURE_OPEN 0x00000100 1118141524Swpaul 1119141524Swpaul/* Status codes */ 1120141524Swpaul 1121125551Swpaul#define STATUS_SUCCESS 0x00000000 1122125551Swpaul#define STATUS_USER_APC 0x000000C0 1123125551Swpaul#define STATUS_KERNEL_APC 0x00000100 1124125551Swpaul#define STATUS_ALERTED 0x00000101 1125125551Swpaul#define STATUS_TIMEOUT 0x00000102 1126142443Swpaul#define STATUS_PENDING 0x00000103 1127125551Swpaul#define STATUS_INVALID_PARAMETER 0xC000000D 1128125551Swpaul#define STATUS_INVALID_DEVICE_REQUEST 0xC0000010 1129141524Swpaul#define STATUS_MORE_PROCESSING_REQUIRED 0xC0000016 1130125551Swpaul#define STATUS_BUFFER_TOO_SMALL 0xC0000023 1131125551Swpaul#define STATUS_MUTANT_NOT_OWNED 0xC0000046 1132125551Swpaul#define STATUS_INVALID_PARAMETER_2 0xC00000F0 1133141524Swpaul#define STATUS_INSUFFICIENT_RESOURCES 0xC000009A 1134125551Swpaul 1135125551Swpaul#define STATUS_WAIT_0 0x00000000 1136125551Swpaul 1137141524Swpaul/* Memory pool types, for ExAllocatePoolWithTag() */ 1138141524Swpaul 1139141524Swpaul#define NonPagedPool 0x00000000 1140141524Swpaul#define PagedPool 0x00000001 1141141524Swpaul#define NonPagedPoolMustSucceed 0x00000002 1142141524Swpaul#define DontUseThisType 0x00000003 1143141524Swpaul#define NonPagedPoolCacheAligned 0x00000004 1144141524Swpaul#define PagedPoolCacheAligned 0x00000005 1145141524Swpaul#define NonPagedPoolCacheAlignedMustS 0x00000006 1146141524Swpaul#define MaxPoolType 0x00000007 1147141524Swpaul 1148127284Swpaul/* 1149127284Swpaul * FreeBSD's kernel stack is 2 pages in size by default. The 1150127284Swpaul * Windows stack is larger, so we need to give our threads more 1151127284Swpaul * stack pages. 4 should be enough, we use 8 just to extra safe. 1152127284Swpaul */ 1153127284Swpaul#define NDIS_KSTACK_PAGES 8 1154127284Swpaul 1155144888Swpaul/* 1156144888Swpaul * Different kinds of function wrapping we can do. 1157144888Swpaul */ 1158144888Swpaul 1159144888Swpaul#define WINDRV_WRAP_STDCALL 1 1160144888Swpaul#define WINDRV_WRAP_FASTCALL 2 1161144888Swpaul#define WINDRV_WRAP_REGPARM 3 1162144888Swpaul#define WINDRV_WRAP_CDECL 4 1163144888Swpaul#define WINDRV_WRAP_AMD64 5 1164144888Swpaul 1165145485Swpaulstruct drvdb_ent { 1166145485Swpaul driver_object *windrv_object; 1167145485Swpaul void *windrv_devlist; 1168145485Swpaul ndis_cfg *windrv_regvals; 1169145485Swpaul interface_type windrv_bustype; 1170145485Swpaul STAILQ_ENTRY(drvdb_ent) link; 1171145485Swpaul}; 1172145485Swpaul 1173123474Swpaulextern image_patch_table ntoskrnl_functbl[]; 1174141963Swpaultypedef void (*funcptr)(void); 1175145485Swpaultypedef int (*matchfuncptr)(void *, void *); 1176123474Swpaul 1177123474Swpaul__BEGIN_DECLS 1178141524Swpaulextern int windrv_libinit(void); 1179141524Swpaulextern int windrv_libfini(void); 1180142399Swpaulextern driver_object *windrv_lookup(vm_offset_t, char *); 1181145485Swpaulextern struct drvdb_ent *windrv_match(matchfuncptr, void *); 1182145485Swpaulextern int windrv_load(module_t, vm_offset_t, int, interface_type, 1183145485Swpaul void *, ndis_cfg *); 1184141524Swpaulextern int windrv_unload(module_t, vm_offset_t, int); 1185141524Swpaulextern int windrv_create_pdo(driver_object *, device_t); 1186141524Swpaulextern void windrv_destroy_pdo(driver_object *, device_t); 1187141524Swpaulextern device_object *windrv_find_pdo(driver_object *, device_t); 1188141524Swpaulextern int windrv_bus_attach(driver_object *, char *); 1189144888Swpaulextern int windrv_wrap(funcptr, funcptr *, int, int); 1190141963Swpaulextern int windrv_unwrap(funcptr); 1191144888Swpaulextern void ctxsw_utow(void); 1192144888Swpaulextern void ctxsw_wtou(void); 1193141524Swpaul 1194123474Swpaulextern int ntoskrnl_libinit(void); 1195123474Swpaulextern int ntoskrnl_libfini(void); 1196144888Swpaulextern void KeInitializeDpc(kdpc *, void *, void *); 1197144888Swpaulextern uint8_t KeInsertQueueDpc(kdpc *, void *, void *); 1198144888Swpaulextern uint8_t KeRemoveQueueDpc(kdpc *); 1199144888Swpaulextern void KeInitializeTimer(ktimer *); 1200144888Swpaulextern void KeInitializeTimerEx(ktimer *, uint32_t); 1201144888Swpaulextern uint8_t KeSetTimer(ktimer *, int64_t, kdpc *); 1202144888Swpaulextern uint8_t KeSetTimerEx(ktimer *, int64_t, uint32_t, kdpc *); 1203144888Swpaulextern uint8_t KeCancelTimer(ktimer *); 1204144888Swpaulextern uint8_t KeReadStateTimer(ktimer *); 1205144888Swpaulextern uint32_t KeWaitForSingleObject(nt_dispatch_header *, uint32_t, 1206127248Swpaul uint32_t, uint8_t, int64_t *); 1207144888Swpaulextern void KeInitializeEvent(nt_kevent *, uint32_t, uint8_t); 1208144888Swpaulextern void KeClearEvent(nt_kevent *); 1209144888Swpaulextern uint32_t KeReadStateEvent(nt_kevent *); 1210144888Swpaulextern uint32_t KeSetEvent(nt_kevent *, uint32_t, uint8_t); 1211144888Swpaulextern uint32_t KeResetEvent(nt_kevent *); 1212144175Swpaul#ifdef __i386__ 1213144888Swpaulextern void KefAcquireSpinLockAtDpcLevel(kspin_lock *); 1214144888Swpaulextern void KefReleaseSpinLockFromDpcLevel(kspin_lock *); 1215144888Swpaulextern uint8_t KeAcquireSpinLockRaiseToDpc(kspin_lock *); 1216144175Swpaul#else 1217144888Swpaulextern void KeAcquireSpinLockAtDpcLevel(kspin_lock *); 1218144888Swpaulextern void KeReleaseSpinLockFromDpcLevel(kspin_lock *); 1219144175Swpaul#endif 1220144888Swpaulextern void KeInitializeSpinLock(kspin_lock *); 1221144888Swpaulextern uintptr_t InterlockedExchange(volatile uint32_t *, 1222144888Swpaul uintptr_t); 1223144888Swpaulextern void *ExAllocatePoolWithTag(uint32_t, size_t, uint32_t); 1224144888Swpaulextern void ExFreePool(void *); 1225144888Swpaulextern uint32_t IoAllocateDriverObjectExtension(driver_object *, 1226141524Swpaul void *, uint32_t, void **); 1227144888Swpaulextern void *IoGetDriverObjectExtension(driver_object *, void *); 1228144888Swpaulextern uint32_t IoCreateDevice(driver_object *, uint32_t, 1229141524Swpaul unicode_string *, uint32_t, uint32_t, uint8_t, device_object **); 1230144888Swpaulextern void IoDeleteDevice(device_object *); 1231144888Swpaulextern device_object *IoGetAttachedDevice(device_object *); 1232144888Swpaulextern uint32_t IofCallDriver(device_object *, irp *); 1233144888Swpaulextern void IofCompleteRequest(irp *, uint8_t); 1234144888Swpaulextern void IoAcquireCancelSpinLock(uint8_t *); 1235144888Swpaulextern void IoReleaseCancelSpinLock(uint8_t); 1236144888Swpaulextern uint8_t IoCancelIrp(irp *); 1237144888Swpaulextern void IoDetachDevice(device_object *); 1238144888Swpaulextern device_object *IoAttachDeviceToDeviceStack(device_object *, 1239141524Swpaul device_object *); 1240144888Swpaulmdl *IoAllocateMdl(void *, uint32_t, uint8_t, uint8_t, irp *); 1241144888Swpaulvoid IoFreeMdl(mdl *); 1242128229Swpaul 1243144888Swpaul#define IoCallDriver(a, b) IofCallDriver(a, b) 1244144888Swpaul#define IoCompleteRequest(a, b) IofCompleteRequest(a, b) 1245140751Swpaul 1246128229Swpaul/* 1247128229Swpaul * On the Windows x86 arch, KeAcquireSpinLock() and KeReleaseSpinLock() 1248128229Swpaul * routines live in the HAL. We try to imitate this behavior. 1249128229Swpaul */ 1250128229Swpaul#ifdef __i386__ 1251144888Swpaul#define KeAcquireSpinLock(a, b) *(b) = KfAcquireSpinLock(a) 1252144888Swpaul#define KeReleaseSpinLock(a, b) KfReleaseSpinLock(a, b) 1253144888Swpaul#define KeRaiseIrql(a) KfRaiseIrql(a) 1254144888Swpaul#define KeLowerIrql(a) KfLowerIrql(a) 1255144888Swpaul#define KeAcquireSpinLockAtDpcLevel(a) KefAcquireSpinLockAtDpcLevel(a) 1256144888Swpaul#define KeReleaseSpinLockFromDpcLevel(a) KefReleaseSpinLockFromDpcLevel(a) 1257128229Swpaul#endif /* __i386__ */ 1258141963Swpaul 1259141963Swpaul#ifdef __amd64__ 1260141980Swpaul#define KeAcquireSpinLock(a, b) *(b) = KfAcquireSpinLock(a) 1261141980Swpaul#define KeReleaseSpinLock(a, b) KfReleaseSpinLock(a, b) 1262141963Swpaul 1263141963Swpaul/* 1264141963Swpaul * These may need to be redefined later; 1265141963Swpaul * not sure where they live on amd64 yet. 1266141963Swpaul */ 1267141963Swpaul#define KeRaiseIrql(a) KfRaiseIrql(a) 1268141963Swpaul#define KeLowerIrql(a) KfLowerIrql(a) 1269141963Swpaul#endif /* __amd64__ */ 1270141963Swpaul 1271123474Swpaul__END_DECLS 1272123474Swpaul 1273123474Swpaul#endif /* _NTOSKRNL_VAR_H_ */ 1274