ReactOS 0.4.16-dev-2300-g249be9e
main.c File Reference
#include "afd.h"
Include dependency graph for main.c:

Go to the source code of this file.

Functions

void OskitDumpBuffer (PCHAR Data, UINT Len)
 
NTSTATUS NTAPI DriverEntry (PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
 
NTSTATUS NTAPI AfdGetDisconnectOptions (PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
 
NTSTATUS NTAPI AfdSetDisconnectOptions (PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
 
NTSTATUS NTAPI AfdSetDisconnectOptionsSize (PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
 
NTSTATUS NTAPI AfdGetDisconnectData (PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
 
NTSTATUS NTAPI AfdSetDisconnectData (PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
 
NTSTATUS NTAPI AfdSetDisconnectDataSize (PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
 
static NTSTATUS NTAPI AfdGetTdiHandles (PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
 
static NTSTATUS NTAPI AfdCreateSocket (PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
 
static NTSTATUS NTAPI AfdCleanupSocket (PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
 
static NTSTATUS NTAPI AfdCloseSocket (PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
 
static NTSTATUS NTAPI DisconnectComplete (PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
 
static NTSTATUS DoDisconnect (PAFD_FCB FCB)
 
VOID RetryDisconnectCompletion (PAFD_FCB FCB)
 
static NTSTATUS NTAPI AfdDisconnect (PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
 
NTSTATUS AfdQueryFsDeviceInfo (PDEVICE_OBJECT DeviceObject, PFILE_FS_DEVICE_INFORMATION Buffer, PULONG Length)
 
static NTSTATUS NTAPI AfdQueryVolumeInformation (PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
 
static NTSTATUS NTAPI AfdDispatch (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
BOOLEAN CheckUnlockExtraBuffers (PAFD_FCB FCB, PIO_STACK_LOCATION IrpSp)
 
VOID CleanupPendingIrp (PAFD_FCB FCB, PIRP Irp, PIO_STACK_LOCATION IrpSp, PAFD_ACTIVE_POLL Poll)
 
VOID NTAPI AfdCancelHandler (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
static VOID NTAPI AfdUnload (PDRIVER_OBJECT DriverObject)
 

Variables

ULONG AfdReceiveWindowSize = 0x2000
 
ULONG AfdSendWindowSize = 0x2000
 
static IO_COMPLETION_ROUTINE DisconnectComplete
 
static DRIVER_DISPATCH AfdDispatch
 
static DRIVER_UNLOAD AfdUnload
 

Function Documentation

◆ AfdCancelHandler()

VOID NTAPI AfdCancelHandler ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 1188 of file main.c.

1190{
1193 PAFD_FCB FCB = FileObject->FsContext;
1195 PIRP CurrentIrp;
1196 PLIST_ENTRY CurrentEntry;
1197 PAFD_DEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
1198 KIRQL OldIrql;
1199 PAFD_ACTIVE_POLL Poll;
1200
1201 IoReleaseCancelSpinLock(Irp->CancelIrql);
1202
1204 return;
1205
1206 switch (IrpSp->MajorFunction)
1207 {
1209 IoctlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode;
1210 break;
1211
1212 case IRP_MJ_READ:
1214 break;
1215
1216 case IRP_MJ_WRITE:
1218 break;
1219
1220 default:
1221 ASSERT(FALSE);
1223 return;
1224 }
1225
1226 switch (IoctlCode)
1227 {
1228 case IOCTL_AFD_RECV:
1231 break;
1232
1233 case IOCTL_AFD_SEND:
1236 break;
1237
1238 case IOCTL_AFD_CONNECT:
1240 break;
1241
1244 break;
1245
1248 break;
1249
1250 case IOCTL_AFD_SELECT:
1251 KeAcquireSpinLock(&DeviceExt->Lock, &OldIrql);
1252
1253 CurrentEntry = DeviceExt->Polls.Flink;
1254 while (CurrentEntry != &DeviceExt->Polls)
1255 {
1256 Poll = CONTAINING_RECORD(CurrentEntry, AFD_ACTIVE_POLL, ListEntry);
1257
1258 if (Irp == Poll->Irp)
1259 {
1260 CleanupPendingIrp(FCB, Irp, IrpSp, Poll);
1261 KeReleaseSpinLock(&DeviceExt->Lock, OldIrql);
1263 return;
1264 }
1265 else
1266 {
1267 CurrentEntry = CurrentEntry->Flink;
1268 }
1269 }
1270
1271 KeReleaseSpinLock(&DeviceExt->Lock, OldIrql);
1272
1274
1275 DbgPrint("WARNING!!! IRP cancellation race could lead to a process hang! (IOCTL_AFD_SELECT)\n");
1276 return;
1277
1280 break;
1281
1282 default:
1283 ASSERT(FALSE);
1285 return;
1286 }
1287
1288 CurrentEntry = FCB->PendingIrpList[Function].Flink;
1289 while (CurrentEntry != &FCB->PendingIrpList[Function])
1290 {
1291 CurrentIrp = CONTAINING_RECORD(CurrentEntry, IRP, Tail.Overlay.ListEntry);
1292
1293 if (CurrentIrp == Irp)
1294 {
1295 RemoveEntryList(CurrentEntry);
1298 return;
1299 }
1300 else
1301 {
1302 CurrentEntry = CurrentEntry->Flink;
1303 }
1304 }
1305
1307
1308 DbgPrint("WARNING!!! IRP cancellation race could lead to a process hang! (Function: %u)\n", Function);
1309}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define FUNCTION_CONNECT
Definition: afd.h:85
#define FUNCTION_RECV
Definition: afd.h:86
#define FUNCTION_PREACCEPT
Definition: afd.h:88
#define FUNCTION_CONNECTEX
Definition: afd.h:92
#define FUNCTION_DISCONNECT
Definition: afd.h:90
#define FUNCTION_SEND
Definition: afd.h:87
_In_ CDROM_SCAN_FOR_SPECIAL_INFO _In_ PCDROM_SCAN_FOR_SPECIAL_HANDLER Function
Definition: cdrom.h:1156
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4138
NTSTATUS NTAPI UnlockAndMaybeComplete(PAFD_FCB FCB, NTSTATUS Status, PIRP Irp, UINT Information)
Definition: lock.c:375
VOID SocketStateUnlock(PAFD_FCB FCB)
Definition: lock.c:370
BOOLEAN SocketAcquireStateLock(PAFD_FCB FCB)
Definition: lock.c:360
VOID CleanupPendingIrp(PAFD_FCB FCB, PIRP Irp, PIO_STACK_LOCATION IrpSp, PAFD_ACTIVE_POLL Poll)
Definition: main.c:1145
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define DbgPrint
Definition: hal.h:12
#define ASSERT(a)
Definition: mode.c:44
VOID NTAPI IoReleaseCancelSpinLock(IN KIRQL Irql)
Definition: util.c:150
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define IOCTL_AFD_WAIT_FOR_LISTEN
Definition: shared.h:280
#define IOCTL_AFD_SELECT
Definition: shared.h:292
#define IOCTL_AFD_RECV
Definition: shared.h:284
#define IOCTL_AFD_CONNECT
Definition: shared.h:276
#define IOCTL_AFD_DISCONNECT
Definition: shared.h:294
#define IOCTL_AFD_SEND_DATAGRAM
Definition: shared.h:290
#define IOCTL_AFD_SUPER_CONNECT
Definition: shared.h:346
#define IOCTL_AFD_RECV_DATAGRAM
Definition: shared.h:286
#define IOCTL_AFD_SEND
Definition: shared.h:288
PIRP Irp
Definition: afd.h:118
LIST_ENTRY Polls
Definition: afd.h:112
KSPIN_LOCK Lock
Definition: afd.h:113
Definition: afd.h:161
Definition: cdstruc.h:902
union _IO_STACK_LOCATION::@1669 Parameters
PFILE_OBJECT FileObject
Definition: iotypes.h:3171
struct _IO_STACK_LOCATION::@1669::@1670 DeviceIoControl
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2061
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_ ULONG IoctlCode
Definition: wdfiotarget.h:1043
* PFILE_OBJECT
Definition: iotypes.h:1998
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778

◆ AfdCleanupSocket()

static NTSTATUS NTAPI AfdCleanupSocket ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp,
PIO_STACK_LOCATION  IrpSp 
)
static

Definition at line 426 of file main.c.

428{
430 PAFD_FCB FCB = FileObject->FsContext;
431 PLIST_ENTRY CurrentEntry, NextEntry;
433 PIRP CurrentIrp;
434
436
437 if( !SocketAcquireStateLock( FCB ) ) return LostSocket(Irp);
438
440 {
441 CurrentEntry = FCB->PendingIrpList[Function].Flink;
442 while (CurrentEntry != &FCB->PendingIrpList[Function])
443 {
444 NextEntry = CurrentEntry->Flink;
445 CurrentIrp = CONTAINING_RECORD(CurrentEntry, IRP, Tail.Overlay.ListEntry);
446
447 /* The cancel routine will remove the IRP from the list */
448 IoCancelIrp(CurrentIrp);
449
450 CurrentEntry = NextEntry;
451 }
452 }
453
454 KillSelectsForFCB( FCB->DeviceExt, FileObject, FALSE );
455
457}
#define MAX_FUNCTIONS
Definition: afd.h:93
NTSTATUS LostSocket(PIRP Irp)
Definition: lock.c:387
VOID KillSelectsForFCB(PAFD_DEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, BOOLEAN OnlyExclusive)
Definition: select.c:125
unsigned int UINT
Definition: ndis.h:50
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
BOOLEAN NTAPI IoCancelIrp(IN PIRP Irp)
Definition: irp.c:1101
#define STATUS_SUCCESS
Definition: shellext.h:65

Referenced by AfdDispatch().

◆ AfdCloseSocket()

static NTSTATUS NTAPI AfdCloseSocket ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp,
PIO_STACK_LOCATION  IrpSp 
)
static

Definition at line 460 of file main.c.

462{
464 PAFD_FCB FCB = FileObject->FsContext;
465 UINT i;
468 PLIST_ENTRY QeltEntry;
469
470
471 AFD_DbgPrint(MID_TRACE,("AfdClose(DeviceObject %p Irp %p)\n",
472 DeviceObject, Irp));
473
475
476 FCB->SharedData.State = SOCKET_STATE_CLOSED;
477
478 InFlightRequest[0] = &FCB->ListenIrp;
479 InFlightRequest[1] = &FCB->ReceiveIrp;
480 InFlightRequest[2] = &FCB->SendIrp;
481 InFlightRequest[3] = &FCB->ConnectIrp;
482 InFlightRequest[4] = &FCB->DisconnectIrp;
483
484 /* Cancel our pending requests */
485 for( i = 0; i < IN_FLIGHT_REQUESTS; i++ ) {
486 if( InFlightRequest[i]->InFlightRequest ) {
487 AFD_DbgPrint(MID_TRACE,("Cancelling in flight irp %u (%p)\n",
488 i, InFlightRequest[i]->InFlightRequest));
489 IoCancelIrp(InFlightRequest[i]->InFlightRequest);
490 }
491 }
492
493 KillSelectsForFCB( FCB->DeviceExt, FileObject, FALSE );
494
495 ASSERT(IsListEmpty(&FCB->PendingIrpList[FUNCTION_CONNECT]));
496 ASSERT(IsListEmpty(&FCB->PendingIrpList[FUNCTION_CONNECTEX]));
497 ASSERT(IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]));
498 ASSERT(IsListEmpty(&FCB->PendingIrpList[FUNCTION_RECV]));
499 ASSERT(IsListEmpty(&FCB->PendingIrpList[FUNCTION_PREACCEPT]));
500 ASSERT(IsListEmpty(&FCB->PendingIrpList[FUNCTION_DISCONNECT]));
501
502 while (!IsListEmpty(&FCB->PendingConnections))
503 {
504 QeltEntry = RemoveHeadList(&FCB->PendingConnections);
505 Qelt = CONTAINING_RECORD(QeltEntry, AFD_TDI_OBJECT_QELT, ListEntry);
506
507 /* We have to close all pending connections or the listen won't get closed */
510 ZwClose(Qelt->Object.Handle);
511
513 }
514
516
517 if( FCB->EventSelect )
518 ObDereferenceObject( FCB->EventSelect );
519
520 if (FCB->Context)
522
523 if (FCB->Recv.Window)
525
526 if (FCB->Send.Window)
528
529 if (FCB->AddressFrom)
531
532 if (FCB->ConnectCallInfo)
534
535 if (FCB->ConnectReturnInfo)
537
538 if (FCB->ConnectData)
540
541 if (FCB->DisconnectData)
543
544 if (FCB->ConnectOptions)
546
547 if (FCB->DisconnectOptions)
549
550 if (FCB->LocalAddress)
552
553 if (FCB->RemoteAddress)
555
556 if (FCB->OnConnectSendBuffer)
558
559 if( FCB->Connection.Object )
560 {
561 TdiDisassociateAddressFile(FCB->Connection.Object);
562 ObDereferenceObject(FCB->Connection.Object);
563 }
564
565 if( FCB->AddressFile.Object )
566 ObDereferenceObject(FCB->AddressFile.Object);
567
568 if( FCB->AddressFile.Handle != INVALID_HANDLE_VALUE )
569 {
570 if (ZwClose(FCB->AddressFile.Handle) == STATUS_INVALID_HANDLE)
571 {
572 DbgPrint("INVALID ADDRESS FILE HANDLE VALUE: %p %p\n", FCB->AddressFile.Handle, FCB->AddressFile.Object);
573 }
574 }
575
576 if( FCB->Connection.Handle != INVALID_HANDLE_VALUE )
577 {
578 if (ZwClose(FCB->Connection.Handle) == STATUS_INVALID_HANDLE)
579 {
580 DbgPrint("INVALID CONNECTION HANDLE VALUE: %p %p\n", FCB->Connection.Handle, FCB->Connection.Object);
581 }
582 }
583
584 if (FCB->TdiDeviceName.Buffer)
585 {
586 ExFreePoolWithTag(FCB->TdiDeviceName.Buffer, TAG_AFD_TRANSPORT_ADDRESS);
587 }
588
590
591 Irp->IoStatus.Status = STATUS_SUCCESS;
592 Irp->IoStatus.Information = 0;
594
595 AFD_DbgPrint(MID_TRACE, ("Returning success.\n"));
596
597 return STATUS_SUCCESS;
598}
#define SOCKET_STATE_CLOSED
Definition: afd.h:83
#define IN_FLIGHT_REQUESTS
Definition: afd.h:95
#define TAG_AFD_DISCONNECT_DATA
Definition: afd.h:42
#define TAG_AFD_TDI_CONNECTION_INFORMATION
Definition: afd.h:54
#define TAG_AFD_SUPER_CONNECT_BUFFER
Definition: afd.h:46
#define TAG_AFD_DISCONNECT_OPTIONS
Definition: afd.h:45
#define TAG_AFD_ACCEPT_QUEUE
Definition: afd.h:47
#define TAG_AFD_CONNECT_OPTIONS
Definition: afd.h:44
#define TAG_AFD_SOCKET_CONTEXT
Definition: afd.h:40
#define TAG_AFD_FCB
Definition: afd.h:49
#define TAG_AFD_CONNECT_DATA
Definition: afd.h:41
#define TAG_AFD_DATA_BUFFER
Definition: afd.h:38
#define TAG_AFD_TRANSPORT_ADDRESS
Definition: afd.h:39
#define MID_TRACE
Definition: debug.h:15
#define STATUS_INVALID_HANDLE
Definition: d3dkmdt.h:40
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define AFD_DbgPrint(_t_, _x_)
Definition: debug.h:60
#define IO_NETWORK_INCREMENT
Definition: tcpip.h:43
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define IoCompleteRequest
Definition: irp.c:1240
#define STATUS_FILE_CLOSED
Definition: ntstatus.h:626
AFD_TDI_OBJECT Object
Definition: afd.h:140
HANDLE Handle
Definition: afd.h:133
PFILE_OBJECT Object
Definition: afd.h:132
NTSTATUS TdiDisassociateAddressFile(PFILE_OBJECT ConnectionObject)
Disassociates a connection endpoint from an address file object.
Definition: tdi.c:414
#define ObDereferenceObject
Definition: obfuncs.h:203

Referenced by AfdDispatch().

◆ AfdCreateSocket()

static NTSTATUS NTAPI AfdCreateSocket ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp,
PIO_STACK_LOCATION  IrpSp 
)
static

Definition at line 302 of file main.c.

303 {
306 PAFD_DEVICE_EXTENSION DeviceExt;
308 PAFD_CREATE_PACKET ConnectInfo = NULL;
309 //ULONG EaLength;
310 PWCHAR EaInfoValue = NULL;
311 //UINT Disposition;
312 UINT i;
314
315 AFD_DbgPrint(MID_TRACE,("AfdCreate(DeviceObject %p Irp %p)\n",
316 DeviceObject, Irp));
317
318 DeviceExt = DeviceObject->DeviceExtension;
320 FileObject->Flags |= FO_NAMED_PIPE;
321 //Disposition = (IrpSp->Parameters.Create.Options >> 24) & 0xff;
322
323 Irp->IoStatus.Information = 0;
324
325 EaInfo = Irp->AssociatedIrp.SystemBuffer;
326
327 if( EaInfo ) {
328 ConnectInfo = (PAFD_CREATE_PACKET)(EaInfo->EaName + EaInfo->EaNameLength + 1);
329 EaInfoValue = (PWCHAR)(((PCHAR)ConnectInfo) + sizeof(AFD_CREATE_PACKET));
330
331 //EaLength = sizeof(FILE_FULL_EA_INFORMATION) + EaInfo->EaNameLength + EaInfo->EaValueLength;
332
333 AFD_DbgPrint(MID_TRACE,("EaInfo: %p, EaInfoValue: %p\n",
334 EaInfo, EaInfoValue));
335 }
336
337 AFD_DbgPrint(MID_TRACE,("About to allocate the new FCB\n"));
338
340 if( FCB == NULL ) {
341 Irp->IoStatus.Status = STATUS_NO_MEMORY;
343 return STATUS_NO_MEMORY;
344 }
345
346 AFD_DbgPrint(MID_TRACE,("Initializing the new FCB @ %p (FileObject %p Flags %x)\n",
347 FCB, FileObject, ConnectInfo ? ConnectInfo->EndpointFlags : 0));
348
349 RtlZeroMemory( FCB, sizeof( *FCB ) );
350
351 FCB->Flags = ConnectInfo ? ConnectInfo->EndpointFlags : 0;
352 FCB->GroupID = ConnectInfo ? ConnectInfo->GroupID : 0;
353 FCB->GroupType = 0; /* FIXME */
354 FCB->SharedData.State = SOCKET_STATE_CREATED;
356 FCB->DeviceExt = DeviceExt;
357 FCB->AddressFile.Handle = INVALID_HANDLE_VALUE;
358 FCB->Connection.Handle = INVALID_HANDLE_VALUE;
359 FCB->Recv.Size = AfdReceiveWindowSize;
360 FCB->Send.Size = AfdSendWindowSize;
361
362 KeInitializeMutex( &FCB->Mutex, 0 );
363
364 for( i = 0; i < MAX_FUNCTIONS; i++ ) {
365 InitializeListHead( &FCB->PendingIrpList[i] );
366 }
367
368 InitializeListHead( &FCB->DatagramList );
369 InitializeListHead( &FCB->PendingConnections );
370
371 AFD_DbgPrint(MID_TRACE,("%p: Checking command channel\n", FCB));
372
373 if( ConnectInfo ) {
374 FCB->TdiDeviceName.Length = ConnectInfo->SizeOfTransportName;
375 FCB->TdiDeviceName.MaximumLength = FCB->TdiDeviceName.Length;
376 FCB->TdiDeviceName.Buffer = ExAllocatePoolWithTag(NonPagedPool,
377 FCB->TdiDeviceName.Length,
379
380 if( !FCB->TdiDeviceName.Buffer ) {
382 AFD_DbgPrint(MID_TRACE,("Could not copy target string\n"));
383 Irp->IoStatus.Status = STATUS_NO_MEMORY;
385 return STATUS_NO_MEMORY;
386 }
387
388 RtlCopyMemory( FCB->TdiDeviceName.Buffer,
389 ConnectInfo->TransportName,
390 FCB->TdiDeviceName.Length );
391
392 AFD_DbgPrint(MID_TRACE,("Success: %s %wZ\n",
393 EaInfo->EaName, &FCB->TdiDeviceName));
394 } else {
395 AFD_DbgPrint(MID_TRACE,("Success: Control connection\n"));
396 }
397
398 FileObject->FsContext = FCB;
399
400 /* It seems that UDP sockets are writable from inception */
402 AFD_DbgPrint(MID_TRACE,("Packet oriented socket\n"));
403
404 /* A datagram socket is always sendable */
405 FCB->PollState |= AFD_EVENT_SEND;
406 FCB->PollStatus[FD_WRITE_BIT] = STATUS_SUCCESS;
407 PollReeval( FCB->DeviceExt, FCB->FileObject );
408 }
409
410 if( !NT_SUCCESS(Status) ) {
411 if (FCB->TdiDeviceName.Buffer)
412 {
413 ExFreePoolWithTag(FCB->TdiDeviceName.Buffer, TAG_AFD_TRANSPORT_ADDRESS);
414 }
416 FileObject->FsContext = NULL;
417 }
418
419 Irp->IoStatus.Status = Status;
421
422 return Status;
423}
#define SOCKET_STATE_CREATED
Definition: afd.h:74
LONG NTSTATUS
Definition: precomp.h:26
struct _FCB FCB
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
ULONG AfdSendWindowSize
Definition: main.c:27
ULONG AfdReceiveWindowSize
Definition: main.c:26
VOID PollReeval(PAFD_DEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
Definition: select.c:407
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define NonPagedPool
Definition: env_spec_w32.h:307
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
Status
Definition: gdiplustypes.h:25
VOID NTAPI KeInitializeMutex(IN PKMUTEX Mutex, IN ULONG Level)
Definition: mutex.c:67
struct _AFD_CREATE_PACKET * PAFD_CREATE_PACKET
#define AFD_EVENT_SEND
Definition: shared.h:211
#define AFD_ENDPOINT_CONNECTIONLESS
Definition: shared.h:159
DWORD EndpointFlags
Definition: shared.h:22
WCHAR TransportName[1]
Definition: shared.h:25
DWORD SizeOfTransportName
Definition: shared.h:24
ULONG Flags
Definition: ntfs.h:536
PFILE_OBJECT FileObject
Definition: ntfs.h:520
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint16_t * PWCHAR
Definition: typedefs.h:56
char * PCHAR
Definition: typedefs.h:51
#define FD_WRITE_BIT
Definition: winsock2.h:289
#define FO_NAMED_PIPE
Definition: iotypes.h:1782
#define IO_NO_INCREMENT
Definition: iotypes.h:598

Referenced by AfdDispatch(), TestSend(), TestSendTo(), TestTcp(), and TestUdp().

◆ AfdDisconnect()

static NTSTATUS NTAPI AfdDisconnect ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp,
PIO_STACK_LOCATION  IrpSp 
)
static

Definition at line 719 of file main.c.

720 {
722 PAFD_FCB FCB = FileObject->FsContext;
726 PLIST_ENTRY CurrentEntry;
727 PIRP CurrentIrp;
728
730
732
733 if (!(DisReq = LockRequest(Irp, IrpSp, FALSE, NULL)))
735 Irp, 0 );
736
737 /* Send direction only */
738 if ((DisReq->DisconnectType & AFD_DISCONNECT_SEND) &&
740 {
741 /* Perform a controlled disconnect */
743 }
744 /* Receive direction or both */
745 else
746 {
747 /* Mark that we can't issue another receive request */
748 FCB->TdiReceiveClosed = TRUE;
749
750 /* Try to cancel a pending TDI receive IRP if there was one in progress */
751 if (FCB->ReceiveIrp.InFlightRequest)
752 IoCancelIrp(FCB->ReceiveIrp.InFlightRequest);
753
754 /* Discard any pending data */
755 FCB->Recv.Content = 0;
756 FCB->Recv.BytesUsed = 0;
757
758 /* Set a successful receive status to indicate a shutdown on overread */
759 FCB->LastReceiveStatus = STATUS_SUCCESS;
760
761 /* Clear the receive event */
762 FCB->PollState &= ~AFD_EVENT_RECEIVE;
763
764 /* Receive direction only */
765 if ((DisReq->DisconnectType & AFD_DISCONNECT_RECV) &&
767 {
768 /* No need to tell the transport driver for receive direction only */
770 }
771 else
772 {
773 /* Perform an abortive disconnect */
775 }
776 }
777
779 {
780 if (!FCB->ConnectCallInfo)
781 {
782 AFD_DbgPrint(MIN_TRACE,("Invalid parameter\n"));
784 Irp, 0 );
785 }
786
787 if (FCB->DisconnectPending)
788 {
789 if (FCB->DisconnectIrp.InFlightRequest)
790 {
791 IoCancelIrp(FCB->DisconnectIrp.InFlightRequest);
792 ASSERT(!FCB->DisconnectIrp.InFlightRequest);
793 }
794 else
795 {
796 while (!IsListEmpty(&FCB->PendingIrpList[FUNCTION_DISCONNECT]))
797 {
798 CurrentEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_DISCONNECT]);
799 CurrentIrp = CONTAINING_RECORD(CurrentEntry, IRP, Tail.Overlay.ListEntry);
800 CurrentIrp->IoStatus.Status = STATUS_CANCELLED;
801 CurrentIrp->IoStatus.Information = 0;
802 UnlockRequest(CurrentIrp, IoGetCurrentIrpStackLocation(CurrentIrp));
803 (void)IoSetCancelRoutine(CurrentIrp, NULL);
805 }
806 }
807 }
808
809 FCB->DisconnectFlags = Flags;
810 FCB->DisconnectTimeout = DisReq->Timeout;
811 FCB->DisconnectPending = TRUE;
812 FCB->SendClosed = TRUE;
813 FCB->PollState &= ~AFD_EVENT_SEND;
814
816 if (Status == STATUS_PENDING)
817 {
818 if ((IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]) && !FCB->SendIrp.InFlightRequest) ||
819 (FCB->DisconnectFlags & TDI_DISCONNECT_ABORT))
820 {
821 /* Go ahead and execute the disconnect because we're ready for it */
823 }
824
825 if (Status != STATUS_PENDING)
826 RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
827 }
828
829 if (Status == STATUS_PENDING)
830 {
832
833 return Status;
834 }
835 }
836 else
837 {
839 {
840 if (!FCB->RemoteAddress)
841 {
842 AFD_DbgPrint(MIN_TRACE,("Invalid parameter\n"));
844 }
845
847
848 FCB->RemoteAddress = NULL;
849 }
850
851 FCB->PollState &= ~AFD_EVENT_SEND;
852 FCB->SendClosed = TRUE;
853 }
854
855 return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
856}
#define MIN_TRACE
Definition: debug.h:14
#define TRUE
Definition: types.h:120
PVOID LockRequest(PIRP Irp, PIO_STACK_LOCATION IrpSp, BOOLEAN Output, KPROCESSOR_MODE *LockMode)
Definition: lock.c:24
VOID UnlockRequest(PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: lock.c:180
NTSTATUS QueueUserModeIrp(PAFD_FCB FCB, PIRP Irp, UINT Function)
Definition: lock.c:397
static NTSTATUS DoDisconnect(PAFD_FCB FCB)
Definition: main.c:672
IoSetCancelRoutine(Irp, CancelRoutine)
unsigned short USHORT
Definition: pedump.c:61
#define AFD_DISCONNECT_RECV
Definition: shared.h:204
#define AFD_DISCONNECT_SEND
Definition: shared.h:203
LARGE_INTEGER Timeout
Definition: shared.h:143
ULONG DisconnectType
Definition: shared.h:142
IO_STATUS_BLOCK IoStatus
#define TDI_DISCONNECT_RELEASE
Definition: tdi.h:144
#define TDI_DISCONNECT_ABORT
Definition: tdi.h:143
#define STATUS_PENDING
Definition: telnetd.h:14
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by AfdDispatch().

◆ AfdDispatch()

static NTSTATUS NTAPI AfdDispatch ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)
static

Definition at line 907 of file main.c.

908{
911#if DBG
913#endif
914
915 AFD_DbgPrint(MID_TRACE,("AfdDispatch: %u\n", IrpSp->MajorFunction));
917 AFD_DbgPrint(MID_TRACE,("FO %p, IrpSp->FO %p\n",
920 }
921
922 Irp->IoStatus.Information = 0;
923
924 switch(IrpSp->MajorFunction)
925 {
926 /* opening and closing handles to the device */
927 case IRP_MJ_CREATE:
928 /* Mostly borrowed from the named pipe file system */
930
931 case IRP_MJ_CLOSE:
932 /* Ditto the borrowing */
934
935 case IRP_MJ_CLEANUP:
937
938 /* write data */
939 case IRP_MJ_WRITE:
941
942 /* read data */
943 case IRP_MJ_READ:
945
946 /* query volume info */
949
951 {
952 switch( IrpSp->Parameters.DeviceIoControl.IoControlCode ) {
953 case IOCTL_AFD_BIND:
955
958
961
964
965 case IOCTL_AFD_RECV:
967 FALSE );
968
969 case IOCTL_AFD_SELECT:
970 return AfdSelect( DeviceObject, Irp, IrpSp );
971
974
977
980
981 case IOCTL_AFD_SEND:
983 FALSE );
984
987
989 return AfdGetInfo( DeviceObject, Irp, IrpSp );
990
992 return AfdSetInfo( DeviceObject, Irp, IrpSp );
993
996
999
1001 return AfdSetContext( DeviceObject, Irp, IrpSp );
1002
1005
1006 case IOCTL_AFD_ACCEPT:
1007 return AfdAccept( DeviceObject, Irp, IrpSp );
1008
1010 return AfdDisconnect( DeviceObject, Irp, IrpSp );
1011
1014
1017
1020
1023
1026
1029
1032
1035
1038
1041
1044
1047
1050
1053
1056
1058 DbgPrint("IOCTL_AFD_DEFER_ACCEPT is UNIMPLEMENTED!\n");
1059 break;
1060
1062 DbgPrint("IOCTL_AFD_GET_PENDING_CONNECT_DATA is UNIMPLEMENTED!\n");
1063 break;
1064
1066 DbgPrint("IOCTL_AFD_VALIDATE_GROUP is UNIMPLEMENTED!\n");
1067 break;
1068
1069 default:
1071 DbgPrint("Unknown IOCTL (0x%x)\n",
1072 IrpSp->Parameters.DeviceIoControl.IoControlCode);
1073 break;
1074 }
1075 break;
1076 }
1077
1078/* unsupported operations */
1079 default:
1080 {
1083 ("Irp: Unknown Major code was %x\n",
1085 break;
1086 }
1087 }
1088
1089 AFD_DbgPrint(MID_TRACE, ("Returning %x\n", Status));
1090 Irp->IoStatus.Status = Status;
1092
1093 return Status;
1094}
#define STATUS_NOT_SUPPORTED
Definition: d3dkmdt.h:48
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
NTSTATUS NTAPI AfdBindSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: bind.c:76
NTSTATUS NTAPI AfdSetConnectData(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: connect.c:157
NTSTATUS NTAPI AfdSetConnectDataSize(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: connect.c:197
NTSTATUS NTAPI AfdStreamSocketConnect(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: connect.c:520
NTSTATUS NTAPI AfdStreamSocketSuperConnect(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: connect.c:673
NTSTATUS NTAPI AfdGetConnectOptions(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: connect.c:15
NTSTATUS NTAPI AfdGetConnectData(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: connect.c:127
NTSTATUS NTAPI AfdSetConnectOptions(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: connect.c:45
NTSTATUS NTAPI AfdSetConnectOptionsSize(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: connect.c:86
NTSTATUS NTAPI AfdSetContext(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: context.c:71
NTSTATUS NTAPI AfdGetContextSize(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: context.c:47
NTSTATUS NTAPI AfdGetContext(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: context.c:14
NTSTATUS NTAPI AfdSetInfo(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: info.c:102
NTSTATUS NTAPI AfdGetSockName(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: info.c:232
NTSTATUS NTAPI AfdGetInfo(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: info.c:14
NTSTATUS NTAPI AfdGetPeerName(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: info.c:281
NTSTATUS AfdAccept(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: listen.c:337
NTSTATUS AfdListenSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: listen.c:225
NTSTATUS AfdWaitForListen(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: listen.c:293
NTSTATUS NTAPI AfdSetDisconnectData(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: main.c:188
static NTSTATUS NTAPI AfdQueryVolumeInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: main.c:878
NTSTATUS NTAPI AfdSetDisconnectDataSize(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: main.c:229
static NTSTATUS NTAPI AfdGetTdiHandles(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: main.c:270
static NTSTATUS NTAPI AfdCreateSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: main.c:302
static NTSTATUS NTAPI AfdCleanupSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: main.c:426
NTSTATUS NTAPI AfdSetDisconnectOptions(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: main.c:76
static NTSTATUS NTAPI AfdDisconnect(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: main.c:719
NTSTATUS NTAPI AfdSetDisconnectOptionsSize(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: main.c:117
static NTSTATUS NTAPI AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: main.c:460
NTSTATUS NTAPI AfdGetDisconnectOptions(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: main.c:46
NTSTATUS NTAPI AfdGetDisconnectData(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: main.c:157
NTSTATUS NTAPI AfdEnumEvents(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: select.c:328
NTSTATUS NTAPI AfdSelect(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: select.c:165
NTSTATUS NTAPI AfdEventSelect(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: select.c:265
NTSTATUS NTAPI AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp, BOOLEAN Short)
Definition: write.c:329
NTSTATUS NTAPI AfdPacketSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: write.c:568
NTSTATUS NTAPI AfdConnectedSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp, BOOLEAN Short)
Definition: read.c:415
NTSTATUS NTAPI AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: read.c:696
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
#define IRP_MJ_QUERY_VOLUME_INFORMATION
Definition: rdpdr.c:50
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define IOCTL_AFD_EVENT_SELECT
Definition: shared.h:336
#define IOCTL_AFD_GET_TDI_HANDLES
Definition: shared.h:300
#define IOCTL_AFD_SET_INFO
Definition: shared.h:302
#define IOCTL_AFD_SET_DISCONNECT_OPTIONS
Definition: shared.h:316
#define IOCTL_AFD_SET_CONNECT_OPTIONS_SIZE
Definition: shared.h:328
#define IOCTL_AFD_GET_SOCK_NAME
Definition: shared.h:296
#define IOCTL_AFD_DEFER_ACCEPT
Definition: shared.h:338
#define IOCTL_AFD_START_LISTEN
Definition: shared.h:278
#define IOCTL_AFD_SET_CONNECT_OPTIONS
Definition: shared.h:312
#define IOCTL_AFD_GET_DISCONNECT_DATA
Definition: shared.h:322
#define IOCTL_AFD_GET_CONTEXT
Definition: shared.h:306
#define IOCTL_AFD_SET_DISCONNECT_DATA_SIZE
Definition: shared.h:330
#define IOCTL_AFD_GET_DISCONNECT_OPTIONS
Definition: shared.h:324
#define IOCTL_AFD_GET_INFO
Definition: shared.h:334
#define IOCTL_AFD_GET_CONTEXT_SIZE
Definition: shared.h:304
#define IOCTL_AFD_GET_CONNECT_OPTIONS
Definition: shared.h:320
#define IOCTL_AFD_SET_CONNECT_DATA
Definition: shared.h:310
#define IOCTL_AFD_ACCEPT
Definition: shared.h:282
#define IOCTL_AFD_BIND
Definition: shared.h:274
#define IOCTL_AFD_VALIDATE_GROUP
Definition: shared.h:344
#define IOCTL_AFD_SET_DISCONNECT_OPTIONS_SIZE
Definition: shared.h:332
#define IOCTL_AFD_ENUM_NETWORK_EVENTS
Definition: shared.h:342
#define IOCTL_AFD_SET_DISCONNECT_DATA
Definition: shared.h:314
#define IOCTL_AFD_GET_PENDING_CONNECT_DATA
Definition: shared.h:340
#define IOCTL_AFD_SET_CONNECT_DATA_SIZE
Definition: shared.h:326
#define IOCTL_AFD_GET_PEER_NAME
Definition: shared.h:298
#define IOCTL_AFD_SET_CONTEXT
Definition: shared.h:308
#define IOCTL_AFD_GET_CONNECT_DATA
Definition: shared.h:318
#define IRP_MJ_CLEANUP

◆ AfdGetDisconnectData()

NTSTATUS NTAPI AfdGetDisconnectData ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp,
PIO_STACK_LOCATION  IrpSp 
)

Definition at line 157 of file main.c.

159{
161 PAFD_FCB FCB = FileObject->FsContext;
162 UINT BufferSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
163
165
167
168 if (FCB->DisconnectDataSize == 0)
169 {
170 AFD_DbgPrint(MIN_TRACE,("Invalid parameter\n"));
172 }
173
174 ASSERT(FCB->DisconnectData);
175
176 if (FCB->FilledDisconnectData < BufferSize)
177 BufferSize = FCB->FilledDisconnectData;
178
179 RtlCopyMemory(Irp->UserBuffer,
180 FCB->DisconnectData,
181 BufferSize);
182
184}
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254

Referenced by AfdDispatch().

◆ AfdGetDisconnectOptions()

NTSTATUS NTAPI AfdGetDisconnectOptions ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp,
PIO_STACK_LOCATION  IrpSp 
)

Definition at line 46 of file main.c.

48{
50 PAFD_FCB FCB = FileObject->FsContext;
51 UINT BufferSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
52
54
56
57 if (FCB->DisconnectOptionsSize == 0)
58 {
59 AFD_DbgPrint(MIN_TRACE,("Invalid parameter\n"));
61 }
62
63 ASSERT(FCB->DisconnectOptions);
64
65 if (FCB->FilledDisconnectOptions < BufferSize) BufferSize = FCB->FilledDisconnectOptions;
66
67 RtlCopyMemory(Irp->UserBuffer,
68 FCB->DisconnectOptions,
70
72}

Referenced by AfdDispatch().

◆ AfdGetTdiHandles()

static NTSTATUS NTAPI AfdGetTdiHandles ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp,
PIO_STACK_LOCATION  IrpSp 
)
static

Definition at line 270 of file main.c.

272{
274 PAFD_FCB FCB = FileObject->FsContext;
275 PULONG HandleFlags = LockRequest(Irp, IrpSp, TRUE, NULL);
276 PAFD_TDI_HANDLE_DATA HandleData = Irp->UserBuffer;
277
279
281
282 if (!HandleFlags)
284
285 if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG) ||
286 IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(*HandleData))
287 {
288 AFD_DbgPrint(MIN_TRACE,("Buffer too small\n"));
290 }
291
292 if ((*HandleFlags) & AFD_ADDRESS_HANDLE)
293 HandleData->TdiAddressHandle = FCB->AddressFile.Handle;
294
295 if ((*HandleFlags) & AFD_CONNECTION_HANDLE)
296 HandleData->TdiConnectionHandle = FCB->Connection.Handle;
297
299}
#define AFD_CONNECTION_HANDLE
Definition: shared.h:168
#define AFD_ADDRESS_HANDLE
Definition: shared.h:167
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
HANDLE TdiConnectionHandle
Definition: shared.h:155
HANDLE TdiAddressHandle
Definition: shared.h:154
uint32_t * PULONG
Definition: typedefs.h:59

Referenced by AfdDispatch().

◆ AfdQueryFsDeviceInfo()

NTSTATUS AfdQueryFsDeviceInfo ( PDEVICE_OBJECT  DeviceObject,
PFILE_FS_DEVICE_INFORMATION  Buffer,
PULONG  Length 
)

Definition at line 859 of file main.c.

860{
861 if (*Length >= sizeof(FILE_FS_DEVICE_INFORMATION))
862 {
863 Buffer->Characteristics = 0;
864 Buffer->DeviceType = FILE_DEVICE_NAMED_PIPE;
865
867
868 return STATUS_SUCCESS;
869 }
870 else
871 {
874 }
875}
Definition: bufpool.h:45
struct _FILE_FS_DEVICE_INFORMATION FILE_FS_DEVICE_INFORMATION
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define FILE_DEVICE_NAMED_PIPE
Definition: winioctl.h:62
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133

Referenced by AfdQueryVolumeInformation().

◆ AfdQueryVolumeInformation()

static NTSTATUS NTAPI AfdQueryVolumeInformation ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp,
PIO_STACK_LOCATION  IrpSp 
)
static

Definition at line 878 of file main.c.

879{
880 FS_INFORMATION_CLASS InfoClass;
884
885 Buffer = Irp->AssociatedIrp.SystemBuffer;
887 InfoClass = IrpSp->Parameters.QueryVolume.FsInformationClass;
888
889 switch (InfoClass)
890 {
893 break;
894 default:
895 break;
896 }
897
898 Irp->IoStatus.Status = Status;
899 Irp->IoStatus.Information = IrpSp->Parameters.QueryVolume.Length - Length;
901
902 return Status;
903}
NTSTATUS AfdQueryFsDeviceInfo(PDEVICE_OBJECT DeviceObject, PFILE_FS_DEVICE_INFORMATION Buffer, PULONG Length)
Definition: main.c:859
@ FileFsDeviceInformation
Definition: from_kernel.h:222
enum _FSINFOCLASS FS_INFORMATION_CLASS
#define STATUS_INVALID_INFO_CLASS
Definition: ntstatus.h:333
struct _IO_STACK_LOCATION::@4265::@4278 QueryVolume

Referenced by AfdDispatch().

◆ AfdSetDisconnectData()

NTSTATUS NTAPI AfdSetDisconnectData ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp,
PIO_STACK_LOCATION  IrpSp 
)

Definition at line 188 of file main.c.

190{
192 PAFD_FCB FCB = FileObject->FsContext;
193 PVOID DisconnectData = LockRequest(Irp, IrpSp, FALSE, NULL);
194 UINT DisconnectDataSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
195
197
199
200 if (!DisconnectData)
202
203 if (FCB->DisconnectData)
204 {
206 FCB->DisconnectData = NULL;
207 FCB->DisconnectDataSize = 0;
208 FCB->FilledDisconnectData = 0;
209 }
210
211 FCB->DisconnectData = ExAllocatePoolWithTag(PagedPool,
212 DisconnectDataSize,
214
215 if (!FCB->DisconnectData)
217
218 RtlCopyMemory(FCB->DisconnectData,
219 DisconnectData,
220 DisconnectDataSize);
221
222 FCB->DisconnectDataSize = DisconnectDataSize;
223
225}
#define PagedPool
Definition: env_spec_w32.h:308

Referenced by AfdDispatch().

◆ AfdSetDisconnectDataSize()

NTSTATUS NTAPI AfdSetDisconnectDataSize ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp,
PIO_STACK_LOCATION  IrpSp 
)

Definition at line 229 of file main.c.

231{
233 PAFD_FCB FCB = FileObject->FsContext;
234 PUINT DisconnectDataSize = LockRequest(Irp, IrpSp, FALSE, NULL);
235 UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
236
238
240
241 if (!DisconnectDataSize)
243
244 if (BufferSize < sizeof(UINT))
245 {
246 AFD_DbgPrint(MIN_TRACE,("Buffer too small\n"));
248 }
249
250 if (FCB->DisconnectData)
251 {
253 FCB->DisconnectDataSize = 0;
254 FCB->FilledDisconnectData = 0;
255 }
256
257 FCB->DisconnectData = ExAllocatePoolWithTag(PagedPool,
258 *DisconnectDataSize,
260
261 if (!FCB->DisconnectData)
263
264 FCB->DisconnectDataSize = *DisconnectDataSize;
265
267}
unsigned int * PUINT
Definition: ndis.h:50

Referenced by AfdDispatch().

◆ AfdSetDisconnectOptions()

NTSTATUS NTAPI AfdSetDisconnectOptions ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp,
PIO_STACK_LOCATION  IrpSp 
)

Definition at line 76 of file main.c.

78{
80 PAFD_FCB FCB = FileObject->FsContext;
81 PVOID DisconnectOptions = LockRequest(Irp, IrpSp, FALSE, NULL);
82 UINT DisconnectOptionsSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
83
85
87
88 if (!DisconnectOptions)
90
91 if (FCB->DisconnectOptions)
92 {
94 FCB->DisconnectOptions = NULL;
95 FCB->DisconnectOptionsSize = 0;
96 FCB->FilledDisconnectOptions = 0;
97 }
98
99 FCB->DisconnectOptions = ExAllocatePoolWithTag(PagedPool,
100 DisconnectOptionsSize,
102
103 if (!FCB->DisconnectOptions)
105
106 RtlCopyMemory(FCB->DisconnectOptions,
107 DisconnectOptions,
108 DisconnectOptionsSize);
109
110 FCB->DisconnectOptionsSize = DisconnectOptionsSize;
111
113}

Referenced by AfdDispatch().

◆ AfdSetDisconnectOptionsSize()

NTSTATUS NTAPI AfdSetDisconnectOptionsSize ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp,
PIO_STACK_LOCATION  IrpSp 
)

Definition at line 117 of file main.c.

119{
121 PAFD_FCB FCB = FileObject->FsContext;
122 PUINT DisconnectOptionsSize = LockRequest(Irp, IrpSp, FALSE, NULL);
123 UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
124
126
128
129 if (!DisconnectOptionsSize)
131
132 if (BufferSize < sizeof(UINT))
133 {
134 AFD_DbgPrint(MIN_TRACE,("Buffer too small\n"));
136 }
137
138 if (FCB->DisconnectOptions)
139 {
141 FCB->DisconnectOptionsSize = 0;
142 FCB->FilledDisconnectOptions = 0;
143 }
144
145 FCB->DisconnectOptions = ExAllocatePoolWithTag(PagedPool,
146 *DisconnectOptionsSize,
148
149 if (!FCB->DisconnectOptions) return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
150
151 FCB->DisconnectOptionsSize = *DisconnectOptionsSize;
152
154}

Referenced by AfdDispatch().

◆ AfdUnload()

static VOID NTAPI AfdUnload ( PDRIVER_OBJECT  DriverObject)
static

Definition at line 1313 of file main.c.

1314{
1316}
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213

◆ CheckUnlockExtraBuffers()

BOOLEAN CheckUnlockExtraBuffers ( PAFD_FCB  FCB,
PIO_STACK_LOCATION  IrpSp 
)

Definition at line 1096 of file main.c.

1097{
1099 {
1101 {
1102 /* read()/write() call - no extra buffers */
1103 return FALSE;
1104 }
1106 {
1108 {
1109 /* recvfrom() call - extra buffers */
1110 return TRUE;
1111 }
1112 else if (IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFD_RECV)
1113 {
1114 /* recv() call - no extra buffers */
1115 return FALSE;
1116 }
1117 else if (IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFD_SEND ||
1119 {
1120 /* send()/sendto() call - no extra buffers */
1121 return FALSE;
1122 }
1123 else
1124 {
1125 /* Unknown IOCTL */
1126 ASSERT(FALSE);
1127 return FALSE;
1128 }
1129 }
1130 else
1131 {
1132 /* Unknown IRP_MJ code */
1133 ASSERT(FALSE);
1134 return FALSE;
1135 }
1136 }
1137 else
1138 {
1139 /* Connection-oriented never has extra buffers */
1140 return FALSE;
1141 }
1142}

Referenced by CleanupPendingIrp(), PacketSocketRecvComplete(), and SatisfyPacketRecvRequest().

◆ CleanupPendingIrp()

VOID CleanupPendingIrp ( PAFD_FCB  FCB,
PIRP  Irp,
PIO_STACK_LOCATION  IrpSp,
PAFD_ACTIVE_POLL  Poll 
)

Definition at line 1145 of file main.c.

1146{
1147 PAFD_RECV_INFO RecvReq;
1148 PAFD_SEND_INFO SendReq;
1149 PAFD_POLL_INFO PollReq;
1150
1152 {
1153 RecvReq = GetLockedData(Irp, IrpSp);
1155 }
1156 else if (IrpSp->MajorFunction == IRP_MJ_WRITE)
1157 {
1158 SendReq = GetLockedData(Irp, IrpSp);
1160 }
1161 else
1162 {
1164
1165 if (IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFD_RECV)
1166 {
1167 RecvReq = GetLockedData(Irp, IrpSp);
1169 }
1170 else if (IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFD_SEND)
1171 {
1172 SendReq = GetLockedData(Irp, IrpSp);
1174 }
1175 else if (IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_AFD_SELECT)
1176 {
1177 ASSERT(Poll);
1178
1179 PollReq = Irp->AssociatedIrp.SystemBuffer;
1180 ZeroEvents(PollReq->Handles, PollReq->HandleCount);
1181 SignalSocket(Poll, NULL, PollReq, STATUS_CANCELLED);
1182 }
1183 }
1184}
VOID UnlockBuffers(PAFD_WSABUF Buf, UINT Count, BOOL Address)
Definition: lock.c:289
PVOID GetLockedData(PIRP Irp, PIO_STACK_LOCATION IrpSp)
Definition: lock.c:13
BOOLEAN CheckUnlockExtraBuffers(PAFD_FCB FCB, PIO_STACK_LOCATION IrpSp)
Definition: main.c:1096
VOID ZeroEvents(PAFD_HANDLE HandleArray, UINT HandleCount)
Definition: select.c:44
VOID SignalSocket(PAFD_ACTIVE_POLL Poll OPTIONAL, PIRP _Irp OPTIONAL, PAFD_POLL_INFO PollReq, NTSTATUS Status)
Definition: select.c:56
ULONG HandleCount
Definition: shared.h:57
AFD_HANDLE Handles[1]
Definition: shared.h:59
ULONG BufferCount
Definition: shared.h:86
PAFD_WSABUF BufferArray
Definition: shared.h:85
ULONG BufferCount
Definition: shared.h:102
PAFD_WSABUF BufferArray
Definition: shared.h:101

Referenced by AfdCancelHandler().

◆ DisconnectComplete()

static NTSTATUS NTAPI DisconnectComplete ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp,
PVOID  Context 
)
static

Definition at line 604 of file main.c.

607{
609 PIRP CurrentIrp;
610 PLIST_ENTRY CurrentEntry;
611
613
615 return STATUS_FILE_CLOSED;
616
617 ASSERT(FCB->DisconnectIrp.InFlightRequest == Irp);
618 FCB->DisconnectIrp.InFlightRequest = NULL;
619
620 ASSERT(FCB->DisconnectPending);
621 ASSERT((IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]) && !FCB->SendIrp.InFlightRequest) ||
622 (FCB->DisconnectFlags & TDI_DISCONNECT_ABORT));
623
624 if (NT_SUCCESS(Irp->IoStatus.Status) && (FCB->DisconnectFlags & TDI_DISCONNECT_RELEASE))
625 {
626 FCB->FilledDisconnectData = MIN(FCB->DisconnectDataSize, FCB->ConnectReturnInfo->UserDataLength);
627 if (FCB->FilledDisconnectData)
628 {
629 RtlCopyMemory(FCB->DisconnectData,
630 FCB->ConnectReturnInfo->UserData,
631 FCB->FilledDisconnectData);
632 }
633
634 FCB->FilledDisconnectOptions = MIN(FCB->DisconnectOptionsSize, FCB->ConnectReturnInfo->OptionsLength);
635 if (FCB->FilledDisconnectOptions)
636 {
637 RtlCopyMemory(FCB->DisconnectOptions,
638 FCB->ConnectReturnInfo->Options,
639 FCB->FilledDisconnectOptions);
640 }
641 }
642
643 FCB->DisconnectPending = FALSE;
644
645 while (!IsListEmpty(&FCB->PendingIrpList[FUNCTION_DISCONNECT]))
646 {
647 CurrentEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_DISCONNECT]);
648 CurrentIrp = CONTAINING_RECORD(CurrentEntry, IRP, Tail.Overlay.ListEntry);
649 CurrentIrp->IoStatus.Status = Irp->IoStatus.Status;
650 CurrentIrp->IoStatus.Information = 0;
651 UnlockRequest(CurrentIrp, IoGetCurrentIrpStackLocation(CurrentIrp));
652 (void)IoSetCancelRoutine(CurrentIrp, NULL);
654 }
655
656 if (!(FCB->DisconnectFlags & TDI_DISCONNECT_RELEASE))
657 {
658 /* Signal complete connection closure immediately */
659 FCB->PollState |= AFD_EVENT_ABORT;
660 FCB->PollStatus[FD_CLOSE_BIT] = Irp->IoStatus.Status;
661 FCB->LastReceiveStatus = STATUS_FILE_CLOSED;
662 PollReeval(FCB->DeviceExt, FCB->FileObject);
663 }
664
666
667 return Irp->IoStatus.Status;
668}
#define MIN(x, y)
Definition: rdesktop.h:171
#define AFD_EVENT_ABORT
Definition: shared.h:213
#define FD_CLOSE_BIT
Definition: winsock2.h:297

◆ DoDisconnect()

static NTSTATUS DoDisconnect ( PAFD_FCB  FCB)
static

Definition at line 672 of file main.c.

673{
675
676 ASSERT(FCB->DisconnectPending);
677 ASSERT((IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]) && !FCB->SendIrp.InFlightRequest) ||
678 (FCB->DisconnectFlags & TDI_DISCONNECT_ABORT));
679
680 if (FCB->DisconnectIrp.InFlightRequest)
681 {
682 return STATUS_PENDING;
683 }
684
685 FCB->ConnectCallInfo->UserData = FCB->DisconnectData;
686 FCB->ConnectCallInfo->UserDataLength = FCB->DisconnectDataSize;
687 FCB->ConnectCallInfo->Options = FCB->DisconnectOptions;
688 FCB->ConnectCallInfo->OptionsLength = FCB->DisconnectOptionsSize;
689
690 Status = TdiDisconnect(&FCB->DisconnectIrp.InFlightRequest,
691 FCB->Connection.Object,
692 &FCB->DisconnectTimeout,
693 FCB->DisconnectFlags,
695 FCB,
696 FCB->ConnectCallInfo,
697 FCB->ConnectReturnInfo);
698 if (Status != STATUS_PENDING)
699 {
700 FCB->DisconnectPending = FALSE;
701 }
702
703 return Status;
704}
static IO_COMPLETION_ROUTINE DisconnectComplete
Definition: main.c:600
NTSTATUS TdiDisconnect(PIRP *Irp, PFILE_OBJECT TransportObject, PLARGE_INTEGER Time, USHORT Flags, PIO_COMPLETION_ROUTINE CompletionRoutine, PVOID CompletionContext, PTDI_CONNECTION_INFORMATION RequestConnectionInfo, PTDI_CONNECTION_INFORMATION ReturnConnectionInfo)
Definition: tdi.c:1260

Referenced by AfdDisconnect(), and RetryDisconnectCompletion().

◆ DriverEntry()

NTSTATUS NTAPI DriverEntry ( PDRIVER_OBJECT  DriverObject,
PUNICODE_STRING  RegistryPath 
)

Definition at line 1319 of file main.c.

1320{
1322 UNICODE_STRING wstrDeviceName = RTL_CONSTANT_STRING(L"\\Device\\Afd");
1323 PAFD_DEVICE_EXTENSION DeviceExt;
1325
1327 /* register driver routines */
1328 DriverObject->MajorFunction[IRP_MJ_CLOSE] = AfdDispatch;
1329 DriverObject->MajorFunction[IRP_MJ_CREATE] = AfdDispatch;
1330 DriverObject->MajorFunction[IRP_MJ_CLEANUP] = AfdDispatch;
1331 DriverObject->MajorFunction[IRP_MJ_WRITE] = AfdDispatch;
1332 DriverObject->MajorFunction[IRP_MJ_READ] = AfdDispatch;
1335 DriverObject->DriverUnload = AfdUnload;
1336
1338 sizeof(AFD_DEVICE_EXTENSION),
1339 &wstrDeviceName,
1341 0,
1342 FALSE,
1343 &DeviceObject);
1344
1345 /* failure */
1346 if (!NT_SUCCESS(Status))
1347 {
1348 return Status;
1349 }
1350
1351 DeviceExt = DeviceObject->DeviceExtension;
1352 KeInitializeSpinLock( &DeviceExt->Lock );
1353 InitializeListHead( &DeviceExt->Polls );
1354
1355 AFD_DbgPrint(MID_TRACE,("Device created: object %p ext %p\n",
1356 DeviceObject, DeviceExt));
1357
1358 return Status;
1359}
#define L(x)
Definition: resources.c:13
static DRIVER_UNLOAD AfdUnload
Definition: main.c:1311
static DRIVER_DISPATCH AfdDispatch
Definition: main.c:905
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
NTSTATUS NTAPI IoCreateDevice(IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1031
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:215

◆ OskitDumpBuffer()

void OskitDumpBuffer ( PCHAR  Data,
UINT  Len 
)

Definition at line 29 of file main.c.

29 {
30 unsigned int i;
31
32 for( i = 0; i < Len; i++ ) {
33 if( i && !(i & 0xf) ) DbgPrint( "\n" );
34 if( !(i & 0xf) ) DbgPrint( "%p: ", (Data + i) );
35 DbgPrint( " %02x", Data[i] & 0xff );
36 }
37 DbgPrint("\n");
38}
#define Len
Definition: deflate.h:82

Referenced by AfdStreamSocketConnect(), and AfdStreamSocketSuperConnect().

◆ RetryDisconnectCompletion()

VOID RetryDisconnectCompletion ( PAFD_FCB  FCB)

Definition at line 707 of file main.c.

708{
709 ASSERT(FCB->RemoteAddress);
710
711 if (IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]) && !FCB->SendIrp.InFlightRequest && FCB->DisconnectPending)
712 {
713 /* Sends are done; fire off a TDI_DISCONNECT request */
715 }
716}

Referenced by SendComplete().

Variable Documentation

◆ AfdDispatch

DRIVER_DISPATCH AfdDispatch
static

Definition at line 905 of file main.c.

Referenced by DriverEntry().

◆ AfdReceiveWindowSize

ULONG AfdReceiveWindowSize = 0x2000

Definition at line 26 of file main.c.

Referenced by AfdCreateSocket().

◆ AfdSendWindowSize

ULONG AfdSendWindowSize = 0x2000

Definition at line 27 of file main.c.

Referenced by AfdCreateSocket().

◆ AfdUnload

DRIVER_UNLOAD AfdUnload
static

Definition at line 1311 of file main.c.

Referenced by DriverEntry().

◆ DisconnectComplete

IO_COMPLETION_ROUTINE DisconnectComplete
static

Definition at line 600 of file main.c.

Referenced by DoDisconnect().