|
|
1.1 ! root 1: /*++ ! 2: ! 3: Copyright (c) 1989-1993 Microsoft Corporation ! 4: ! 5: Module Name: ! 6: ! 7: stdrvr.c ! 8: ! 9: Abstract: ! 10: ! 11: This module contains code which defines the NT Sample ! 12: transport provider's device object. ! 13: ! 14: Environment: ! 15: ! 16: Kernel mode ! 17: ! 18: Revision History: ! 19: ! 20: ! 21: --*/ ! 22: ! 23: #include "st.h" ! 24: ! 25: ! 26: // ! 27: // This is a list of all the device contexts that ST owns, ! 28: // used while unloading. ! 29: // ! 30: ! 31: LIST_ENTRY StDeviceList = {0,0}; // initialized for real at runtime. ! 32: ! 33: ! 34: ! 35: // ! 36: // Forward declaration of various routines used in this module. ! 37: // ! 38: ! 39: NTSTATUS ! 40: DriverEntry( ! 41: IN PDRIVER_OBJECT DriverObject, ! 42: IN PUNICODE_STRING RegistryPath ! 43: ); ! 44: ! 45: VOID ! 46: StUnload( ! 47: IN PDRIVER_OBJECT DriverObject ! 48: ); ! 49: ! 50: NTSTATUS ! 51: StConfigureTransport ( ! 52: IN PUNICODE_STRING RegistryPath, ! 53: IN PCONFIG_DATA * ConfigData ! 54: ); ! 55: ! 56: VOID ! 57: StFreeConfigurationInfo ( ! 58: IN PCONFIG_DATA ConfigurationInfo ! 59: ); ! 60: ! 61: NTSTATUS ! 62: StDeviceControl( ! 63: IN PDEVICE_OBJECT DeviceObject, ! 64: IN PIRP Irp, ! 65: IN PIO_STACK_LOCATION IrpSp ! 66: ); ! 67: ! 68: NTSTATUS ! 69: StOpenAddress( ! 70: IN PDEVICE_OBJECT DeviceObject, ! 71: IN PIRP Irp, ! 72: IN PIO_STACK_LOCATION IrpSp ! 73: ); ! 74: ! 75: NTSTATUS ! 76: StCloseAddress( ! 77: IN PDEVICE_OBJECT DeviceObject, ! 78: IN PIRP Irp, ! 79: IN PIO_STACK_LOCATION IrpSp ! 80: ); ! 81: ! 82: NTSTATUS ! 83: StOpenConnection( ! 84: IN PDEVICE_OBJECT DeviceObject, ! 85: IN PIRP Irp, ! 86: IN PIO_STACK_LOCATION IrpSp ! 87: ); ! 88: ! 89: NTSTATUS ! 90: StCloseConnection( ! 91: IN PDEVICE_OBJECT DeviceObject, ! 92: IN PIRP Irp, ! 93: IN PIO_STACK_LOCATION IrpSp ! 94: ); ! 95: ! 96: NTSTATUS ! 97: StTdiAccept( ! 98: IN PIRP Irp ! 99: ); ! 100: ! 101: NTSTATUS ! 102: StTdiConnect( ! 103: IN PIRP Irp ! 104: ); ! 105: ! 106: NTSTATUS ! 107: StTdiDisconnect( ! 108: IN PIRP Irp ! 109: ); ! 110: ! 111: NTSTATUS ! 112: StTdiDisassociateAddress ( ! 113: IN PIRP Irp ! 114: ); ! 115: ! 116: NTSTATUS ! 117: StTdiAssociateAddress( ! 118: IN PIRP Irp ! 119: ); ! 120: ! 121: NTSTATUS ! 122: StTdiListen( ! 123: IN PIRP Irp ! 124: ); ! 125: ! 126: NTSTATUS ! 127: StTdiQueryInformation( ! 128: IN PDEVICE_CONTEXT DeviceContext, ! 129: IN PIRP Irp ! 130: ); ! 131: ! 132: NTSTATUS ! 133: StTdiReceive( ! 134: IN PIRP Irp ! 135: ); ! 136: ! 137: NTSTATUS ! 138: StTdiReceiveDatagram( ! 139: IN PIRP Irp ! 140: ); ! 141: ! 142: NTSTATUS ! 143: StTdiSend( ! 144: IN PIRP Irp ! 145: ); ! 146: ! 147: NTSTATUS ! 148: StTdiSendDatagram( ! 149: IN PIRP Irp ! 150: ); ! 151: ! 152: NTSTATUS ! 153: StTdiSetEventHandler( ! 154: IN PIRP Irp ! 155: ); ! 156: ! 157: NTSTATUS ! 158: StTdiSetInformation( ! 159: IN PIRP Irp ! 160: ); ! 161: ! 162: VOID ! 163: StDeallocateResources( ! 164: IN PDEVICE_CONTEXT DeviceContext ! 165: ); ! 166: ! 167: #ifdef ALLOC_PRAGMA ! 168: #pragma alloc_text(init,DriverEntry) ! 169: #endif ! 170: ! 171: ! 172: ! 173: NTSTATUS ! 174: DriverEntry( ! 175: IN PDRIVER_OBJECT DriverObject, ! 176: IN PUNICODE_STRING RegistryPath ! 177: ) ! 178: ! 179: /*++ ! 180: ! 181: Routine Description: ! 182: ! 183: This routine performs initialization of the sample ! 184: transport driver. It creates the device objects for the transport ! 185: provider and performs other driver initialization. ! 186: ! 187: Arguments: ! 188: ! 189: DriverObject - Pointer to driver object created by the system. ! 190: ! 191: RegistryPath - The name of ST's node in the registry. ! 192: ! 193: Return Value: ! 194: ! 195: The function value is the final status from the initialization operation. ! 196: ! 197: --*/ ! 198: ! 199: { ! 200: ULONG i, j; ! 201: STRING nameString; ! 202: PDEVICE_CONTEXT DeviceContext; ! 203: PTP_REQUEST Request; ! 204: PTP_CONNECTION Connection; ! 205: PTP_ADDRESS_FILE AddressFile; ! 206: PTP_ADDRESS Address; ! 207: PTP_PACKET Packet; ! 208: PNDIS_PACKET NdisPacket; ! 209: PRECEIVE_PACKET_TAG ReceiveTag; ! 210: PBUFFER_TAG BufferTag; ! 211: NTSTATUS status; ! 212: UINT SuccessfulOpens; ! 213: UINT MaxUserData; ! 214: ! 215: PCONFIG_DATA StConfig = NULL; ! 216: ! 217: ! 218: ASSERT (sizeof (SHORT) == 2); ! 219: ! 220: // ! 221: // This allocates the CONFIG_DATA structure and returns ! 222: // it in StConfig. ! 223: // ! 224: ! 225: status = StConfigureTransport(RegistryPath, &StConfig); ! 226: ! 227: if (!NT_SUCCESS (status)) { ! 228: PANIC (" Failed to initialize transport, St initialization failed.\n"); ! 229: return STATUS_INSUFFICIENT_RESOURCES; ! 230: } ! 231: ! 232: // ! 233: // make ourselves known to the NDIS wrapper. ! 234: // ! 235: ! 236: RtlInitString( &nameString, ST_DEVICE_NAME ); ! 237: ! 238: status = StRegisterProtocol (&nameString); ! 239: ! 240: if (!NT_SUCCESS (status)) { ! 241: ! 242: StFreeConfigurationInfo(StConfig); ! 243: PANIC ("StInitialize: RegisterProtocol failed!\n"); ! 244: ! 245: StWriteGeneralErrorLog( ! 246: (PVOID)DriverObject, ! 247: EVENT_TRANSPORT_REGISTER_FAILED, ! 248: 607, ! 249: status, ! 250: NULL, ! 251: 0, ! 252: NULL); ! 253: ! 254: return STATUS_INSUFFICIENT_RESOURCES; ! 255: ! 256: } ! 257: ! 258: ! 259: // ! 260: // Initialize the driver object with this driver's entry points. ! 261: // ! 262: ! 263: DriverObject->MajorFunction [IRP_MJ_CREATE] = StDispatchOpenClose; ! 264: DriverObject->MajorFunction [IRP_MJ_CLOSE] = StDispatchOpenClose; ! 265: DriverObject->MajorFunction [IRP_MJ_CLEANUP] = StDispatchOpenClose; ! 266: DriverObject->MajorFunction [IRP_MJ_INTERNAL_DEVICE_CONTROL] = StDispatchInternal; ! 267: DriverObject->MajorFunction [IRP_MJ_DEVICE_CONTROL] = StDispatch; ! 268: ! 269: DriverObject->DriverUnload = StUnload; ! 270: ! 271: // ! 272: // Initialize the global list of devices. ! 273: // ! 274: ! 275: InitializeListHead (&StDeviceList); ! 276: ! 277: SuccessfulOpens = 0; ! 278: ! 279: for (j=0;j<StConfig->NumAdapters;j++ ) { ! 280: ! 281: ! 282: // ! 283: // Loop through all the adapters that are in the configuration ! 284: // information structure. Allocate a device object for each ! 285: // one that we find. ! 286: // ! 287: ! 288: status = StCreateDeviceContext (DriverObject, &StConfig->Names[StConfig->DevicesOffset+j], &DeviceContext); ! 289: ! 290: if (!NT_SUCCESS (status)) { ! 291: continue; ! 292: } ! 293: ! 294: // ! 295: // Initialize our counter that records memory usage. ! 296: // ! 297: ! 298: DeviceContext->MemoryUsage = 0; ! 299: DeviceContext->MemoryLimit = StConfig->MaxMemoryUsage; ! 300: ! 301: // ! 302: // Now fire up NDIS so this adapter talks ! 303: // ! 304: ! 305: status = StInitializeNdis (DeviceContext, ! 306: StConfig, ! 307: j); ! 308: ! 309: if (!NT_SUCCESS (status)) { ! 310: ! 311: // ! 312: // Log an error. ! 313: // ! 314: ! 315: StWriteGeneralErrorLog( ! 316: DeviceContext, ! 317: EVENT_TRANSPORT_BINDING_FAILED, ! 318: 601, ! 319: status, ! 320: StConfig->Names[j].Buffer, ! 321: 0, ! 322: NULL); ! 323: ! 324: StDereferenceDeviceContext ("Initialize NDIS failed", DeviceContext); ! 325: continue; ! 326: ! 327: } ! 328: ! 329: ! 330: // ! 331: // Initialize our provider information structure; since it ! 332: // doesn't change, we just keep it around and copy it to ! 333: // whoever requests it. ! 334: // ! 335: ! 336: ! 337: MacReturnMaxDataSize( ! 338: &DeviceContext->MacInfo, ! 339: NULL, ! 340: 0, ! 341: DeviceContext->MaxSendPacketSize, ! 342: &MaxUserData); ! 343: ! 344: DeviceContext->Information.Version = 0x0100; ! 345: DeviceContext->Information.MaxSendSize = 0x1fffe; // 128k - 2 ! 346: DeviceContext->Information.MaxConnectionUserData = 0; ! 347: DeviceContext->Information.MaxDatagramSize = MaxUserData - sizeof(ST_HEADER); ! 348: DeviceContext->Information.ServiceFlags = ST_SERVICE_FLAGS; ! 349: DeviceContext->Information.MinimumLookaheadData = 128; ! 350: DeviceContext->Information.MaximumLookaheadData = ! 351: DeviceContext->MaxReceivePacketSize - sizeof(ST_HEADER); ! 352: DeviceContext->Information.NumberOfResources = ST_TDI_RESOURCES; ! 353: KeQuerySystemTime (&DeviceContext->Information.StartTime); ! 354: ! 355: ! 356: // ! 357: // Allocate various structures we will need. ! 358: // ! 359: ! 360: ! 361: // ! 362: // The TP_PACKET structure has a CHAR[1] field at the end ! 363: // which we expand upon to include all the headers needed; ! 364: // the size of the MAC header depends on what the adapter ! 365: // told us about its max header size. ! 366: // ! 367: ! 368: DeviceContext->PacketHeaderLength = ! 369: DeviceContext->MacInfo.MaxHeaderLength + ! 370: sizeof (ST_HEADER); ! 371: ! 372: DeviceContext->PacketLength = ! 373: FIELD_OFFSET(TP_PACKET, Header[0]) + ! 374: DeviceContext->PacketHeaderLength; ! 375: ! 376: ! 377: // ! 378: // The BUFFER_TAG structure has a CHAR[1] field at the end ! 379: // which we expand upong to include all the frame data. ! 380: // ! 381: ! 382: DeviceContext->ReceiveBufferLength = ! 383: DeviceContext->MaxReceivePacketSize + ! 384: FIELD_OFFSET(BUFFER_TAG, Buffer[0]); ! 385: ! 386: ! 387: for (i=0; i<StConfig->InitRequests; i++) { ! 388: ! 389: StAllocateRequest (DeviceContext, &Request); ! 390: ! 391: if (Request == NULL) { ! 392: PANIC ("StInitialize: insufficient memory to allocate requests.\n"); ! 393: status = STATUS_INSUFFICIENT_RESOURCES; ! 394: goto cleanup; ! 395: } ! 396: ! 397: InsertTailList (&DeviceContext->RequestPool, &Request->Linkage); ! 398: } ! 399: ! 400: DeviceContext->RequestInitAllocated = StConfig->InitRequests; ! 401: DeviceContext->RequestMaxAllocated = StConfig->MaxRequests; ! 402: ! 403: ! 404: for (i=0; i<StConfig->InitConnections; i++) { ! 405: ! 406: StAllocateConnection (DeviceContext, &Connection); ! 407: ! 408: if (Connection == NULL) { ! 409: PANIC ("StInitialize: insufficient memory to allocate connections.\n"); ! 410: status = STATUS_INSUFFICIENT_RESOURCES; ! 411: goto cleanup; ! 412: } ! 413: ! 414: InsertTailList (&DeviceContext->ConnectionPool, &Connection->LinkList); ! 415: } ! 416: ! 417: DeviceContext->ConnectionInitAllocated = StConfig->InitConnections; ! 418: DeviceContext->ConnectionMaxAllocated = StConfig->MaxConnections; ! 419: ! 420: ! 421: for (i=0; i<StConfig->InitAddressFiles; i++) { ! 422: ! 423: StAllocateAddressFile (DeviceContext, &AddressFile); ! 424: ! 425: if (AddressFile == NULL) { ! 426: PANIC ("StInitialize: insufficient memory to allocate Address Files.\n"); ! 427: status = STATUS_INSUFFICIENT_RESOURCES; ! 428: goto cleanup; ! 429: } ! 430: ! 431: InsertTailList (&DeviceContext->AddressFilePool, &AddressFile->Linkage); ! 432: } ! 433: ! 434: DeviceContext->AddressFileInitAllocated = StConfig->InitAddressFiles; ! 435: DeviceContext->AddressFileMaxAllocated = StConfig->MaxAddressFiles; ! 436: ! 437: ! 438: for (i=0; i<StConfig->InitAddresses; i++) { ! 439: ! 440: StAllocateAddress (DeviceContext, &Address); ! 441: if (Address == NULL) { ! 442: PANIC ("StInitialize: insufficient memory to allocate addresses.\n"); ! 443: status = STATUS_INSUFFICIENT_RESOURCES; ! 444: goto cleanup; ! 445: } ! 446: ! 447: InsertTailList (&DeviceContext->AddressPool, &Address->Linkage); ! 448: } ! 449: ! 450: DeviceContext->AddressInitAllocated = StConfig->InitAddresses; ! 451: DeviceContext->AddressMaxAllocated = StConfig->MaxAddresses; ! 452: ! 453: ! 454: for (i=0; i<StConfig->InitPackets; i++) { ! 455: ! 456: StAllocateSendPacket (DeviceContext, &Packet); ! 457: if (Packet == NULL) { ! 458: PANIC ("StInitialize: insufficient memory to allocate packets.\n"); ! 459: status = STATUS_INSUFFICIENT_RESOURCES; ! 460: goto cleanup; ! 461: } ! 462: ! 463: PushEntryList (&DeviceContext->PacketPool, (PSINGLE_LIST_ENTRY)&Packet->Linkage); ! 464: } ! 465: ! 466: DeviceContext->PacketInitAllocated = StConfig->InitPackets; ! 467: ! 468: ! 469: for (i=0; i<StConfig->InitReceivePackets; i++) { ! 470: ! 471: StAllocateReceivePacket (DeviceContext, &NdisPacket); ! 472: ! 473: if (NdisPacket == NULL) { ! 474: PANIC ("StInitialize: insufficient memory to allocate packet MDLs.\n"); ! 475: status = STATUS_INSUFFICIENT_RESOURCES; ! 476: goto cleanup; ! 477: } ! 478: ! 479: ReceiveTag = (PRECEIVE_PACKET_TAG)NdisPacket->ProtocolReserved; ! 480: PushEntryList (&DeviceContext->ReceivePacketPool, (PSINGLE_LIST_ENTRY)&ReceiveTag->Linkage); ! 481: ! 482: } ! 483: ! 484: DeviceContext->ReceivePacketInitAllocated = StConfig->InitReceivePackets; ! 485: ! 486: ! 487: for (i=0; i<StConfig->InitReceiveBuffers; i++) { ! 488: ! 489: StAllocateReceiveBuffer (DeviceContext, &BufferTag); ! 490: ! 491: if (BufferTag == NULL) { ! 492: PANIC ("StInitialize: Unable to allocate receive packet.\n"); ! 493: status = STATUS_INSUFFICIENT_RESOURCES; ! 494: goto cleanup; ! 495: } ! 496: ! 497: PushEntryList (&DeviceContext->ReceiveBufferPool, &BufferTag->Linkage); ! 498: ! 499: } ! 500: ! 501: DeviceContext->ReceiveBufferInitAllocated = StConfig->InitReceiveBuffers; ! 502: ! 503: ! 504: // ! 505: // Now link the device into the global list. ! 506: // ! 507: ! 508: InsertTailList (&StDeviceList, &DeviceContext->Linkage); ! 509: ! 510: DeviceContext->State = DEVICECONTEXT_STATE_OPEN; ! 511: ! 512: ++SuccessfulOpens; ! 513: ! 514: continue; ! 515: ! 516: cleanup: ! 517: ! 518: StWriteResourceErrorLog (DeviceContext, DeviceContext->MemoryUsage, 501); ! 519: ! 520: // ! 521: // Cleanup whatever device context we were initializing ! 522: // when we failed. ! 523: // ! 524: ! 525: StFreeResources (DeviceContext); ! 526: StCloseNdis (DeviceContext); ! 527: StDereferenceDeviceContext ("Load failed", DeviceContext); ! 528: ! 529: } ! 530: ! 531: StFreeConfigurationInfo(StConfig); ! 532: ! 533: return ((SuccessfulOpens > 0) ? STATUS_SUCCESS : STATUS_DEVICE_DOES_NOT_EXIST); ! 534: ! 535: } ! 536: ! 537: VOID ! 538: StUnload( ! 539: IN PDRIVER_OBJECT DriverObject ! 540: ) ! 541: ! 542: /*++ ! 543: ! 544: Routine Description: ! 545: ! 546: This routine unloads the sample transport driver. ! 547: It unbinds from any NDIS drivers that are open and frees all resources ! 548: associated with the transport. The I/O system will not call us until ! 549: nobody above has ST open. ! 550: ! 551: Arguments: ! 552: ! 553: DriverObject - Pointer to driver object created by the system. ! 554: ! 555: Return Value: ! 556: ! 557: None. When the function returns, the driver is unloaded. ! 558: ! 559: --*/ ! 560: ! 561: { ! 562: ! 563: PDEVICE_CONTEXT DeviceContext; ! 564: PLIST_ENTRY p; ! 565: ! 566: ! 567: UNREFERENCED_PARAMETER (DriverObject); ! 568: ! 569: // ! 570: // Walk the list of device contexts. ! 571: // ! 572: ! 573: while (!IsListEmpty (&StDeviceList)) { ! 574: ! 575: p = RemoveHeadList (&StDeviceList); ! 576: DeviceContext = CONTAINING_RECORD (p, DEVICE_CONTEXT, Linkage); ! 577: ! 578: // ! 579: // Remove all the storage associated with the device. ! 580: // ! 581: ! 582: StFreeResources (DeviceContext); ! 583: ! 584: // ! 585: // Free the packet pools, etc. and close the ! 586: // adapter. ! 587: // ! 588: ! 589: StCloseNdis (DeviceContext); ! 590: ! 591: // ! 592: // And remove the creation reference from the device ! 593: // context. ! 594: // ! 595: ! 596: StDereferenceDeviceContext ("Unload", DeviceContext); ! 597: ! 598: } ! 599: ! 600: ! 601: // ! 602: // Finally, remove ourselves as an NDIS protocol. ! 603: // ! 604: ! 605: StDeregisterProtocol(); ! 606: ! 607: return; ! 608: ! 609: } ! 610: ! 611: ! 612: VOID ! 613: StFreeResources ( ! 614: IN PDEVICE_CONTEXT DeviceContext ! 615: ) ! 616: /*++ ! 617: ! 618: Routine Description: ! 619: ! 620: This routine is called by ST to clean up the data structures associated ! 621: with a given DeviceContext. When this routine exits, the DeviceContext ! 622: should be deleted as it no longer has any assocaited resources. ! 623: ! 624: Arguments: ! 625: ! 626: DeviceContext - Pointer to the DeviceContext we wish to clean up. ! 627: ! 628: Return Value: ! 629: ! 630: None. ! 631: ! 632: --*/ ! 633: { ! 634: PLIST_ENTRY p; ! 635: PSINGLE_LIST_ENTRY s; ! 636: PTP_PACKET packet; ! 637: PTP_ADDRESS address; ! 638: PTP_CONNECTION connection; ! 639: PTP_REQUEST request; ! 640: PTP_ADDRESS_FILE addressFile; ! 641: PNDIS_PACKET ndisPacket; ! 642: PBUFFER_TAG BufferTag; ! 643: ! 644: ! 645: // ! 646: // Clean up packet pool. ! 647: // ! 648: ! 649: while ( DeviceContext->PacketPool.Next != NULL ) { ! 650: s = PopEntryList( &DeviceContext->PacketPool ); ! 651: packet = CONTAINING_RECORD( s, TP_PACKET, Linkage ); ! 652: ! 653: StDeallocateSendPacket (DeviceContext, packet); ! 654: } ! 655: ! 656: // ! 657: // Clean up address pool. ! 658: // ! 659: ! 660: while ( !IsListEmpty (&DeviceContext->AddressPool) ) { ! 661: p = RemoveHeadList (&DeviceContext->AddressPool); ! 662: address = CONTAINING_RECORD (p, TP_ADDRESS, Linkage); ! 663: ! 664: StDeallocateAddress (DeviceContext, address); ! 665: } ! 666: ! 667: // ! 668: // Clean up address file pool. ! 669: // ! 670: ! 671: while ( !IsListEmpty (&DeviceContext->AddressFilePool) ) { ! 672: p = RemoveHeadList (&DeviceContext->AddressFilePool); ! 673: addressFile = CONTAINING_RECORD (p, TP_ADDRESS_FILE, Linkage); ! 674: ! 675: StDeallocateAddressFile (DeviceContext, addressFile); ! 676: } ! 677: ! 678: // ! 679: // Clean up connection pool. ! 680: // ! 681: ! 682: while ( !IsListEmpty (&DeviceContext->ConnectionPool) ) { ! 683: p = RemoveHeadList (&DeviceContext->ConnectionPool); ! 684: connection = CONTAINING_RECORD (p, TP_CONNECTION, LinkList); ! 685: ! 686: StDeallocateConnection (DeviceContext, connection); ! 687: } ! 688: ! 689: // ! 690: // Clean up request pool. ! 691: // ! 692: ! 693: while ( !IsListEmpty( &DeviceContext->RequestPool ) ) { ! 694: p = RemoveHeadList( &DeviceContext->RequestPool ); ! 695: request = CONTAINING_RECORD (p, TP_REQUEST, Linkage ); ! 696: ! 697: StDeallocateRequest (DeviceContext, request); ! 698: } ! 699: ! 700: // ! 701: // Clean up receive packet pool ! 702: // ! 703: ! 704: while ( DeviceContext->ReceivePacketPool.Next != NULL) { ! 705: s = PopEntryList (&DeviceContext->ReceivePacketPool); ! 706: ! 707: // ! 708: // HACK: This works because Linkage is the first field in ! 709: // ProtocolReserved for a receive packet. ! 710: // ! 711: ! 712: ndisPacket = CONTAINING_RECORD (s, NDIS_PACKET, ProtocolReserved[0]); ! 713: ! 714: StDeallocateReceivePacket (DeviceContext, ndisPacket); ! 715: } ! 716: ! 717: ! 718: // ! 719: // Clean up receive buffer pool. ! 720: // ! 721: ! 722: while ( DeviceContext->ReceiveBufferPool.Next != NULL ) { ! 723: s = PopEntryList( &DeviceContext->ReceiveBufferPool ); ! 724: BufferTag = CONTAINING_RECORD (s, BUFFER_TAG, Linkage ); ! 725: ! 726: StDeallocateReceiveBuffer (DeviceContext, BufferTag); ! 727: } ! 728: ! 729: ! 730: return; ! 731: ! 732: } /* StFreeResources */ ! 733: ! 734: ! 735: NTSTATUS ! 736: StDispatch( ! 737: IN PDEVICE_OBJECT DeviceObject, ! 738: IN PIRP Irp ! 739: ) ! 740: ! 741: /*++ ! 742: ! 743: Routine Description: ! 744: ! 745: This routine is the main dispatch routine for the ST device driver. ! 746: It accepts an I/O Request Packet, performs the request, and then ! 747: returns with the appropriate status. ! 748: ! 749: Arguments: ! 750: ! 751: DeviceObject - Pointer to the device object for this driver. ! 752: ! 753: Irp - Pointer to the request packet representing the I/O request. ! 754: ! 755: Return Value: ! 756: ! 757: The function value is the status of the operation. ! 758: ! 759: --*/ ! 760: ! 761: { ! 762: NTSTATUS Status; ! 763: PIO_STACK_LOCATION IrpSp; ! 764: PDEVICE_CONTEXT DeviceContext; ! 765: ! 766: // ! 767: // Check to see if ST has been initialized; if not, don't allow any use. ! 768: // Note that this only covers any user mode code use; kernel TDI clients ! 769: // will fail on their creation of an endpoint. ! 770: // ! 771: ! 772: DeviceContext = (PDEVICE_CONTEXT)DeviceObject; ! 773: if (DeviceContext->State != DEVICECONTEXT_STATE_OPEN) { ! 774: Irp->IoStatus.Status = STATUS_INVALID_DEVICE_STATE; ! 775: IoCompleteRequest (Irp, IO_NETWORK_INCREMENT); ! 776: return STATUS_INVALID_DEVICE_STATE; ! 777: } ! 778: ! 779: // ! 780: // Make sure status information is consistent every time. ! 781: // ! 782: ! 783: IoMarkIrpPending (Irp); ! 784: Irp->IoStatus.Status = STATUS_PENDING; ! 785: Irp->IoStatus.Information = 0; ! 786: ! 787: // ! 788: // Get a pointer to the current stack location in the IRP. This is where ! 789: // the function codes and parameters are stored. ! 790: // ! 791: ! 792: IrpSp = IoGetCurrentIrpStackLocation (Irp); ! 793: ! 794: // ! 795: // Case on the function that is being performed by the requestor. If the ! 796: // operation is a valid one for this device, then make it look like it was ! 797: // successfully completed, where possible. ! 798: // ! 799: ! 800: ! 801: switch (IrpSp->MajorFunction) { ! 802: ! 803: case IRP_MJ_DEVICE_CONTROL: ! 804: Status = StDeviceControl (DeviceObject, Irp, IrpSp); ! 805: break; ! 806: ! 807: default: ! 808: Status = STATUS_INVALID_DEVICE_REQUEST; ! 809: ! 810: } /* major function switch */ ! 811: ! 812: if (Status != STATUS_PENDING) { ! 813: IrpSp->Control &= ~SL_PENDING_RETURNED; ! 814: Irp->IoStatus.Status = Status; ! 815: IoCompleteRequest (Irp, IO_NETWORK_INCREMENT); ! 816: } ! 817: ! 818: // ! 819: // Return the immediate status code to the caller. ! 820: // ! 821: ! 822: return Status; ! 823: } /* StDispatch */ ! 824: ! 825: ! 826: NTSTATUS ! 827: StDispatchOpenClose( ! 828: IN PDEVICE_OBJECT DeviceObject, ! 829: IN PIRP Irp ! 830: ) ! 831: ! 832: /*++ ! 833: ! 834: Routine Description: ! 835: ! 836: This routine is the main dispatch routine for the ST device driver. ! 837: It accepts an I/O Request Packet, performs the request, and then ! 838: returns with the appropriate status. ! 839: ! 840: Arguments: ! 841: ! 842: DeviceObject - Pointer to the device object for this driver. ! 843: ! 844: Irp - Pointer to the request packet representing the I/O request. ! 845: ! 846: Return Value: ! 847: ! 848: The function value is the status of the operation. ! 849: ! 850: --*/ ! 851: ! 852: { ! 853: KIRQL oldirql; ! 854: PDEVICE_CONTEXT DeviceContext; ! 855: NTSTATUS Status; ! 856: PIO_STACK_LOCATION IrpSp; ! 857: PFILE_FULL_EA_INFORMATION openType; ! 858: USHORT i; ! 859: BOOLEAN found; ! 860: PTP_ADDRESS_FILE AddressFile; ! 861: PTP_CONNECTION Connection; ! 862: ! 863: // ! 864: // Check to see if ST has been initialized; if not, don't allow any use. ! 865: // Note that this only covers any user mode code use; kernel TDI clients ! 866: // will fail on their creation of an endpoint. ! 867: // ! 868: ! 869: DeviceContext = (PDEVICE_CONTEXT)DeviceObject; ! 870: if (DeviceContext->State != DEVICECONTEXT_STATE_OPEN) { ! 871: Irp->IoStatus.Status = STATUS_INVALID_DEVICE_STATE; ! 872: IoCompleteRequest (Irp, IO_NETWORK_INCREMENT); ! 873: return STATUS_INVALID_DEVICE_STATE; ! 874: } ! 875: ! 876: // ! 877: // Make sure status information is consistent every time. ! 878: // ! 879: ! 880: IoMarkIrpPending (Irp); ! 881: Irp->IoStatus.Status = STATUS_PENDING; ! 882: Irp->IoStatus.Information = 0; ! 883: ! 884: // ! 885: // Get a pointer to the current stack location in the IRP. This is where ! 886: // the function codes and parameters are stored. ! 887: // ! 888: ! 889: IrpSp = IoGetCurrentIrpStackLocation (Irp); ! 890: ! 891: // ! 892: // Case on the function that is being performed by the requestor. If the ! 893: // operation is a valid one for this device, then make it look like it was ! 894: // successfully completed, where possible. ! 895: // ! 896: ! 897: ! 898: switch (IrpSp->MajorFunction) { ! 899: ! 900: // ! 901: // The Create function opens a transport object (either address or ! 902: // connection). Access checking is performed on the specified ! 903: // address to ensure security of transport-layer addresses. ! 904: // ! 905: ! 906: case IRP_MJ_CREATE: ! 907: ! 908: openType = ! 909: (PFILE_FULL_EA_INFORMATION)Irp->AssociatedIrp.SystemBuffer; ! 910: ! 911: if (openType != NULL) { ! 912: ! 913: found = TRUE; ! 914: ! 915: for (i=0;i<(USHORT)openType->EaNameLength;i++) { ! 916: if (openType->EaName[i] == TdiTransportAddress[i]) { ! 917: continue; ! 918: } else { ! 919: found = FALSE; ! 920: break; ! 921: } ! 922: } ! 923: ! 924: if (found) { ! 925: Status = StOpenAddress (DeviceObject, Irp, IrpSp); ! 926: break; ! 927: } ! 928: ! 929: // ! 930: // Connection? ! 931: // ! 932: ! 933: found = TRUE; ! 934: ! 935: for (i=0;i<(USHORT)openType->EaNameLength;i++) { ! 936: if (openType->EaName[i] == TdiConnectionContext[i]) { ! 937: continue; ! 938: } else { ! 939: found = FALSE; ! 940: break; ! 941: } ! 942: } ! 943: ! 944: if (found) { ! 945: Status = StOpenConnection (DeviceObject, Irp, IrpSp); ! 946: break; ! 947: } ! 948: ! 949: } else { ! 950: ! 951: ACQUIRE_SPIN_LOCK (&DeviceContext->SpinLock, &oldirql); ! 952: ! 953: IrpSp->FileObject->FsContext = (PVOID)(DeviceContext->ControlChannelIdentifier); ! 954: ++DeviceContext->ControlChannelIdentifier; ! 955: if (DeviceContext->ControlChannelIdentifier == 0) { ! 956: DeviceContext->ControlChannelIdentifier = 1; ! 957: } ! 958: ! 959: RELEASE_SPIN_LOCK (&DeviceContext->SpinLock, oldirql); ! 960: ! 961: IrpSp->FileObject->FsContext2 = (PVOID)ST_FILE_TYPE_CONTROL; ! 962: Status = STATUS_SUCCESS; ! 963: } ! 964: ! 965: break; ! 966: ! 967: case IRP_MJ_CLOSE: ! 968: ! 969: // ! 970: // The Close function closes a transport endpoint, terminates ! 971: // all outstanding transport activity on the endpoint, and unbinds ! 972: // the endpoint from its transport address, if any. If this ! 973: // is the last transport endpoint bound to the address, then ! 974: // the address is removed from the provider. ! 975: // ! 976: ! 977: switch ((ULONG)IrpSp->FileObject->FsContext2) { ! 978: case TDI_TRANSPORT_ADDRESS_FILE: ! 979: AddressFile = (PTP_ADDRESS_FILE)IrpSp->FileObject->FsContext; ! 980: ! 981: // ! 982: // This creates a reference to AddressFile->Address ! 983: // which is removed by StCloseAddress. ! 984: // ! 985: ! 986: Status = StVerifyAddressObject(AddressFile); ! 987: ! 988: if (!NT_SUCCESS (Status)) { ! 989: Status = STATUS_INVALID_HANDLE; ! 990: } else { ! 991: Status = StCloseAddress (DeviceObject, Irp, IrpSp); ! 992: } ! 993: ! 994: break; ! 995: ! 996: case TDI_CONNECTION_FILE: ! 997: ! 998: // ! 999: // This is a connection ! 1000: // ! 1001: ! 1002: Connection = (PTP_CONNECTION)IrpSp->FileObject->FsContext; ! 1003: Status = StVerifyConnectionObject (Connection); ! 1004: if (NT_SUCCESS (Status)) { ! 1005: ! 1006: Status = StCloseConnection (DeviceObject, Irp, IrpSp); ! 1007: StDereferenceConnection ("Temporary Use",Connection); ! 1008: ! 1009: } ! 1010: ! 1011: break; ! 1012: ! 1013: case ST_FILE_TYPE_CONTROL: ! 1014: ! 1015: // ! 1016: // this always succeeds ! 1017: // ! 1018: ! 1019: Status = STATUS_SUCCESS; ! 1020: break; ! 1021: ! 1022: default: ! 1023: Status = STATUS_INVALID_HANDLE; ! 1024: } ! 1025: ! 1026: break; ! 1027: ! 1028: case IRP_MJ_CLEANUP: ! 1029: ! 1030: // ! 1031: // Handle the two stage IRP for a file close operation. When the first ! 1032: // stage hits, run down all activity on the object of interest. This ! 1033: // do everything to it but remove the creation hold. Then, when the ! 1034: // CLOSE irp hits, actually close the object. ! 1035: // ! 1036: ! 1037: switch ((ULONG)IrpSp->FileObject->FsContext2) { ! 1038: case TDI_TRANSPORT_ADDRESS_FILE: ! 1039: AddressFile = (PTP_ADDRESS_FILE)IrpSp->FileObject->FsContext; ! 1040: Status = StVerifyAddressObject(AddressFile); ! 1041: if (!NT_SUCCESS (Status)) { ! 1042: ! 1043: Status = STATUS_INVALID_HANDLE; ! 1044: ! 1045: } else { ! 1046: ! 1047: StStopAddressFile (AddressFile, AddressFile->Address); ! 1048: StDereferenceAddress ("IRP_MJ_CLEANUP", AddressFile->Address); ! 1049: Status = STATUS_SUCCESS; ! 1050: } ! 1051: ! 1052: break; ! 1053: ! 1054: case TDI_CONNECTION_FILE: ! 1055: ! 1056: Connection = (PTP_CONNECTION)IrpSp->FileObject->FsContext; ! 1057: Status = StVerifyConnectionObject (Connection); ! 1058: if (NT_SUCCESS (Status)) { ! 1059: StStopConnection (Connection, STATUS_LOCAL_DISCONNECT); ! 1060: Status = STATUS_SUCCESS; ! 1061: StDereferenceConnection ("Temporary Use",Connection); ! 1062: } ! 1063: ! 1064: break; ! 1065: ! 1066: case ST_FILE_TYPE_CONTROL: ! 1067: ! 1068: Status = STATUS_SUCCESS; ! 1069: break; ! 1070: ! 1071: default: ! 1072: Status = STATUS_INVALID_HANDLE; ! 1073: } ! 1074: ! 1075: break; ! 1076: ! 1077: default: ! 1078: Status = STATUS_INVALID_DEVICE_REQUEST; ! 1079: ! 1080: } /* major function switch */ ! 1081: ! 1082: if (Status != STATUS_PENDING) { ! 1083: IrpSp->Control &= ~SL_PENDING_RETURNED; ! 1084: Irp->IoStatus.Status = Status; ! 1085: IoCompleteRequest (Irp, IO_NETWORK_INCREMENT); ! 1086: } ! 1087: ! 1088: ! 1089: // ! 1090: // Return the immediate status code to the caller. ! 1091: // ! 1092: ! 1093: return Status; ! 1094: } /* StDispatchOpenClose */ ! 1095: ! 1096: ! 1097: NTSTATUS ! 1098: StDeviceControl( ! 1099: IN PDEVICE_OBJECT DeviceObject, ! 1100: IN PIRP Irp, ! 1101: IN PIO_STACK_LOCATION IrpSp ! 1102: ) ! 1103: ! 1104: /*++ ! 1105: ! 1106: Routine Description: ! 1107: ! 1108: This routine dispatches TDI request types to different handlers based ! 1109: on the minor IOCTL function code in the IRP's current stack location. ! 1110: In addition to cracking the minor function code, this routine also ! 1111: reaches into the IRP and passes the packetized parameters stored there ! 1112: as parameters to the various TDI request handlers so that they are ! 1113: not IRP-dependent. ! 1114: ! 1115: Arguments: ! 1116: ! 1117: DeviceObject - Pointer to the device object for this driver. ! 1118: ! 1119: Irp - Pointer to the request packet representing the I/O request. ! 1120: ! 1121: IrpSp - Pointer to current IRP stack frame. ! 1122: ! 1123: Return Value: ! 1124: ! 1125: The function value is the status of the operation. ! 1126: ! 1127: --*/ ! 1128: ! 1129: { ! 1130: NTSTATUS Status; ! 1131: PDEVICE_CONTEXT DeviceContext = (PDEVICE_CONTEXT)DeviceObject; ! 1132: ! 1133: ! 1134: // ! 1135: // Branch to the appropriate request handler. Preliminary checking of ! 1136: // the size of the request block is performed here so that it is known ! 1137: // in the handlers that the minimum input parameters are readable. It ! 1138: // is *not* determined here whether variable length input fields are ! 1139: // passed correctly; this is a check which must be made within each routine. ! 1140: // ! 1141: ! 1142: switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) { ! 1143: ! 1144: default: ! 1145: ! 1146: // ! 1147: // Convert the user call to the proper internal device call. ! 1148: // ! 1149: ! 1150: Status = TdiMapUserRequest (DeviceObject, Irp, IrpSp); ! 1151: ! 1152: if (Status == STATUS_SUCCESS) { ! 1153: ! 1154: // ! 1155: // If TdiMapUserRequest returns SUCCESS then the IRP ! 1156: // has been converted into an IRP_MJ_INTERNAL_DEVICE_CONTROL ! 1157: // IRP, so we dispatch it as usual. The IRP will ! 1158: // be completed by this call. ! 1159: // ! 1160: // StDispatchInternal expects to complete the IRP, ! 1161: // so we change Status to PENDING so we don't. ! 1162: // ! 1163: ! 1164: (VOID)StDispatchInternal (DeviceObject, Irp); ! 1165: Status = STATUS_PENDING; ! 1166: ! 1167: } ! 1168: } ! 1169: ! 1170: return Status; ! 1171: } /* StDeviceControl */ ! 1172: ! 1173: ! 1174: NTSTATUS ! 1175: StDispatchInternal ( ! 1176: IN PDEVICE_OBJECT DeviceObject, ! 1177: IN PIRP Irp ! 1178: ) ! 1179: ! 1180: /*++ ! 1181: ! 1182: Routine Description: ! 1183: ! 1184: This routine dispatches TDI request types to different handlers based ! 1185: on the minor IOCTL function code in the IRP's current stack location. ! 1186: In addition to cracking the minor function code, this routine also ! 1187: reaches into the IRP and passes the packetized parameters stored there ! 1188: as parameters to the various TDI request handlers so that they are ! 1189: not IRP-dependent. ! 1190: ! 1191: Arguments: ! 1192: ! 1193: DeviceObject - Pointer to the device object for this driver. ! 1194: ! 1195: Irp - Pointer to the request packet representing the I/O request. ! 1196: ! 1197: Return Value: ! 1198: ! 1199: The function value is the status of the operation. ! 1200: ! 1201: --*/ ! 1202: ! 1203: { ! 1204: NTSTATUS Status; ! 1205: PDEVICE_CONTEXT DeviceContext; ! 1206: PIO_STACK_LOCATION IrpSp; ! 1207: ! 1208: ! 1209: // ! 1210: // Get a pointer to the current stack location in the IRP. This is where ! 1211: // the function codes and parameters are stored. ! 1212: // ! 1213: ! 1214: IrpSp = IoGetCurrentIrpStackLocation (Irp); ! 1215: ! 1216: DeviceContext = (PDEVICE_CONTEXT)DeviceObject; ! 1217: ! 1218: ! 1219: if (DeviceContext->State != DEVICECONTEXT_STATE_OPEN) { ! 1220: Irp->IoStatus.Status = STATUS_INVALID_DEVICE_STATE; ! 1221: IoCompleteRequest (Irp, IO_NETWORK_INCREMENT); ! 1222: return STATUS_INVALID_DEVICE_STATE; ! 1223: } ! 1224: ! 1225: ! 1226: // ! 1227: // Make sure status information is consistent every time. ! 1228: // ! 1229: ! 1230: IoMarkIrpPending (Irp); ! 1231: Irp->IoStatus.Status = STATUS_PENDING; ! 1232: Irp->IoStatus.Information = 0; ! 1233: ! 1234: ! 1235: // ! 1236: // Branch to the appropriate request handler. Preliminary checking of ! 1237: // the size of the request block is performed here so that it is known ! 1238: // in the handlers that the minimum input parameters are readable. It ! 1239: // is *not* determined here whether variable length input fields are ! 1240: // passed correctly; this is a check which must be made within each routine. ! 1241: // ! 1242: ! 1243: switch (IrpSp->MinorFunction) { ! 1244: ! 1245: case TDI_ACCEPT: ! 1246: Status = StTdiAccept (Irp); ! 1247: break; ! 1248: ! 1249: case TDI_ACTION: ! 1250: Status = STATUS_SUCCESS; ! 1251: break; ! 1252: ! 1253: case TDI_ASSOCIATE_ADDRESS: ! 1254: Status = StTdiAssociateAddress (Irp); ! 1255: break; ! 1256: ! 1257: case TDI_DISASSOCIATE_ADDRESS: ! 1258: Status = StTdiDisassociateAddress (Irp); ! 1259: break; ! 1260: ! 1261: case TDI_CONNECT: ! 1262: Status = StTdiConnect (Irp); ! 1263: break; ! 1264: ! 1265: case TDI_DISCONNECT: ! 1266: Status = StTdiDisconnect (Irp); ! 1267: break; ! 1268: ! 1269: case TDI_LISTEN: ! 1270: Status = StTdiListen (Irp); ! 1271: break; ! 1272: ! 1273: case TDI_QUERY_INFORMATION: ! 1274: Status = StTdiQueryInformation (DeviceContext, Irp); ! 1275: break; ! 1276: ! 1277: case TDI_RECEIVE: ! 1278: Status = StTdiReceive (Irp); ! 1279: break; ! 1280: ! 1281: case TDI_RECEIVE_DATAGRAM: ! 1282: Status = StTdiReceiveDatagram (Irp); ! 1283: break; ! 1284: ! 1285: case TDI_SEND: ! 1286: Status = StTdiSend (Irp); ! 1287: break; ! 1288: ! 1289: case TDI_SEND_DATAGRAM: ! 1290: Status = StTdiSendDatagram (Irp); ! 1291: break; ! 1292: ! 1293: case TDI_SET_EVENT_HANDLER: ! 1294: ! 1295: // ! 1296: // Because this request will enable direct callouts from the ! 1297: // transport provider at DISPATCH_LEVEL to a client-specified ! 1298: // routine, this request is only valid in kernel mode, denying ! 1299: // access to this request in user mode. ! 1300: // ! 1301: ! 1302: Status = StTdiSetEventHandler (Irp); ! 1303: break; ! 1304: ! 1305: case TDI_SET_INFORMATION: ! 1306: Status = StTdiSetInformation (Irp); ! 1307: break; ! 1308: ! 1309: ! 1310: // ! 1311: // Something we don't know about was submitted. ! 1312: // ! 1313: ! 1314: default: ! 1315: Status = STATUS_INVALID_DEVICE_REQUEST; ! 1316: } ! 1317: ! 1318: if (Status != STATUS_PENDING) { ! 1319: IrpSp->Control &= ~SL_PENDING_RETURNED; ! 1320: Irp->IoStatus.Status = Status; ! 1321: IoCompleteRequest (Irp, IO_NETWORK_INCREMENT); ! 1322: } ! 1323: ! 1324: ! 1325: // ! 1326: // Return the immediate status code to the caller. ! 1327: // ! 1328: ! 1329: return Status; ! 1330: ! 1331: } /* StDispatchInternal */ ! 1332: ! 1333: ! 1334: VOID ! 1335: StWriteResourceErrorLog( ! 1336: IN PDEVICE_CONTEXT DeviceContext, ! 1337: IN ULONG BytesNeeded, ! 1338: IN ULONG UniqueErrorValue ! 1339: ) ! 1340: ! 1341: /*++ ! 1342: ! 1343: Routine Description: ! 1344: ! 1345: This routine allocates and writes an error log entry indicating ! 1346: an out of resources condition. ! 1347: ! 1348: Arguments: ! 1349: ! 1350: DeviceContext - Pointer to the device context. ! 1351: ! 1352: BytesNeeded - If applicable, the number of bytes that could not ! 1353: be allocated. ! 1354: ! 1355: UniqueErrorValue - Used as the UniqueErrorValue in the error log ! 1356: packet. ! 1357: ! 1358: Return Value: ! 1359: ! 1360: None. ! 1361: ! 1362: --*/ ! 1363: ! 1364: { ! 1365: PIO_ERROR_LOG_PACKET errorLogEntry; ! 1366: UCHAR EntrySize; ! 1367: PUCHAR StringLoc; ! 1368: ULONG TempUniqueError; ! 1369: static WCHAR UniqueErrorBuffer[4] = L"000"; ! 1370: UINT i; ! 1371: ! 1372: ! 1373: EntrySize = sizeof(IO_ERROR_LOG_PACKET) + ! 1374: DeviceContext->DeviceNameLength + ! 1375: sizeof(UniqueErrorBuffer); ! 1376: ! 1377: errorLogEntry = (PIO_ERROR_LOG_PACKET)IoAllocateErrorLogEntry( ! 1378: (PDEVICE_OBJECT)DeviceContext, ! 1379: EntrySize ! 1380: ); ! 1381: ! 1382: // ! 1383: // Convert the error value into a buffer. ! 1384: // ! 1385: ! 1386: TempUniqueError = UniqueErrorValue; ! 1387: for (i=1; i>=0; i--) { ! 1388: UniqueErrorBuffer[i] = (WCHAR)((TempUniqueError % 10) + L'0'); ! 1389: TempUniqueError /= 10; ! 1390: } ! 1391: ! 1392: if (errorLogEntry != NULL) { ! 1393: ! 1394: errorLogEntry->MajorFunctionCode = (UCHAR)-1; ! 1395: errorLogEntry->RetryCount = (UCHAR)-1; ! 1396: errorLogEntry->DumpDataSize = sizeof(ULONG); ! 1397: errorLogEntry->NumberOfStrings = 2; ! 1398: errorLogEntry->StringOffset = sizeof(IO_ERROR_LOG_PACKET); ! 1399: errorLogEntry->EventCategory = 0; ! 1400: errorLogEntry->ErrorCode = EVENT_TRANSPORT_RESOURCE_POOL; ! 1401: errorLogEntry->UniqueErrorValue = UniqueErrorValue; ! 1402: errorLogEntry->FinalStatus = STATUS_INSUFFICIENT_RESOURCES; ! 1403: errorLogEntry->SequenceNumber = (ULONG)-1; ! 1404: errorLogEntry->IoControlCode = 0; ! 1405: errorLogEntry->DumpData[0] = BytesNeeded; ! 1406: ! 1407: StringLoc = ((PUCHAR)errorLogEntry) + errorLogEntry->StringOffset; ! 1408: RtlCopyMemory (StringLoc, DeviceContext->DeviceName, DeviceContext->DeviceNameLength); ! 1409: ! 1410: StringLoc += DeviceContext->DeviceNameLength; ! 1411: RtlCopyMemory (StringLoc, UniqueErrorBuffer, sizeof(UniqueErrorBuffer)); ! 1412: ! 1413: IoWriteErrorLogEntry(errorLogEntry); ! 1414: ! 1415: } ! 1416: ! 1417: } /* StWriteResourceErrorLog */ ! 1418: ! 1419: ! 1420: VOID ! 1421: StWriteGeneralErrorLog( ! 1422: IN PDEVICE_CONTEXT DeviceContext, ! 1423: IN NTSTATUS ErrorCode, ! 1424: IN ULONG UniqueErrorValue, ! 1425: IN NTSTATUS FinalStatus, ! 1426: IN PWSTR SecondString, ! 1427: IN ULONG DumpDataCount, ! 1428: IN ULONG DumpData[] ! 1429: ) ! 1430: ! 1431: /*++ ! 1432: ! 1433: Routine Description: ! 1434: ! 1435: This routine allocates and writes an error log entry indicating ! 1436: a general problem as indicated by the parameters. It handles ! 1437: event codes REGISTER_FAILED, BINDING_FAILED, ADAPTER_NOT_FOUND, ! 1438: TRANSFER_DATA, TOO_MANY_LINKS, and BAD_PROTOCOL. All these ! 1439: events have messages with one or two strings in them. ! 1440: ! 1441: Arguments: ! 1442: ! 1443: DeviceContext - Pointer to the device context, or this may be ! 1444: a driver object instead. ! 1445: ! 1446: ErrorCode - The transport event code. ! 1447: ! 1448: UniqueErrorValue - Used as the UniqueErrorValue in the error log ! 1449: packet. ! 1450: ! 1451: FinalStatus - Used as the FinalStatus in the error log packet. ! 1452: ! 1453: SecondString - If not NULL, the string to use as the %3 ! 1454: value in the error log packet. ! 1455: ! 1456: DumpDataCount - The number of ULONGs of dump data. ! 1457: ! 1458: DumpData - Dump data for the packet. ! 1459: ! 1460: Return Value: ! 1461: ! 1462: None. ! 1463: ! 1464: --*/ ! 1465: ! 1466: { ! 1467: PIO_ERROR_LOG_PACKET errorLogEntry; ! 1468: UCHAR EntrySize; ! 1469: ULONG SecondStringSize; ! 1470: PUCHAR StringLoc; ! 1471: static WCHAR DriverName[3] = L"St"; ! 1472: ! 1473: EntrySize = sizeof(IO_ERROR_LOG_PACKET) + ! 1474: (DumpDataCount * sizeof(ULONG)); ! 1475: ! 1476: if (DeviceContext->Type == IO_TYPE_DEVICE) { ! 1477: EntrySize += (UCHAR)DeviceContext->DeviceNameLength; ! 1478: } else { ! 1479: EntrySize += sizeof(DriverName); ! 1480: } ! 1481: ! 1482: if (SecondString) { ! 1483: SecondStringSize = (wcslen(SecondString)*sizeof(WCHAR)) + sizeof(UNICODE_NULL); ! 1484: EntrySize += (UCHAR)SecondStringSize; ! 1485: } ! 1486: ! 1487: errorLogEntry = (PIO_ERROR_LOG_PACKET)IoAllocateErrorLogEntry( ! 1488: (PDEVICE_OBJECT)DeviceContext, ! 1489: EntrySize ! 1490: ); ! 1491: ! 1492: if (errorLogEntry != NULL) { ! 1493: ! 1494: errorLogEntry->MajorFunctionCode = (UCHAR)-1; ! 1495: errorLogEntry->RetryCount = (UCHAR)-1; ! 1496: errorLogEntry->DumpDataSize = (USHORT)(DumpDataCount * sizeof(ULONG)); ! 1497: errorLogEntry->NumberOfStrings = (SecondString == NULL) ? 1 : 2; ! 1498: errorLogEntry->StringOffset = ! 1499: sizeof(IO_ERROR_LOG_PACKET) + ((DumpDataCount-1) * sizeof(ULONG)); ! 1500: errorLogEntry->EventCategory = 0; ! 1501: errorLogEntry->ErrorCode = ErrorCode; ! 1502: errorLogEntry->UniqueErrorValue = UniqueErrorValue; ! 1503: errorLogEntry->FinalStatus = FinalStatus; ! 1504: errorLogEntry->SequenceNumber = (ULONG)-1; ! 1505: errorLogEntry->IoControlCode = 0; ! 1506: ! 1507: if (DumpDataCount) { ! 1508: RtlCopyMemory(errorLogEntry->DumpData, DumpData, DumpDataCount * sizeof(ULONG)); ! 1509: } ! 1510: ! 1511: StringLoc = ((PUCHAR)errorLogEntry) + errorLogEntry->StringOffset; ! 1512: if (DeviceContext->Type == IO_TYPE_DEVICE) { ! 1513: RtlCopyMemory (StringLoc, DeviceContext->DeviceName, DeviceContext->DeviceNameLength); ! 1514: StringLoc += DeviceContext->DeviceNameLength; ! 1515: } else { ! 1516: RtlCopyMemory (StringLoc, DriverName, sizeof(DriverName)); ! 1517: StringLoc += sizeof(DriverName); ! 1518: } ! 1519: if (SecondString) { ! 1520: RtlCopyMemory (StringLoc, SecondString, SecondStringSize); ! 1521: } ! 1522: ! 1523: IoWriteErrorLogEntry(errorLogEntry); ! 1524: ! 1525: } ! 1526: ! 1527: } /* StWriteGeneralErrorLog */ ! 1528: ! 1529: ! 1530: VOID ! 1531: StWriteOidErrorLog( ! 1532: IN PDEVICE_CONTEXT DeviceContext, ! 1533: IN NTSTATUS ErrorCode, ! 1534: IN NTSTATUS FinalStatus, ! 1535: IN PWSTR AdapterString, ! 1536: IN ULONG OidValue ! 1537: ) ! 1538: ! 1539: /*++ ! 1540: ! 1541: Routine Description: ! 1542: ! 1543: This routine allocates and writes an error log entry indicating ! 1544: a problem querying or setting an OID on an adapter. It handles ! 1545: event codes SET_OID_FAILED and QUERY_OID_FAILED. ! 1546: ! 1547: Arguments: ! 1548: ! 1549: DeviceContext - Pointer to the device context. ! 1550: ! 1551: ErrorCode - Used as the ErrorCode in the error log packet. ! 1552: ! 1553: FinalStatus - Used as the FinalStatus in the error log packet. ! 1554: ! 1555: AdapterString - The name of the adapter we were bound to. ! 1556: ! 1557: OidValue - The OID which could not be set or queried. ! 1558: ! 1559: Return Value: ! 1560: ! 1561: None. ! 1562: ! 1563: --*/ ! 1564: ! 1565: { ! 1566: PIO_ERROR_LOG_PACKET errorLogEntry; ! 1567: UCHAR EntrySize; ! 1568: ULONG AdapterStringSize; ! 1569: PUCHAR StringLoc; ! 1570: static WCHAR OidBuffer[9] = L"00000000"; ! 1571: UINT i; ! 1572: UINT CurrentDigit; ! 1573: ! 1574: AdapterStringSize = (wcslen(AdapterString)*sizeof(WCHAR)) + sizeof(UNICODE_NULL); ! 1575: EntrySize = sizeof(IO_ERROR_LOG_PACKET) - ! 1576: sizeof(ULONG) + ! 1577: DeviceContext->DeviceNameLength + ! 1578: AdapterStringSize + ! 1579: sizeof(OidBuffer); ! 1580: ! 1581: errorLogEntry = (PIO_ERROR_LOG_PACKET)IoAllocateErrorLogEntry( ! 1582: (PDEVICE_OBJECT)DeviceContext, ! 1583: EntrySize ! 1584: ); ! 1585: ! 1586: // ! 1587: // Convert the OID into a buffer. ! 1588: // ! 1589: ! 1590: for (i=7; i>=0; i--) { ! 1591: CurrentDigit = OidValue & 0xf; ! 1592: OidValue >>= 4; ! 1593: if (CurrentDigit >= 0xa) { ! 1594: OidBuffer[i] = (WCHAR)(CurrentDigit - 0xa + L'A'); ! 1595: } else { ! 1596: OidBuffer[i] = (WCHAR)(CurrentDigit + L'0'); ! 1597: } ! 1598: } ! 1599: ! 1600: if (errorLogEntry != NULL) { ! 1601: ! 1602: errorLogEntry->MajorFunctionCode = (UCHAR)-1; ! 1603: errorLogEntry->RetryCount = (UCHAR)-1; ! 1604: errorLogEntry->DumpDataSize = 0; ! 1605: errorLogEntry->NumberOfStrings = 3; ! 1606: errorLogEntry->StringOffset = sizeof(IO_ERROR_LOG_PACKET) - sizeof(ULONG); ! 1607: errorLogEntry->EventCategory = 0; ! 1608: errorLogEntry->ErrorCode = ErrorCode; ! 1609: errorLogEntry->UniqueErrorValue = 0; ! 1610: errorLogEntry->FinalStatus = FinalStatus; ! 1611: errorLogEntry->SequenceNumber = (ULONG)-1; ! 1612: errorLogEntry->IoControlCode = 0; ! 1613: ! 1614: StringLoc = ((PUCHAR)errorLogEntry) + errorLogEntry->StringOffset; ! 1615: RtlCopyMemory (StringLoc, DeviceContext->DeviceName, DeviceContext->DeviceNameLength); ! 1616: StringLoc += DeviceContext->DeviceNameLength; ! 1617: ! 1618: RtlCopyMemory (StringLoc, OidBuffer, sizeof(OidBuffer)); ! 1619: StringLoc += sizeof(OidBuffer); ! 1620: ! 1621: RtlCopyMemory (StringLoc, AdapterString, AdapterStringSize); ! 1622: ! 1623: IoWriteErrorLogEntry(errorLogEntry); ! 1624: ! 1625: } ! 1626: ! 1627: } /* StWriteOidErrorLog */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.