ntoskrnl_var.h revision 140827
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 140827 2005-01-25 17:00:54Z 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) \ 197125551Swpaul 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; \ 239125551Swpaul b->nle_flink = e; \ 240125551Swpaul 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; 501140751Swpaul}; 502140751Swpaul 503140751Swpaultypedef struct driver_extension driver_extension; 504140751Swpaul 505140751Swpaul/* 506140751Swpaul * In Windows, there are Physical Device Objects (PDOs) and 507140751Swpaul * Functional Device Objects (FDOs). Physical Device Objects are 508140751Swpaul * created and maintained by bus drivers. For example, the PCI 509140751Swpaul * bus driver might detect two PCI ethernet cards on a given 510140751Swpaul * bus. The PCI bus driver will then allocate two device_objects 511140751Swpaul * for its own internal bookeeping purposes. This is analagous 512140751Swpaul * to the device_t that the FreeBSD PCI code allocates and passes 513140751Swpaul * into each PCI driver's probe and attach routines. 514140751Swpaul * 515140751Swpaul * When an ethernet driver claims one of the ethernet cards 516140751Swpaul * on the bus, it will create its own device_object. This is 517140751Swpaul * the Functional Device Object. This object is analagous to the 518140751Swpaul * device-specific softc structure. 519140751Swpaul */ 520140751Swpaul 521125551Swpaulstruct device_object { 522125551Swpaul uint16_t do_type; 523125551Swpaul uint16_t do_size; 524125551Swpaul uint32_t do_refcnt; 525125551Swpaul struct device_object *do_drvobj; 526125551Swpaul struct device_object *do_nextdev; 527125551Swpaul struct device_object *do_attacheddev; 528125551Swpaul struct irp *do_currirp; 529125551Swpaul void *do_iotimer; 530125551Swpaul uint32_t do_flags; 531125551Swpaul uint32_t do_characteristics; 532125551Swpaul void *do_vpb; 533125551Swpaul void *do_devext; 534125551Swpaul uint8_t do_stacksize; 535125551Swpaul union { 536125551Swpaul list_entry do_listent; 537125551Swpaul wait_ctx_block do_wcb; 538125551Swpaul } queue; 539125551Swpaul uint32_t do_alignreq; 540125551Swpaul kdevice_queue do_devqueue; 541125551Swpaul struct kdpc do_dpc; 542125551Swpaul uint32_t do_activethreads; 543125551Swpaul void *do_securitydesc; 544125551Swpaul struct nt_kevent do_devlock; 545125551Swpaul uint16_t do_sectorsz; 546125551Swpaul uint16_t do_spare1; 547140751Swpaul struct devobj_extension *do_devobj_ext; 548125551Swpaul void *do_rsvd; 549125551Swpaul}; 550125551Swpaul 551125551Swpaultypedef struct device_object device_object; 552125551Swpaul 553140751Swpaulstruct devobj_extension { 554140751Swpaul uint16_t dve_type; 555140751Swpaul uint16_t dve_size; 556140751Swpaul device_object *dve_devobj; 557140751Swpaul}; 558140751Swpaul 559140751Swpaultypedef struct devobj_extension devobj_extension; 560140751Swpaul 561140751Swpaul#define IO_NO_INCREMENT 0 562140751Swpaul#define IO_CD_ROM_INCREMENT 1 563140751Swpaul#define IO_DISK_INCREMENT 1 564140751Swpaul#define IO_KEYBOARD_INCREMENT 6 565140751Swpaul#define IO_MAILSLOT_INCREMENT 2 566140751Swpaul#define IO_MOUSE_INCREMENT 6 567140751Swpaul#define IO_NAMED_PIPE_INCREMENT 2 568140751Swpaul#define IO_NETWORK_INCREMENT 2 569140751Swpaul#define IO_PARALLEL_INCREMENT 1 570140751Swpaul#define IO_SERIAL_INCREMENT 2 571140751Swpaul#define IO_SOUND_INCREMENT 8 572140751Swpaul#define IO_VIDEO_INCREMENT 1 573140751Swpaul 574140751Swpaul/* IRP major codes */ 575140751Swpaul 576140751Swpaul#define IRP_MJ_CREATE 0x00 577140751Swpaul#define IRP_MJ_CREATE_NAMED_PIPE 0x01 578140751Swpaul#define IRP_MJ_CLOSE 0x02 579140751Swpaul#define IRP_MJ_READ 0x03 580140751Swpaul#define IRP_MJ_WRITE 0x04 581140751Swpaul#define IRP_MJ_QUERY_INFORMATION 0x05 582140751Swpaul#define IRP_MJ_SET_INFORMATION 0x06 583140751Swpaul#define IRP_MJ_QUERY_EA 0x07 584140751Swpaul#define IRP_MJ_SET_EA 0x08 585140751Swpaul#define IRP_MJ_FLUSH_BUFFERS 0x09 586140751Swpaul#define IRP_MJ_QUERY_VOLUME_INFORMATION 0x0a 587140751Swpaul#define IRP_MJ_SET_VOLUME_INFORMATION 0x0b 588140751Swpaul#define IRP_MJ_DIRECTORY_CONTROL 0x0c 589140751Swpaul#define IRP_MJ_FILE_SYSTEM_CONTROL 0x0d 590140751Swpaul#define IRP_MJ_DEVICE_CONTROL 0x0e 591140751Swpaul#define IRP_MJ_INTERNAL_DEVICE_CONTROL 0x0f 592140751Swpaul#define IRP_MJ_SHUTDOWN 0x10 593140751Swpaul#define IRP_MJ_LOCK_CONTROL 0x11 594140751Swpaul#define IRP_MJ_CLEANUP 0x12 595140751Swpaul#define IRP_MJ_CREATE_MAILSLOT 0x13 596140751Swpaul#define IRP_MJ_QUERY_SECURITY 0x14 597140751Swpaul#define IRP_MJ_SET_SECURITY 0x15 598140751Swpaul#define IRP_MJ_POWER 0x16 599140751Swpaul#define IRP_MJ_SYSTEM_CONTROL 0x17 600140751Swpaul#define IRP_MJ_DEVICE_CHANGE 0x18 601140751Swpaul#define IRP_MJ_QUERY_QUOTA 0x19 602140751Swpaul#define IRP_MJ_SET_QUOTA 0x1a 603140751Swpaul#define IRP_MJ_PNP 0x1b 604140751Swpaul#define IRP_MJ_PNP_POWER IRP_MJ_PNP // Obsolete.... 605140751Swpaul#define IRP_MJ_MAXIMUM_FUNCTION 0x1b 606140751Swpaul#define IRP_MJ_SCSI IRP_MJ_INTERNAL_DEVICE_CONTROL 607140751Swpaul 608140751Swpaul/* IRP minor codes */ 609140751Swpaul 610140751Swpaul#define IRP_MN_QUERY_DIRECTORY 0x01 611140751Swpaul#define IRP_MN_NOTIFY_CHANGE_DIRECTORY 0x02 612140751Swpaul#define IRP_MN_USER_FS_REQUEST 0x00 613140751Swpaul 614140751Swpaul#define IRP_MN_MOUNT_VOLUME 0x01 615140751Swpaul#define IRP_MN_VERIFY_VOLUME 0x02 616140751Swpaul#define IRP_MN_LOAD_FILE_SYSTEM 0x03 617140751Swpaul#define IRP_MN_TRACK_LINK 0x04 // To be obsoleted soon 618140751Swpaul#define IRP_MN_KERNEL_CALL 0x04 619140751Swpaul 620140751Swpaul#define IRP_MN_LOCK 0x01 621140751Swpaul#define IRP_MN_UNLOCK_SINGLE 0x02 622140751Swpaul#define IRP_MN_UNLOCK_ALL 0x03 623140751Swpaul#define IRP_MN_UNLOCK_ALL_BY_KEY 0x04 624140751Swpaul 625140751Swpaul#define IRP_MN_NORMAL 0x00 626140751Swpaul#define IRP_MN_DPC 0x01 627140751Swpaul#define IRP_MN_MDL 0x02 628140751Swpaul#define IRP_MN_COMPLETE 0x04 629140751Swpaul#define IRP_MN_COMPRESSED 0x08 630140751Swpaul 631140751Swpaul#define IRP_MN_MDL_DPC (IRP_MN_MDL | IRP_MN_DPC) 632140751Swpaul#define IRP_MN_COMPLETE_MDL (IRP_MN_COMPLETE | IRP_MN_MDL) 633140751Swpaul#define IRP_MN_COMPLETE_MDL_DPC (IRP_MN_COMPLETE_MDL | IRP_MN_DPC) 634140751Swpaul 635140751Swpaul#define IRP_MN_SCSI_CLASS 0x01 636140751Swpaul 637140751Swpaul#define IRP_MN_START_DEVICE 0x00 638140751Swpaul#define IRP_MN_QUERY_REMOVE_DEVICE 0x01 639140751Swpaul#define IRP_MN_REMOVE_DEVICE 0x02 640140751Swpaul#define IRP_MN_CANCEL_REMOVE_DEVICE 0x03 641140751Swpaul#define IRP_MN_STOP_DEVICE 0x04 642140751Swpaul#define IRP_MN_QUERY_STOP_DEVICE 0x05 643140751Swpaul#define IRP_MN_CANCEL_STOP_DEVICE 0x06 644140751Swpaul 645140751Swpaul#define IRP_MN_QUERY_DEVICE_RELATIONS 0x07 646140751Swpaul#define IRP_MN_QUERY_INTERFACE 0x08 647140751Swpaul#define IRP_MN_QUERY_CAPABILITIES 0x09 648140751Swpaul#define IRP_MN_QUERY_RESOURCES 0x0A 649140751Swpaul#define IRP_MN_QUERY_RESOURCE_REQUIREMENTS 0x0B 650140751Swpaul#define IRP_MN_QUERY_DEVICE_TEXT 0x0C 651140751Swpaul#define IRP_MN_FILTER_RESOURCE_REQUIREMENTS 0x0D 652140751Swpaul 653140751Swpaul#define IRP_MN_READ_CONFIG 0x0F 654140751Swpaul#define IRP_MN_WRITE_CONFIG 0x10 655140751Swpaul#define IRP_MN_EJECT 0x11 656140751Swpaul#define IRP_MN_SET_LOCK 0x12 657140751Swpaul#define IRP_MN_QUERY_ID 0x13 658140751Swpaul#define IRP_MN_QUERY_PNP_DEVICE_STATE 0x14 659140751Swpaul#define IRP_MN_QUERY_BUS_INFORMATION 0x15 660140751Swpaul#define IRP_MN_DEVICE_USAGE_NOTIFICATION 0x16 661140751Swpaul#define IRP_MN_SURPRISE_REMOVAL 0x17 662140751Swpaul#define IRP_MN_QUERY_LEGACY_BUS_INFORMATION 0x18 663140751Swpaul 664140751Swpaul#define IRP_MN_WAIT_WAKE 0x00 665140751Swpaul#define IRP_MN_POWER_SEQUENCE 0x01 666140751Swpaul#define IRP_MN_SET_POWER 0x02 667140751Swpaul#define IRP_MN_QUERY_POWER 0x03 668140751Swpaul 669140751Swpaul#define IRP_MN_QUERY_ALL_DATA 0x00 670140751Swpaul#define IRP_MN_QUERY_SINGLE_INSTANCE 0x01 671140751Swpaul#define IRP_MN_CHANGE_SINGLE_INSTANCE 0x02 672140751Swpaul#define IRP_MN_CHANGE_SINGLE_ITEM 0x03 673140751Swpaul#define IRP_MN_ENABLE_EVENTS 0x04 674140751Swpaul#define IRP_MN_DISABLE_EVENTS 0x05 675140751Swpaul#define IRP_MN_ENABLE_COLLECTION 0x06 676140751Swpaul#define IRP_MN_DISABLE_COLLECTION 0x07 677140751Swpaul#define IRP_MN_REGINFO 0x08 678140751Swpaul#define IRP_MN_EXECUTE_METHOD 0x09 679140751Swpaul#define IRP_MN_REGINFO_EX 0x0b 680140751Swpaul 681140751Swpaul/* IRP flags */ 682140751Swpaul 683140751Swpaul#define IRP_NOCACHE 0x00000001 684140751Swpaul#define IRP_PAGING_IO 0x00000002 685140751Swpaul#define IRP_MOUNT_COMPLETION 0x00000002 686140751Swpaul#define IRP_SYNCHRONOUS_API 0x00000004 687140751Swpaul#define IRP_ASSOCIATED_IRP 0x00000008 688140751Swpaul#define IRP_BUFFERED_IO 0x00000010 689140751Swpaul#define IRP_DEALLOCATE_BUFFER 0x00000020 690140751Swpaul#define IRP_INPUT_OPERATION 0x00000040 691140751Swpaul#define IRP_SYNCHRONOUS_PAGING_IO 0x00000040 692140751Swpaul#define IRP_CREATE_OPERATION 0x00000080 693140751Swpaul#define IRP_READ_OPERATION 0x00000100 694140751Swpaul#define IRP_WRITE_OPERATION 0x00000200 695140751Swpaul#define IRP_CLOSE_OPERATION 0x00000400 696140751Swpaul#define IRP_DEFER_IO_COMPLETION 0x00000800 697140751Swpaul#define IRP_OB_QUERY_NAME 0x00001000 698140751Swpaul#define IRP_HOLD_DEVICE_QUEUE 0x00002000 699140751Swpaul#define IRP_RETRY_IO_COMPLETION 0x00004000 700140751Swpaul#define IRP_CLASS_CACHE_OPERATION 0x00008000 701140751Swpaul#define IRP_SET_USER_EVENT IRP_CLOSE_OPERATION 702140751Swpaul 703140751Swpaul/* IRP I/O control flags */ 704140751Swpaul 705140751Swpaul#define IRP_QUOTA_CHARGED 0x01 706140751Swpaul#define IRP_ALLOCATED_MUST_SUCCEED 0x02 707140751Swpaul#define IRP_ALLOCATED_FIXED_SIZE 0x04 708140751Swpaul#define IRP_LOOKASIDE_ALLOCATION 0x08 709140751Swpaul 710140751Swpaulstruct io_status_block { 711140751Swpaul union { 712140751Swpaul uint32_t isb_status; 713140751Swpaul void *isb_ptr; 714140751Swpaul } u; 715140751Swpaul register_t isb_info; 716140751Swpaul}; 717140751Swpaul 718140751Swpaultypedef struct io_status_block io_status_block; 719140751Swpaul 720140751Swpaulstruct kapc { 721140751Swpaul uint16_t apc_type; 722140751Swpaul uint16_t apc_size; 723140751Swpaul uint32_t apc_spare0; 724140751Swpaul void *apc_thread; 725140751Swpaul list_entry apc_list; 726140751Swpaul void *apc_kernfunc; 727140751Swpaul void *apc_rundownfunc; 728140751Swpaul void *apc_normalfunc; 729140751Swpaul void *apc_normctx; 730140751Swpaul void *apc_sysarg1; 731140751Swpaul void *apc_sysarg2; 732140751Swpaul uint8_t apc_stateidx; 733140751Swpaul uint8_t apc_cpumode; 734140751Swpaul uint8_t apc_inserted; 735140751Swpaul}; 736140751Swpaul 737140751Swpaultypedef struct kapc kapc; 738140751Swpaul 739140751Swpaulstruct io_stack_location { 740140751Swpaul uint8_t isl_major; 741140751Swpaul uint8_t isl_minor; 742140751Swpaul uint8_t isl_flags; 743140751Swpaul uint8_t isl_ctl; 744140751Swpaul 745140751Swpaul /* 746140751Swpaul * There's a big-ass union here in the actual Windows 747140751Swpaul * definition of the stucture, but it contains stuff 748140751Swpaul * that doesn't really apply to BSD, and defining it 749140751Swpaul * all properly would require duplicating over a dozen 750140751Swpaul * other structures that we'll never use. Since the 751140751Swpaul * io_stack_location structure is opaque to drivers 752140751Swpaul * anyway, I'm not going to bother with the extra crap. 753140751Swpaul */ 754140751Swpaul 755140751Swpaul union { 756140751Swpaul struct { 757140751Swpaul void *isl_arg1; 758140751Swpaul void *isl_arg2; 759140751Swpaul void *isl_arg3; 760140751Swpaul void *isl_arg4; 761140751Swpaul } isl_others; 762140751Swpaul } isl_parameters; 763140751Swpaul 764140751Swpaul void *isl_devobj; 765140751Swpaul void *isl_fileobj; 766140751Swpaul void *isl_completionfunc; 767140751Swpaul void *isl_completionctx; 768140751Swpaul}; 769140751Swpaul 770140751Swpaultypedef struct io_stack_location io_stack_location; 771140751Swpaul 772140751Swpaul/* Stack location control flags */ 773140751Swpaul 774140751Swpaul#define SL_PENDING_RETURNED 0x01 775140751Swpaul#define SL_INVOKE_ON_CANCEL 0x20 776140751Swpaul#define SL_INVOKE_ON_SUCCESS 0x40 777140751Swpaul#define SL_INVOKE_ON_ERROR 0x80 778140751Swpaul 779125551Swpaulstruct irp { 780140751Swpaul uint16_t irp_type; 781140751Swpaul uint16_t irp_size; 782140751Swpaul mdl *irp_mdl; 783140751Swpaul uint32_t irp_flags; 784140751Swpaul union { 785140751Swpaul struct irp *irp_master; 786140751Swpaul uint32_t irp_irpcnt; 787140751Swpaul void *irp_sysbuf; 788140751Swpaul } irp_assoc; 789140751Swpaul list_entry irp_thlist; 790140751Swpaul io_status_block irp_iostat; 791140751Swpaul uint8_t irp_reqmode; 792140751Swpaul uint8_t irp_pendingreturned; 793140751Swpaul uint8_t irp_stackcnt; 794140751Swpaul uint8_t irp_currentstackloc; 795140751Swpaul uint8_t irp_cancel; 796140751Swpaul uint8_t irp_cancelirql; 797140751Swpaul uint8_t irp_apcenv; 798140751Swpaul uint8_t irp_allocflags; 799140751Swpaul io_status_block *irp_usriostat; 800140751Swpaul nt_kevent irp_userevent; 801140751Swpaul union { 802140751Swpaul struct { 803140751Swpaul void *irp_apcfunc; 804140751Swpaul void *irp_apcctx; 805140751Swpaul } irp_asyncparms; 806140751Swpaul uint64_t irp_allocsz; 807140751Swpaul } irp_overlay; 808140751Swpaul void *irp_cancelfunc; 809140751Swpaul void *irp_userbuf; 810140751Swpaul 811140751Swpaul /* Windows kernel info */ 812140751Swpaul 813140751Swpaul union { 814140751Swpaul struct { 815140751Swpaul union { 816140751Swpaul kdevice_qentry irp_dqe; 817140751Swpaul struct { 818140751Swpaul void *irp_drvctx[4]; 819140751Swpaul } s1; 820140751Swpaul } u1; 821140751Swpaul void *irp_thread; 822140751Swpaul char *irp_auxbuf; 823140751Swpaul struct { 824140751Swpaul list_entry irp_list; 825140751Swpaul union { 826140751Swpaul io_stack_location *irp_csl; 827140751Swpaul uint32_t irp_pkttype; 828140751Swpaul } u2; 829140751Swpaul } s2; 830140751Swpaul void *irp_fileobj; 831140751Swpaul } irp_overlay; 832140751Swpaul kapc irp_apc; 833140751Swpaul void *irp_compkey; 834140751Swpaul } irp_tail; 835125551Swpaul}; 836125551Swpaul 837140751Swpaul#define irp_csl s2.u2.irp_csl 838140751Swpaul#define irp_pkttype s2.u2.irp_pkttype 839140751Swpaul 840125551Swpaultypedef struct irp irp; 841125551Swpaul 842140751Swpaul#define IoGetCurrentIrpStackLocation(irp) \ 843140751Swpaul (irp)->irp_tail.irp_overlay.irp_csl 844140751Swpaul 845140751Swpaul#define IoGetNextIrpStackLocation(irp) \ 846140751Swpaul ((irp)->irp_tail.irp_overlay.irp_csl - 1) 847140751Swpaul 848140751Swpaul#define IoSetCompletionRoutine(irp, func, ctx, ok, err, cancel) \ 849140751Swpaul do { \ 850140751Swpaul io_stack_location *s; \ 851140751Swpaul s = IoGetNextIrpStackLocation((irp)); \ 852140751Swpaul s->isl_completionfunc = (func); \ 853140751Swpaul s->isl_completionctx = (ctx); \ 854140751Swpaul s->isl_ctl = 0; \ 855140751Swpaul if (ok) irp->ctl = SL_INVOKE_ON_SUCCESS; \ 856140751Swpaul if (err) irp->ctl |= SL_INVOKE_ON_ERROR; \ 857140751Swpaul if (cancel) irp->ctl |= SL_INVOKE_ON_CANCEL; \ 858140751Swpaul } while(0) 859140751Swpaul 860140751Swpaul#define IoMarkIrpPending(irp) \ 861140751Swpaul IoGetCurrentIrpStackLocation(irp)->isl_ctl |= SL_PENDING_RETURNED 862140751Swpaul 863140751Swpaul#define IoSizeOfIrp(s) \ 864140751Swpaul ((uint16_t) (sizeof(itp) + ((s) * (sizeof(io_stack_location))))) 865140751Swpaul 866140751Swpaul#define IoCopyCurrentIrpStackLocationToNext(irp) \ 867140751Swpaul do { \ 868140751Swpaul io_stack_location *src, *dst; \ 869140751Swpaul src = IoGetCurrentIrpStackLocation(irp); \ 870140751Swpaul dst = IoGetNextIrpStackLocation(irp); \ 871140751Swpaul bcopy((char *)src, (char *)dst, \ 872140751Swpaul offsetof(io_stack_location, isl_completionfunc)); \ 873140751Swpaul } while(0) 874140751Swpaul 875140751Swpaul#define IoSkipCurrentIrpStackLocation(irp) \ 876140751Swpaul do { \ 877140751Swpaul (irp)->irp_currentstackloc++; \ 878140751Swpaul (irp)->irp_tail.irp_overlay.irp_csl++; \ 879140751Swpaul } while(0) 880140751Swpaul 881125551Swpaultypedef uint32_t (*driver_dispatch)(device_object *, irp *); 882125551Swpaul 883140751Swpaul/* 884140751Swpaul * The driver_object is allocated once for each driver that's loaded 885140751Swpaul * into the system. A new one is allocated for each driver and 886140751Swpaul * populated a bit via the driver's DriverEntry function. 887140751Swpaul * In general, a Windows DriverEntry() function will provide a pointer 888140751Swpaul * to its AddDevice() method and set up the dispatch table. 889140751Swpaul * For NDIS drivers, this is all done behind the scenes in the 890140751Swpaul * NdisInitializeWrapper() and/or NdisMRegisterMiniport() routines. 891140751Swpaul */ 892140751Swpaul 893140751Swpaulstruct driver_object { 894140751Swpaul uint16_t dro_type; 895140751Swpaul uint16_t dro_size; 896140751Swpaul device_object *dro_devobj; 897140751Swpaul uint32_t dro_flags; 898140751Swpaul void *dro_driverstart; 899140751Swpaul uint32_t dro_driversize; 900140751Swpaul void *dro_driversection; 901140751Swpaul driver_extension dro_driverext; 902140751Swpaul unicode_string dro_drivername; 903140751Swpaul unicode_string *dro_hwdb; 904140751Swpaul void *dro_pfastiodispatch; 905140751Swpaul void *dro_driverinitfunc; 906140751Swpaul void *dro_driverstartiofunc; 907140751Swpaul void *dro_driverunloadfunc; 908140751Swpaul void *dro_dispatch[IRP_MJ_MAXIMUM_FUNCTION + 1]; 909140751Swpaul}; 910140751Swpaul 911140751Swpaultypedef struct driver_object driver_object; 912140751Swpaul 913125551Swpaul#define DEVPROP_DEVICE_DESCRIPTION 0x00000000 914125551Swpaul#define DEVPROP_HARDWARE_ID 0x00000001 915125551Swpaul#define DEVPROP_COMPATIBLE_IDS 0x00000002 916125551Swpaul#define DEVPROP_BOOTCONF 0x00000003 917125551Swpaul#define DEVPROP_BOOTCONF_TRANSLATED 0x00000004 918125551Swpaul#define DEVPROP_CLASS_NAME 0x00000005 919125551Swpaul#define DEVPROP_CLASS_GUID 0x00000006 920125551Swpaul#define DEVPROP_DRIVER_KEYNAME 0x00000007 921125551Swpaul#define DEVPROP_MANUFACTURER 0x00000008 922125551Swpaul#define DEVPROP_FRIENDLYNAME 0x00000009 923125551Swpaul#define DEVPROP_LOCATION_INFO 0x0000000A 924125551Swpaul#define DEVPROP_PHYSDEV_NAME 0x0000000B 925125551Swpaul#define DEVPROP_BUSTYPE_GUID 0x0000000C 926125551Swpaul#define DEVPROP_LEGACY_BUSTYPE 0x0000000D 927125551Swpaul#define DEVPROP_BUS_NUMBER 0x0000000E 928125551Swpaul#define DEVPROP_ENUMERATOR_NAME 0x0000000F 929125551Swpaul#define DEVPROP_ADDRESS 0x00000010 930125551Swpaul#define DEVPROP_UINUMBER 0x00000011 931125551Swpaul#define DEVPROP_INSTALL_STATE 0x00000012 932125551Swpaul#define DEVPROP_REMOVAL_POLICY 0x00000013 933125551Swpaul 934125551Swpaul#define STATUS_SUCCESS 0x00000000 935125551Swpaul#define STATUS_USER_APC 0x000000C0 936125551Swpaul#define STATUS_KERNEL_APC 0x00000100 937125551Swpaul#define STATUS_ALERTED 0x00000101 938125551Swpaul#define STATUS_TIMEOUT 0x00000102 939125551Swpaul#define STATUS_INVALID_PARAMETER 0xC000000D 940125551Swpaul#define STATUS_INVALID_DEVICE_REQUEST 0xC0000010 941125551Swpaul#define STATUS_BUFFER_TOO_SMALL 0xC0000023 942125551Swpaul#define STATUS_MUTANT_NOT_OWNED 0xC0000046 943125551Swpaul#define STATUS_INVALID_PARAMETER_2 0xC00000F0 944125551Swpaul 945125551Swpaul#define STATUS_WAIT_0 0x00000000 946125551Swpaul 947127284Swpaul/* 948127284Swpaul * FreeBSD's kernel stack is 2 pages in size by default. The 949127284Swpaul * Windows stack is larger, so we need to give our threads more 950127284Swpaul * stack pages. 4 should be enough, we use 8 just to extra safe. 951127284Swpaul */ 952127284Swpaul#define NDIS_KSTACK_PAGES 8 953127284Swpaul 954123474Swpaulextern image_patch_table ntoskrnl_functbl[]; 955123474Swpaul 956123474Swpaul__BEGIN_DECLS 957123474Swpaulextern int ntoskrnl_libinit(void); 958123474Swpaulextern int ntoskrnl_libfini(void); 959140751Swpaul__stdcall extern void KeInitializeDpc(kdpc *, void *, void *); 960140751Swpaul__stdcall extern uint8_t KeInsertQueueDpc(kdpc *, void *, void *); 961140751Swpaul__stdcall extern uint8_t KeRemoveQueueDpc(kdpc *); 962140751Swpaul__stdcall extern void KeInitializeTimer(ktimer *); 963140751Swpaul__stdcall extern void KeInitializeTimerEx(ktimer *, uint32_t); 964140751Swpaul__stdcall extern uint8_t KeSetTimer(ktimer *, int64_t, kdpc *); 965140751Swpaul__stdcall extern uint8_t KeSetTimerEx(ktimer *, int64_t, 966127248Swpaul uint32_t, kdpc *); 967140751Swpaul__stdcall extern uint8_t KeCancelTimer(ktimer *); 968140751Swpaul__stdcall extern uint8_t KeReadStateTimer(ktimer *); 969140751Swpaul__stdcall extern uint32_t KeWaitForSingleObject(nt_dispatch_header *, uint32_t, 970127248Swpaul uint32_t, uint8_t, int64_t *); 971140751Swpaul__stdcall extern void KeInitializeEvent(nt_kevent *, uint32_t, uint8_t); 972140751Swpaul__stdcall extern void KeClearEvent(nt_kevent *); 973140751Swpaul__stdcall extern uint32_t KeReadStateEvent(nt_kevent *); 974140751Swpaul__stdcall extern uint32_t KeSetEvent(nt_kevent *, uint32_t, uint8_t); 975140751Swpaul__stdcall extern uint32_t KeResetEvent(nt_kevent *); 976140751Swpaul__fastcall extern void KefAcquireSpinLockAtDpcLevel(REGARGS1(kspin_lock *)); 977140751Swpaul__fastcall extern void KefReleaseSpinLockFromDpcLevel(REGARGS1(kspin_lock *)); 978140751Swpaul__stdcall extern void KeInitializeSpinLock(kspin_lock *); 979140751Swpaul__fastcall extern uint32_t IofCallDriver(REGARGS2(device_object *, irp *)); 980140751Swpaul__fastcall extern void IofCompleteRequest(REGARGS2(irp *, uint8_t)); 981128229Swpaul 982140751Swpaul#define IoCallDriver(a, b) FASTCALL2(IofCallDriver, a, b) 983140751Swpaul#define IoCompleteRequest(a, b) FASTCALL2(IofCompleteRequest, a, b) 984140751Swpaul 985128229Swpaul/* 986128229Swpaul * On the Windows x86 arch, KeAcquireSpinLock() and KeReleaseSpinLock() 987128229Swpaul * routines live in the HAL. We try to imitate this behavior. 988128229Swpaul */ 989128229Swpaul#ifdef __i386__ 990140751Swpaul#define KeAcquireSpinLock(a, b) *(b) = FASTCALL1(KfAcquireSpinLock, a) 991140751Swpaul#define KeReleaseSpinLock(a, b) FASTCALL2(KfReleaseSpinLock, a, b) 992140751Swpaul#define KeRaiseIrql(a) FASTCALL1(KfRaiseIrql, a) 993140751Swpaul#define KeLowerIrql(a) FASTCALL1(KfLowerIrql, a) 994128229Swpaul#endif /* __i386__ */ 995123474Swpaul__END_DECLS 996123474Swpaul 997123474Swpaul#endif /* _NTOSKRNL_VAR_H_ */ 998