ntoskrnl_var.h revision 141524
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 141524 2005-02-08 17:23:25Z 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 103140751Swpaul 104123512Swpaul/* Note: assumes x86 page size of 4K. */ 105140751Swpaul 106140751Swpaul#if PAGE_SIZE == 4096 107123512Swpaul#define PAGE_SHIFT 12 108140751Swpaul#elif PAGE_SIZE == 8192 109140751Swpaul#define PAGE_SHIFT 13 110140751Swpaul#else 111140751Swpaul#error PAGE_SHIFT undefined! 112140751Swpaul#endif 113140751Swpaul 114123512Swpaul#define SPAN_PAGES(ptr, len) \ 115140751Swpaul ((uint32_t)((((uintptr_t)(ptr) & (PAGE_SIZE - 1)) + \ 116123512Swpaul (len) + (PAGE_SIZE - 1)) >> PAGE_SHIFT)) 117140751Swpaul 118123757Swpaul#define PAGE_ALIGN(ptr) \ 119123757Swpaul ((void *)((uintptr_t)(ptr) & ~(PAGE_SIZE - 1))) 120140751Swpaul 121123757Swpaul#define BYTE_OFFSET(ptr) \ 122123757Swpaul ((uint32_t)((uintptr_t)(ptr) & (PAGE_SIZE - 1))) 123140751Swpaul 124140751Swpaul#define MDL_PAGES(m) (vm_offset_t *)(m + 1) 125140751Swpaul 126140751Swpaul#define MmInitializeMdl(b, baseva, len) \ 127140751Swpaul (b)->mdl_next = NULL; \ 128140751Swpaul (b)->mdl_size = (uint16_t)(sizeof(mdl) + \ 129123757Swpaul (sizeof(uint32_t) * SPAN_PAGES((baseva), (len)))); \ 130140751Swpaul (b)->mdl_flags = 0; \ 131140751Swpaul (b)->mdl_startva = (void *)PAGE_ALIGN((baseva)); \ 132140751Swpaul (b)->mdl_byteoffset = BYTE_OFFSET((baseva)); \ 133140751Swpaul (b)->mdl_bytecount = (uint32_t)(len); 134123512Swpaul 135140751Swpaul#define MmGetMdlByteOffset(mdl) ((mdl)->mdl_byteoffset) 136140751Swpaul#define MmGetMdlByteCount(mdl) ((mdl)->mdl_bytecount) 137140751Swpaul#define MmGetMdlVirtualAddress(mdl) \ 138140751Swpaul ((void *)((char *)((mdl)->mdl_startva) + (mdl)->mdl_byteoffset)) 139140751Swpaul#define MmGetMdlStartVa(mdl) ((mdl)->mdl_startva) 140140751Swpaul#define MmGetMdlPfnArray(mdl) MDL_PAGES(mdl) 141140751Swpaul 142124729Swpaul#define WDM_MAJOR 1 143124729Swpaul#define WDM_MINOR_WIN98 0x00 144124729Swpaul#define WDM_MINOR_WINME 0x05 145124729Swpaul#define WDM_MINOR_WIN2000 0x10 146124729Swpaul#define WDM_MINOR_WINXP 0x20 147124729Swpaul#define WDM_MINOR_WIN2003 0x30 148124729Swpaul 149124582Sobrien/*- 150124582Sobrien * The ndis_kspin_lock type is called KSPIN_LOCK in MS-Windows. 151124582Sobrien * According to the Windows DDK header files, KSPIN_LOCK is defined like this: 152124582Sobrien * typedef ULONG_PTR KSPIN_LOCK; 153124582Sobrien * 154124582Sobrien * From basetsd.h (SDK, Feb. 2003): 155124582Sobrien * typedef [public] unsigned __int3264 ULONG_PTR, *PULONG_PTR; 156124582Sobrien * typedef unsigned __int64 ULONG_PTR, *PULONG_PTR; 157124582Sobrien * typedef _W64 unsigned long ULONG_PTR, *PULONG_PTR; 158124582Sobrien * 159124582Sobrien * The keyword __int3264 specifies an integral type that has the following 160124582Sobrien * properties: 161124582Sobrien * + It is 32-bit on 32-bit platforms 162124582Sobrien * + It is 64-bit on 64-bit platforms 163124582Sobrien * + It is 32-bit on the wire for backward compatibility. 164124582Sobrien * It gets truncated on the sending side and extended appropriately 165124582Sobrien * (signed or unsigned) on the receiving side. 166124582Sobrien * 167124582Sobrien * Thus register_t seems the proper mapping onto FreeBSD for spin locks. 168124582Sobrien */ 169123474Swpaul 170124582Sobrientypedef register_t kspin_lock; 171124582Sobrien 172123474Swpaulstruct slist_entry { 173123474Swpaul struct slist_entry *sl_next; 174123474Swpaul}; 175123474Swpaul 176123474Swpaultypedef struct slist_entry slist_entry; 177123474Swpaul 178123474Swpaulunion slist_header { 179123474Swpaul uint64_t slh_align; 180123474Swpaul struct { 181123474Swpaul struct slist_entry *slh_next; 182123474Swpaul uint16_t slh_depth; 183123474Swpaul uint16_t slh_seq; 184123474Swpaul } slh_list; 185123474Swpaul}; 186123474Swpaul 187123474Swpaultypedef union slist_header slist_header; 188123474Swpaul 189123507Swpaulstruct list_entry { 190123507Swpaul struct list_entry *nle_flink; 191123507Swpaul struct list_entry *nle_blink; 192123507Swpaul}; 193123507Swpaul 194123507Swpaultypedef struct list_entry list_entry; 195123507Swpaul 196125551Swpaul#define INIT_LIST_HEAD(l) \ 197141524Swpaul (l)->nle_flink = (l)->nle_blink = (l) 198125551Swpaul 199125551Swpaul#define REMOVE_LIST_ENTRY(e) \ 200125551Swpaul do { \ 201125551Swpaul list_entry *b; \ 202125551Swpaul list_entry *f; \ 203125551Swpaul \ 204125551Swpaul f = e->nle_flink; \ 205125551Swpaul b = e->nle_blink; \ 206125551Swpaul b->nle_flink = f; \ 207125551Swpaul f->nle_blink = b; \ 208125551Swpaul } while (0) 209125551Swpaul 210125551Swpaul#define REMOVE_LIST_HEAD(l) \ 211125551Swpaul do { \ 212125551Swpaul list_entry *f; \ 213125551Swpaul list_entry *e; \ 214125551Swpaul \ 215125551Swpaul e = l->nle_flink; \ 216125551Swpaul f = e->nle_flink; \ 217125551Swpaul l->nle_flink = f; \ 218125551Swpaul f->nle_blink = l; \ 219125551Swpaul } while (0) 220125551Swpaul 221125551Swpaul#define REMOVE_LIST_TAIL(l) \ 222125551Swpaul do { \ 223125551Swpaul list_entry *b; \ 224125551Swpaul list_entry *e; \ 225125551Swpaul \ 226125551Swpaul e = l->nle_blink; \ 227125551Swpaul b = e->nle_blink; \ 228125551Swpaul l->nle_blink = b; \ 229125551Swpaul b->nle_flink = l; \ 230125551Swpaul } while (0) 231125551Swpaul 232125551Swpaul#define INSERT_LIST_TAIL(l, e) \ 233125551Swpaul do { \ 234125551Swpaul list_entry *b; \ 235125551Swpaul \ 236125551Swpaul b = l->nle_blink; \ 237125860Swpaul e->nle_flink = l; \ 238125551Swpaul e->nle_blink = b; \ 239141524Swpaul b->nle_flink = (e); \ 240141524Swpaul l->nle_blink = (e); \ 241125551Swpaul } while (0) 242125551Swpaul 243125551Swpaul#define INSERT_LIST_HEAD(l, e) \ 244125551Swpaul do { \ 245125551Swpaul list_entry *f; \ 246125551Swpaul \ 247125551Swpaul f = l->nle_flink; \ 248125551Swpaul e->nle_flink = f; \ 249125551Swpaul e->nle_blink = l; \ 250125551Swpaul f->nle_blink = e; \ 251125551Swpaul l->nle_flink = e; \ 252125551Swpaul } while (0) 253125551Swpaul 254125551Swpaulstruct nt_dispatch_header { 255125551Swpaul uint8_t dh_type; 256125551Swpaul uint8_t dh_abs; 257125551Swpaul uint8_t dh_size; 258125551Swpaul uint8_t dh_inserted; 259125551Swpaul uint32_t dh_sigstate; 260125551Swpaul list_entry dh_waitlisthead; 261125551Swpaul}; 262125551Swpaul 263125551Swpaultypedef struct nt_dispatch_header nt_dispatch_header; 264125551Swpaul 265125551Swpaul#define OTYPE_EVENT 0 266125551Swpaul#define OTYPE_MUTEX 1 267125551Swpaul#define OTYPE_THREAD 2 268125551Swpaul#define OTYPE_TIMER 3 269125551Swpaul 270125551Swpaul/* Windows dispatcher levels. */ 271125551Swpaul 272125551Swpaul#define PASSIVE_LEVEL 0 273125551Swpaul#define LOW_LEVEL 0 274125551Swpaul#define APC_LEVEL 1 275125551Swpaul#define DISPATCH_LEVEL 2 276128229Swpaul#define DEVICE_LEVEL (DISPATCH_LEVEL + 1) 277125551Swpaul#define PROFILE_LEVEL 27 278125551Swpaul#define CLOCK1_LEVEL 28 279125551Swpaul#define CLOCK2_LEVEL 28 280125551Swpaul#define IPI_LEVEL 29 281125551Swpaul#define POWER_LEVEL 30 282125551Swpaul#define HIGH_LEVEL 31 283125551Swpaul 284125551Swpaul#define SYNC_LEVEL_UP DISPATCH_LEVEL 285125551Swpaul#define SYNC_LEVEL_MP (IPI_LEVEL - 1) 286125551Swpaul 287128229Swpaul#define AT_PASSIVE_LEVEL(td) \ 288128229Swpaul ((td)->td_proc->p_flag & P_KTHREAD == FALSE) 289128229Swpaul 290128229Swpaul#define AT_DISPATCH_LEVEL(td) \ 291128449Swpaul ((td)->td_base_pri == PI_REALTIME) 292128229Swpaul 293128229Swpaul#define AT_DIRQL_LEVEL(td) \ 294128295Swpaul ((td)->td_priority <= PI_NET) 295128229Swpaul 296128229Swpaul#define AT_HIGH_LEVEL(td) \ 297128229Swpaul ((td)->td_critnest != 0) 298128229Swpaul 299125551Swpaulstruct nt_objref { 300125551Swpaul nt_dispatch_header no_dh; 301125551Swpaul void *no_obj; 302125551Swpaul TAILQ_ENTRY(nt_objref) link; 303125551Swpaul}; 304125551Swpaul 305125551SwpaulTAILQ_HEAD(nt_objref_head, nt_objref); 306125551Swpaul 307125551Swpaultypedef struct nt_objref nt_objref; 308125551Swpaul 309125551Swpaul#define EVENT_TYPE_NOTIFY 0 310125551Swpaul#define EVENT_TYPE_SYNC 1 311125551Swpaul 312126620Swpaul/* 313126620Swpaul * We need to use the timeout()/untimeout() API for ktimers 314126620Swpaul * since timers can be initialized, but not destroyed (so 315126620Swpaul * malloc()ing our own callout structures would mean a leak, 316126620Swpaul * since there'd be no way to free() them). This means we 317126620Swpaul * need to use struct callout_handle, which is really just a 318126620Swpaul * pointer. To make it easier to deal with, we use a union 319126620Swpaul * to overlay the callout_handle over the k_timerlistentry. 320126620Swpaul * The latter is a list_entry, which is two pointers, so 321126620Swpaul * there's enough space available to hide a callout_handle 322126620Swpaul * there. 323126620Swpaul */ 324126620Swpaul 325125551Swpaulstruct ktimer { 326125551Swpaul nt_dispatch_header k_header; 327125551Swpaul uint64_t k_duetime; 328126620Swpaul union { 329126620Swpaul list_entry k_timerlistentry; 330126620Swpaul struct callout_handle k_handle; 331126620Swpaul } u; 332125551Swpaul void *k_dpc; 333125551Swpaul uint32_t k_period; 334125551Swpaul}; 335125551Swpaul 336126620Swpaul#define k_timerlistentry u.k_timerlistentry 337126620Swpaul#define k_handle u.k_handle 338126620Swpaul 339126620Swpaultypedef struct ktimer ktimer; 340126620Swpaul 341125551Swpaulstruct nt_kevent { 342125551Swpaul nt_dispatch_header k_header; 343125551Swpaul}; 344125551Swpaul 345125551Swpaultypedef struct nt_kevent nt_kevent; 346125551Swpaul 347125551Swpaul/* Kernel defered procedure call (i.e. timer callback) */ 348125551Swpaul 349125551Swpaulstruct kdpc; 350125551Swpaultypedef void (*kdpc_func)(struct kdpc *, void *, void *, void *); 351125551Swpaul 352125551Swpaulstruct kdpc { 353125551Swpaul uint16_t k_type; 354125551Swpaul uint8_t k_num; 355125551Swpaul uint8_t k_importance; 356125551Swpaul list_entry k_dpclistentry; 357140827Swpaul void *k_deferedfunc; 358125551Swpaul void *k_deferredctx; 359125551Swpaul void *k_sysarg1; 360125551Swpaul void *k_sysarg2; 361127552Swpaul register_t k_lock; 362125551Swpaul}; 363125551Swpaul 364126620Swpaultypedef struct kdpc kdpc; 365126620Swpaul 366125551Swpaul/* 367125551Swpaul * Note: the acquisition count is BSD-specific. The Microsoft 368125551Swpaul * documentation says that mutexes can be acquired recursively 369125551Swpaul * by a given thread, but that you must release the mutex as 370125551Swpaul * many times as you acquired it before it will be set to the 371125551Swpaul * signalled state (i.e. before any other threads waiting on 372125551Swpaul * the object will be woken up). However the Windows KMUTANT 373125551Swpaul * structure has no field for keeping track of the number of 374125551Swpaul * acquisitions, so we need to add one ourselves. As long as 375125551Swpaul * driver code treats the mutex as opaque, we should be ok. 376125551Swpaul */ 377125551Swpaulstruct kmutant { 378125551Swpaul nt_dispatch_header km_header; 379126620Swpaul union { 380126620Swpaul list_entry km_listentry; 381126620Swpaul uint32_t km_acquirecnt; 382126620Swpaul } u; 383125551Swpaul void *km_ownerthread; 384125551Swpaul uint8_t km_abandoned; 385125551Swpaul uint8_t km_apcdisable; 386125551Swpaul}; 387125551Swpaul 388126620Swpaul#define km_listentry u.km_listentry 389126620Swpaul#define km_acquirecnt u.km_acquirecnt 390126620Swpaul 391125551Swpaultypedef struct kmutant kmutant; 392125551Swpaul 393125860Swpaul#define LOOKASIDE_DEPTH 256 394125860Swpaul 395123474Swpaulstruct general_lookaside { 396123474Swpaul slist_header gl_listhead; 397123474Swpaul uint16_t gl_depth; 398123474Swpaul uint16_t gl_maxdepth; 399123474Swpaul uint32_t gl_totallocs; 400123474Swpaul union { 401123474Swpaul uint32_t gl_allocmisses; 402123474Swpaul uint32_t gl_allochits; 403123474Swpaul } u_a; 404123474Swpaul uint32_t gl_totalfrees; 405123474Swpaul union { 406123474Swpaul uint32_t gl_freemisses; 407123474Swpaul uint32_t gl_freehits; 408123474Swpaul } u_m; 409123474Swpaul uint32_t gl_type; 410123474Swpaul uint32_t gl_tag; 411123474Swpaul uint32_t gl_size; 412123474Swpaul void *gl_allocfunc; 413123474Swpaul void *gl_freefunc; 414123507Swpaul list_entry gl_listent; 415123474Swpaul uint32_t gl_lasttotallocs; 416123474Swpaul union { 417123474Swpaul uint32_t gl_lastallocmisses; 418123474Swpaul uint32_t gl_lastallochits; 419123474Swpaul } u_l; 420123474Swpaul uint32_t gl_rsvd[2]; 421123474Swpaul}; 422123474Swpaul 423123474Swpaultypedef struct general_lookaside general_lookaside; 424123474Swpaul 425123474Swpaulstruct npaged_lookaside_list { 426123474Swpaul general_lookaside nll_l; 427123474Swpaul kspin_lock nll_obsoletelock; 428123474Swpaul}; 429123474Swpaul 430123474Swpaultypedef struct npaged_lookaside_list npaged_lookaside_list; 431123474Swpaultypedef struct npaged_lookaside_list paged_lookaside_list; 432123474Swpaul 433123474Swpaultypedef void * (*lookaside_alloc_func)(uint32_t, size_t, uint32_t); 434123474Swpaultypedef void (*lookaside_free_func)(void *); 435123474Swpaul 436125551Swpaulstruct irp; 437123474Swpaul 438125551Swpaulstruct kdevice_qentry { 439125551Swpaul list_entry kqe_devlistent; 440125551Swpaul uint32_t kqe_sortkey; 441125551Swpaul uint8_t kqe_inserted; 442125551Swpaul}; 443125551Swpaul 444125551Swpaultypedef struct kdevice_qentry kdevice_qentry; 445125551Swpaul 446125551Swpaulstruct kdevice_queue { 447125551Swpaul uint16_t kq_type; 448125551Swpaul uint16_t kq_size; 449125551Swpaul list_entry kq_devlisthead; 450125551Swpaul kspin_lock kq_lock; 451125551Swpaul uint8_t kq_busy; 452125551Swpaul}; 453125551Swpaul 454125551Swpaultypedef struct kdevice_queue kdevice_queue; 455125551Swpaul 456125551Swpaulstruct wait_ctx_block { 457125551Swpaul kdevice_qentry wcb_waitqueue; 458125551Swpaul void *wcb_devfunc; 459125551Swpaul void *wcb_devctx; 460125551Swpaul uint32_t wcb_mapregcnt; 461125551Swpaul void *wcb_devobj; 462125551Swpaul void *wcb_curirp; 463125551Swpaul void *wcb_bufchaindpc; 464125551Swpaul}; 465125551Swpaul 466125551Swpaultypedef struct wait_ctx_block wait_ctx_block; 467125551Swpaul 468125551Swpaulstruct wait_block { 469125551Swpaul list_entry wb_waitlist; 470125551Swpaul void *wb_kthread; 471125551Swpaul nt_dispatch_header *wb_object; 472125551Swpaul struct wait_block *wb_next; 473125551Swpaul uint16_t wb_waitkey; 474125551Swpaul uint16_t wb_waittype; 475125551Swpaul}; 476125551Swpaul 477125551Swpaultypedef struct wait_block wait_block; 478125551Swpaul 479125551Swpaul#define THREAD_WAIT_OBJECTS 3 480125551Swpaul#define MAX_WAIT_OBJECTS 64 481125551Swpaul 482125551Swpaul#define WAITTYPE_ALL 0 483125551Swpaul#define WAITTYPE_ANY 1 484125551Swpaul 485125551Swpaulstruct thread_context { 486125551Swpaul void *tc_thrctx; 487125551Swpaul void *tc_thrfunc; 488125551Swpaul}; 489125551Swpaul 490125551Swpaultypedef struct thread_context thread_context; 491125551Swpaul 492140751Swpaul/* Forward declaration */ 493140751Swpaulstruct driver_object; 494140751Swpaulstruct devobj_extension; 495140751Swpaul 496140751Swpaulstruct driver_extension { 497140751Swpaul struct driver_object *dre_driverobj; 498140751Swpaul void *dre_adddevicefunc; 499140751Swpaul uint32_t dre_reinitcnt; 500140751Swpaul unicode_string dre_srvname; 501141524Swpaul 502141524Swpaul /* 503141524Swpaul * Drivers are allowed to add one or more custom extensions 504141524Swpaul * to the driver object, but there's no special pointer 505141524Swpaul * for them. Hang them off here for now. 506141524Swpaul */ 507141524Swpaul 508141524Swpaul list_entry dre_usrext; 509140751Swpaul}; 510140751Swpaul 511140751Swpaultypedef struct driver_extension driver_extension; 512140751Swpaul 513141524Swpaulstruct custom_extension { 514141524Swpaul list_entry ce_list; 515141524Swpaul void *ce_clid; 516141524Swpaul}; 517141524Swpaul 518141524Swpaultypedef struct custom_extension custom_extension; 519141524Swpaul 520140751Swpaul/* 521140751Swpaul * In Windows, there are Physical Device Objects (PDOs) and 522140751Swpaul * Functional Device Objects (FDOs). Physical Device Objects are 523140751Swpaul * created and maintained by bus drivers. For example, the PCI 524140751Swpaul * bus driver might detect two PCI ethernet cards on a given 525140751Swpaul * bus. The PCI bus driver will then allocate two device_objects 526140751Swpaul * for its own internal bookeeping purposes. This is analagous 527140751Swpaul * to the device_t that the FreeBSD PCI code allocates and passes 528140751Swpaul * into each PCI driver's probe and attach routines. 529140751Swpaul * 530140751Swpaul * When an ethernet driver claims one of the ethernet cards 531140751Swpaul * on the bus, it will create its own device_object. This is 532140751Swpaul * the Functional Device Object. This object is analagous to the 533140751Swpaul * device-specific softc structure. 534140751Swpaul */ 535140751Swpaul 536125551Swpaulstruct device_object { 537125551Swpaul uint16_t do_type; 538125551Swpaul uint16_t do_size; 539125551Swpaul uint32_t do_refcnt; 540141524Swpaul struct driver_object *do_drvobj; 541125551Swpaul struct device_object *do_nextdev; 542125551Swpaul struct device_object *do_attacheddev; 543125551Swpaul struct irp *do_currirp; 544125551Swpaul void *do_iotimer; 545125551Swpaul uint32_t do_flags; 546125551Swpaul uint32_t do_characteristics; 547125551Swpaul void *do_vpb; 548125551Swpaul void *do_devext; 549141524Swpaul uint32_t do_devtype; 550125551Swpaul uint8_t do_stacksize; 551125551Swpaul union { 552125551Swpaul list_entry do_listent; 553125551Swpaul wait_ctx_block do_wcb; 554125551Swpaul } queue; 555125551Swpaul uint32_t do_alignreq; 556125551Swpaul kdevice_queue do_devqueue; 557125551Swpaul struct kdpc do_dpc; 558125551Swpaul uint32_t do_activethreads; 559125551Swpaul void *do_securitydesc; 560125551Swpaul struct nt_kevent do_devlock; 561125551Swpaul uint16_t do_sectorsz; 562125551Swpaul uint16_t do_spare1; 563140751Swpaul struct devobj_extension *do_devobj_ext; 564125551Swpaul void *do_rsvd; 565125551Swpaul}; 566125551Swpaul 567125551Swpaultypedef struct device_object device_object; 568125551Swpaul 569140751Swpaulstruct devobj_extension { 570140751Swpaul uint16_t dve_type; 571140751Swpaul uint16_t dve_size; 572140751Swpaul device_object *dve_devobj; 573140751Swpaul}; 574140751Swpaul 575140751Swpaultypedef struct devobj_extension devobj_extension; 576140751Swpaul 577140751Swpaul#define IO_NO_INCREMENT 0 578140751Swpaul#define IO_CD_ROM_INCREMENT 1 579140751Swpaul#define IO_DISK_INCREMENT 1 580140751Swpaul#define IO_KEYBOARD_INCREMENT 6 581140751Swpaul#define IO_MAILSLOT_INCREMENT 2 582140751Swpaul#define IO_MOUSE_INCREMENT 6 583140751Swpaul#define IO_NAMED_PIPE_INCREMENT 2 584140751Swpaul#define IO_NETWORK_INCREMENT 2 585140751Swpaul#define IO_PARALLEL_INCREMENT 1 586140751Swpaul#define IO_SERIAL_INCREMENT 2 587140751Swpaul#define IO_SOUND_INCREMENT 8 588140751Swpaul#define IO_VIDEO_INCREMENT 1 589140751Swpaul 590140751Swpaul/* IRP major codes */ 591140751Swpaul 592140751Swpaul#define IRP_MJ_CREATE 0x00 593140751Swpaul#define IRP_MJ_CREATE_NAMED_PIPE 0x01 594140751Swpaul#define IRP_MJ_CLOSE 0x02 595140751Swpaul#define IRP_MJ_READ 0x03 596140751Swpaul#define IRP_MJ_WRITE 0x04 597140751Swpaul#define IRP_MJ_QUERY_INFORMATION 0x05 598140751Swpaul#define IRP_MJ_SET_INFORMATION 0x06 599140751Swpaul#define IRP_MJ_QUERY_EA 0x07 600140751Swpaul#define IRP_MJ_SET_EA 0x08 601140751Swpaul#define IRP_MJ_FLUSH_BUFFERS 0x09 602140751Swpaul#define IRP_MJ_QUERY_VOLUME_INFORMATION 0x0a 603140751Swpaul#define IRP_MJ_SET_VOLUME_INFORMATION 0x0b 604140751Swpaul#define IRP_MJ_DIRECTORY_CONTROL 0x0c 605140751Swpaul#define IRP_MJ_FILE_SYSTEM_CONTROL 0x0d 606140751Swpaul#define IRP_MJ_DEVICE_CONTROL 0x0e 607140751Swpaul#define IRP_MJ_INTERNAL_DEVICE_CONTROL 0x0f 608140751Swpaul#define IRP_MJ_SHUTDOWN 0x10 609140751Swpaul#define IRP_MJ_LOCK_CONTROL 0x11 610140751Swpaul#define IRP_MJ_CLEANUP 0x12 611140751Swpaul#define IRP_MJ_CREATE_MAILSLOT 0x13 612140751Swpaul#define IRP_MJ_QUERY_SECURITY 0x14 613140751Swpaul#define IRP_MJ_SET_SECURITY 0x15 614140751Swpaul#define IRP_MJ_POWER 0x16 615140751Swpaul#define IRP_MJ_SYSTEM_CONTROL 0x17 616140751Swpaul#define IRP_MJ_DEVICE_CHANGE 0x18 617140751Swpaul#define IRP_MJ_QUERY_QUOTA 0x19 618140751Swpaul#define IRP_MJ_SET_QUOTA 0x1a 619140751Swpaul#define IRP_MJ_PNP 0x1b 620140751Swpaul#define IRP_MJ_PNP_POWER IRP_MJ_PNP // Obsolete.... 621140751Swpaul#define IRP_MJ_MAXIMUM_FUNCTION 0x1b 622140751Swpaul#define IRP_MJ_SCSI IRP_MJ_INTERNAL_DEVICE_CONTROL 623140751Swpaul 624140751Swpaul/* IRP minor codes */ 625140751Swpaul 626140751Swpaul#define IRP_MN_QUERY_DIRECTORY 0x01 627140751Swpaul#define IRP_MN_NOTIFY_CHANGE_DIRECTORY 0x02 628140751Swpaul#define IRP_MN_USER_FS_REQUEST 0x00 629140751Swpaul 630140751Swpaul#define IRP_MN_MOUNT_VOLUME 0x01 631140751Swpaul#define IRP_MN_VERIFY_VOLUME 0x02 632140751Swpaul#define IRP_MN_LOAD_FILE_SYSTEM 0x03 633140751Swpaul#define IRP_MN_TRACK_LINK 0x04 // To be obsoleted soon 634140751Swpaul#define IRP_MN_KERNEL_CALL 0x04 635140751Swpaul 636140751Swpaul#define IRP_MN_LOCK 0x01 637140751Swpaul#define IRP_MN_UNLOCK_SINGLE 0x02 638140751Swpaul#define IRP_MN_UNLOCK_ALL 0x03 639140751Swpaul#define IRP_MN_UNLOCK_ALL_BY_KEY 0x04 640140751Swpaul 641140751Swpaul#define IRP_MN_NORMAL 0x00 642140751Swpaul#define IRP_MN_DPC 0x01 643140751Swpaul#define IRP_MN_MDL 0x02 644140751Swpaul#define IRP_MN_COMPLETE 0x04 645140751Swpaul#define IRP_MN_COMPRESSED 0x08 646140751Swpaul 647140751Swpaul#define IRP_MN_MDL_DPC (IRP_MN_MDL | IRP_MN_DPC) 648140751Swpaul#define IRP_MN_COMPLETE_MDL (IRP_MN_COMPLETE | IRP_MN_MDL) 649140751Swpaul#define IRP_MN_COMPLETE_MDL_DPC (IRP_MN_COMPLETE_MDL | IRP_MN_DPC) 650140751Swpaul 651140751Swpaul#define IRP_MN_SCSI_CLASS 0x01 652140751Swpaul 653140751Swpaul#define IRP_MN_START_DEVICE 0x00 654140751Swpaul#define IRP_MN_QUERY_REMOVE_DEVICE 0x01 655140751Swpaul#define IRP_MN_REMOVE_DEVICE 0x02 656140751Swpaul#define IRP_MN_CANCEL_REMOVE_DEVICE 0x03 657140751Swpaul#define IRP_MN_STOP_DEVICE 0x04 658140751Swpaul#define IRP_MN_QUERY_STOP_DEVICE 0x05 659140751Swpaul#define IRP_MN_CANCEL_STOP_DEVICE 0x06 660140751Swpaul 661140751Swpaul#define IRP_MN_QUERY_DEVICE_RELATIONS 0x07 662140751Swpaul#define IRP_MN_QUERY_INTERFACE 0x08 663140751Swpaul#define IRP_MN_QUERY_CAPABILITIES 0x09 664140751Swpaul#define IRP_MN_QUERY_RESOURCES 0x0A 665140751Swpaul#define IRP_MN_QUERY_RESOURCE_REQUIREMENTS 0x0B 666140751Swpaul#define IRP_MN_QUERY_DEVICE_TEXT 0x0C 667140751Swpaul#define IRP_MN_FILTER_RESOURCE_REQUIREMENTS 0x0D 668140751Swpaul 669140751Swpaul#define IRP_MN_READ_CONFIG 0x0F 670140751Swpaul#define IRP_MN_WRITE_CONFIG 0x10 671140751Swpaul#define IRP_MN_EJECT 0x11 672140751Swpaul#define IRP_MN_SET_LOCK 0x12 673140751Swpaul#define IRP_MN_QUERY_ID 0x13 674140751Swpaul#define IRP_MN_QUERY_PNP_DEVICE_STATE 0x14 675140751Swpaul#define IRP_MN_QUERY_BUS_INFORMATION 0x15 676140751Swpaul#define IRP_MN_DEVICE_USAGE_NOTIFICATION 0x16 677140751Swpaul#define IRP_MN_SURPRISE_REMOVAL 0x17 678140751Swpaul#define IRP_MN_QUERY_LEGACY_BUS_INFORMATION 0x18 679140751Swpaul 680140751Swpaul#define IRP_MN_WAIT_WAKE 0x00 681140751Swpaul#define IRP_MN_POWER_SEQUENCE 0x01 682140751Swpaul#define IRP_MN_SET_POWER 0x02 683140751Swpaul#define IRP_MN_QUERY_POWER 0x03 684140751Swpaul 685140751Swpaul#define IRP_MN_QUERY_ALL_DATA 0x00 686140751Swpaul#define IRP_MN_QUERY_SINGLE_INSTANCE 0x01 687140751Swpaul#define IRP_MN_CHANGE_SINGLE_INSTANCE 0x02 688140751Swpaul#define IRP_MN_CHANGE_SINGLE_ITEM 0x03 689140751Swpaul#define IRP_MN_ENABLE_EVENTS 0x04 690140751Swpaul#define IRP_MN_DISABLE_EVENTS 0x05 691140751Swpaul#define IRP_MN_ENABLE_COLLECTION 0x06 692140751Swpaul#define IRP_MN_DISABLE_COLLECTION 0x07 693140751Swpaul#define IRP_MN_REGINFO 0x08 694140751Swpaul#define IRP_MN_EXECUTE_METHOD 0x09 695140751Swpaul#define IRP_MN_REGINFO_EX 0x0b 696140751Swpaul 697140751Swpaul/* IRP flags */ 698140751Swpaul 699140751Swpaul#define IRP_NOCACHE 0x00000001 700140751Swpaul#define IRP_PAGING_IO 0x00000002 701140751Swpaul#define IRP_MOUNT_COMPLETION 0x00000002 702140751Swpaul#define IRP_SYNCHRONOUS_API 0x00000004 703140751Swpaul#define IRP_ASSOCIATED_IRP 0x00000008 704140751Swpaul#define IRP_BUFFERED_IO 0x00000010 705140751Swpaul#define IRP_DEALLOCATE_BUFFER 0x00000020 706140751Swpaul#define IRP_INPUT_OPERATION 0x00000040 707140751Swpaul#define IRP_SYNCHRONOUS_PAGING_IO 0x00000040 708140751Swpaul#define IRP_CREATE_OPERATION 0x00000080 709140751Swpaul#define IRP_READ_OPERATION 0x00000100 710140751Swpaul#define IRP_WRITE_OPERATION 0x00000200 711140751Swpaul#define IRP_CLOSE_OPERATION 0x00000400 712140751Swpaul#define IRP_DEFER_IO_COMPLETION 0x00000800 713140751Swpaul#define IRP_OB_QUERY_NAME 0x00001000 714140751Swpaul#define IRP_HOLD_DEVICE_QUEUE 0x00002000 715140751Swpaul#define IRP_RETRY_IO_COMPLETION 0x00004000 716140751Swpaul#define IRP_CLASS_CACHE_OPERATION 0x00008000 717140751Swpaul#define IRP_SET_USER_EVENT IRP_CLOSE_OPERATION 718140751Swpaul 719140751Swpaul/* IRP I/O control flags */ 720140751Swpaul 721140751Swpaul#define IRP_QUOTA_CHARGED 0x01 722140751Swpaul#define IRP_ALLOCATED_MUST_SUCCEED 0x02 723140751Swpaul#define IRP_ALLOCATED_FIXED_SIZE 0x04 724140751Swpaul#define IRP_LOOKASIDE_ALLOCATION 0x08 725140751Swpaul 726140751Swpaulstruct io_status_block { 727140751Swpaul union { 728140751Swpaul uint32_t isb_status; 729140751Swpaul void *isb_ptr; 730140751Swpaul } u; 731140751Swpaul register_t isb_info; 732140751Swpaul}; 733141524Swpaul#define isb_status u.isb_status 734141524Swpaul#define isb_ptr u.isb_ptr 735140751Swpaul 736140751Swpaultypedef struct io_status_block io_status_block; 737140751Swpaul 738140751Swpaulstruct kapc { 739140751Swpaul uint16_t apc_type; 740140751Swpaul uint16_t apc_size; 741140751Swpaul uint32_t apc_spare0; 742140751Swpaul void *apc_thread; 743140751Swpaul list_entry apc_list; 744140751Swpaul void *apc_kernfunc; 745140751Swpaul void *apc_rundownfunc; 746140751Swpaul void *apc_normalfunc; 747140751Swpaul void *apc_normctx; 748140751Swpaul void *apc_sysarg1; 749140751Swpaul void *apc_sysarg2; 750140751Swpaul uint8_t apc_stateidx; 751140751Swpaul uint8_t apc_cpumode; 752140751Swpaul uint8_t apc_inserted; 753140751Swpaul}; 754140751Swpaul 755140751Swpaultypedef struct kapc kapc; 756140751Swpaul 757141524Swpaultypedef __stdcall uint32_t (*completion_func)(device_object *, 758141524Swpaul struct irp *, void *); 759141524Swpaul 760140751Swpaulstruct io_stack_location { 761140751Swpaul uint8_t isl_major; 762140751Swpaul uint8_t isl_minor; 763140751Swpaul uint8_t isl_flags; 764140751Swpaul uint8_t isl_ctl; 765140751Swpaul 766140751Swpaul /* 767140751Swpaul * There's a big-ass union here in the actual Windows 768140751Swpaul * definition of the stucture, but it contains stuff 769140751Swpaul * that doesn't really apply to BSD, and defining it 770140751Swpaul * all properly would require duplicating over a dozen 771140751Swpaul * other structures that we'll never use. Since the 772140751Swpaul * io_stack_location structure is opaque to drivers 773140751Swpaul * anyway, I'm not going to bother with the extra crap. 774140751Swpaul */ 775140751Swpaul 776140751Swpaul union { 777140751Swpaul struct { 778140751Swpaul void *isl_arg1; 779140751Swpaul void *isl_arg2; 780140751Swpaul void *isl_arg3; 781140751Swpaul void *isl_arg4; 782140751Swpaul } isl_others; 783140751Swpaul } isl_parameters; 784140751Swpaul 785140751Swpaul void *isl_devobj; 786140751Swpaul void *isl_fileobj; 787141524Swpaul completion_func isl_completionfunc; 788140751Swpaul void *isl_completionctx; 789140751Swpaul}; 790140751Swpaul 791140751Swpaultypedef struct io_stack_location io_stack_location; 792140751Swpaul 793140751Swpaul/* Stack location control flags */ 794140751Swpaul 795140751Swpaul#define SL_PENDING_RETURNED 0x01 796140751Swpaul#define SL_INVOKE_ON_CANCEL 0x20 797140751Swpaul#define SL_INVOKE_ON_SUCCESS 0x40 798140751Swpaul#define SL_INVOKE_ON_ERROR 0x80 799140751Swpaul 800125551Swpaulstruct irp { 801140751Swpaul uint16_t irp_type; 802140751Swpaul uint16_t irp_size; 803140751Swpaul mdl *irp_mdl; 804140751Swpaul uint32_t irp_flags; 805140751Swpaul union { 806140751Swpaul struct irp *irp_master; 807140751Swpaul uint32_t irp_irpcnt; 808140751Swpaul void *irp_sysbuf; 809140751Swpaul } irp_assoc; 810140751Swpaul list_entry irp_thlist; 811140751Swpaul io_status_block irp_iostat; 812140751Swpaul uint8_t irp_reqmode; 813140751Swpaul uint8_t irp_pendingreturned; 814140751Swpaul uint8_t irp_stackcnt; 815140751Swpaul uint8_t irp_currentstackloc; 816140751Swpaul uint8_t irp_cancel; 817140751Swpaul uint8_t irp_cancelirql; 818140751Swpaul uint8_t irp_apcenv; 819140751Swpaul uint8_t irp_allocflags; 820140751Swpaul io_status_block *irp_usriostat; 821141524Swpaul nt_kevent *irp_usrevent; 822140751Swpaul union { 823140751Swpaul struct { 824140751Swpaul void *irp_apcfunc; 825140751Swpaul void *irp_apcctx; 826140751Swpaul } irp_asyncparms; 827140751Swpaul uint64_t irp_allocsz; 828140751Swpaul } irp_overlay; 829140751Swpaul void *irp_cancelfunc; 830140751Swpaul void *irp_userbuf; 831140751Swpaul 832140751Swpaul /* Windows kernel info */ 833140751Swpaul 834140751Swpaul union { 835140751Swpaul struct { 836140751Swpaul union { 837140751Swpaul kdevice_qentry irp_dqe; 838140751Swpaul struct { 839140751Swpaul void *irp_drvctx[4]; 840140751Swpaul } s1; 841140751Swpaul } u1; 842140751Swpaul void *irp_thread; 843140751Swpaul char *irp_auxbuf; 844140751Swpaul struct { 845140751Swpaul list_entry irp_list; 846140751Swpaul union { 847140751Swpaul io_stack_location *irp_csl; 848140751Swpaul uint32_t irp_pkttype; 849140751Swpaul } u2; 850140751Swpaul } s2; 851140751Swpaul void *irp_fileobj; 852140751Swpaul } irp_overlay; 853140751Swpaul kapc irp_apc; 854140751Swpaul void *irp_compkey; 855140751Swpaul } irp_tail; 856125551Swpaul}; 857125551Swpaul 858140751Swpaul#define irp_csl s2.u2.irp_csl 859140751Swpaul#define irp_pkttype s2.u2.irp_pkttype 860140751Swpaul 861125551Swpaultypedef struct irp irp; 862125551Swpaul 863141524Swpaul#define IoSizeOfIrp(ssize) \ 864141524Swpaul ((uint16_t) (sizeof(irp) + ((ssize) * (sizeof(io_stack_location))))) 865141524Swpaul 866141524Swpaul 867140751Swpaul#define IoGetCurrentIrpStackLocation(irp) \ 868140751Swpaul (irp)->irp_tail.irp_overlay.irp_csl 869140751Swpaul 870140751Swpaul#define IoGetNextIrpStackLocation(irp) \ 871140751Swpaul ((irp)->irp_tail.irp_overlay.irp_csl - 1) 872140751Swpaul 873141524Swpaul#define IoSetNextIrpStackLocation(irp) \ 874141524Swpaul do { \ 875141524Swpaul irp->irp_currentstackloc--; \ 876141524Swpaul irp->irp_tail.irp_overlay.irp_csl--; \ 877141524Swpaul } while(0) 878141524Swpaul 879140751Swpaul#define IoSetCompletionRoutine(irp, func, ctx, ok, err, cancel) \ 880140751Swpaul do { \ 881140751Swpaul io_stack_location *s; \ 882140751Swpaul s = IoGetNextIrpStackLocation((irp)); \ 883140751Swpaul s->isl_completionfunc = (func); \ 884140751Swpaul s->isl_completionctx = (ctx); \ 885140751Swpaul s->isl_ctl = 0; \ 886141524Swpaul if (ok) s->isl_ctl = SL_INVOKE_ON_SUCCESS; \ 887141524Swpaul if (err) s->isl_ctl |= SL_INVOKE_ON_ERROR; \ 888141524Swpaul if (cancel) s->isl_ctl |= SL_INVOKE_ON_CANCEL; \ 889140751Swpaul } while(0) 890140751Swpaul 891140751Swpaul#define IoMarkIrpPending(irp) \ 892140751Swpaul IoGetCurrentIrpStackLocation(irp)->isl_ctl |= SL_PENDING_RETURNED 893140751Swpaul 894140751Swpaul#define IoCopyCurrentIrpStackLocationToNext(irp) \ 895140751Swpaul do { \ 896140751Swpaul io_stack_location *src, *dst; \ 897140751Swpaul src = IoGetCurrentIrpStackLocation(irp); \ 898140751Swpaul dst = IoGetNextIrpStackLocation(irp); \ 899140751Swpaul bcopy((char *)src, (char *)dst, \ 900140751Swpaul offsetof(io_stack_location, isl_completionfunc)); \ 901140751Swpaul } while(0) 902140751Swpaul 903140751Swpaul#define IoSkipCurrentIrpStackLocation(irp) \ 904140751Swpaul do { \ 905140751Swpaul (irp)->irp_currentstackloc++; \ 906140751Swpaul (irp)->irp_tail.irp_overlay.irp_csl++; \ 907140751Swpaul } while(0) 908140751Swpaul 909141524Swpaultypedef __stdcall uint32_t (*driver_dispatch)(device_object *, irp *); 910125551Swpaul 911140751Swpaul/* 912140751Swpaul * The driver_object is allocated once for each driver that's loaded 913140751Swpaul * into the system. A new one is allocated for each driver and 914140751Swpaul * populated a bit via the driver's DriverEntry function. 915140751Swpaul * In general, a Windows DriverEntry() function will provide a pointer 916140751Swpaul * to its AddDevice() method and set up the dispatch table. 917140751Swpaul * For NDIS drivers, this is all done behind the scenes in the 918140751Swpaul * NdisInitializeWrapper() and/or NdisMRegisterMiniport() routines. 919140751Swpaul */ 920140751Swpaul 921140751Swpaulstruct driver_object { 922140751Swpaul uint16_t dro_type; 923140751Swpaul uint16_t dro_size; 924140751Swpaul device_object *dro_devobj; 925140751Swpaul uint32_t dro_flags; 926140751Swpaul void *dro_driverstart; 927140751Swpaul uint32_t dro_driversize; 928140751Swpaul void *dro_driversection; 929141524Swpaul driver_extension *dro_driverext; 930140751Swpaul unicode_string dro_drivername; 931140751Swpaul unicode_string *dro_hwdb; 932140751Swpaul void *dro_pfastiodispatch; 933140751Swpaul void *dro_driverinitfunc; 934140751Swpaul void *dro_driverstartiofunc; 935140751Swpaul void *dro_driverunloadfunc; 936141524Swpaul driver_dispatch dro_dispatch[IRP_MJ_MAXIMUM_FUNCTION + 1]; 937140751Swpaul}; 938140751Swpaul 939140751Swpaultypedef struct driver_object driver_object; 940140751Swpaul 941125551Swpaul#define DEVPROP_DEVICE_DESCRIPTION 0x00000000 942125551Swpaul#define DEVPROP_HARDWARE_ID 0x00000001 943125551Swpaul#define DEVPROP_COMPATIBLE_IDS 0x00000002 944125551Swpaul#define DEVPROP_BOOTCONF 0x00000003 945125551Swpaul#define DEVPROP_BOOTCONF_TRANSLATED 0x00000004 946125551Swpaul#define DEVPROP_CLASS_NAME 0x00000005 947125551Swpaul#define DEVPROP_CLASS_GUID 0x00000006 948125551Swpaul#define DEVPROP_DRIVER_KEYNAME 0x00000007 949125551Swpaul#define DEVPROP_MANUFACTURER 0x00000008 950125551Swpaul#define DEVPROP_FRIENDLYNAME 0x00000009 951125551Swpaul#define DEVPROP_LOCATION_INFO 0x0000000A 952125551Swpaul#define DEVPROP_PHYSDEV_NAME 0x0000000B 953125551Swpaul#define DEVPROP_BUSTYPE_GUID 0x0000000C 954125551Swpaul#define DEVPROP_LEGACY_BUSTYPE 0x0000000D 955125551Swpaul#define DEVPROP_BUS_NUMBER 0x0000000E 956125551Swpaul#define DEVPROP_ENUMERATOR_NAME 0x0000000F 957125551Swpaul#define DEVPROP_ADDRESS 0x00000010 958125551Swpaul#define DEVPROP_UINUMBER 0x00000011 959125551Swpaul#define DEVPROP_INSTALL_STATE 0x00000012 960125551Swpaul#define DEVPROP_REMOVAL_POLICY 0x00000013 961125551Swpaul 962141524Swpaul/* Various supported device types (used with IoCreateDevice()) */ 963141524Swpaul 964141524Swpaul#define FILE_DEVICE_BEEP 0x00000001 965141524Swpaul#define FILE_DEVICE_CD_ROM 0x00000002 966141524Swpaul#define FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003 967141524Swpaul#define FILE_DEVICE_CONTROLLER 0x00000004 968141524Swpaul#define FILE_DEVICE_DATALINK 0x00000005 969141524Swpaul#define FILE_DEVICE_DFS 0x00000006 970141524Swpaul#define FILE_DEVICE_DISK 0x00000007 971141524Swpaul#define FILE_DEVICE_DISK_FILE_SYSTEM 0x00000008 972141524Swpaul#define FILE_DEVICE_FILE_SYSTEM 0x00000009 973141524Swpaul#define FILE_DEVICE_INPORT_PORT 0x0000000A 974141524Swpaul#define FILE_DEVICE_KEYBOARD 0x0000000B 975141524Swpaul#define FILE_DEVICE_MAILSLOT 0x0000000C 976141524Swpaul#define FILE_DEVICE_MIDI_IN 0x0000000D 977141524Swpaul#define FILE_DEVICE_MIDI_OUT 0x0000000E 978141524Swpaul#define FILE_DEVICE_MOUSE 0x0000000F 979141524Swpaul#define FILE_DEVICE_MULTI_UNC_PROVIDER 0x00000010 980141524Swpaul#define FILE_DEVICE_NAMED_PIPE 0x00000011 981141524Swpaul#define FILE_DEVICE_NETWORK 0x00000012 982141524Swpaul#define FILE_DEVICE_NETWORK_BROWSER 0x00000013 983141524Swpaul#define FILE_DEVICE_NETWORK_FILE_SYSTEM 0x00000014 984141524Swpaul#define FILE_DEVICE_NULL 0x00000015 985141524Swpaul#define FILE_DEVICE_PARALLEL_PORT 0x00000016 986141524Swpaul#define FILE_DEVICE_PHYSICAL_NETCARD 0x00000017 987141524Swpaul#define FILE_DEVICE_PRINTER 0x00000018 988141524Swpaul#define FILE_DEVICE_SCANNER 0x00000019 989141524Swpaul#define FILE_DEVICE_SERIAL_MOUSE_PORT 0x0000001A 990141524Swpaul#define FILE_DEVICE_SERIAL_PORT 0x0000001B 991141524Swpaul#define FILE_DEVICE_SCREEN 0x0000001C 992141524Swpaul#define FILE_DEVICE_SOUND 0x0000001D 993141524Swpaul#define FILE_DEVICE_STREAMS 0x0000001E 994141524Swpaul#define FILE_DEVICE_TAPE 0x0000001F 995141524Swpaul#define FILE_DEVICE_TAPE_FILE_SYSTEM 0x00000020 996141524Swpaul#define FILE_DEVICE_TRANSPORT 0x00000021 997141524Swpaul#define FILE_DEVICE_UNKNOWN 0x00000022 998141524Swpaul#define FILE_DEVICE_VIDEO 0x00000023 999141524Swpaul#define FILE_DEVICE_VIRTUAL_DISK 0x00000024 1000141524Swpaul#define FILE_DEVICE_WAVE_IN 0x00000025 1001141524Swpaul#define FILE_DEVICE_WAVE_OUT 0x00000026 1002141524Swpaul#define FILE_DEVICE_8042_PORT 0x00000027 1003141524Swpaul#define FILE_DEVICE_NETWORK_REDIRECTOR 0x00000028 1004141524Swpaul#define FILE_DEVICE_BATTERY 0x00000029 1005141524Swpaul#define FILE_DEVICE_BUS_EXTENDER 0x0000002A 1006141524Swpaul#define FILE_DEVICE_MODEM 0x0000002B 1007141524Swpaul#define FILE_DEVICE_VDM 0x0000002C 1008141524Swpaul#define FILE_DEVICE_MASS_STORAGE 0x0000002D 1009141524Swpaul#define FILE_DEVICE_SMB 0x0000002E 1010141524Swpaul#define FILE_DEVICE_KS 0x0000002F 1011141524Swpaul#define FILE_DEVICE_CHANGER 0x00000030 1012141524Swpaul#define FILE_DEVICE_SMARTCARD 0x00000031 1013141524Swpaul#define FILE_DEVICE_ACPI 0x00000032 1014141524Swpaul#define FILE_DEVICE_DVD 0x00000033 1015141524Swpaul#define FILE_DEVICE_FULLSCREEN_VIDEO 0x00000034 1016141524Swpaul#define FILE_DEVICE_DFS_FILE_SYSTEM 0x00000035 1017141524Swpaul#define FILE_DEVICE_DFS_VOLUME 0x00000036 1018141524Swpaul#define FILE_DEVICE_SERENUM 0x00000037 1019141524Swpaul#define FILE_DEVICE_TERMSRV 0x00000038 1020141524Swpaul#define FILE_DEVICE_KSEC 0x00000039 1021141524Swpaul#define FILE_DEVICE_FIPS 0x0000003A 1022141524Swpaul 1023141524Swpaul/* Device characteristics */ 1024141524Swpaul 1025141524Swpaul#define FILE_REMOVABLE_MEDIA 0x00000001 1026141524Swpaul#define FILE_READ_ONLY_DEVICE 0x00000002 1027141524Swpaul#define FILE_FLOPPY_DISKETTE 0x00000004 1028141524Swpaul#define FILE_WRITE_ONCE_MEDIA 0x00000008 1029141524Swpaul#define FILE_REMOTE_DEVICE 0x00000010 1030141524Swpaul#define FILE_DEVICE_IS_MOUNTED 0x00000020 1031141524Swpaul#define FILE_VIRTUAL_VOLUME 0x00000040 1032141524Swpaul#define FILE_AUTOGENERATED_DEVICE_NAME 0x00000080 1033141524Swpaul#define FILE_DEVICE_SECURE_OPEN 0x00000100 1034141524Swpaul 1035141524Swpaul/* Status codes */ 1036141524Swpaul 1037125551Swpaul#define STATUS_SUCCESS 0x00000000 1038125551Swpaul#define STATUS_USER_APC 0x000000C0 1039125551Swpaul#define STATUS_KERNEL_APC 0x00000100 1040125551Swpaul#define STATUS_ALERTED 0x00000101 1041125551Swpaul#define STATUS_TIMEOUT 0x00000102 1042125551Swpaul#define STATUS_INVALID_PARAMETER 0xC000000D 1043125551Swpaul#define STATUS_INVALID_DEVICE_REQUEST 0xC0000010 1044141524Swpaul#define STATUS_MORE_PROCESSING_REQUIRED 0xC0000016 1045125551Swpaul#define STATUS_BUFFER_TOO_SMALL 0xC0000023 1046125551Swpaul#define STATUS_MUTANT_NOT_OWNED 0xC0000046 1047125551Swpaul#define STATUS_INVALID_PARAMETER_2 0xC00000F0 1048141524Swpaul#define STATUS_INSUFFICIENT_RESOURCES 0xC000009A 1049125551Swpaul 1050125551Swpaul#define STATUS_WAIT_0 0x00000000 1051125551Swpaul 1052141524Swpaul/* Memory pool types, for ExAllocatePoolWithTag() */ 1053141524Swpaul 1054141524Swpaul#define NonPagedPool 0x00000000 1055141524Swpaul#define PagedPool 0x00000001 1056141524Swpaul#define NonPagedPoolMustSucceed 0x00000002 1057141524Swpaul#define DontUseThisType 0x00000003 1058141524Swpaul#define NonPagedPoolCacheAligned 0x00000004 1059141524Swpaul#define PagedPoolCacheAligned 0x00000005 1060141524Swpaul#define NonPagedPoolCacheAlignedMustS 0x00000006 1061141524Swpaul#define MaxPoolType 0x00000007 1062141524Swpaul 1063127284Swpaul/* 1064127284Swpaul * FreeBSD's kernel stack is 2 pages in size by default. The 1065127284Swpaul * Windows stack is larger, so we need to give our threads more 1066127284Swpaul * stack pages. 4 should be enough, we use 8 just to extra safe. 1067127284Swpaul */ 1068127284Swpaul#define NDIS_KSTACK_PAGES 8 1069127284Swpaul 1070123474Swpaulextern image_patch_table ntoskrnl_functbl[]; 1071123474Swpaul 1072123474Swpaul__BEGIN_DECLS 1073141524Swpaulextern int windrv_libinit(void); 1074141524Swpaulextern int windrv_libfini(void); 1075141524Swpaulextern driver_object *windrv_lookup(vm_offset_t); 1076141524Swpaulextern int windrv_load(module_t, vm_offset_t, int); 1077141524Swpaulextern int windrv_unload(module_t, vm_offset_t, int); 1078141524Swpaulextern int windrv_create_pdo(driver_object *, device_t); 1079141524Swpaulextern void windrv_destroy_pdo(driver_object *, device_t); 1080141524Swpaulextern device_object *windrv_find_pdo(driver_object *, device_t); 1081141524Swpaulextern int windrv_bus_attach(driver_object *, char *); 1082141524Swpaul 1083123474Swpaulextern int ntoskrnl_libinit(void); 1084123474Swpaulextern int ntoskrnl_libfini(void); 1085140751Swpaul__stdcall extern void KeInitializeDpc(kdpc *, void *, void *); 1086140751Swpaul__stdcall extern uint8_t KeInsertQueueDpc(kdpc *, void *, void *); 1087140751Swpaul__stdcall extern uint8_t KeRemoveQueueDpc(kdpc *); 1088140751Swpaul__stdcall extern void KeInitializeTimer(ktimer *); 1089140751Swpaul__stdcall extern void KeInitializeTimerEx(ktimer *, uint32_t); 1090140751Swpaul__stdcall extern uint8_t KeSetTimer(ktimer *, int64_t, kdpc *); 1091141524Swpaul__stdcall extern uint8_t KeSetTimerEx(ktimer *, int64_t, uint32_t, kdpc *); 1092140751Swpaul__stdcall extern uint8_t KeCancelTimer(ktimer *); 1093140751Swpaul__stdcall extern uint8_t KeReadStateTimer(ktimer *); 1094140751Swpaul__stdcall extern uint32_t KeWaitForSingleObject(nt_dispatch_header *, uint32_t, 1095127248Swpaul uint32_t, uint8_t, int64_t *); 1096140751Swpaul__stdcall extern void KeInitializeEvent(nt_kevent *, uint32_t, uint8_t); 1097140751Swpaul__stdcall extern void KeClearEvent(nt_kevent *); 1098140751Swpaul__stdcall extern uint32_t KeReadStateEvent(nt_kevent *); 1099140751Swpaul__stdcall extern uint32_t KeSetEvent(nt_kevent *, uint32_t, uint8_t); 1100140751Swpaul__stdcall extern uint32_t KeResetEvent(nt_kevent *); 1101140751Swpaul__fastcall extern void KefAcquireSpinLockAtDpcLevel(REGARGS1(kspin_lock *)); 1102140751Swpaul__fastcall extern void KefReleaseSpinLockFromDpcLevel(REGARGS1(kspin_lock *)); 1103140751Swpaul__stdcall extern void KeInitializeSpinLock(kspin_lock *); 1104141524Swpaul__stdcall extern void *ExAllocatePoolWithTag(uint32_t, size_t, uint32_t); 1105141524Swpaul__stdcall extern void ExFreePool(void *); 1106141524Swpaul__stdcall extern uint32_t IoAllocateDriverObjectExtension(driver_object *, 1107141524Swpaul void *, uint32_t, void **); 1108141524Swpaul__stdcall extern void *IoGetDriverObjectExtension(driver_object *, void *); 1109141524Swpaul__stdcall extern uint32_t IoCreateDevice(driver_object *, uint32_t, 1110141524Swpaul unicode_string *, uint32_t, uint32_t, uint8_t, device_object **); 1111141524Swpaul__stdcall extern void IoDeleteDevice(device_object *); 1112141524Swpaul__stdcall extern device_object *IoGetAttachedDevice(device_object *); 1113140751Swpaul__fastcall extern uint32_t IofCallDriver(REGARGS2(device_object *, irp *)); 1114140751Swpaul__fastcall extern void IofCompleteRequest(REGARGS2(irp *, uint8_t)); 1115141524Swpaul__stdcall extern void IoDetachDevice(device_object *); 1116141524Swpaul__stdcall extern device_object *IoAttachDeviceToDeviceStack(device_object *, 1117141524Swpaul device_object *); 1118128229Swpaul 1119140751Swpaul#define IoCallDriver(a, b) FASTCALL2(IofCallDriver, a, b) 1120140751Swpaul#define IoCompleteRequest(a, b) FASTCALL2(IofCompleteRequest, a, b) 1121140751Swpaul 1122128229Swpaul/* 1123128229Swpaul * On the Windows x86 arch, KeAcquireSpinLock() and KeReleaseSpinLock() 1124128229Swpaul * routines live in the HAL. We try to imitate this behavior. 1125128229Swpaul */ 1126128229Swpaul#ifdef __i386__ 1127140751Swpaul#define KeAcquireSpinLock(a, b) *(b) = FASTCALL1(KfAcquireSpinLock, a) 1128140751Swpaul#define KeReleaseSpinLock(a, b) FASTCALL2(KfReleaseSpinLock, a, b) 1129140751Swpaul#define KeRaiseIrql(a) FASTCALL1(KfRaiseIrql, a) 1130140751Swpaul#define KeLowerIrql(a) FASTCALL1(KfLowerIrql, a) 1131128229Swpaul#endif /* __i386__ */ 1132123474Swpaul__END_DECLS 1133123474Swpaul 1134123474Swpaul#endif /* _NTOSKRNL_VAR_H_ */ 1135