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