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