ntoskrnl_var.h revision 142443
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 142443 2005-02-25 08:34:32Z 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 577142311Swpaul/* Device object flags */ 578142311Swpaul 579142311Swpaul#define DO_VERIFY_VOLUME 0x00000002 580142311Swpaul#define DO_BUFFERED_IO 0x00000004 581142311Swpaul#define DO_EXCLUSIVE 0x00000008 582142311Swpaul#define DO_DIRECT_IO 0x00000010 583142311Swpaul#define DO_MAP_IO_BUFFER 0x00000020 584142311Swpaul#define DO_DEVICE_HAS_NAME 0x00000040 585142311Swpaul#define DO_DEVICE_INITIALIZING 0x00000080 586142311Swpaul#define DO_SYSTEM_BOOT_PARTITION 0x00000100 587142311Swpaul#define DO_LONG_TERM_REQUESTS 0x00000200 588142311Swpaul#define DO_NEVER_LAST_DEVICE 0x00000400 589142311Swpaul#define DO_SHUTDOWN_REGISTERED 0x00000800 590142311Swpaul#define DO_BUS_ENUMERATED_DEVICE 0x00001000 591142311Swpaul#define DO_POWER_PAGABLE 0x00002000 592142311Swpaul#define DO_POWER_INRUSH 0x00004000 593142311Swpaul#define DO_LOW_PRIORITY_FILESYSTEM 0x00010000 594142311Swpaul 595142311Swpaul/* Priority boosts */ 596142311Swpaul 597140751Swpaul#define IO_NO_INCREMENT 0 598140751Swpaul#define IO_CD_ROM_INCREMENT 1 599140751Swpaul#define IO_DISK_INCREMENT 1 600140751Swpaul#define IO_KEYBOARD_INCREMENT 6 601140751Swpaul#define IO_MAILSLOT_INCREMENT 2 602140751Swpaul#define IO_MOUSE_INCREMENT 6 603140751Swpaul#define IO_NAMED_PIPE_INCREMENT 2 604140751Swpaul#define IO_NETWORK_INCREMENT 2 605140751Swpaul#define IO_PARALLEL_INCREMENT 1 606140751Swpaul#define IO_SERIAL_INCREMENT 2 607140751Swpaul#define IO_SOUND_INCREMENT 8 608140751Swpaul#define IO_VIDEO_INCREMENT 1 609140751Swpaul 610140751Swpaul/* IRP major codes */ 611140751Swpaul 612140751Swpaul#define IRP_MJ_CREATE 0x00 613140751Swpaul#define IRP_MJ_CREATE_NAMED_PIPE 0x01 614140751Swpaul#define IRP_MJ_CLOSE 0x02 615140751Swpaul#define IRP_MJ_READ 0x03 616140751Swpaul#define IRP_MJ_WRITE 0x04 617140751Swpaul#define IRP_MJ_QUERY_INFORMATION 0x05 618140751Swpaul#define IRP_MJ_SET_INFORMATION 0x06 619140751Swpaul#define IRP_MJ_QUERY_EA 0x07 620140751Swpaul#define IRP_MJ_SET_EA 0x08 621140751Swpaul#define IRP_MJ_FLUSH_BUFFERS 0x09 622140751Swpaul#define IRP_MJ_QUERY_VOLUME_INFORMATION 0x0a 623140751Swpaul#define IRP_MJ_SET_VOLUME_INFORMATION 0x0b 624140751Swpaul#define IRP_MJ_DIRECTORY_CONTROL 0x0c 625140751Swpaul#define IRP_MJ_FILE_SYSTEM_CONTROL 0x0d 626140751Swpaul#define IRP_MJ_DEVICE_CONTROL 0x0e 627140751Swpaul#define IRP_MJ_INTERNAL_DEVICE_CONTROL 0x0f 628140751Swpaul#define IRP_MJ_SHUTDOWN 0x10 629140751Swpaul#define IRP_MJ_LOCK_CONTROL 0x11 630140751Swpaul#define IRP_MJ_CLEANUP 0x12 631140751Swpaul#define IRP_MJ_CREATE_MAILSLOT 0x13 632140751Swpaul#define IRP_MJ_QUERY_SECURITY 0x14 633140751Swpaul#define IRP_MJ_SET_SECURITY 0x15 634140751Swpaul#define IRP_MJ_POWER 0x16 635140751Swpaul#define IRP_MJ_SYSTEM_CONTROL 0x17 636140751Swpaul#define IRP_MJ_DEVICE_CHANGE 0x18 637140751Swpaul#define IRP_MJ_QUERY_QUOTA 0x19 638140751Swpaul#define IRP_MJ_SET_QUOTA 0x1a 639140751Swpaul#define IRP_MJ_PNP 0x1b 640140751Swpaul#define IRP_MJ_PNP_POWER IRP_MJ_PNP // Obsolete.... 641140751Swpaul#define IRP_MJ_MAXIMUM_FUNCTION 0x1b 642140751Swpaul#define IRP_MJ_SCSI IRP_MJ_INTERNAL_DEVICE_CONTROL 643140751Swpaul 644140751Swpaul/* IRP minor codes */ 645140751Swpaul 646140751Swpaul#define IRP_MN_QUERY_DIRECTORY 0x01 647140751Swpaul#define IRP_MN_NOTIFY_CHANGE_DIRECTORY 0x02 648140751Swpaul#define IRP_MN_USER_FS_REQUEST 0x00 649140751Swpaul 650140751Swpaul#define IRP_MN_MOUNT_VOLUME 0x01 651140751Swpaul#define IRP_MN_VERIFY_VOLUME 0x02 652140751Swpaul#define IRP_MN_LOAD_FILE_SYSTEM 0x03 653140751Swpaul#define IRP_MN_TRACK_LINK 0x04 // To be obsoleted soon 654140751Swpaul#define IRP_MN_KERNEL_CALL 0x04 655140751Swpaul 656140751Swpaul#define IRP_MN_LOCK 0x01 657140751Swpaul#define IRP_MN_UNLOCK_SINGLE 0x02 658140751Swpaul#define IRP_MN_UNLOCK_ALL 0x03 659140751Swpaul#define IRP_MN_UNLOCK_ALL_BY_KEY 0x04 660140751Swpaul 661140751Swpaul#define IRP_MN_NORMAL 0x00 662140751Swpaul#define IRP_MN_DPC 0x01 663140751Swpaul#define IRP_MN_MDL 0x02 664140751Swpaul#define IRP_MN_COMPLETE 0x04 665140751Swpaul#define IRP_MN_COMPRESSED 0x08 666140751Swpaul 667140751Swpaul#define IRP_MN_MDL_DPC (IRP_MN_MDL | IRP_MN_DPC) 668140751Swpaul#define IRP_MN_COMPLETE_MDL (IRP_MN_COMPLETE | IRP_MN_MDL) 669140751Swpaul#define IRP_MN_COMPLETE_MDL_DPC (IRP_MN_COMPLETE_MDL | IRP_MN_DPC) 670140751Swpaul 671140751Swpaul#define IRP_MN_SCSI_CLASS 0x01 672140751Swpaul 673140751Swpaul#define IRP_MN_START_DEVICE 0x00 674140751Swpaul#define IRP_MN_QUERY_REMOVE_DEVICE 0x01 675140751Swpaul#define IRP_MN_REMOVE_DEVICE 0x02 676140751Swpaul#define IRP_MN_CANCEL_REMOVE_DEVICE 0x03 677140751Swpaul#define IRP_MN_STOP_DEVICE 0x04 678140751Swpaul#define IRP_MN_QUERY_STOP_DEVICE 0x05 679140751Swpaul#define IRP_MN_CANCEL_STOP_DEVICE 0x06 680140751Swpaul 681140751Swpaul#define IRP_MN_QUERY_DEVICE_RELATIONS 0x07 682140751Swpaul#define IRP_MN_QUERY_INTERFACE 0x08 683140751Swpaul#define IRP_MN_QUERY_CAPABILITIES 0x09 684140751Swpaul#define IRP_MN_QUERY_RESOURCES 0x0A 685140751Swpaul#define IRP_MN_QUERY_RESOURCE_REQUIREMENTS 0x0B 686140751Swpaul#define IRP_MN_QUERY_DEVICE_TEXT 0x0C 687140751Swpaul#define IRP_MN_FILTER_RESOURCE_REQUIREMENTS 0x0D 688140751Swpaul 689140751Swpaul#define IRP_MN_READ_CONFIG 0x0F 690140751Swpaul#define IRP_MN_WRITE_CONFIG 0x10 691140751Swpaul#define IRP_MN_EJECT 0x11 692140751Swpaul#define IRP_MN_SET_LOCK 0x12 693140751Swpaul#define IRP_MN_QUERY_ID 0x13 694140751Swpaul#define IRP_MN_QUERY_PNP_DEVICE_STATE 0x14 695140751Swpaul#define IRP_MN_QUERY_BUS_INFORMATION 0x15 696140751Swpaul#define IRP_MN_DEVICE_USAGE_NOTIFICATION 0x16 697140751Swpaul#define IRP_MN_SURPRISE_REMOVAL 0x17 698140751Swpaul#define IRP_MN_QUERY_LEGACY_BUS_INFORMATION 0x18 699140751Swpaul 700140751Swpaul#define IRP_MN_WAIT_WAKE 0x00 701140751Swpaul#define IRP_MN_POWER_SEQUENCE 0x01 702140751Swpaul#define IRP_MN_SET_POWER 0x02 703140751Swpaul#define IRP_MN_QUERY_POWER 0x03 704140751Swpaul 705140751Swpaul#define IRP_MN_QUERY_ALL_DATA 0x00 706140751Swpaul#define IRP_MN_QUERY_SINGLE_INSTANCE 0x01 707140751Swpaul#define IRP_MN_CHANGE_SINGLE_INSTANCE 0x02 708140751Swpaul#define IRP_MN_CHANGE_SINGLE_ITEM 0x03 709140751Swpaul#define IRP_MN_ENABLE_EVENTS 0x04 710140751Swpaul#define IRP_MN_DISABLE_EVENTS 0x05 711140751Swpaul#define IRP_MN_ENABLE_COLLECTION 0x06 712140751Swpaul#define IRP_MN_DISABLE_COLLECTION 0x07 713140751Swpaul#define IRP_MN_REGINFO 0x08 714140751Swpaul#define IRP_MN_EXECUTE_METHOD 0x09 715140751Swpaul#define IRP_MN_REGINFO_EX 0x0b 716140751Swpaul 717140751Swpaul/* IRP flags */ 718140751Swpaul 719140751Swpaul#define IRP_NOCACHE 0x00000001 720140751Swpaul#define IRP_PAGING_IO 0x00000002 721140751Swpaul#define IRP_MOUNT_COMPLETION 0x00000002 722140751Swpaul#define IRP_SYNCHRONOUS_API 0x00000004 723140751Swpaul#define IRP_ASSOCIATED_IRP 0x00000008 724140751Swpaul#define IRP_BUFFERED_IO 0x00000010 725140751Swpaul#define IRP_DEALLOCATE_BUFFER 0x00000020 726140751Swpaul#define IRP_INPUT_OPERATION 0x00000040 727140751Swpaul#define IRP_SYNCHRONOUS_PAGING_IO 0x00000040 728140751Swpaul#define IRP_CREATE_OPERATION 0x00000080 729140751Swpaul#define IRP_READ_OPERATION 0x00000100 730140751Swpaul#define IRP_WRITE_OPERATION 0x00000200 731140751Swpaul#define IRP_CLOSE_OPERATION 0x00000400 732140751Swpaul#define IRP_DEFER_IO_COMPLETION 0x00000800 733140751Swpaul#define IRP_OB_QUERY_NAME 0x00001000 734140751Swpaul#define IRP_HOLD_DEVICE_QUEUE 0x00002000 735140751Swpaul#define IRP_RETRY_IO_COMPLETION 0x00004000 736140751Swpaul#define IRP_CLASS_CACHE_OPERATION 0x00008000 737140751Swpaul#define IRP_SET_USER_EVENT IRP_CLOSE_OPERATION 738140751Swpaul 739140751Swpaul/* IRP I/O control flags */ 740140751Swpaul 741140751Swpaul#define IRP_QUOTA_CHARGED 0x01 742140751Swpaul#define IRP_ALLOCATED_MUST_SUCCEED 0x02 743140751Swpaul#define IRP_ALLOCATED_FIXED_SIZE 0x04 744140751Swpaul#define IRP_LOOKASIDE_ALLOCATION 0x08 745140751Swpaul 746142311Swpaul/* I/O method types */ 747142311Swpaul 748142311Swpaul#define METHOD_BUFFERED 0 749142311Swpaul#define METHOD_IN_DIRECT 1 750142311Swpaul#define METHOD_OUT_DIRECT 2 751142311Swpaul#define METHOD_NEITHER 3 752142311Swpaul 753142311Swpaul#define IO_METHOD(x) ((x) & 0xFFFFFFFC) 754142311Swpaul 755140751Swpaulstruct io_status_block { 756140751Swpaul union { 757140751Swpaul uint32_t isb_status; 758140751Swpaul void *isb_ptr; 759140751Swpaul } u; 760140751Swpaul register_t isb_info; 761140751Swpaul}; 762141524Swpaul#define isb_status u.isb_status 763141524Swpaul#define isb_ptr u.isb_ptr 764140751Swpaul 765140751Swpaultypedef struct io_status_block io_status_block; 766140751Swpaul 767140751Swpaulstruct kapc { 768140751Swpaul uint16_t apc_type; 769140751Swpaul uint16_t apc_size; 770140751Swpaul uint32_t apc_spare0; 771140751Swpaul void *apc_thread; 772140751Swpaul list_entry apc_list; 773140751Swpaul void *apc_kernfunc; 774140751Swpaul void *apc_rundownfunc; 775140751Swpaul void *apc_normalfunc; 776140751Swpaul void *apc_normctx; 777140751Swpaul void *apc_sysarg1; 778140751Swpaul void *apc_sysarg2; 779140751Swpaul uint8_t apc_stateidx; 780140751Swpaul uint8_t apc_cpumode; 781140751Swpaul uint8_t apc_inserted; 782140751Swpaul}; 783140751Swpaul 784140751Swpaultypedef struct kapc kapc; 785140751Swpaul 786141524Swpaultypedef __stdcall uint32_t (*completion_func)(device_object *, 787141524Swpaul struct irp *, void *); 788142311Swpaultypedef __stdcall uint32_t (*cancel_func)(device_object *, 789142311Swpaul struct irp *); 790141524Swpaul 791140751Swpaulstruct io_stack_location { 792140751Swpaul uint8_t isl_major; 793140751Swpaul uint8_t isl_minor; 794140751Swpaul uint8_t isl_flags; 795140751Swpaul uint8_t isl_ctl; 796140751Swpaul 797140751Swpaul /* 798140751Swpaul * There's a big-ass union here in the actual Windows 799140751Swpaul * definition of the stucture, but it contains stuff 800140751Swpaul * that doesn't really apply to BSD, and defining it 801140751Swpaul * all properly would require duplicating over a dozen 802140751Swpaul * other structures that we'll never use. Since the 803140751Swpaul * io_stack_location structure is opaque to drivers 804140751Swpaul * anyway, I'm not going to bother with the extra crap. 805140751Swpaul */ 806140751Swpaul 807140751Swpaul union { 808140751Swpaul struct { 809142311Swpaul uint32_t isl_len; 810142311Swpaul uint32_t *isl_key; 811142311Swpaul uint64_t isl_byteoff; 812142311Swpaul } isl_read; 813142311Swpaul struct { 814142311Swpaul uint32_t isl_len; 815142311Swpaul uint32_t *isl_key; 816142311Swpaul uint64_t isl_byteoff; 817142311Swpaul } isl_write; 818142311Swpaul struct { 819142311Swpaul uint32_t isl_obuflen; 820142311Swpaul uint32_t isl_ibuflen; 821142311Swpaul uint32_t isl_iocode; 822142311Swpaul void *isl_type3ibuf; 823142311Swpaul } isl_ioctl; 824142311Swpaul struct { 825140751Swpaul void *isl_arg1; 826140751Swpaul void *isl_arg2; 827140751Swpaul void *isl_arg3; 828140751Swpaul void *isl_arg4; 829140751Swpaul } isl_others; 830142311Swpaul } isl_parameters __attribute__((packed)); 831140751Swpaul 832140751Swpaul void *isl_devobj; 833140751Swpaul void *isl_fileobj; 834141524Swpaul completion_func isl_completionfunc; 835140751Swpaul void *isl_completionctx; 836140751Swpaul}; 837140751Swpaul 838140751Swpaultypedef struct io_stack_location io_stack_location; 839140751Swpaul 840140751Swpaul/* Stack location control flags */ 841140751Swpaul 842140751Swpaul#define SL_PENDING_RETURNED 0x01 843140751Swpaul#define SL_INVOKE_ON_CANCEL 0x20 844140751Swpaul#define SL_INVOKE_ON_SUCCESS 0x40 845140751Swpaul#define SL_INVOKE_ON_ERROR 0x80 846140751Swpaul 847125551Swpaulstruct irp { 848140751Swpaul uint16_t irp_type; 849140751Swpaul uint16_t irp_size; 850140751Swpaul mdl *irp_mdl; 851140751Swpaul uint32_t irp_flags; 852140751Swpaul union { 853140751Swpaul struct irp *irp_master; 854140751Swpaul uint32_t irp_irpcnt; 855140751Swpaul void *irp_sysbuf; 856140751Swpaul } irp_assoc; 857140751Swpaul list_entry irp_thlist; 858140751Swpaul io_status_block irp_iostat; 859140751Swpaul uint8_t irp_reqmode; 860140751Swpaul uint8_t irp_pendingreturned; 861140751Swpaul uint8_t irp_stackcnt; 862140751Swpaul uint8_t irp_currentstackloc; 863140751Swpaul uint8_t irp_cancel; 864140751Swpaul uint8_t irp_cancelirql; 865140751Swpaul uint8_t irp_apcenv; 866140751Swpaul uint8_t irp_allocflags; 867140751Swpaul io_status_block *irp_usriostat; 868141524Swpaul nt_kevent *irp_usrevent; 869140751Swpaul union { 870140751Swpaul struct { 871140751Swpaul void *irp_apcfunc; 872140751Swpaul void *irp_apcctx; 873140751Swpaul } irp_asyncparms; 874140751Swpaul uint64_t irp_allocsz; 875140751Swpaul } irp_overlay; 876142311Swpaul cancel_func irp_cancelfunc; 877140751Swpaul void *irp_userbuf; 878140751Swpaul 879140751Swpaul /* Windows kernel info */ 880140751Swpaul 881140751Swpaul union { 882140751Swpaul struct { 883140751Swpaul union { 884140751Swpaul kdevice_qentry irp_dqe; 885140751Swpaul struct { 886140751Swpaul void *irp_drvctx[4]; 887140751Swpaul } s1; 888140751Swpaul } u1; 889140751Swpaul void *irp_thread; 890140751Swpaul char *irp_auxbuf; 891140751Swpaul struct { 892140751Swpaul list_entry irp_list; 893140751Swpaul union { 894140751Swpaul io_stack_location *irp_csl; 895140751Swpaul uint32_t irp_pkttype; 896140751Swpaul } u2; 897140751Swpaul } s2; 898140751Swpaul void *irp_fileobj; 899140751Swpaul } irp_overlay; 900140751Swpaul kapc irp_apc; 901140751Swpaul void *irp_compkey; 902140751Swpaul } irp_tail; 903125551Swpaul}; 904125551Swpaul 905140751Swpaul#define irp_csl s2.u2.irp_csl 906140751Swpaul#define irp_pkttype s2.u2.irp_pkttype 907140751Swpaul 908125551Swpaultypedef struct irp irp; 909125551Swpaul 910142311Swpaul#define InterlockedExchangePointer(dst, val) \ 911142311Swpaul (void *)FASTCALL2(InterlockedExchange, (uint32_t *)(dst), \ 912142311Swpaul (uintptr_t)(val)) 913142311Swpaul 914141524Swpaul#define IoSizeOfIrp(ssize) \ 915141524Swpaul ((uint16_t) (sizeof(irp) + ((ssize) * (sizeof(io_stack_location))))) 916141524Swpaul 917142311Swpaul#define IoSetCancelRoutine(irp, func) \ 918142311Swpaul (cancel_func)InterlockedExchangePointer( \ 919142311Swpaul (void *)&(ip)->irp_cancelfunc, (void *)(func)) 920141524Swpaul 921140751Swpaul#define IoGetCurrentIrpStackLocation(irp) \ 922140751Swpaul (irp)->irp_tail.irp_overlay.irp_csl 923140751Swpaul 924140751Swpaul#define IoGetNextIrpStackLocation(irp) \ 925140751Swpaul ((irp)->irp_tail.irp_overlay.irp_csl - 1) 926140751Swpaul 927141524Swpaul#define IoSetNextIrpStackLocation(irp) \ 928141524Swpaul do { \ 929141524Swpaul irp->irp_currentstackloc--; \ 930141524Swpaul irp->irp_tail.irp_overlay.irp_csl--; \ 931141524Swpaul } while(0) 932141524Swpaul 933140751Swpaul#define IoSetCompletionRoutine(irp, func, ctx, ok, err, cancel) \ 934140751Swpaul do { \ 935140751Swpaul io_stack_location *s; \ 936140751Swpaul s = IoGetNextIrpStackLocation((irp)); \ 937140751Swpaul s->isl_completionfunc = (func); \ 938140751Swpaul s->isl_completionctx = (ctx); \ 939140751Swpaul s->isl_ctl = 0; \ 940141524Swpaul if (ok) s->isl_ctl = SL_INVOKE_ON_SUCCESS; \ 941141524Swpaul if (err) s->isl_ctl |= SL_INVOKE_ON_ERROR; \ 942141524Swpaul if (cancel) s->isl_ctl |= SL_INVOKE_ON_CANCEL; \ 943140751Swpaul } while(0) 944140751Swpaul 945140751Swpaul#define IoMarkIrpPending(irp) \ 946140751Swpaul IoGetCurrentIrpStackLocation(irp)->isl_ctl |= SL_PENDING_RETURNED 947140751Swpaul 948140751Swpaul#define IoCopyCurrentIrpStackLocationToNext(irp) \ 949140751Swpaul do { \ 950140751Swpaul io_stack_location *src, *dst; \ 951140751Swpaul src = IoGetCurrentIrpStackLocation(irp); \ 952140751Swpaul dst = IoGetNextIrpStackLocation(irp); \ 953140751Swpaul bcopy((char *)src, (char *)dst, \ 954140751Swpaul offsetof(io_stack_location, isl_completionfunc)); \ 955140751Swpaul } while(0) 956140751Swpaul 957140751Swpaul#define IoSkipCurrentIrpStackLocation(irp) \ 958140751Swpaul do { \ 959140751Swpaul (irp)->irp_currentstackloc++; \ 960140751Swpaul (irp)->irp_tail.irp_overlay.irp_csl++; \ 961140751Swpaul } while(0) 962140751Swpaul 963141524Swpaultypedef __stdcall uint32_t (*driver_dispatch)(device_object *, irp *); 964125551Swpaul 965140751Swpaul/* 966140751Swpaul * The driver_object is allocated once for each driver that's loaded 967140751Swpaul * into the system. A new one is allocated for each driver and 968140751Swpaul * populated a bit via the driver's DriverEntry function. 969140751Swpaul * In general, a Windows DriverEntry() function will provide a pointer 970140751Swpaul * to its AddDevice() method and set up the dispatch table. 971140751Swpaul * For NDIS drivers, this is all done behind the scenes in the 972140751Swpaul * NdisInitializeWrapper() and/or NdisMRegisterMiniport() routines. 973140751Swpaul */ 974140751Swpaul 975140751Swpaulstruct driver_object { 976140751Swpaul uint16_t dro_type; 977140751Swpaul uint16_t dro_size; 978140751Swpaul device_object *dro_devobj; 979140751Swpaul uint32_t dro_flags; 980140751Swpaul void *dro_driverstart; 981140751Swpaul uint32_t dro_driversize; 982140751Swpaul void *dro_driversection; 983141524Swpaul driver_extension *dro_driverext; 984140751Swpaul unicode_string dro_drivername; 985140751Swpaul unicode_string *dro_hwdb; 986140751Swpaul void *dro_pfastiodispatch; 987140751Swpaul void *dro_driverinitfunc; 988140751Swpaul void *dro_driverstartiofunc; 989140751Swpaul void *dro_driverunloadfunc; 990141524Swpaul driver_dispatch dro_dispatch[IRP_MJ_MAXIMUM_FUNCTION + 1]; 991140751Swpaul}; 992140751Swpaul 993140751Swpaultypedef struct driver_object driver_object; 994140751Swpaul 995125551Swpaul#define DEVPROP_DEVICE_DESCRIPTION 0x00000000 996125551Swpaul#define DEVPROP_HARDWARE_ID 0x00000001 997125551Swpaul#define DEVPROP_COMPATIBLE_IDS 0x00000002 998125551Swpaul#define DEVPROP_BOOTCONF 0x00000003 999125551Swpaul#define DEVPROP_BOOTCONF_TRANSLATED 0x00000004 1000125551Swpaul#define DEVPROP_CLASS_NAME 0x00000005 1001125551Swpaul#define DEVPROP_CLASS_GUID 0x00000006 1002125551Swpaul#define DEVPROP_DRIVER_KEYNAME 0x00000007 1003125551Swpaul#define DEVPROP_MANUFACTURER 0x00000008 1004125551Swpaul#define DEVPROP_FRIENDLYNAME 0x00000009 1005125551Swpaul#define DEVPROP_LOCATION_INFO 0x0000000A 1006125551Swpaul#define DEVPROP_PHYSDEV_NAME 0x0000000B 1007125551Swpaul#define DEVPROP_BUSTYPE_GUID 0x0000000C 1008125551Swpaul#define DEVPROP_LEGACY_BUSTYPE 0x0000000D 1009125551Swpaul#define DEVPROP_BUS_NUMBER 0x0000000E 1010125551Swpaul#define DEVPROP_ENUMERATOR_NAME 0x0000000F 1011125551Swpaul#define DEVPROP_ADDRESS 0x00000010 1012125551Swpaul#define DEVPROP_UINUMBER 0x00000011 1013125551Swpaul#define DEVPROP_INSTALL_STATE 0x00000012 1014125551Swpaul#define DEVPROP_REMOVAL_POLICY 0x00000013 1015125551Swpaul 1016141524Swpaul/* Various supported device types (used with IoCreateDevice()) */ 1017141524Swpaul 1018141524Swpaul#define FILE_DEVICE_BEEP 0x00000001 1019141524Swpaul#define FILE_DEVICE_CD_ROM 0x00000002 1020141524Swpaul#define FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003 1021141524Swpaul#define FILE_DEVICE_CONTROLLER 0x00000004 1022141524Swpaul#define FILE_DEVICE_DATALINK 0x00000005 1023141524Swpaul#define FILE_DEVICE_DFS 0x00000006 1024141524Swpaul#define FILE_DEVICE_DISK 0x00000007 1025141524Swpaul#define FILE_DEVICE_DISK_FILE_SYSTEM 0x00000008 1026141524Swpaul#define FILE_DEVICE_FILE_SYSTEM 0x00000009 1027141524Swpaul#define FILE_DEVICE_INPORT_PORT 0x0000000A 1028141524Swpaul#define FILE_DEVICE_KEYBOARD 0x0000000B 1029141524Swpaul#define FILE_DEVICE_MAILSLOT 0x0000000C 1030141524Swpaul#define FILE_DEVICE_MIDI_IN 0x0000000D 1031141524Swpaul#define FILE_DEVICE_MIDI_OUT 0x0000000E 1032141524Swpaul#define FILE_DEVICE_MOUSE 0x0000000F 1033141524Swpaul#define FILE_DEVICE_MULTI_UNC_PROVIDER 0x00000010 1034141524Swpaul#define FILE_DEVICE_NAMED_PIPE 0x00000011 1035141524Swpaul#define FILE_DEVICE_NETWORK 0x00000012 1036141524Swpaul#define FILE_DEVICE_NETWORK_BROWSER 0x00000013 1037141524Swpaul#define FILE_DEVICE_NETWORK_FILE_SYSTEM 0x00000014 1038141524Swpaul#define FILE_DEVICE_NULL 0x00000015 1039141524Swpaul#define FILE_DEVICE_PARALLEL_PORT 0x00000016 1040141524Swpaul#define FILE_DEVICE_PHYSICAL_NETCARD 0x00000017 1041141524Swpaul#define FILE_DEVICE_PRINTER 0x00000018 1042141524Swpaul#define FILE_DEVICE_SCANNER 0x00000019 1043141524Swpaul#define FILE_DEVICE_SERIAL_MOUSE_PORT 0x0000001A 1044141524Swpaul#define FILE_DEVICE_SERIAL_PORT 0x0000001B 1045141524Swpaul#define FILE_DEVICE_SCREEN 0x0000001C 1046141524Swpaul#define FILE_DEVICE_SOUND 0x0000001D 1047141524Swpaul#define FILE_DEVICE_STREAMS 0x0000001E 1048141524Swpaul#define FILE_DEVICE_TAPE 0x0000001F 1049141524Swpaul#define FILE_DEVICE_TAPE_FILE_SYSTEM 0x00000020 1050141524Swpaul#define FILE_DEVICE_TRANSPORT 0x00000021 1051141524Swpaul#define FILE_DEVICE_UNKNOWN 0x00000022 1052141524Swpaul#define FILE_DEVICE_VIDEO 0x00000023 1053141524Swpaul#define FILE_DEVICE_VIRTUAL_DISK 0x00000024 1054141524Swpaul#define FILE_DEVICE_WAVE_IN 0x00000025 1055141524Swpaul#define FILE_DEVICE_WAVE_OUT 0x00000026 1056141524Swpaul#define FILE_DEVICE_8042_PORT 0x00000027 1057141524Swpaul#define FILE_DEVICE_NETWORK_REDIRECTOR 0x00000028 1058141524Swpaul#define FILE_DEVICE_BATTERY 0x00000029 1059141524Swpaul#define FILE_DEVICE_BUS_EXTENDER 0x0000002A 1060141524Swpaul#define FILE_DEVICE_MODEM 0x0000002B 1061141524Swpaul#define FILE_DEVICE_VDM 0x0000002C 1062141524Swpaul#define FILE_DEVICE_MASS_STORAGE 0x0000002D 1063141524Swpaul#define FILE_DEVICE_SMB 0x0000002E 1064141524Swpaul#define FILE_DEVICE_KS 0x0000002F 1065141524Swpaul#define FILE_DEVICE_CHANGER 0x00000030 1066141524Swpaul#define FILE_DEVICE_SMARTCARD 0x00000031 1067141524Swpaul#define FILE_DEVICE_ACPI 0x00000032 1068141524Swpaul#define FILE_DEVICE_DVD 0x00000033 1069141524Swpaul#define FILE_DEVICE_FULLSCREEN_VIDEO 0x00000034 1070141524Swpaul#define FILE_DEVICE_DFS_FILE_SYSTEM 0x00000035 1071141524Swpaul#define FILE_DEVICE_DFS_VOLUME 0x00000036 1072141524Swpaul#define FILE_DEVICE_SERENUM 0x00000037 1073141524Swpaul#define FILE_DEVICE_TERMSRV 0x00000038 1074141524Swpaul#define FILE_DEVICE_KSEC 0x00000039 1075141524Swpaul#define FILE_DEVICE_FIPS 0x0000003A 1076141524Swpaul 1077141524Swpaul/* Device characteristics */ 1078141524Swpaul 1079141524Swpaul#define FILE_REMOVABLE_MEDIA 0x00000001 1080141524Swpaul#define FILE_READ_ONLY_DEVICE 0x00000002 1081141524Swpaul#define FILE_FLOPPY_DISKETTE 0x00000004 1082141524Swpaul#define FILE_WRITE_ONCE_MEDIA 0x00000008 1083141524Swpaul#define FILE_REMOTE_DEVICE 0x00000010 1084141524Swpaul#define FILE_DEVICE_IS_MOUNTED 0x00000020 1085141524Swpaul#define FILE_VIRTUAL_VOLUME 0x00000040 1086141524Swpaul#define FILE_AUTOGENERATED_DEVICE_NAME 0x00000080 1087141524Swpaul#define FILE_DEVICE_SECURE_OPEN 0x00000100 1088141524Swpaul 1089141524Swpaul/* Status codes */ 1090141524Swpaul 1091125551Swpaul#define STATUS_SUCCESS 0x00000000 1092125551Swpaul#define STATUS_USER_APC 0x000000C0 1093125551Swpaul#define STATUS_KERNEL_APC 0x00000100 1094125551Swpaul#define STATUS_ALERTED 0x00000101 1095125551Swpaul#define STATUS_TIMEOUT 0x00000102 1096142443Swpaul#define STATUS_PENDING 0x00000103 1097125551Swpaul#define STATUS_INVALID_PARAMETER 0xC000000D 1098125551Swpaul#define STATUS_INVALID_DEVICE_REQUEST 0xC0000010 1099141524Swpaul#define STATUS_MORE_PROCESSING_REQUIRED 0xC0000016 1100125551Swpaul#define STATUS_BUFFER_TOO_SMALL 0xC0000023 1101125551Swpaul#define STATUS_MUTANT_NOT_OWNED 0xC0000046 1102125551Swpaul#define STATUS_INVALID_PARAMETER_2 0xC00000F0 1103141524Swpaul#define STATUS_INSUFFICIENT_RESOURCES 0xC000009A 1104125551Swpaul 1105125551Swpaul#define STATUS_WAIT_0 0x00000000 1106125551Swpaul 1107141524Swpaul/* Memory pool types, for ExAllocatePoolWithTag() */ 1108141524Swpaul 1109141524Swpaul#define NonPagedPool 0x00000000 1110141524Swpaul#define PagedPool 0x00000001 1111141524Swpaul#define NonPagedPoolMustSucceed 0x00000002 1112141524Swpaul#define DontUseThisType 0x00000003 1113141524Swpaul#define NonPagedPoolCacheAligned 0x00000004 1114141524Swpaul#define PagedPoolCacheAligned 0x00000005 1115141524Swpaul#define NonPagedPoolCacheAlignedMustS 0x00000006 1116141524Swpaul#define MaxPoolType 0x00000007 1117141524Swpaul 1118127284Swpaul/* 1119127284Swpaul * FreeBSD's kernel stack is 2 pages in size by default. The 1120127284Swpaul * Windows stack is larger, so we need to give our threads more 1121127284Swpaul * stack pages. 4 should be enough, we use 8 just to extra safe. 1122127284Swpaul */ 1123127284Swpaul#define NDIS_KSTACK_PAGES 8 1124127284Swpaul 1125123474Swpaulextern image_patch_table ntoskrnl_functbl[]; 1126141963Swpaultypedef void (*funcptr)(void); 1127123474Swpaul 1128123474Swpaul__BEGIN_DECLS 1129141524Swpaulextern int windrv_libinit(void); 1130141524Swpaulextern int windrv_libfini(void); 1131142399Swpaulextern driver_object *windrv_lookup(vm_offset_t, char *); 1132141524Swpaulextern int windrv_load(module_t, vm_offset_t, int); 1133141524Swpaulextern int windrv_unload(module_t, vm_offset_t, int); 1134141524Swpaulextern int windrv_create_pdo(driver_object *, device_t); 1135141524Swpaulextern void windrv_destroy_pdo(driver_object *, device_t); 1136141524Swpaulextern device_object *windrv_find_pdo(driver_object *, device_t); 1137141524Swpaulextern int windrv_bus_attach(driver_object *, char *); 1138141963Swpaulextern int windrv_wrap(funcptr, funcptr *); 1139141963Swpaulextern int windrv_unwrap(funcptr); 1140141524Swpaul 1141123474Swpaulextern int ntoskrnl_libinit(void); 1142123474Swpaulextern int ntoskrnl_libfini(void); 1143140751Swpaul__stdcall extern void KeInitializeDpc(kdpc *, void *, void *); 1144140751Swpaul__stdcall extern uint8_t KeInsertQueueDpc(kdpc *, void *, void *); 1145140751Swpaul__stdcall extern uint8_t KeRemoveQueueDpc(kdpc *); 1146140751Swpaul__stdcall extern void KeInitializeTimer(ktimer *); 1147140751Swpaul__stdcall extern void KeInitializeTimerEx(ktimer *, uint32_t); 1148140751Swpaul__stdcall extern uint8_t KeSetTimer(ktimer *, int64_t, kdpc *); 1149141524Swpaul__stdcall extern uint8_t KeSetTimerEx(ktimer *, int64_t, uint32_t, kdpc *); 1150140751Swpaul__stdcall extern uint8_t KeCancelTimer(ktimer *); 1151140751Swpaul__stdcall extern uint8_t KeReadStateTimer(ktimer *); 1152140751Swpaul__stdcall extern uint32_t KeWaitForSingleObject(nt_dispatch_header *, uint32_t, 1153127248Swpaul uint32_t, uint8_t, int64_t *); 1154140751Swpaul__stdcall extern void KeInitializeEvent(nt_kevent *, uint32_t, uint8_t); 1155140751Swpaul__stdcall extern void KeClearEvent(nt_kevent *); 1156140751Swpaul__stdcall extern uint32_t KeReadStateEvent(nt_kevent *); 1157140751Swpaul__stdcall extern uint32_t KeSetEvent(nt_kevent *, uint32_t, uint8_t); 1158140751Swpaul__stdcall extern uint32_t KeResetEvent(nt_kevent *); 1159140751Swpaul__fastcall extern void KefAcquireSpinLockAtDpcLevel(REGARGS1(kspin_lock *)); 1160140751Swpaul__fastcall extern void KefReleaseSpinLockFromDpcLevel(REGARGS1(kspin_lock *)); 1161140751Swpaul__stdcall extern void KeInitializeSpinLock(kspin_lock *); 1162142311Swpaul__fastcall extern uintptr_t InterlockedExchange(REGARGS2(volatile uint32_t *, 1163142311Swpaul uintptr_t)); 1164141524Swpaul__stdcall extern void *ExAllocatePoolWithTag(uint32_t, size_t, uint32_t); 1165141524Swpaul__stdcall extern void ExFreePool(void *); 1166141524Swpaul__stdcall extern uint32_t IoAllocateDriverObjectExtension(driver_object *, 1167141524Swpaul void *, uint32_t, void **); 1168141524Swpaul__stdcall extern void *IoGetDriverObjectExtension(driver_object *, void *); 1169141524Swpaul__stdcall extern uint32_t IoCreateDevice(driver_object *, uint32_t, 1170141524Swpaul unicode_string *, uint32_t, uint32_t, uint8_t, device_object **); 1171141524Swpaul__stdcall extern void IoDeleteDevice(device_object *); 1172141524Swpaul__stdcall extern device_object *IoGetAttachedDevice(device_object *); 1173140751Swpaul__fastcall extern uint32_t IofCallDriver(REGARGS2(device_object *, irp *)); 1174140751Swpaul__fastcall extern void IofCompleteRequest(REGARGS2(irp *, uint8_t)); 1175142311Swpaul__stdcall extern void IoAcquireCancelSpinLock(uint8_t *); 1176142311Swpaul__stdcall extern void IoReleaseCancelSpinLock(uint8_t); 1177142311Swpaul__stdcall extern uint8_t IoCancelIrp(irp *); 1178141524Swpaul__stdcall extern void IoDetachDevice(device_object *); 1179141524Swpaul__stdcall extern device_object *IoAttachDeviceToDeviceStack(device_object *, 1180141524Swpaul device_object *); 1181141963Swpaul__stdcall mdl *IoAllocateMdl(void *, uint32_t, uint8_t, uint8_t, irp *); 1182141963Swpaul__stdcall void IoFreeMdl(mdl *); 1183128229Swpaul 1184140751Swpaul#define IoCallDriver(a, b) FASTCALL2(IofCallDriver, a, b) 1185140751Swpaul#define IoCompleteRequest(a, b) FASTCALL2(IofCompleteRequest, a, b) 1186140751Swpaul 1187128229Swpaul/* 1188128229Swpaul * On the Windows x86 arch, KeAcquireSpinLock() and KeReleaseSpinLock() 1189128229Swpaul * routines live in the HAL. We try to imitate this behavior. 1190128229Swpaul */ 1191128229Swpaul#ifdef __i386__ 1192140751Swpaul#define KeAcquireSpinLock(a, b) *(b) = FASTCALL1(KfAcquireSpinLock, a) 1193140751Swpaul#define KeReleaseSpinLock(a, b) FASTCALL2(KfReleaseSpinLock, a, b) 1194140751Swpaul#define KeRaiseIrql(a) FASTCALL1(KfRaiseIrql, a) 1195140751Swpaul#define KeLowerIrql(a) FASTCALL1(KfLowerIrql, a) 1196128229Swpaul#endif /* __i386__ */ 1197141963Swpaul 1198141963Swpaul#ifdef __amd64__ 1199141980Swpaul#define KeAcquireSpinLock(a, b) *(b) = KfAcquireSpinLock(a) 1200141980Swpaul#define KeReleaseSpinLock(a, b) KfReleaseSpinLock(a, b) 1201141963Swpaul 1202141963Swpaul/* 1203141963Swpaul * These may need to be redefined later; 1204141963Swpaul * not sure where they live on amd64 yet. 1205141963Swpaul */ 1206141963Swpaul#define KeRaiseIrql(a) KfRaiseIrql(a) 1207141963Swpaul#define KeLowerIrql(a) KfLowerIrql(a) 1208141963Swpaul#endif /* __amd64__ */ 1209141963Swpaul 1210123474Swpaul__END_DECLS 1211123474Swpaul 1212123474Swpaul#endif /* _NTOSKRNL_VAR_H_ */ 1213