Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygentdi.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS Ancillary Function Driver 00004 * FILE: afd/tdi.c 00005 * PURPOSE: Transport Driver Interface functions 00006 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net) 00007 * REVISIONS: 00008 * CSH 01/09-2000 Created 00009 */ 00010 #include <afd.h> 00011 #include <pseh/pseh2.h> 00012 #include "debug.h" 00013 #include "tdiconn.h" 00014 #include "tdi_proto.h" 00015 00016 #if DBG 00017 #if 0 00018 static VOID DisplayBuffer( 00019 PVOID Buffer, 00020 ULONG Size) 00021 { 00022 ULONG i; 00023 PCHAR p; 00024 00025 if ((DebugTraceLevel & MAX_TRACE) == 0) 00026 return; 00027 00028 if (!Buffer) { 00029 AFD_DbgPrint(MIN_TRACE, ("Cannot display null buffer.\n")); 00030 return; 00031 } 00032 00033 AFD_DbgPrint(MID_TRACE, ("Displaying buffer at (0x%X) Size (%d).\n", Buffer, Size)); 00034 00035 p = (PCHAR)Buffer; 00036 for (i = 0; i < Size; i++) { 00037 if (i % 16 == 0) 00038 DbgPrint("\n"); 00039 DbgPrint("%02X ", (p[i]) & 0xFF); 00040 } 00041 DbgPrint("\n"); 00042 } 00043 #endif 00044 #endif /* DBG */ 00045 00046 static NTSTATUS TdiCall( 00047 PIRP Irp, 00048 PDEVICE_OBJECT DeviceObject, 00049 PKEVENT Event, 00050 PIO_STATUS_BLOCK Iosb) 00051 /* 00052 * FUNCTION: Calls a transport driver device 00053 * ARGUMENTS: 00054 * Irp = Pointer to I/O Request Packet 00055 * DeviceObject = Pointer to device object to call 00056 * Event = An optional pointer to an event handle that will be 00057 * waited upon 00058 * Iosb = Pointer to an IO status block 00059 * RETURNS: 00060 * Status of operation 00061 */ 00062 { 00063 NTSTATUS Status; 00064 00065 AFD_DbgPrint(MID_TRACE, ("Called\n")); 00066 00067 AFD_DbgPrint(MID_TRACE, ("Irp->UserEvent = %x\n", Irp->UserEvent)); 00068 00069 Status = IoCallDriver(DeviceObject, Irp); 00070 AFD_DbgPrint(MID_TRACE, ("IoCallDriver: %08x\n", Status)); 00071 00072 if ((Status == STATUS_PENDING) && (Event != NULL)) { 00073 AFD_DbgPrint(MAX_TRACE, ("Waiting on transport.\n")); 00074 KeWaitForSingleObject(Event, 00075 Executive, 00076 KernelMode, 00077 FALSE, 00078 NULL); 00079 Status = Iosb->Status; 00080 } 00081 00082 AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status)); 00083 00084 return Status; 00085 } 00086 00087 00088 static NTSTATUS TdiOpenDevice( 00089 PUNICODE_STRING DeviceName, 00090 ULONG EaLength, 00091 PFILE_FULL_EA_INFORMATION EaInfo, 00092 PHANDLE Handle, 00093 PFILE_OBJECT *Object) 00094 /* 00095 * FUNCTION: Opens a device 00096 * ARGUMENTS: 00097 * DeviceName = Pointer to counted string with name of device 00098 * EaLength = Length of EA information 00099 * EaInfo = Pointer to buffer with EA information 00100 * Handle = Address of buffer to place device handle 00101 * Object = Address of buffer to place device object 00102 * RETURNS: 00103 * Status of operation 00104 */ 00105 { 00106 OBJECT_ATTRIBUTES Attr; 00107 IO_STATUS_BLOCK Iosb; 00108 NTSTATUS Status; 00109 00110 AFD_DbgPrint(MAX_TRACE, ("Called. DeviceName (%wZ)\n", DeviceName)); 00111 00112 InitializeObjectAttributes(&Attr, /* Attribute buffer */ 00113 DeviceName, /* Device name */ 00114 OBJ_CASE_INSENSITIVE | /* Attributes */ 00115 OBJ_KERNEL_HANDLE, 00116 NULL, /* Root directory */ 00117 NULL); /* Security descriptor */ 00118 00119 Status = ZwCreateFile(Handle, /* Return file handle */ 00120 GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, /* Desired access */ 00121 &Attr, /* Object attributes */ 00122 &Iosb, /* IO status */ 00123 0, /* Initial allocation size */ 00124 FILE_ATTRIBUTE_NORMAL, /* File attributes */ 00125 0, /* Share access */ 00126 FILE_OPEN_IF, /* Create disposition */ 00127 0, /* Create options */ 00128 EaInfo, /* EA buffer */ 00129 EaLength); /* EA length */ 00130 if (NT_SUCCESS(Status)) { 00131 Status = ObReferenceObjectByHandle(*Handle, /* Handle to open file */ 00132 GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, /* Access mode */ 00133 IoFileObjectType, /* Object type */ 00134 KernelMode, /* Access mode */ 00135 (PVOID*)Object, /* Pointer to object */ 00136 NULL); /* Handle information */ 00137 if (!NT_SUCCESS(Status)) { 00138 AFD_DbgPrint(MIN_TRACE, ("ObReferenceObjectByHandle() failed with status (0x%X).\n", Status)); 00139 ZwClose(*Handle); 00140 } else { 00141 AFD_DbgPrint(MAX_TRACE, ("Got handle (0x%X) Object (0x%X)\n", 00142 *Handle, *Object)); 00143 } 00144 } else { 00145 AFD_DbgPrint(MIN_TRACE, ("ZwCreateFile() failed with status (0x%X)\n", Status)); 00146 } 00147 00148 if (!NT_SUCCESS(Status)) { 00149 *Handle = INVALID_HANDLE_VALUE; 00150 *Object = NULL; 00151 } 00152 00153 return Status; 00154 } 00155 00156 NTSTATUS TdiOpenAddressFile( 00157 PUNICODE_STRING DeviceName, 00158 PTRANSPORT_ADDRESS Name, 00159 PHANDLE AddressHandle, 00160 PFILE_OBJECT *AddressObject) 00161 /* 00162 * FUNCTION: Opens an IPv4 address file object 00163 * ARGUMENTS: 00164 * DeviceName = Pointer to counted string with name of device 00165 * Name = Pointer to socket name (IPv4 address family) 00166 * AddressHandle = Address of buffer to place address file handle 00167 * AddressObject = Address of buffer to place address file object 00168 * RETURNS: 00169 * Status of operation 00170 */ 00171 { 00172 PFILE_FULL_EA_INFORMATION EaInfo; 00173 NTSTATUS Status; 00174 ULONG EaLength; 00175 PTRANSPORT_ADDRESS Address; 00176 00177 AFD_DbgPrint(MAX_TRACE, ("Called. DeviceName (%wZ) Name (0x%X)\n", 00178 DeviceName, Name)); 00179 00180 /* EaName must be 0-terminated, even though TDI_TRANSPORT_ADDRESS_LENGTH does *not* include the 0 */ 00181 EaLength = sizeof(FILE_FULL_EA_INFORMATION) + 00182 TDI_TRANSPORT_ADDRESS_LENGTH + 00183 TaLengthOfTransportAddress( Name ) + 1; 00184 EaInfo = (PFILE_FULL_EA_INFORMATION)ExAllocatePool(NonPagedPool, EaLength); 00185 if (!EaInfo) 00186 return STATUS_INSUFFICIENT_RESOURCES; 00187 00188 RtlZeroMemory(EaInfo, EaLength); 00189 EaInfo->EaNameLength = TDI_TRANSPORT_ADDRESS_LENGTH; 00190 /* Don't copy the terminating 0; we have already zeroed it */ 00191 RtlCopyMemory(EaInfo->EaName, 00192 TdiTransportAddress, 00193 TDI_TRANSPORT_ADDRESS_LENGTH); 00194 EaInfo->EaValueLength = sizeof(TA_IP_ADDRESS); 00195 Address = 00196 (PTRANSPORT_ADDRESS)(EaInfo->EaName + TDI_TRANSPORT_ADDRESS_LENGTH + 1); /* 0-terminated */ 00197 TaCopyTransportAddressInPlace( Address, Name ); 00198 00199 Status = TdiOpenDevice(DeviceName, 00200 EaLength, 00201 EaInfo, 00202 AddressHandle, 00203 AddressObject); 00204 ExFreePool(EaInfo); 00205 return Status; 00206 } 00207 00208 NTSTATUS TdiQueryMaxDatagramLength( 00209 PFILE_OBJECT FileObject, 00210 PUINT MaxDatagramLength) 00211 { 00212 PMDL Mdl; 00213 PTDI_MAX_DATAGRAM_INFO Buffer; 00214 NTSTATUS Status = STATUS_SUCCESS; 00215 00216 Buffer = ExAllocatePool(NonPagedPool, sizeof(TDI_MAX_DATAGRAM_INFO)); 00217 if (!Buffer) return STATUS_NO_MEMORY; 00218 00219 Mdl = IoAllocateMdl(Buffer, sizeof(TDI_MAX_DATAGRAM_INFO), FALSE, FALSE, NULL); 00220 if (!Mdl) 00221 { 00222 ExFreePool(Buffer); 00223 return STATUS_NO_MEMORY; 00224 } 00225 00226 _SEH2_TRY 00227 { 00228 MmProbeAndLockPages(Mdl, KernelMode, IoModifyAccess); 00229 } 00230 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 00231 { 00232 Status = _SEH2_GetExceptionCode(); 00233 } 00234 _SEH2_END; 00235 00236 if (!NT_SUCCESS(Status)) 00237 { 00238 AFD_DbgPrint(MIN_TRACE,("Failed to lock pages\n")); 00239 IoFreeMdl(Mdl); 00240 ExFreePool(Buffer); 00241 return Status; 00242 } 00243 00244 Status = TdiQueryInformation(FileObject, 00245 TDI_QUERY_MAX_DATAGRAM_INFO, 00246 Mdl); 00247 if (!NT_SUCCESS(Status)) 00248 { 00249 ExFreePool(Buffer); 00250 return Status; 00251 } 00252 00253 *MaxDatagramLength = Buffer->MaxDatagramSize; 00254 00255 ExFreePool(Buffer); 00256 00257 return STATUS_SUCCESS; 00258 } 00259 00260 NTSTATUS TdiOpenConnectionEndpointFile( 00261 PUNICODE_STRING DeviceName, 00262 PHANDLE ConnectionHandle, 00263 PFILE_OBJECT *ConnectionObject) 00264 /* 00265 * FUNCTION: Opens a connection endpoint file object 00266 * ARGUMENTS: 00267 * DeviceName = Pointer to counted string with name of device 00268 * ConnectionHandle = Address of buffer to place connection endpoint file handle 00269 * ConnectionObject = Address of buffer to place connection endpoint file object 00270 * RETURNS: 00271 * Status of operation 00272 */ 00273 { 00274 PFILE_FULL_EA_INFORMATION EaInfo; 00275 PVOID *ContextArea; 00276 NTSTATUS Status; 00277 ULONG EaLength; 00278 00279 AFD_DbgPrint(MAX_TRACE, ("Called. DeviceName (%wZ)\n", DeviceName)); 00280 00281 /* EaName must be 0-terminated, even though TDI_TRANSPORT_ADDRESS_LENGTH does *not* include the 0 */ 00282 EaLength = sizeof(FILE_FULL_EA_INFORMATION) + 00283 TDI_CONNECTION_CONTEXT_LENGTH + 00284 sizeof(PVOID) + 1; 00285 00286 EaInfo = (PFILE_FULL_EA_INFORMATION)ExAllocatePool(NonPagedPool, EaLength); 00287 if (!EaInfo) 00288 return STATUS_INSUFFICIENT_RESOURCES; 00289 00290 RtlZeroMemory(EaInfo, EaLength); 00291 EaInfo->EaNameLength = TDI_CONNECTION_CONTEXT_LENGTH; 00292 /* Don't copy the terminating 0; we have already zeroed it */ 00293 RtlCopyMemory(EaInfo->EaName, 00294 TdiConnectionContext, 00295 TDI_CONNECTION_CONTEXT_LENGTH); 00296 EaInfo->EaValueLength = sizeof(PVOID); 00297 ContextArea = (PVOID*)(EaInfo->EaName + TDI_CONNECTION_CONTEXT_LENGTH + 1); /* 0-terminated */ 00298 /* FIXME: Allocate context area */ 00299 *ContextArea = NULL; 00300 Status = TdiOpenDevice(DeviceName, 00301 EaLength, 00302 EaInfo, 00303 ConnectionHandle, 00304 ConnectionObject); 00305 ExFreePool(EaInfo); 00306 return Status; 00307 } 00308 00309 00310 NTSTATUS TdiConnect( 00311 PIRP *Irp, 00312 PFILE_OBJECT ConnectionObject, 00313 PTDI_CONNECTION_INFORMATION ConnectionCallInfo, 00314 PTDI_CONNECTION_INFORMATION ConnectionReturnInfo, 00315 PIO_STATUS_BLOCK Iosb, 00316 PIO_COMPLETION_ROUTINE CompletionRoutine, 00317 PVOID CompletionContext) 00318 /* 00319 * FUNCTION: Connect a connection endpoint to a remote peer 00320 * ARGUMENTS: 00321 * ConnectionObject = Pointer to connection endpoint file object 00322 * RemoteAddress = Pointer to remote address 00323 * RETURNS: 00324 * Status of operation 00325 */ 00326 { 00327 PDEVICE_OBJECT DeviceObject; 00328 00329 AFD_DbgPrint(MAX_TRACE, ("Called\n")); 00330 00331 ASSERT(*Irp == NULL); 00332 00333 if (!ConnectionObject) { 00334 AFD_DbgPrint(MIN_TRACE, ("Bad connection object.\n")); 00335 return STATUS_INVALID_PARAMETER; 00336 } 00337 00338 DeviceObject = IoGetRelatedDeviceObject(ConnectionObject); 00339 if (!DeviceObject) { 00340 AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n")); 00341 return STATUS_INVALID_PARAMETER; 00342 } 00343 00344 *Irp = TdiBuildInternalDeviceControlIrp(TDI_CONNECT, /* Sub function */ 00345 DeviceObject, /* Device object */ 00346 ConnectionObject, /* File object */ 00347 NULL, /* Event */ 00348 Iosb); /* Status */ 00349 if (!*Irp) { 00350 return STATUS_INSUFFICIENT_RESOURCES; 00351 } 00352 00353 TdiBuildConnect(*Irp, /* IRP */ 00354 DeviceObject, /* Device object */ 00355 ConnectionObject, /* File object */ 00356 CompletionRoutine, /* Completion routine */ 00357 CompletionContext, /* Completion routine context */ 00358 NULL, /* Time */ 00359 ConnectionCallInfo, /* Request connection information */ 00360 ConnectionReturnInfo); /* Return connection information */ 00361 00362 TdiCall(*Irp, DeviceObject, NULL, Iosb); 00363 00364 return STATUS_PENDING; 00365 } 00366 00367 00368 NTSTATUS TdiAssociateAddressFile( 00369 HANDLE AddressHandle, 00370 PFILE_OBJECT ConnectionObject) 00371 /* 00372 * FUNCTION: Associates a connection endpoint to an address file object 00373 * ARGUMENTS: 00374 * AddressHandle = Handle to address file object 00375 * ConnectionObject = Connection endpoint file object 00376 * RETURNS: 00377 * Status of operation 00378 */ 00379 { 00380 PDEVICE_OBJECT DeviceObject; 00381 IO_STATUS_BLOCK Iosb; 00382 KEVENT Event; 00383 PIRP Irp; 00384 00385 AFD_DbgPrint(MAX_TRACE, ("Called. AddressHandle (0x%X) ConnectionObject (0x%X)\n", 00386 AddressHandle, ConnectionObject)); 00387 00388 if (!ConnectionObject) { 00389 AFD_DbgPrint(MIN_TRACE, ("Bad connection object.\n")); 00390 return STATUS_INVALID_PARAMETER; 00391 } 00392 00393 DeviceObject = IoGetRelatedDeviceObject(ConnectionObject); 00394 if (!DeviceObject) { 00395 AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n")); 00396 return STATUS_INVALID_PARAMETER; 00397 } 00398 00399 KeInitializeEvent(&Event, NotificationEvent, FALSE); 00400 00401 Irp = TdiBuildInternalDeviceControlIrp(TDI_ASSOCIATE_ADDRESS, /* Sub function */ 00402 DeviceObject, /* Device object */ 00403 ConnectionObject, /* File object */ 00404 &Event, /* Event */ 00405 &Iosb); /* Status */ 00406 if (!Irp) 00407 return STATUS_INSUFFICIENT_RESOURCES; 00408 00409 TdiBuildAssociateAddress(Irp, 00410 DeviceObject, 00411 ConnectionObject, 00412 NULL, 00413 NULL, 00414 AddressHandle); 00415 00416 return TdiCall(Irp, DeviceObject, &Event, &Iosb); 00417 } 00418 00419 NTSTATUS TdiDisassociateAddressFile( 00420 PFILE_OBJECT ConnectionObject) 00421 /* 00422 * FUNCTION: Disassociates a connection endpoint from an address file object 00423 * ARGUMENTS: 00424 * ConnectionObject = Connection endpoint file object 00425 * RETURNS: 00426 * Status of operation 00427 */ 00428 { 00429 PDEVICE_OBJECT DeviceObject; 00430 IO_STATUS_BLOCK Iosb; 00431 KEVENT Event; 00432 PIRP Irp; 00433 00434 AFD_DbgPrint(MAX_TRACE, ("Called. ConnectionObject (0x%X)\n", ConnectionObject)); 00435 00436 if (!ConnectionObject) { 00437 AFD_DbgPrint(MIN_TRACE, ("Bad connection object.\n")); 00438 return STATUS_INVALID_PARAMETER; 00439 } 00440 00441 DeviceObject = IoGetRelatedDeviceObject(ConnectionObject); 00442 if (!DeviceObject) { 00443 AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n")); 00444 return STATUS_INVALID_PARAMETER; 00445 } 00446 00447 KeInitializeEvent(&Event, NotificationEvent, FALSE); 00448 00449 Irp = TdiBuildInternalDeviceControlIrp(TDI_DISASSOCIATE_ADDRESS, /* Sub function */ 00450 DeviceObject, /* Device object */ 00451 ConnectionObject, /* File object */ 00452 &Event, /* Event */ 00453 &Iosb); /* Status */ 00454 if (!Irp) 00455 return STATUS_INSUFFICIENT_RESOURCES; 00456 00457 TdiBuildDisassociateAddress(Irp, 00458 DeviceObject, 00459 ConnectionObject, 00460 NULL, 00461 NULL); 00462 00463 return TdiCall(Irp, DeviceObject, &Event, &Iosb); 00464 } 00465 00466 NTSTATUS TdiListen( 00467 PIRP *Irp, 00468 PFILE_OBJECT ConnectionObject, 00469 PTDI_CONNECTION_INFORMATION *RequestConnectionInfo, 00470 PTDI_CONNECTION_INFORMATION *ReturnConnectionInfo, 00471 PIO_STATUS_BLOCK Iosb, 00472 PIO_COMPLETION_ROUTINE CompletionRoutine, 00473 PVOID CompletionContext) 00474 /* 00475 * FUNCTION: Listen on a connection endpoint for a connection request from a remote peer 00476 * ARGUMENTS: 00477 * CompletionRoutine = Routine to be called when IRP is completed 00478 * CompletionContext = Context for CompletionRoutine 00479 * RETURNS: 00480 * Status of operation 00481 * May return STATUS_PENDING 00482 */ 00483 { 00484 PDEVICE_OBJECT DeviceObject; 00485 00486 AFD_DbgPrint(MAX_TRACE, ("Called\n")); 00487 00488 ASSERT(*Irp == NULL); 00489 00490 if (!ConnectionObject) { 00491 AFD_DbgPrint(MIN_TRACE, ("Bad connection object.\n")); 00492 return STATUS_INVALID_PARAMETER; 00493 } 00494 00495 DeviceObject = IoGetRelatedDeviceObject(ConnectionObject); 00496 if (!DeviceObject) { 00497 AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n")); 00498 return STATUS_INVALID_PARAMETER; 00499 } 00500 00501 *Irp = TdiBuildInternalDeviceControlIrp(TDI_LISTEN, /* Sub function */ 00502 DeviceObject, /* Device object */ 00503 ConnectionObject, /* File object */ 00504 NULL, /* Event */ 00505 Iosb); /* Status */ 00506 if (*Irp == NULL) 00507 return STATUS_INSUFFICIENT_RESOURCES; 00508 00509 TdiBuildListen(*Irp, /* IRP */ 00510 DeviceObject, /* Device object */ 00511 ConnectionObject, /* File object */ 00512 CompletionRoutine, /* Completion routine */ 00513 CompletionContext, /* Completion routine context */ 00514 0, /* Flags */ 00515 *RequestConnectionInfo, /* Request connection information */ 00516 *ReturnConnectionInfo); /* Return connection information */ 00517 00518 TdiCall(*Irp, DeviceObject, NULL /* Don't wait for completion */, Iosb); 00519 00520 return STATUS_PENDING; 00521 } 00522 00523 00524 NTSTATUS TdiSetEventHandler( 00525 PFILE_OBJECT FileObject, 00526 LONG EventType, 00527 PVOID Handler, 00528 PVOID Context) 00529 /* 00530 * FUNCTION: Sets or resets an event handler 00531 * ARGUMENTS: 00532 * FileObject = Pointer to file object 00533 * EventType = Event code 00534 * Handler = Event handler to be called when the event occurs 00535 * Context = Context input to handler when the event occurs 00536 * RETURNS: 00537 * Status of operation 00538 * NOTES: 00539 * Specify NULL for Handler to stop calling event handler 00540 */ 00541 { 00542 PDEVICE_OBJECT DeviceObject; 00543 IO_STATUS_BLOCK Iosb; 00544 KEVENT Event; 00545 PIRP Irp; 00546 00547 AFD_DbgPrint(MAX_TRACE, ("Called\n")); 00548 00549 if (!FileObject) { 00550 AFD_DbgPrint(MIN_TRACE, ("Bad file object.\n")); 00551 return STATUS_INVALID_PARAMETER; 00552 } 00553 00554 DeviceObject = IoGetRelatedDeviceObject(FileObject); 00555 if (!DeviceObject) { 00556 AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n")); 00557 return STATUS_INVALID_PARAMETER; 00558 } 00559 00560 KeInitializeEvent(&Event, NotificationEvent, FALSE); 00561 00562 Irp = TdiBuildInternalDeviceControlIrp(TDI_SET_EVENT_HANDLER, /* Sub function */ 00563 DeviceObject, /* Device object */ 00564 FileObject, /* File object */ 00565 &Event, /* Event */ 00566 &Iosb); /* Status */ 00567 if (!Irp) 00568 return STATUS_INSUFFICIENT_RESOURCES; 00569 00570 00571 00572 TdiBuildSetEventHandler(Irp, 00573 DeviceObject, 00574 FileObject, 00575 NULL, 00576 NULL, 00577 EventType, 00578 Handler, 00579 Context); 00580 00581 return TdiCall(Irp, DeviceObject, &Event, &Iosb); 00582 } 00583 00584 00585 NTSTATUS TdiQueryDeviceControl( 00586 PFILE_OBJECT FileObject, 00587 ULONG IoControlCode, 00588 PVOID InputBuffer, 00589 ULONG InputBufferLength, 00590 PVOID OutputBuffer, 00591 ULONG OutputBufferLength, 00592 PULONG Return) 00593 /* 00594 * FUNCTION: Queries a device for information 00595 * ARGUMENTS: 00596 * FileObject = Pointer to file object 00597 * IoControlCode = I/O control code 00598 * InputBuffer = Pointer to buffer with input data 00599 * InputBufferLength = Length of InputBuffer 00600 * OutputBuffer = Address of buffer to place output data 00601 * OutputBufferLength = Length of OutputBuffer 00602 * RETURNS: 00603 * Status of operation 00604 */ 00605 { 00606 PDEVICE_OBJECT DeviceObject; 00607 IO_STATUS_BLOCK Iosb; 00608 NTSTATUS Status; 00609 KEVENT Event; 00610 PIRP Irp; 00611 00612 if (!FileObject) { 00613 AFD_DbgPrint(MIN_TRACE, ("Bad file object.\n")); 00614 return STATUS_INVALID_PARAMETER; 00615 } 00616 00617 DeviceObject = IoGetRelatedDeviceObject(FileObject); 00618 if (!DeviceObject) { 00619 AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n")); 00620 return STATUS_INVALID_PARAMETER; 00621 } 00622 00623 KeInitializeEvent(&Event, NotificationEvent, FALSE); 00624 00625 Irp = IoBuildDeviceIoControlRequest(IoControlCode, 00626 DeviceObject, 00627 InputBuffer, 00628 InputBufferLength, 00629 OutputBuffer, 00630 OutputBufferLength, 00631 FALSE, 00632 &Event, 00633 &Iosb); 00634 if (!Irp) 00635 return STATUS_INSUFFICIENT_RESOURCES; 00636 00637 Status = TdiCall(Irp, DeviceObject, &Event, &Iosb); 00638 00639 if (Return) 00640 *Return = Iosb.Information; 00641 00642 return Status; 00643 } 00644 00645 00646 NTSTATUS TdiQueryInformation( 00647 PFILE_OBJECT FileObject, 00648 LONG QueryType, 00649 PMDL MdlBuffer) 00650 /* 00651 * FUNCTION: Query for information 00652 * ARGUMENTS: 00653 * FileObject = Pointer to file object 00654 * QueryType = Query type 00655 * MdlBuffer = Pointer to MDL buffer specific for query type 00656 * RETURNS: 00657 * Status of operation 00658 */ 00659 { 00660 PDEVICE_OBJECT DeviceObject; 00661 IO_STATUS_BLOCK Iosb; 00662 KEVENT Event; 00663 PIRP Irp; 00664 00665 if (!FileObject) { 00666 AFD_DbgPrint(MIN_TRACE, ("Bad file object.\n")); 00667 return STATUS_INVALID_PARAMETER; 00668 } 00669 00670 DeviceObject = IoGetRelatedDeviceObject(FileObject); 00671 if (!DeviceObject) { 00672 AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n")); 00673 return STATUS_INVALID_PARAMETER; 00674 } 00675 00676 KeInitializeEvent(&Event, NotificationEvent, FALSE); 00677 00678 Irp = TdiBuildInternalDeviceControlIrp(TDI_QUERY_INFORMATION, /* Sub function */ 00679 DeviceObject, /* Device object */ 00680 ConnectionObject, /* File object */ 00681 &Event, /* Event */ 00682 &Iosb); /* Status */ 00683 if (!Irp) { 00684 return STATUS_INSUFFICIENT_RESOURCES; 00685 } 00686 00687 TdiBuildQueryInformation(Irp, 00688 DeviceObject, 00689 FileObject, 00690 NULL, 00691 NULL, 00692 QueryType, 00693 MdlBuffer); 00694 00695 return TdiCall(Irp, DeviceObject, &Event, &Iosb); 00696 } 00697 00698 NTSTATUS TdiQueryInformationEx( 00699 PFILE_OBJECT FileObject, 00700 ULONG Entity, 00701 ULONG Instance, 00702 ULONG Class, 00703 ULONG Type, 00704 ULONG Id, 00705 PVOID OutputBuffer, 00706 PULONG OutputLength) 00707 /* 00708 * FUNCTION: Extended query for information 00709 * ARGUMENTS: 00710 * FileObject = Pointer to file object 00711 * Entity = Entity 00712 * Instance = Instance 00713 * Class = Entity class 00714 * Type = Entity type 00715 * Id = Entity id 00716 * OutputBuffer = Address of buffer to place data 00717 * OutputLength = Address of buffer with length of OutputBuffer (updated) 00718 * RETURNS: 00719 * Status of operation 00720 */ 00721 { 00722 TCP_REQUEST_QUERY_INFORMATION_EX QueryInfo; 00723 00724 RtlZeroMemory(&QueryInfo, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX)); 00725 QueryInfo.ID.toi_entity.tei_entity = Entity; 00726 QueryInfo.ID.toi_entity.tei_instance = Instance; 00727 QueryInfo.ID.toi_class = Class; 00728 QueryInfo.ID.toi_type = Type; 00729 QueryInfo.ID.toi_id = Id; 00730 00731 return TdiQueryDeviceControl(FileObject, /* Transport/connection object */ 00732 IOCTL_TCP_QUERY_INFORMATION_EX, /* Control code */ 00733 &QueryInfo, /* Input buffer */ 00734 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX), /* Input buffer length */ 00735 OutputBuffer, /* Output buffer */ 00736 *OutputLength, /* Output buffer length */ 00737 OutputLength); /* Return information */ 00738 } 00739 00740 NTSTATUS TdiQueryAddress( 00741 PFILE_OBJECT FileObject, 00742 PULONG Address) 00743 /* 00744 * FUNCTION: Queries for a local IP address 00745 * ARGUMENTS: 00746 * FileObject = Pointer to file object 00747 * Address = Address of buffer to place local address 00748 * RETURNS: 00749 * Status of operation 00750 */ 00751 { 00752 UINT i; 00753 TDIEntityID *Entities; 00754 ULONG EntityCount; 00755 ULONG EntityType; 00756 IPSNMP_INFO SnmpInfo; 00757 PIPADDR_ENTRY IpAddress; 00758 ULONG BufferSize; 00759 NTSTATUS Status = STATUS_SUCCESS; 00760 00761 AFD_DbgPrint(MAX_TRACE, ("Called\n")); 00762 00763 BufferSize = sizeof(TDIEntityID) * 20; 00764 Entities = (TDIEntityID*)ExAllocatePool(NonPagedPool, BufferSize); 00765 if (!Entities) { 00766 AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); 00767 return STATUS_INSUFFICIENT_RESOURCES; 00768 } 00769 00770 /* Query device for supported entities */ 00771 00772 Status = TdiQueryInformationEx(FileObject, /* File object */ 00773 GENERIC_ENTITY, /* Entity */ 00774 TL_INSTANCE, /* Instance */ 00775 INFO_CLASS_GENERIC, /* Entity class */ 00776 INFO_TYPE_PROVIDER, /* Entity type */ 00777 ENTITY_LIST_ID, /* Entity id */ 00778 Entities, /* Output buffer */ 00779 &BufferSize); /* Output buffer size */ 00780 if (!NT_SUCCESS(Status)) { 00781 AFD_DbgPrint(MIN_TRACE, ("Unable to get list of supported entities (Status = 0x%X).\n", Status)); 00782 ExFreePool(Entities); 00783 return Status; 00784 } 00785 00786 /* Locate an IP entity */ 00787 EntityCount = BufferSize / sizeof(TDIEntityID); 00788 00789 AFD_DbgPrint(MAX_TRACE, ("EntityCount = %d\n", EntityCount)); 00790 00791 for (i = 0; i < EntityCount; i++) { 00792 if (Entities[i].tei_entity == CL_NL_ENTITY) { 00793 /* Query device for entity type */ 00794 00795 BufferSize = sizeof(EntityType); 00796 Status = TdiQueryInformationEx(FileObject, /* File object */ 00797 CL_NL_ENTITY, /* Entity */ 00798 Entities[i].tei_instance, /* Instance */ 00799 INFO_CLASS_GENERIC, /* Entity class */ 00800 INFO_TYPE_PROVIDER, /* Entity type */ 00801 ENTITY_TYPE_ID, /* Entity id */ 00802 &EntityType, /* Output buffer */ 00803 &BufferSize); /* Output buffer size */ 00804 if (!NT_SUCCESS(Status) || (EntityType != CL_NL_IP)) { 00805 AFD_DbgPrint(MIN_TRACE, ("Unable to get entity of type IP (Status = 0x%X).\n", Status)); 00806 break; 00807 } 00808 00809 /* Query device for SNMP information */ 00810 00811 BufferSize = sizeof(SnmpInfo); 00812 Status = TdiQueryInformationEx(FileObject, /* File object */ 00813 CL_NL_ENTITY, /* Entity */ 00814 Entities[i].tei_instance, /* Instance */ 00815 INFO_CLASS_PROTOCOL, /* Entity class */ 00816 INFO_TYPE_PROVIDER, /* Entity type */ 00817 IP_MIB_STATS_ID, /* Entity id */ 00818 &SnmpInfo, /* Output buffer */ 00819 &BufferSize); /* Output buffer size */ 00820 if (!NT_SUCCESS(Status) || (SnmpInfo.NumAddr == 0)) { 00821 AFD_DbgPrint(MIN_TRACE, ("Unable to get SNMP information or no IP addresses available (Status = 0x%X).\n", Status)); 00822 break; 00823 } 00824 00825 /* Query device for all IP addresses */ 00826 00827 if (SnmpInfo.NumAddr != 0) { 00828 BufferSize = SnmpInfo.NumAddr * sizeof(IPADDR_ENTRY); 00829 IpAddress = (PIPADDR_ENTRY)ExAllocatePool(NonPagedPool, BufferSize); 00830 if (!IpAddress) { 00831 AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); 00832 break; 00833 } 00834 00835 Status = TdiQueryInformationEx(FileObject, /* File object */ 00836 CL_NL_ENTITY, /* Entity */ 00837 Entities[i].tei_instance, /* Instance */ 00838 INFO_CLASS_PROTOCOL, /* Entity class */ 00839 INFO_TYPE_PROVIDER, /* Entity type */ 00840 IP_MIB_ADDRTABLE_ENTRY_ID, /* Entity id */ 00841 IpAddress, /* Output buffer */ 00842 &BufferSize); /* Output buffer size */ 00843 if (!NT_SUCCESS(Status)) { 00844 AFD_DbgPrint(MIN_TRACE, ("Unable to get IP address (Status = 0x%X).\n", Status)); 00845 ExFreePool(IpAddress); 00846 break; 00847 } 00848 00849 if (SnmpInfo.NumAddr != 1) { 00850 /* Skip loopback address */ 00851 *Address = DN2H(IpAddress[1].Addr); 00852 } else { 00853 /* Select the first address returned */ 00854 *Address = DN2H(IpAddress->Addr); 00855 } 00856 00857 ExFreePool(IpAddress); 00858 } else { 00859 Status = STATUS_UNSUCCESSFUL; 00860 break; 00861 } 00862 } 00863 } 00864 00865 ExFreePool(Entities); 00866 00867 AFD_DbgPrint(MAX_TRACE, ("Leaving\n")); 00868 00869 return Status; 00870 } 00871 00872 NTSTATUS TdiSend( 00873 PIRP *Irp, 00874 PFILE_OBJECT TransportObject, 00875 USHORT Flags, 00876 PCHAR Buffer, 00877 UINT BufferLength, 00878 PIO_STATUS_BLOCK Iosb, 00879 PIO_COMPLETION_ROUTINE CompletionRoutine, 00880 PVOID CompletionContext) 00881 { 00882 PDEVICE_OBJECT DeviceObject; 00883 PMDL Mdl; 00884 00885 ASSERT(*Irp == NULL); 00886 00887 if (!TransportObject) { 00888 AFD_DbgPrint(MIN_TRACE, ("Bad transport object.\n")); 00889 return STATUS_INVALID_PARAMETER; 00890 } 00891 00892 DeviceObject = IoGetRelatedDeviceObject(TransportObject); 00893 if (!DeviceObject) { 00894 AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n")); 00895 return STATUS_INVALID_PARAMETER; 00896 } 00897 00898 *Irp = TdiBuildInternalDeviceControlIrp(TDI_SEND, /* Sub function */ 00899 DeviceObject, /* Device object */ 00900 TransportObject, /* File object */ 00901 NULL, /* Event */ 00902 Iosb); /* Status */ 00903 00904 if (!*Irp) { 00905 AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); 00906 return STATUS_INSUFFICIENT_RESOURCES; 00907 } 00908 00909 AFD_DbgPrint(MID_TRACE, ("Allocating irp for %x:%d\n", Buffer,BufferLength)); 00910 00911 Mdl = IoAllocateMdl(Buffer, /* Virtual address */ 00912 BufferLength, /* Length of buffer */ 00913 FALSE, /* Not secondary */ 00914 FALSE, /* Don't charge quota */ 00915 NULL); /* Don't use IRP */ 00916 if (!Mdl) { 00917 AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); 00918 IoCompleteRequest(*Irp, IO_NO_INCREMENT); 00919 *Irp = NULL; 00920 return STATUS_INSUFFICIENT_RESOURCES; 00921 } 00922 00923 _SEH2_TRY { 00924 MmProbeAndLockPages(Mdl, (*Irp)->RequestorMode, IoModifyAccess); 00925 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { 00926 AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n")); 00927 IoFreeMdl(Mdl); 00928 IoCompleteRequest(*Irp, IO_NO_INCREMENT); 00929 *Irp = NULL; 00930 _SEH2_YIELD(return STATUS_INSUFFICIENT_RESOURCES); 00931 } _SEH2_END; 00932 00933 AFD_DbgPrint(MID_TRACE,("AFD>>> Got an MDL: %x\n", Mdl)); 00934 00935 TdiBuildSend(*Irp, /* I/O Request Packet */ 00936 DeviceObject, /* Device object */ 00937 TransportObject, /* File object */ 00938 CompletionRoutine, /* Completion routine */ 00939 CompletionContext, /* Completion context */ 00940 Mdl, /* Data buffer */ 00941 Flags, /* Flags */ 00942 BufferLength); /* Length of data */ 00943 00944 TdiCall(*Irp, DeviceObject, NULL, Iosb); 00945 /* Does not block... The MDL is deleted in the receive completion 00946 routine. */ 00947 00948 return STATUS_PENDING; 00949 } 00950 00951 NTSTATUS TdiReceive( 00952 PIRP *Irp, 00953 PFILE_OBJECT TransportObject, 00954 USHORT Flags, 00955 PCHAR Buffer, 00956 UINT BufferLength, 00957 PIO_STATUS_BLOCK Iosb, 00958 PIO_COMPLETION_ROUTINE CompletionRoutine, 00959 PVOID CompletionContext) 00960 { 00961 PDEVICE_OBJECT DeviceObject; 00962 PMDL Mdl; 00963 00964 ASSERT(*Irp == NULL); 00965 00966 if (!TransportObject) { 00967 AFD_DbgPrint(MIN_TRACE, ("Bad transport object.\n")); 00968 return STATUS_INVALID_PARAMETER; 00969 } 00970 00971 DeviceObject = IoGetRelatedDeviceObject(TransportObject); 00972 if (!DeviceObject) { 00973 AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n")); 00974 return STATUS_INVALID_PARAMETER; 00975 } 00976 00977 *Irp = TdiBuildInternalDeviceControlIrp(TDI_RECEIVE, /* Sub function */ 00978 DeviceObject, /* Device object */ 00979 TransportObject, /* File object */ 00980 NULL, /* Event */ 00981 Iosb); /* Status */ 00982 00983 if (!*Irp) { 00984 AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); 00985 return STATUS_INSUFFICIENT_RESOURCES; 00986 } 00987 00988 AFD_DbgPrint(MID_TRACE, ("Allocating irp for %x:%d\n", Buffer,BufferLength)); 00989 00990 Mdl = IoAllocateMdl(Buffer, /* Virtual address */ 00991 BufferLength, /* Length of buffer */ 00992 FALSE, /* Not secondary */ 00993 FALSE, /* Don't charge quota */ 00994 NULL); /* Don't use IRP */ 00995 if (!Mdl) { 00996 AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); 00997 IoCompleteRequest(*Irp, IO_NO_INCREMENT); 00998 *Irp = NULL; 00999 return STATUS_INSUFFICIENT_RESOURCES; 01000 } 01001 01002 _SEH2_TRY { 01003 AFD_DbgPrint(MID_TRACE, ("probe and lock\n")); 01004 MmProbeAndLockPages(Mdl, (*Irp)->RequestorMode, IoModifyAccess); 01005 AFD_DbgPrint(MID_TRACE, ("probe and lock done\n")); 01006 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { 01007 AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n")); 01008 IoFreeMdl(Mdl); 01009 IoCompleteRequest(*Irp, IO_NO_INCREMENT); 01010 *Irp = NULL; 01011 _SEH2_YIELD(return STATUS_INSUFFICIENT_RESOURCES); 01012 } _SEH2_END; 01013 01014 AFD_DbgPrint(MID_TRACE,("AFD>>> Got an MDL: %x\n", Mdl)); 01015 01016 TdiBuildReceive(*Irp, /* I/O Request Packet */ 01017 DeviceObject, /* Device object */ 01018 TransportObject, /* File object */ 01019 CompletionRoutine, /* Completion routine */ 01020 CompletionContext, /* Completion context */ 01021 Mdl, /* Data buffer */ 01022 Flags, /* Flags */ 01023 BufferLength); /* Length of data */ 01024 01025 01026 TdiCall(*Irp, DeviceObject, NULL, Iosb); 01027 /* Does not block... The MDL is deleted in the receive completion 01028 routine. */ 01029 01030 return STATUS_PENDING; 01031 } 01032 01033 01034 NTSTATUS TdiReceiveDatagram( 01035 PIRP *Irp, 01036 PFILE_OBJECT TransportObject, 01037 USHORT Flags, 01038 PCHAR Buffer, 01039 UINT BufferLength, 01040 PTDI_CONNECTION_INFORMATION Addr, 01041 PIO_STATUS_BLOCK Iosb, 01042 PIO_COMPLETION_ROUTINE CompletionRoutine, 01043 PVOID CompletionContext) 01044 /* 01045 * FUNCTION: Receives a datagram 01046 * ARGUMENTS: 01047 * TransportObject = Pointer to transport object 01048 * From = Receive filter (NULL if none) 01049 * Address = Address of buffer to place remote address 01050 * Buffer = Address of buffer to place received data 01051 * BufferSize = Address of buffer with length of Buffer (updated) 01052 * RETURNS: 01053 * Status of operation 01054 */ 01055 { 01056 PDEVICE_OBJECT DeviceObject; 01057 PMDL Mdl; 01058 01059 ASSERT(*Irp == NULL); 01060 01061 if (!TransportObject) { 01062 AFD_DbgPrint(MIN_TRACE, ("Bad tranport object.\n")); 01063 return STATUS_INVALID_PARAMETER; 01064 } 01065 01066 DeviceObject = IoGetRelatedDeviceObject(TransportObject); 01067 if (!DeviceObject) { 01068 AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n")); 01069 return STATUS_INVALID_PARAMETER; 01070 } 01071 01072 *Irp = TdiBuildInternalDeviceControlIrp(TDI_RECEIVE_DATAGRAM, /* Sub function */ 01073 DeviceObject, /* Device object */ 01074 TransportObject, /* File object */ 01075 NULL, /* Event */ 01076 Iosb); /* Status */ 01077 01078 if (!*Irp) { 01079 AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); 01080 return STATUS_INSUFFICIENT_RESOURCES; 01081 } 01082 01083 AFD_DbgPrint(MID_TRACE, ("Allocating irp for %x:%d\n", Buffer,BufferLength)); 01084 01085 Mdl = IoAllocateMdl(Buffer, /* Virtual address */ 01086 BufferLength, /* Length of buffer */ 01087 FALSE, /* Not secondary */ 01088 FALSE, /* Don't charge quota */ 01089 NULL); /* Don't use IRP */ 01090 if (!Mdl) { 01091 AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); 01092 IoCompleteRequest(*Irp, IO_NO_INCREMENT); 01093 *Irp = NULL; 01094 return STATUS_INSUFFICIENT_RESOURCES; 01095 } 01096 01097 _SEH2_TRY { 01098 MmProbeAndLockPages(Mdl, (*Irp)->RequestorMode, IoModifyAccess); 01099 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { 01100 AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n")); 01101 IoFreeMdl(Mdl); 01102 IoCompleteRequest(*Irp, IO_NO_INCREMENT); 01103 *Irp = NULL; 01104 _SEH2_YIELD(return STATUS_INSUFFICIENT_RESOURCES); 01105 } _SEH2_END; 01106 01107 AFD_DbgPrint(MID_TRACE,("AFD>>> Got an MDL: %x\n", Mdl)); 01108 01109 TdiBuildReceiveDatagram(*Irp, /* I/O Request Packet */ 01110 DeviceObject, /* Device object */ 01111 TransportObject, /* File object */ 01112 CompletionRoutine, /* Completion routine */ 01113 CompletionContext, /* Completion context */ 01114 Mdl, /* Data buffer */ 01115 BufferLength, 01116 Addr, 01117 Addr, 01118 Flags); /* Length of data */ 01119 01120 TdiCall(*Irp, DeviceObject, NULL, Iosb); 01121 /* Does not block... The MDL is deleted in the receive completion 01122 routine. */ 01123 01124 return STATUS_PENDING; 01125 } 01126 01127 01128 NTSTATUS TdiSendDatagram( 01129 PIRP *Irp, 01130 PFILE_OBJECT TransportObject, 01131 PCHAR Buffer, 01132 UINT BufferLength, 01133 PTDI_CONNECTION_INFORMATION Addr, 01134 PIO_STATUS_BLOCK Iosb, 01135 PIO_COMPLETION_ROUTINE CompletionRoutine, 01136 PVOID CompletionContext) 01137 /* 01138 * FUNCTION: Sends a datagram 01139 * ARGUMENTS: 01140 * TransportObject = Pointer to transport object 01141 * From = Send filter (NULL if none) 01142 * Address = Address of buffer to place remote address 01143 * Buffer = Address of buffer to place send data 01144 * BufferSize = Address of buffer with length of Buffer (updated) 01145 * RETURNS: 01146 * Status of operation 01147 */ 01148 { 01149 PDEVICE_OBJECT DeviceObject; 01150 PMDL Mdl; 01151 01152 ASSERT(*Irp == NULL); 01153 01154 if (!TransportObject) { 01155 AFD_DbgPrint(MIN_TRACE, ("Bad transport object.\n")); 01156 return STATUS_INVALID_PARAMETER; 01157 } 01158 01159 AFD_DbgPrint(MID_TRACE,("Called(TransportObject %x)\n", TransportObject)); 01160 01161 DeviceObject = IoGetRelatedDeviceObject(TransportObject); 01162 if (!DeviceObject) { 01163 AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n")); 01164 return STATUS_INVALID_PARAMETER; 01165 } 01166 01167 *Irp = TdiBuildInternalDeviceControlIrp(TDI_SEND_DATAGRAM, /* Sub function */ 01168 DeviceObject, /* Device object */ 01169 TransportObject, /* File object */ 01170 NULL, /* Event */ 01171 Iosb); /* Status */ 01172 01173 if (!*Irp) { 01174 AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); 01175 return STATUS_INSUFFICIENT_RESOURCES; 01176 } 01177 01178 AFD_DbgPrint(MID_TRACE, ("Allocating irp for %x:%d\n", Buffer,BufferLength)); 01179 01180 Mdl = IoAllocateMdl(Buffer, /* Virtual address */ 01181 BufferLength, /* Length of buffer */ 01182 FALSE, /* Not secondary */ 01183 FALSE, /* Don't charge quota */ 01184 NULL); /* Don't use IRP */ 01185 01186 if (!Mdl) { 01187 AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); 01188 IoCompleteRequest(*Irp, IO_NO_INCREMENT); 01189 *Irp = NULL; 01190 return STATUS_INSUFFICIENT_RESOURCES; 01191 } 01192 01193 _SEH2_TRY { 01194 MmProbeAndLockPages(Mdl, (*Irp)->RequestorMode, IoModifyAccess); 01195 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { 01196 AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n")); 01197 IoFreeMdl(Mdl); 01198 IoCompleteRequest(*Irp, IO_NO_INCREMENT); 01199 *Irp = NULL; 01200 _SEH2_YIELD(return STATUS_INSUFFICIENT_RESOURCES); 01201 } _SEH2_END; 01202 01203 AFD_DbgPrint(MID_TRACE,("AFD>>> Got an MDL: %x\n", Mdl)); 01204 01205 TdiBuildSendDatagram(*Irp, /* I/O Request Packet */ 01206 DeviceObject, /* Device object */ 01207 TransportObject, /* File object */ 01208 CompletionRoutine, /* Completion routine */ 01209 CompletionContext, /* Completion context */ 01210 Mdl, /* Data buffer */ 01211 BufferLength, /* Bytes to send */ 01212 Addr); /* Address */ 01213 01214 TdiCall(*Irp, DeviceObject, NULL, Iosb); 01215 /* Does not block... The MDL is deleted in the send completion 01216 routine. */ 01217 01218 return STATUS_PENDING; 01219 } 01220 01221 NTSTATUS TdiDisconnect( 01222 PIRP *Irp, 01223 PFILE_OBJECT TransportObject, 01224 PLARGE_INTEGER Time, 01225 USHORT Flags, 01226 PIO_STATUS_BLOCK Iosb, 01227 PIO_COMPLETION_ROUTINE CompletionRoutine, 01228 PVOID CompletionContext, 01229 PTDI_CONNECTION_INFORMATION RequestConnectionInfo, 01230 PTDI_CONNECTION_INFORMATION ReturnConnectionInfo) { 01231 PDEVICE_OBJECT DeviceObject; 01232 01233 if (!TransportObject) { 01234 AFD_DbgPrint(MIN_TRACE, ("Bad transport object.\n")); 01235 return STATUS_INVALID_PARAMETER; 01236 } 01237 01238 AFD_DbgPrint(MID_TRACE,("Called(TransportObject %x)\n", TransportObject)); 01239 01240 DeviceObject = IoGetRelatedDeviceObject(TransportObject); 01241 if (!DeviceObject) { 01242 AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n")); 01243 return STATUS_INVALID_PARAMETER; 01244 } 01245 01246 *Irp = TdiBuildInternalDeviceControlIrp(TDI_DISCONNECT, /* Sub function */ 01247 DeviceObject, /* Device object */ 01248 TransportObject, /* File object */ 01249 NULL, /* Event */ 01250 Iosb); /* Status */ 01251 01252 if (!*Irp) { 01253 AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); 01254 return STATUS_INSUFFICIENT_RESOURCES; 01255 } 01256 01257 TdiBuildDisconnect(*Irp, /* I/O Request Packet */ 01258 DeviceObject, /* Device object */ 01259 TransportObject, /* File object */ 01260 CompletionRoutine, /* Completion routine */ 01261 CompletionContext, /* Completion context */ 01262 Time, /* Time */ 01263 Flags, /* Disconnect flags */ 01264 RequestConnectionInfo, /* Indication of who to disconnect */ 01265 ReturnConnectionInfo); /* Indication of who disconnected */ 01266 01267 TdiCall(*Irp, DeviceObject, NULL, Iosb); 01268 01269 return STATUS_PENDING; 01270 } 01271 01272 /* EOF */ Generated on Sat May 26 2012 04:26:36 for ReactOS by
1.7.6.1
|