Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenmain.c
Go to the documentation of this file.
00001 /* $Id: main.c 56389 2012-04-22 13:11:54Z tfaber $ 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS kernel 00004 * FILE: drivers/net/afd/afd/main.c 00005 * PURPOSE: Ancillary functions driver 00006 * PROGRAMMER: Art Yerkes (ayerkes@speakeasy.net) 00007 * UPDATE HISTORY: 00008 * 20040630 Created 00009 * 00010 * Suggestions: Uniform naming (AfdXxx) 00011 */ 00012 00013 /* INCLUDES */ 00014 00015 #include "afd.h" 00016 00017 #if DBG 00018 00019 /* See debug.h for debug/trace constants */ 00020 //DWORD DebugTraceLevel = DEBUG_ULTRA; 00021 DWORD DebugTraceLevel = MIN_TRACE; 00022 00023 #endif /* DBG */ 00024 00025 void OskitDumpBuffer( PCHAR Data, UINT Len ) { 00026 unsigned int i; 00027 00028 for( i = 0; i < Len; i++ ) { 00029 if( i && !(i & 0xf) ) DbgPrint( "\n" ); 00030 if( !(i & 0xf) ) DbgPrint( "%08x: ", (UINT)(Data + i) ); 00031 DbgPrint( " %02x", Data[i] & 0xff ); 00032 } 00033 DbgPrint("\n"); 00034 } 00035 00036 /* FUNCTIONS */ 00037 00038 NTSTATUS NTAPI 00039 DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath); 00040 00041 NTSTATUS NTAPI 00042 AfdGetDisconnectOptions(PDEVICE_OBJECT DeviceObject, PIRP Irp, 00043 PIO_STACK_LOCATION IrpSp) 00044 { 00045 PFILE_OBJECT FileObject = IrpSp->FileObject; 00046 PAFD_FCB FCB = FileObject->FsContext; 00047 UINT BufferSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength; 00048 00049 if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp); 00050 00051 if (FCB->DisconnectOptionsSize == 0) 00052 { 00053 AFD_DbgPrint(MIN_TRACE,("Invalid parameter\n")); 00054 return UnlockAndMaybeComplete(FCB, STATUS_INVALID_PARAMETER, Irp, 0); 00055 } 00056 00057 ASSERT(FCB->DisconnectOptions); 00058 00059 if (FCB->FilledDisconnectOptions < BufferSize) BufferSize = FCB->FilledDisconnectOptions; 00060 00061 RtlCopyMemory(Irp->UserBuffer, 00062 FCB->DisconnectOptions, 00063 BufferSize); 00064 00065 return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, BufferSize); 00066 } 00067 00068 NTSTATUS 00069 NTAPI 00070 AfdSetDisconnectOptions(PDEVICE_OBJECT DeviceObject, PIRP Irp, 00071 PIO_STACK_LOCATION IrpSp) 00072 { 00073 PFILE_OBJECT FileObject = IrpSp->FileObject; 00074 PAFD_FCB FCB = FileObject->FsContext; 00075 PVOID DisconnectOptions = LockRequest(Irp, IrpSp); 00076 UINT DisconnectOptionsSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength; 00077 00078 if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp); 00079 00080 if (!DisconnectOptions) 00081 return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0); 00082 00083 if (FCB->DisconnectOptions) 00084 { 00085 ExFreePool(FCB->DisconnectOptions); 00086 FCB->DisconnectOptions = NULL; 00087 FCB->DisconnectOptionsSize = 0; 00088 FCB->FilledDisconnectOptions = 0; 00089 } 00090 00091 FCB->DisconnectOptions = ExAllocatePool(PagedPool, DisconnectOptionsSize); 00092 if (!FCB->DisconnectOptions) 00093 return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0); 00094 00095 RtlCopyMemory(FCB->DisconnectOptions, 00096 DisconnectOptions, 00097 DisconnectOptionsSize); 00098 00099 FCB->DisconnectOptionsSize = DisconnectOptionsSize; 00100 00101 return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, 0); 00102 } 00103 00104 NTSTATUS 00105 NTAPI 00106 AfdSetDisconnectOptionsSize(PDEVICE_OBJECT DeviceObject, PIRP Irp, 00107 PIO_STACK_LOCATION IrpSp) 00108 { 00109 PFILE_OBJECT FileObject = IrpSp->FileObject; 00110 PAFD_FCB FCB = FileObject->FsContext; 00111 PUINT DisconnectOptionsSize = LockRequest(Irp, IrpSp); 00112 UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength; 00113 00114 if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp); 00115 00116 if (!DisconnectOptionsSize) 00117 return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0); 00118 00119 if (BufferSize < sizeof(UINT)) 00120 { 00121 AFD_DbgPrint(MIN_TRACE,("Buffer too small\n")); 00122 return UnlockAndMaybeComplete(FCB, STATUS_BUFFER_TOO_SMALL, Irp, 0); 00123 } 00124 00125 if (FCB->DisconnectOptions) 00126 { 00127 ExFreePool(FCB->DisconnectOptions); 00128 FCB->DisconnectOptionsSize = 0; 00129 FCB->FilledDisconnectOptions = 0; 00130 } 00131 00132 FCB->DisconnectOptions = ExAllocatePool(PagedPool, *DisconnectOptionsSize); 00133 if (!FCB->DisconnectOptions) return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0); 00134 00135 FCB->DisconnectOptionsSize = *DisconnectOptionsSize; 00136 00137 return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, 0); 00138 } 00139 00140 NTSTATUS NTAPI 00141 AfdGetDisconnectData(PDEVICE_OBJECT DeviceObject, PIRP Irp, 00142 PIO_STACK_LOCATION IrpSp) 00143 { 00144 PFILE_OBJECT FileObject = IrpSp->FileObject; 00145 PAFD_FCB FCB = FileObject->FsContext; 00146 UINT BufferSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength; 00147 00148 if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp); 00149 00150 if (FCB->DisconnectDataSize == 0) 00151 { 00152 AFD_DbgPrint(MIN_TRACE,("Invalid parameter\n")); 00153 return UnlockAndMaybeComplete(FCB, STATUS_INVALID_PARAMETER, Irp, 0); 00154 } 00155 00156 ASSERT(FCB->DisconnectData); 00157 00158 if (FCB->FilledDisconnectData < BufferSize) 00159 BufferSize = FCB->FilledDisconnectData; 00160 00161 RtlCopyMemory(Irp->UserBuffer, 00162 FCB->DisconnectData, 00163 BufferSize); 00164 00165 return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, BufferSize); 00166 } 00167 00168 NTSTATUS 00169 NTAPI 00170 AfdSetDisconnectData(PDEVICE_OBJECT DeviceObject, PIRP Irp, 00171 PIO_STACK_LOCATION IrpSp) 00172 { 00173 PFILE_OBJECT FileObject = IrpSp->FileObject; 00174 PAFD_FCB FCB = FileObject->FsContext; 00175 PVOID DisconnectData = LockRequest(Irp, IrpSp); 00176 UINT DisconnectDataSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength; 00177 00178 if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp); 00179 00180 if (!DisconnectData) 00181 return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0); 00182 00183 if (FCB->DisconnectData) 00184 { 00185 ExFreePool(FCB->DisconnectData); 00186 FCB->DisconnectData = NULL; 00187 FCB->DisconnectDataSize = 0; 00188 FCB->FilledDisconnectData = 0; 00189 } 00190 00191 FCB->DisconnectData = ExAllocatePool(PagedPool, DisconnectDataSize); 00192 if (!FCB->DisconnectData) 00193 return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0); 00194 00195 RtlCopyMemory(FCB->DisconnectData, 00196 DisconnectData, 00197 DisconnectDataSize); 00198 00199 FCB->DisconnectDataSize = DisconnectDataSize; 00200 00201 return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, 0); 00202 } 00203 00204 NTSTATUS 00205 NTAPI 00206 AfdSetDisconnectDataSize(PDEVICE_OBJECT DeviceObject, PIRP Irp, 00207 PIO_STACK_LOCATION IrpSp) 00208 { 00209 PFILE_OBJECT FileObject = IrpSp->FileObject; 00210 PAFD_FCB FCB = FileObject->FsContext; 00211 PUINT DisconnectDataSize = LockRequest(Irp, IrpSp); 00212 UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength; 00213 00214 if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp); 00215 00216 if (!DisconnectDataSize) 00217 return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0); 00218 00219 if (BufferSize < sizeof(UINT)) 00220 { 00221 AFD_DbgPrint(MIN_TRACE,("Buffer too small\n")); 00222 return UnlockAndMaybeComplete(FCB, STATUS_BUFFER_TOO_SMALL, Irp, 0); 00223 } 00224 00225 if (FCB->DisconnectData) 00226 { 00227 ExFreePool(FCB->DisconnectData); 00228 FCB->DisconnectDataSize = 0; 00229 FCB->FilledDisconnectData = 0; 00230 } 00231 00232 FCB->DisconnectData = ExAllocatePool(PagedPool, *DisconnectDataSize); 00233 if (!FCB->DisconnectData) 00234 return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0); 00235 00236 FCB->DisconnectDataSize = *DisconnectDataSize; 00237 00238 return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, 0); 00239 } 00240 00241 static NTSTATUS NTAPI 00242 AfdGetTdiHandles(PDEVICE_OBJECT DeviceObject, PIRP Irp, 00243 PIO_STACK_LOCATION IrpSp) 00244 { 00245 PFILE_OBJECT FileObject = IrpSp->FileObject; 00246 PAFD_FCB FCB = FileObject->FsContext; 00247 PULONG HandleFlags = LockRequest(Irp, IrpSp); 00248 PAFD_TDI_HANDLE_DATA HandleData = Irp->UserBuffer; 00249 00250 if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp); 00251 00252 if (!HandleFlags) 00253 return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0); 00254 00255 if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG) || 00256 IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(*HandleData)) 00257 { 00258 AFD_DbgPrint(MIN_TRACE,("Buffer too small\n")); 00259 return UnlockAndMaybeComplete(FCB, STATUS_BUFFER_TOO_SMALL, Irp, 0); 00260 } 00261 00262 if ((*HandleFlags) & AFD_ADDRESS_HANDLE) 00263 HandleData->TdiAddressHandle = FCB->AddressFile.Handle; 00264 00265 if ((*HandleFlags) & AFD_CONNECTION_HANDLE) 00266 HandleData->TdiConnectionHandle = FCB->Connection.Handle; 00267 00268 return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, 0); 00269 } 00270 00271 static NTSTATUS NTAPI 00272 AfdCreateSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, 00273 PIO_STACK_LOCATION IrpSp) { 00274 PAFD_FCB FCB; 00275 PFILE_OBJECT FileObject; 00276 PAFD_DEVICE_EXTENSION DeviceExt; 00277 PFILE_FULL_EA_INFORMATION EaInfo; 00278 PAFD_CREATE_PACKET ConnectInfo = NULL; 00279 //ULONG EaLength; 00280 PWCHAR EaInfoValue = NULL; 00281 //UINT Disposition; 00282 UINT i; 00283 NTSTATUS Status = STATUS_SUCCESS; 00284 00285 AFD_DbgPrint(MID_TRACE,("AfdCreate(DeviceObject %p Irp %p)\n", 00286 DeviceObject, Irp)); 00287 00288 DeviceExt = DeviceObject->DeviceExtension; 00289 FileObject = IrpSp->FileObject; 00290 //Disposition = (IrpSp->Parameters.Create.Options >> 24) & 0xff; 00291 00292 Irp->IoStatus.Information = 0; 00293 00294 EaInfo = Irp->AssociatedIrp.SystemBuffer; 00295 00296 if( EaInfo ) { 00297 ConnectInfo = (PAFD_CREATE_PACKET)(EaInfo->EaName + EaInfo->EaNameLength + 1); 00298 EaInfoValue = (PWCHAR)(((PCHAR)ConnectInfo) + sizeof(AFD_CREATE_PACKET)); 00299 00300 //EaLength = sizeof(FILE_FULL_EA_INFORMATION) + EaInfo->EaNameLength + EaInfo->EaValueLength; 00301 00302 AFD_DbgPrint(MID_TRACE,("EaInfo: %x, EaInfoValue: %x\n", 00303 EaInfo, EaInfoValue)); 00304 } 00305 00306 AFD_DbgPrint(MID_TRACE,("About to allocate the new FCB\n")); 00307 00308 FCB = ExAllocatePool(NonPagedPool, sizeof(AFD_FCB)); 00309 if( FCB == NULL ) { 00310 Irp->IoStatus.Status = STATUS_NO_MEMORY; 00311 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00312 return STATUS_NO_MEMORY; 00313 } 00314 00315 AFD_DbgPrint(MID_TRACE,("Initializing the new FCB @ %x (FileObject %x Flags %x)\n", 00316 FCB, FileObject, ConnectInfo ? ConnectInfo->EndpointFlags : 0)); 00317 00318 RtlZeroMemory( FCB, sizeof( *FCB ) ); 00319 00320 FCB->Flags = ConnectInfo ? ConnectInfo->EndpointFlags : 0; 00321 FCB->GroupID = ConnectInfo ? ConnectInfo->GroupID : 0; 00322 FCB->GroupType = 0; /* FIXME */ 00323 FCB->State = SOCKET_STATE_CREATED; 00324 FCB->FileObject = FileObject; 00325 FCB->DeviceExt = DeviceExt; 00326 FCB->AddressFile.Handle = INVALID_HANDLE_VALUE; 00327 FCB->Connection.Handle = INVALID_HANDLE_VALUE; 00328 00329 KeInitializeMutex( &FCB->Mutex, 0 ); 00330 00331 for( i = 0; i < MAX_FUNCTIONS; i++ ) { 00332 InitializeListHead( &FCB->PendingIrpList[i] ); 00333 } 00334 00335 InitializeListHead( &FCB->DatagramList ); 00336 InitializeListHead( &FCB->PendingConnections ); 00337 00338 AFD_DbgPrint(MID_TRACE,("%x: Checking command channel\n", FCB)); 00339 00340 if( ConnectInfo ) { 00341 FCB->TdiDeviceName.Length = ConnectInfo->SizeOfTransportName; 00342 FCB->TdiDeviceName.MaximumLength = FCB->TdiDeviceName.Length; 00343 FCB->TdiDeviceName.Buffer = 00344 ExAllocatePool( NonPagedPool, FCB->TdiDeviceName.Length ); 00345 00346 if( !FCB->TdiDeviceName.Buffer ) { 00347 ExFreePool(FCB); 00348 AFD_DbgPrint(MID_TRACE,("Could not copy target string\n")); 00349 Irp->IoStatus.Status = STATUS_NO_MEMORY; 00350 IoCompleteRequest( Irp, IO_NETWORK_INCREMENT ); 00351 return STATUS_NO_MEMORY; 00352 } 00353 00354 RtlCopyMemory( FCB->TdiDeviceName.Buffer, 00355 ConnectInfo->TransportName, 00356 FCB->TdiDeviceName.Length ); 00357 00358 AFD_DbgPrint(MID_TRACE,("Success: %s %wZ\n", 00359 EaInfo->EaName, &FCB->TdiDeviceName)); 00360 } else { 00361 AFD_DbgPrint(MID_TRACE,("Success: Control connection\n")); 00362 } 00363 00364 FileObject->FsContext = FCB; 00365 00366 /* It seems that UDP sockets are writable from inception */ 00367 if( FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS ) { 00368 AFD_DbgPrint(MID_TRACE,("Packet oriented socket\n")); 00369 00370 /* A datagram socket is always sendable */ 00371 FCB->PollState |= AFD_EVENT_SEND; 00372 FCB->PollStatus[FD_WRITE_BIT] = STATUS_SUCCESS; 00373 PollReeval( FCB->DeviceExt, FCB->FileObject ); 00374 } 00375 00376 if( !NT_SUCCESS(Status) ) { 00377 if( FCB->TdiDeviceName.Buffer ) ExFreePool( FCB->TdiDeviceName.Buffer ); 00378 ExFreePool( FCB ); 00379 FileObject->FsContext = NULL; 00380 } 00381 00382 Irp->IoStatus.Status = Status; 00383 IoCompleteRequest( Irp, IO_NETWORK_INCREMENT ); 00384 00385 return Status; 00386 } 00387 00388 static NTSTATUS NTAPI 00389 AfdCleanupSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, 00390 PIO_STACK_LOCATION IrpSp) 00391 { 00392 PFILE_OBJECT FileObject = IrpSp->FileObject; 00393 PAFD_FCB FCB = FileObject->FsContext; 00394 PLIST_ENTRY CurrentEntry, NextEntry; 00395 UINT Function; 00396 PIRP CurrentIrp; 00397 00398 if( !SocketAcquireStateLock( FCB ) ) return LostSocket(Irp); 00399 00400 for (Function = 0; Function < MAX_FUNCTIONS; Function++) 00401 { 00402 CurrentEntry = FCB->PendingIrpList[Function].Flink; 00403 while (CurrentEntry != &FCB->PendingIrpList[Function]) 00404 { 00405 NextEntry = CurrentEntry->Flink; 00406 CurrentIrp = CONTAINING_RECORD(CurrentEntry, IRP, Tail.Overlay.ListEntry); 00407 00408 /* The cancel routine will remove the IRP from the list */ 00409 IoCancelIrp(CurrentIrp); 00410 00411 CurrentEntry = NextEntry; 00412 } 00413 } 00414 00415 KillSelectsForFCB( FCB->DeviceExt, FileObject, FALSE ); 00416 00417 return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, 0); 00418 } 00419 00420 static NTSTATUS NTAPI 00421 AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, 00422 PIO_STACK_LOCATION IrpSp) 00423 { 00424 PFILE_OBJECT FileObject = IrpSp->FileObject; 00425 PAFD_FCB FCB = FileObject->FsContext; 00426 UINT i; 00427 PAFD_IN_FLIGHT_REQUEST InFlightRequest[IN_FLIGHT_REQUESTS]; 00428 PAFD_TDI_OBJECT_QELT Qelt; 00429 PLIST_ENTRY QeltEntry; 00430 00431 00432 AFD_DbgPrint(MID_TRACE,("AfdClose(DeviceObject %p Irp %p)\n", 00433 DeviceObject, Irp)); 00434 00435 if( !SocketAcquireStateLock( FCB ) ) return STATUS_FILE_CLOSED; 00436 00437 FCB->State = SOCKET_STATE_CLOSED; 00438 00439 InFlightRequest[0] = &FCB->ListenIrp; 00440 InFlightRequest[1] = &FCB->ReceiveIrp; 00441 InFlightRequest[2] = &FCB->SendIrp; 00442 InFlightRequest[3] = &FCB->ConnectIrp; 00443 InFlightRequest[4] = &FCB->DisconnectIrp; 00444 00445 /* Cancel our pending requests */ 00446 for( i = 0; i < IN_FLIGHT_REQUESTS; i++ ) { 00447 if( InFlightRequest[i]->InFlightRequest ) { 00448 AFD_DbgPrint(MID_TRACE,("Cancelling in flight irp %d (%x)\n", 00449 i, InFlightRequest[i]->InFlightRequest)); 00450 IoCancelIrp(InFlightRequest[i]->InFlightRequest); 00451 } 00452 } 00453 00454 KillSelectsForFCB( FCB->DeviceExt, FileObject, FALSE ); 00455 00456 ASSERT(IsListEmpty(&FCB->PendingIrpList[FUNCTION_CONNECT])); 00457 ASSERT(IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND])); 00458 ASSERT(IsListEmpty(&FCB->PendingIrpList[FUNCTION_RECV])); 00459 ASSERT(IsListEmpty(&FCB->PendingIrpList[FUNCTION_PREACCEPT])); 00460 ASSERT(IsListEmpty(&FCB->PendingIrpList[FUNCTION_DISCONNECT])); 00461 00462 while (!IsListEmpty(&FCB->PendingConnections)) 00463 { 00464 QeltEntry = RemoveHeadList(&FCB->PendingConnections); 00465 Qelt = CONTAINING_RECORD(QeltEntry, AFD_TDI_OBJECT_QELT, ListEntry); 00466 00467 /* We have to close all pending connections or the listen won't get closed */ 00468 TdiDisassociateAddressFile(Qelt->Object.Object); 00469 ObDereferenceObject(Qelt->Object.Object); 00470 ZwClose(Qelt->Object.Handle); 00471 00472 ExFreePool(Qelt); 00473 } 00474 00475 SocketStateUnlock( FCB ); 00476 00477 if( FCB->EventSelect ) 00478 ObDereferenceObject( FCB->EventSelect ); 00479 00480 if( FCB->Context ) 00481 ExFreePool( FCB->Context ); 00482 00483 if( FCB->Recv.Window ) 00484 ExFreePool( FCB->Recv.Window ); 00485 00486 if( FCB->Send.Window ) 00487 ExFreePool( FCB->Send.Window ); 00488 00489 if( FCB->AddressFrom ) 00490 ExFreePool( FCB->AddressFrom ); 00491 00492 if( FCB->ConnectCallInfo ) 00493 ExFreePool( FCB->ConnectCallInfo ); 00494 00495 if( FCB->ConnectReturnInfo ) 00496 ExFreePool( FCB->ConnectReturnInfo ); 00497 00498 if( FCB->ConnectData ) 00499 ExFreePool( FCB->ConnectData ); 00500 00501 if( FCB->DisconnectData ) 00502 ExFreePool( FCB->DisconnectData ); 00503 00504 if( FCB->ConnectOptions ) 00505 ExFreePool( FCB->ConnectOptions ); 00506 00507 if( FCB->DisconnectOptions ) 00508 ExFreePool( FCB->DisconnectOptions ); 00509 00510 if( FCB->LocalAddress ) 00511 ExFreePool( FCB->LocalAddress ); 00512 00513 if( FCB->RemoteAddress ) 00514 ExFreePool( FCB->RemoteAddress ); 00515 00516 if( FCB->Connection.Object ) 00517 { 00518 TdiDisassociateAddressFile(FCB->Connection.Object); 00519 ObDereferenceObject(FCB->Connection.Object); 00520 } 00521 00522 if( FCB->AddressFile.Object ) 00523 ObDereferenceObject(FCB->AddressFile.Object); 00524 00525 if( FCB->AddressFile.Handle != INVALID_HANDLE_VALUE ) 00526 { 00527 if (ZwClose(FCB->AddressFile.Handle) == STATUS_INVALID_HANDLE) 00528 { 00529 DbgPrint("INVALID ADDRESS FILE HANDLE VALUE: %x %x\n", FCB->AddressFile.Handle, FCB->AddressFile.Object); 00530 } 00531 } 00532 00533 if( FCB->Connection.Handle != INVALID_HANDLE_VALUE ) 00534 { 00535 if (ZwClose(FCB->Connection.Handle) == STATUS_INVALID_HANDLE) 00536 { 00537 DbgPrint("INVALID CONNECTION HANDLE VALUE: %x %x\n", FCB->Connection.Handle, FCB->Connection.Object); 00538 } 00539 } 00540 00541 if( FCB->TdiDeviceName.Buffer ) 00542 ExFreePool(FCB->TdiDeviceName.Buffer); 00543 00544 ExFreePool(FCB); 00545 00546 Irp->IoStatus.Status = STATUS_SUCCESS; 00547 Irp->IoStatus.Information = 0; 00548 IoCompleteRequest(Irp, IO_NETWORK_INCREMENT); 00549 00550 AFD_DbgPrint(MID_TRACE, ("Returning success.\n")); 00551 00552 return STATUS_SUCCESS; 00553 } 00554 00555 static 00556 NTSTATUS 00557 NTAPI 00558 DisconnectComplete(PDEVICE_OBJECT DeviceObject, 00559 PIRP Irp, 00560 PVOID Context) 00561 { 00562 PAFD_FCB FCB = Context; 00563 PIRP CurrentIrp; 00564 PLIST_ENTRY CurrentEntry; 00565 00566 if (!SocketAcquireStateLock(FCB)) 00567 return STATUS_FILE_CLOSED; 00568 00569 ASSERT(FCB->DisconnectIrp.InFlightRequest == Irp); 00570 FCB->DisconnectIrp.InFlightRequest = NULL; 00571 00572 ASSERT(FCB->DisconnectPending); 00573 ASSERT((IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]) && !FCB->SendIrp.InFlightRequest) || 00574 (FCB->DisconnectFlags & TDI_DISCONNECT_ABORT)); 00575 00576 if (NT_SUCCESS(Irp->IoStatus.Status) && (FCB->DisconnectFlags & TDI_DISCONNECT_RELEASE)) 00577 { 00578 FCB->FilledDisconnectData = MIN(FCB->DisconnectDataSize, FCB->ConnectReturnInfo->UserDataLength); 00579 if (FCB->FilledDisconnectData) 00580 { 00581 RtlCopyMemory(FCB->DisconnectData, 00582 FCB->ConnectReturnInfo->UserData, 00583 FCB->FilledDisconnectData); 00584 } 00585 00586 FCB->FilledDisconnectOptions = MIN(FCB->DisconnectOptionsSize, FCB->ConnectReturnInfo->OptionsLength); 00587 if (FCB->FilledDisconnectOptions) 00588 { 00589 RtlCopyMemory(FCB->DisconnectOptions, 00590 FCB->ConnectReturnInfo->Options, 00591 FCB->FilledDisconnectOptions); 00592 } 00593 } 00594 00595 FCB->DisconnectPending = FALSE; 00596 00597 while (!IsListEmpty(&FCB->PendingIrpList[FUNCTION_DISCONNECT])) 00598 { 00599 CurrentEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_DISCONNECT]); 00600 CurrentIrp = CONTAINING_RECORD(CurrentEntry, IRP, Tail.Overlay.ListEntry); 00601 CurrentIrp->IoStatus.Status = Irp->IoStatus.Status; 00602 CurrentIrp->IoStatus.Information = 0; 00603 UnlockRequest(CurrentIrp, IoGetCurrentIrpStackLocation(CurrentIrp)); 00604 (void)IoSetCancelRoutine(CurrentIrp, NULL); 00605 IoCompleteRequest(CurrentIrp, IO_NETWORK_INCREMENT ); 00606 } 00607 00608 if (!(FCB->DisconnectFlags & TDI_DISCONNECT_RELEASE)) 00609 { 00610 /* Signal complete connection closure immediately */ 00611 FCB->PollState |= AFD_EVENT_ABORT; 00612 FCB->PollStatus[FD_CLOSE_BIT] = Irp->IoStatus.Status; 00613 PollReeval(FCB->DeviceExt, FCB->FileObject); 00614 } 00615 00616 SocketStateUnlock(FCB); 00617 00618 return Irp->IoStatus.Status; 00619 } 00620 00621 static 00622 NTSTATUS 00623 DoDisconnect(PAFD_FCB FCB) 00624 { 00625 NTSTATUS Status; 00626 00627 ASSERT(FCB->DisconnectPending); 00628 ASSERT((IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]) && !FCB->SendIrp.InFlightRequest) || 00629 (FCB->DisconnectFlags & TDI_DISCONNECT_ABORT)); 00630 00631 if (FCB->DisconnectIrp.InFlightRequest) 00632 { 00633 return STATUS_PENDING; 00634 } 00635 00636 FCB->ConnectCallInfo->UserData = FCB->DisconnectData; 00637 FCB->ConnectCallInfo->UserDataLength = FCB->DisconnectDataSize; 00638 FCB->ConnectCallInfo->Options = FCB->DisconnectOptions; 00639 FCB->ConnectCallInfo->OptionsLength = FCB->DisconnectOptionsSize; 00640 00641 Status = TdiDisconnect(&FCB->DisconnectIrp.InFlightRequest, 00642 FCB->Connection.Object, 00643 &FCB->DisconnectTimeout, 00644 FCB->DisconnectFlags, 00645 &FCB->DisconnectIrp.Iosb, 00646 DisconnectComplete, 00647 FCB, 00648 FCB->ConnectCallInfo, 00649 FCB->ConnectReturnInfo); 00650 if (Status != STATUS_PENDING) 00651 { 00652 FCB->DisconnectPending = FALSE; 00653 } 00654 00655 return Status; 00656 } 00657 00658 VOID 00659 RetryDisconnectCompletion(PAFD_FCB FCB) 00660 { 00661 ASSERT(FCB->RemoteAddress); 00662 00663 if (IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]) && !FCB->SendIrp.InFlightRequest && FCB->DisconnectPending) 00664 { 00665 /* Sends are done; fire off a TDI_DISCONNECT request */ 00666 DoDisconnect(FCB); 00667 } 00668 } 00669 00670 static NTSTATUS NTAPI 00671 AfdDisconnect(PDEVICE_OBJECT DeviceObject, PIRP Irp, 00672 PIO_STACK_LOCATION IrpSp) { 00673 PFILE_OBJECT FileObject = IrpSp->FileObject; 00674 PAFD_FCB FCB = FileObject->FsContext; 00675 PAFD_DISCONNECT_INFO DisReq; 00676 NTSTATUS Status = STATUS_SUCCESS; 00677 USHORT Flags; 00678 PLIST_ENTRY CurrentEntry; 00679 PIRP CurrentIrp; 00680 00681 if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp); 00682 00683 if (!(DisReq = LockRequest(Irp, IrpSp))) 00684 return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY, 00685 Irp, 0 ); 00686 00687 /* Send direction only */ 00688 if ((DisReq->DisconnectType & AFD_DISCONNECT_SEND) && 00689 !(DisReq->DisconnectType & AFD_DISCONNECT_RECV)) 00690 { 00691 /* Perform a controlled disconnect */ 00692 Flags = TDI_DISCONNECT_RELEASE; 00693 } 00694 /* Receive direction or both */ 00695 else 00696 { 00697 /* Mark that we can't issue another receive request */ 00698 FCB->TdiReceiveClosed = TRUE; 00699 00700 /* Try to cancel a pending TDI receive IRP if there was one in progress */ 00701 if (FCB->ReceiveIrp.InFlightRequest) 00702 IoCancelIrp(FCB->ReceiveIrp.InFlightRequest); 00703 00704 /* Discard any pending data */ 00705 FCB->Recv.Content = 0; 00706 FCB->Recv.BytesUsed = 0; 00707 00708 /* Mark us as overread to complete future reads with an error */ 00709 FCB->Overread = TRUE; 00710 00711 /* Set a successful close status to indicate a shutdown on overread */ 00712 FCB->PollStatus[FD_CLOSE_BIT] = STATUS_SUCCESS; 00713 00714 /* Clear the receive event */ 00715 FCB->PollState &= ~AFD_EVENT_RECEIVE; 00716 00717 /* Receive direction only */ 00718 if ((DisReq->DisconnectType & AFD_DISCONNECT_RECV) && 00719 !(DisReq->DisconnectType & AFD_DISCONNECT_SEND)) 00720 { 00721 /* No need to tell the transport driver for receive direction only */ 00722 return UnlockAndMaybeComplete( FCB, STATUS_SUCCESS, Irp, 0 ); 00723 } 00724 else 00725 { 00726 /* Perform an abortive disconnect */ 00727 Flags = TDI_DISCONNECT_ABORT; 00728 } 00729 } 00730 00731 if (!(FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS)) 00732 { 00733 if (!FCB->ConnectCallInfo) 00734 { 00735 AFD_DbgPrint(MIN_TRACE,("Invalid parameter\n")); 00736 return UnlockAndMaybeComplete( FCB, STATUS_INVALID_PARAMETER, 00737 Irp, 0 ); 00738 } 00739 00740 if (FCB->DisconnectPending) 00741 { 00742 if (FCB->DisconnectIrp.InFlightRequest) 00743 { 00744 IoCancelIrp(FCB->DisconnectIrp.InFlightRequest); 00745 ASSERT(!FCB->DisconnectIrp.InFlightRequest); 00746 } 00747 else 00748 { 00749 while (!IsListEmpty(&FCB->PendingIrpList[FUNCTION_DISCONNECT])) 00750 { 00751 CurrentEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_DISCONNECT]); 00752 CurrentIrp = CONTAINING_RECORD(CurrentEntry, IRP, Tail.Overlay.ListEntry); 00753 CurrentIrp->IoStatus.Status = STATUS_CANCELLED; 00754 CurrentIrp->IoStatus.Information = 0; 00755 UnlockRequest(CurrentIrp, IoGetCurrentIrpStackLocation(CurrentIrp)); 00756 (void)IoSetCancelRoutine(CurrentIrp, NULL); 00757 IoCompleteRequest(CurrentIrp, IO_NETWORK_INCREMENT ); 00758 } 00759 } 00760 } 00761 00762 FCB->DisconnectFlags = Flags; 00763 FCB->DisconnectTimeout = DisReq->Timeout; 00764 FCB->DisconnectPending = TRUE; 00765 FCB->SendClosed = TRUE; 00766 FCB->PollState &= ~AFD_EVENT_SEND; 00767 00768 Status = QueueUserModeIrp(FCB, Irp, FUNCTION_DISCONNECT); 00769 if (Status == STATUS_PENDING) 00770 { 00771 if ((IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]) && !FCB->SendIrp.InFlightRequest) || 00772 (FCB->DisconnectFlags & TDI_DISCONNECT_ABORT)) 00773 { 00774 /* Go ahead and execute the disconnect because we're ready for it */ 00775 Status = DoDisconnect(FCB); 00776 } 00777 00778 if (Status != STATUS_PENDING) 00779 RemoveEntryList(&Irp->Tail.Overlay.ListEntry); 00780 } 00781 00782 if (Status == STATUS_PENDING) 00783 { 00784 SocketStateUnlock(FCB); 00785 00786 return Status; 00787 } 00788 } 00789 else 00790 { 00791 if (!(Flags & TDI_DISCONNECT_RELEASE)) 00792 { 00793 if (!FCB->RemoteAddress) 00794 { 00795 AFD_DbgPrint(MIN_TRACE,("Invalid parameter\n")); 00796 return UnlockAndMaybeComplete(FCB, STATUS_INVALID_PARAMETER, Irp, 0); 00797 } 00798 00799 ExFreePool(FCB->RemoteAddress); 00800 00801 FCB->RemoteAddress = NULL; 00802 } 00803 00804 FCB->PollState &= ~AFD_EVENT_SEND; 00805 FCB->SendClosed = TRUE; 00806 } 00807 00808 return UnlockAndMaybeComplete( FCB, Status, Irp, 0 ); 00809 } 00810 00811 static NTSTATUS NTAPI 00812 AfdDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp) 00813 { 00814 PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); 00815 NTSTATUS Status = STATUS_NOT_IMPLEMENTED; 00816 #if DBG 00817 PFILE_OBJECT FileObject = IrpSp->FileObject; 00818 #endif 00819 00820 AFD_DbgPrint(MID_TRACE,("AfdDispatch: %d\n", IrpSp->MajorFunction)); 00821 if( IrpSp->MajorFunction != IRP_MJ_CREATE) { 00822 AFD_DbgPrint(MID_TRACE,("FO %x, IrpSp->FO %x\n", 00823 FileObject, IrpSp->FileObject)); 00824 ASSERT(FileObject == IrpSp->FileObject); 00825 } 00826 00827 Irp->IoStatus.Information = 0; 00828 00829 switch(IrpSp->MajorFunction) 00830 { 00831 /* opening and closing handles to the device */ 00832 case IRP_MJ_CREATE: 00833 /* Mostly borrowed from the named pipe file system */ 00834 return AfdCreateSocket(DeviceObject, Irp, IrpSp); 00835 00836 case IRP_MJ_CLOSE: 00837 /* Ditto the borrowing */ 00838 return AfdCloseSocket(DeviceObject, Irp, IrpSp); 00839 00840 case IRP_MJ_CLEANUP: 00841 return AfdCleanupSocket(DeviceObject, Irp, IrpSp); 00842 00843 /* write data */ 00844 case IRP_MJ_WRITE: 00845 return AfdConnectedSocketWriteData( DeviceObject, Irp, IrpSp, TRUE ); 00846 00847 /* read data */ 00848 case IRP_MJ_READ: 00849 return AfdConnectedSocketReadData( DeviceObject, Irp, IrpSp, TRUE ); 00850 00851 case IRP_MJ_DEVICE_CONTROL: 00852 { 00853 switch( IrpSp->Parameters.DeviceIoControl.IoControlCode ) { 00854 case IOCTL_AFD_BIND: 00855 return AfdBindSocket( DeviceObject, Irp, IrpSp ); 00856 00857 case IOCTL_AFD_CONNECT: 00858 return AfdStreamSocketConnect( DeviceObject, Irp, IrpSp ); 00859 00860 case IOCTL_AFD_START_LISTEN: 00861 return AfdListenSocket( DeviceObject, Irp, IrpSp ); 00862 00863 case IOCTL_AFD_RECV: 00864 return AfdConnectedSocketReadData( DeviceObject, Irp, IrpSp, 00865 FALSE ); 00866 00867 case IOCTL_AFD_SELECT: 00868 return AfdSelect( DeviceObject, Irp, IrpSp ); 00869 00870 case IOCTL_AFD_EVENT_SELECT: 00871 return AfdEventSelect( DeviceObject, Irp, IrpSp ); 00872 00873 case IOCTL_AFD_ENUM_NETWORK_EVENTS: 00874 return AfdEnumEvents( DeviceObject, Irp, IrpSp ); 00875 00876 case IOCTL_AFD_RECV_DATAGRAM: 00877 return AfdPacketSocketReadData( DeviceObject, Irp, IrpSp ); 00878 00879 case IOCTL_AFD_SEND: 00880 return AfdConnectedSocketWriteData( DeviceObject, Irp, IrpSp, 00881 FALSE ); 00882 00883 case IOCTL_AFD_SEND_DATAGRAM: 00884 return AfdPacketSocketWriteData( DeviceObject, Irp, IrpSp ); 00885 00886 case IOCTL_AFD_GET_INFO: 00887 return AfdGetInfo( DeviceObject, Irp, IrpSp ); 00888 00889 case IOCTL_AFD_SET_INFO: 00890 return AfdSetInfo( DeviceObject, Irp, IrpSp ); 00891 00892 case IOCTL_AFD_GET_CONTEXT_SIZE: 00893 return AfdGetContextSize( DeviceObject, Irp, IrpSp ); 00894 00895 case IOCTL_AFD_GET_CONTEXT: 00896 return AfdGetContext( DeviceObject, Irp, IrpSp ); 00897 00898 case IOCTL_AFD_SET_CONTEXT: 00899 return AfdSetContext( DeviceObject, Irp, IrpSp ); 00900 00901 case IOCTL_AFD_WAIT_FOR_LISTEN: 00902 return AfdWaitForListen( DeviceObject, Irp, IrpSp ); 00903 00904 case IOCTL_AFD_ACCEPT: 00905 return AfdAccept( DeviceObject, Irp, IrpSp ); 00906 00907 case IOCTL_AFD_DISCONNECT: 00908 return AfdDisconnect( DeviceObject, Irp, IrpSp ); 00909 00910 case IOCTL_AFD_GET_SOCK_NAME: 00911 return AfdGetSockName( DeviceObject, Irp, IrpSp ); 00912 00913 case IOCTL_AFD_GET_PEER_NAME: 00914 return AfdGetPeerName( DeviceObject, Irp, IrpSp ); 00915 00916 case IOCTL_AFD_GET_CONNECT_DATA: 00917 return AfdGetConnectData(DeviceObject, Irp, IrpSp); 00918 00919 case IOCTL_AFD_SET_CONNECT_DATA: 00920 return AfdSetConnectData(DeviceObject, Irp, IrpSp); 00921 00922 case IOCTL_AFD_SET_DISCONNECT_DATA: 00923 return AfdSetDisconnectData(DeviceObject, Irp, IrpSp); 00924 00925 case IOCTL_AFD_GET_DISCONNECT_DATA: 00926 return AfdGetDisconnectData(DeviceObject, Irp, IrpSp); 00927 00928 case IOCTL_AFD_SET_CONNECT_DATA_SIZE: 00929 return AfdSetConnectDataSize(DeviceObject, Irp, IrpSp); 00930 00931 case IOCTL_AFD_SET_DISCONNECT_DATA_SIZE: 00932 return AfdSetDisconnectDataSize(DeviceObject, Irp, IrpSp); 00933 00934 case IOCTL_AFD_SET_CONNECT_OPTIONS: 00935 return AfdSetConnectOptions(DeviceObject, Irp, IrpSp); 00936 00937 case IOCTL_AFD_SET_DISCONNECT_OPTIONS: 00938 return AfdSetDisconnectOptions(DeviceObject, Irp, IrpSp); 00939 00940 case IOCTL_AFD_GET_CONNECT_OPTIONS: 00941 return AfdGetConnectOptions(DeviceObject, Irp, IrpSp); 00942 00943 case IOCTL_AFD_GET_DISCONNECT_OPTIONS: 00944 return AfdGetDisconnectOptions(DeviceObject, Irp, IrpSp); 00945 00946 case IOCTL_AFD_SET_CONNECT_OPTIONS_SIZE: 00947 return AfdSetConnectOptionsSize(DeviceObject, Irp, IrpSp); 00948 00949 case IOCTL_AFD_SET_DISCONNECT_OPTIONS_SIZE: 00950 return AfdSetDisconnectOptionsSize(DeviceObject, Irp, IrpSp); 00951 00952 case IOCTL_AFD_GET_TDI_HANDLES: 00953 return AfdGetTdiHandles(DeviceObject, Irp, IrpSp); 00954 00955 case IOCTL_AFD_DEFER_ACCEPT: 00956 DbgPrint("IOCTL_AFD_DEFER_ACCEPT is UNIMPLEMENTED!\n"); 00957 break; 00958 00959 case IOCTL_AFD_GET_PENDING_CONNECT_DATA: 00960 DbgPrint("IOCTL_AFD_GET_PENDING_CONNECT_DATA is UNIMPLEMENTED!\n"); 00961 break; 00962 00963 case IOCTL_AFD_VALIDATE_GROUP: 00964 DbgPrint("IOCTL_AFD_VALIDATE_GROUP is UNIMPLEMENTED!\n"); 00965 break; 00966 00967 default: 00968 Status = STATUS_NOT_SUPPORTED; 00969 DbgPrint("Unknown IOCTL (0x%x)\n", 00970 IrpSp->Parameters.DeviceIoControl.IoControlCode); 00971 break; 00972 } 00973 break; 00974 } 00975 00976 /* unsupported operations */ 00977 default: 00978 { 00979 Status = STATUS_NOT_IMPLEMENTED; 00980 AFD_DbgPrint(MIN_TRACE, 00981 ("Irp: Unknown Major code was %x\n", 00982 IrpSp->MajorFunction)); 00983 break; 00984 } 00985 } 00986 00987 AFD_DbgPrint(MID_TRACE, ("Returning %x\n", Status)); 00988 Irp->IoStatus.Status = Status; 00989 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00990 00991 return Status; 00992 } 00993 00994 BOOLEAN CheckUnlockExtraBuffers(PAFD_FCB FCB, PIO_STACK_LOCATION IrpSp) 00995 { 00996 if (FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS) 00997 { 00998 if (IrpSp->MajorFunction == IRP_MJ_READ || IrpSp->MajorFunction == IRP_MJ_WRITE) 00999 { 01000 /* read()/write() call - no extra buffers */ 01001 return FALSE; 01002 } 01003 else if (IrpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL) 01004 { 01005 if (IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFD_RECV_DATAGRAM) 01006 { 01007 /* recvfrom() call - extra buffers */ 01008 return TRUE; 01009 } 01010 else if (IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFD_RECV) 01011 { 01012 /* recv() call - no extra buffers */ 01013 return FALSE; 01014 } 01015 else if (IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFD_SEND || 01016 IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFD_SEND_DATAGRAM) 01017 { 01018 /* send()/sendto() call - no extra buffers */ 01019 return FALSE; 01020 } 01021 else 01022 { 01023 /* Unknown IOCTL */ 01024 ASSERT(FALSE); 01025 return FALSE; 01026 } 01027 } 01028 else 01029 { 01030 /* Unknown IRP_MJ code */ 01031 ASSERT(FALSE); 01032 return FALSE; 01033 } 01034 } 01035 else 01036 { 01037 /* Connection-oriented never has extra buffers */ 01038 return FALSE; 01039 } 01040 } 01041 01042 VOID 01043 CleanupPendingIrp(PAFD_FCB FCB, PIRP Irp, PIO_STACK_LOCATION IrpSp, PAFD_ACTIVE_POLL Poll) 01044 { 01045 PAFD_RECV_INFO RecvReq; 01046 PAFD_SEND_INFO SendReq; 01047 PAFD_POLL_INFO PollReq; 01048 01049 if (IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFD_RECV || 01050 IrpSp->MajorFunction == IRP_MJ_READ) 01051 { 01052 RecvReq = GetLockedData(Irp, IrpSp); 01053 UnlockBuffers(RecvReq->BufferArray, RecvReq->BufferCount, CheckUnlockExtraBuffers(FCB, IrpSp)); 01054 } 01055 else if (IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFD_SEND || 01056 IrpSp->MajorFunction == IRP_MJ_WRITE) 01057 { 01058 SendReq = GetLockedData(Irp, IrpSp); 01059 UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, CheckUnlockExtraBuffers(FCB, IrpSp)); 01060 } 01061 else if (IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFD_SELECT) 01062 { 01063 PollReq = Irp->AssociatedIrp.SystemBuffer; 01064 ZeroEvents(PollReq->Handles, PollReq->HandleCount); 01065 SignalSocket(Poll, NULL, PollReq, STATUS_CANCELLED); 01066 } 01067 } 01068 01069 VOID NTAPI 01070 AfdCancelHandler(PDEVICE_OBJECT DeviceObject, 01071 PIRP Irp) 01072 { 01073 PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); 01074 PFILE_OBJECT FileObject = IrpSp->FileObject; 01075 PAFD_FCB FCB = FileObject->FsContext; 01076 ULONG Function, IoctlCode; 01077 PIRP CurrentIrp; 01078 PLIST_ENTRY CurrentEntry; 01079 PAFD_DEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension; 01080 KIRQL OldIrql; 01081 PAFD_ACTIVE_POLL Poll; 01082 01083 IoReleaseCancelSpinLock(Irp->CancelIrql); 01084 01085 if (!SocketAcquireStateLock(FCB)) 01086 return; 01087 01088 switch (IrpSp->MajorFunction) 01089 { 01090 case IRP_MJ_DEVICE_CONTROL: 01091 IoctlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode; 01092 break; 01093 01094 case IRP_MJ_READ: 01095 IoctlCode = IOCTL_AFD_RECV; 01096 break; 01097 01098 case IRP_MJ_WRITE: 01099 IoctlCode = IOCTL_AFD_SEND; 01100 break; 01101 01102 default: 01103 ASSERT(FALSE); 01104 SocketStateUnlock(FCB); 01105 return; 01106 } 01107 01108 switch (IoctlCode) 01109 { 01110 case IOCTL_AFD_RECV: 01111 case IOCTL_AFD_RECV_DATAGRAM: 01112 Function = FUNCTION_RECV; 01113 break; 01114 01115 case IOCTL_AFD_SEND: 01116 case IOCTL_AFD_SEND_DATAGRAM: 01117 Function = FUNCTION_SEND; 01118 break; 01119 01120 case IOCTL_AFD_CONNECT: 01121 Function = FUNCTION_CONNECT; 01122 break; 01123 01124 case IOCTL_AFD_WAIT_FOR_LISTEN: 01125 Function = FUNCTION_PREACCEPT; 01126 break; 01127 01128 case IOCTL_AFD_SELECT: 01129 KeAcquireSpinLock(&DeviceExt->Lock, &OldIrql); 01130 01131 CurrentEntry = DeviceExt->Polls.Flink; 01132 while (CurrentEntry != &DeviceExt->Polls) 01133 { 01134 Poll = CONTAINING_RECORD(CurrentEntry, AFD_ACTIVE_POLL, ListEntry); 01135 01136 if (Irp == Poll->Irp) 01137 { 01138 CleanupPendingIrp(FCB, Irp, IrpSp, Poll); 01139 KeReleaseSpinLock(&DeviceExt->Lock, OldIrql); 01140 SocketStateUnlock(FCB); 01141 return; 01142 } 01143 else 01144 { 01145 CurrentEntry = CurrentEntry->Flink; 01146 } 01147 } 01148 01149 KeReleaseSpinLock(&DeviceExt->Lock, OldIrql); 01150 01151 SocketStateUnlock(FCB); 01152 01153 DbgPrint("WARNING!!! IRP cancellation race could lead to a process hang! (IOCTL_AFD_SELECT)\n"); 01154 return; 01155 01156 case IOCTL_AFD_DISCONNECT: 01157 Function = FUNCTION_DISCONNECT; 01158 break; 01159 01160 default: 01161 ASSERT(FALSE); 01162 UnlockAndMaybeComplete(FCB, STATUS_CANCELLED, Irp, 0); 01163 return; 01164 } 01165 01166 CurrentEntry = FCB->PendingIrpList[Function].Flink; 01167 while (CurrentEntry != &FCB->PendingIrpList[Function]) 01168 { 01169 CurrentIrp = CONTAINING_RECORD(CurrentEntry, IRP, Tail.Overlay.ListEntry); 01170 01171 if (CurrentIrp == Irp) 01172 { 01173 RemoveEntryList(CurrentEntry); 01174 CleanupPendingIrp(FCB, Irp, IrpSp, NULL); 01175 UnlockAndMaybeComplete(FCB, STATUS_CANCELLED, Irp, 0); 01176 return; 01177 } 01178 else 01179 { 01180 CurrentEntry = CurrentEntry->Flink; 01181 } 01182 } 01183 01184 SocketStateUnlock(FCB); 01185 01186 DbgPrint("WARNING!!! IRP cancellation race could lead to a process hang! (Function: %d)\n", Function); 01187 } 01188 01189 static VOID NTAPI 01190 AfdUnload(PDRIVER_OBJECT DriverObject) 01191 { 01192 } 01193 01194 NTSTATUS NTAPI 01195 DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) 01196 { 01197 PDEVICE_OBJECT DeviceObject; 01198 UNICODE_STRING wstrDeviceName = RTL_CONSTANT_STRING(L"\\Device\\Afd"); 01199 PAFD_DEVICE_EXTENSION DeviceExt; 01200 NTSTATUS Status; 01201 01202 /* register driver routines */ 01203 DriverObject->MajorFunction[IRP_MJ_CLOSE] = AfdDispatch; 01204 DriverObject->MajorFunction[IRP_MJ_CREATE] = AfdDispatch; 01205 DriverObject->MajorFunction[IRP_MJ_CLEANUP] = AfdDispatch; 01206 DriverObject->MajorFunction[IRP_MJ_WRITE] = AfdDispatch; 01207 DriverObject->MajorFunction[IRP_MJ_READ] = AfdDispatch; 01208 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = AfdDispatch; 01209 DriverObject->DriverUnload = AfdUnload; 01210 01211 Status = IoCreateDevice(DriverObject, 01212 sizeof(AFD_DEVICE_EXTENSION), 01213 &wstrDeviceName, 01214 FILE_DEVICE_NAMED_PIPE, 01215 0, 01216 FALSE, 01217 &DeviceObject); 01218 01219 /* failure */ 01220 if (!NT_SUCCESS(Status)) 01221 { 01222 return Status; 01223 } 01224 01225 DeviceExt = DeviceObject->DeviceExtension; 01226 KeInitializeSpinLock( &DeviceExt->Lock ); 01227 InitializeListHead( &DeviceExt->Polls ); 01228 01229 AFD_DbgPrint(MID_TRACE,("Device created: object %x ext %x\n", 01230 DeviceObject, DeviceExt)); 01231 01232 return Status; 01233 } 01234 01235 /* EOF */ Generated on Mon May 28 2012 04:16:48 for ReactOS by
1.7.6.1
|