// // To clean up terminated PrimarySession is performed here // VOID Primary_AcceptConnection( IN PPRIMARY Primary, IN HANDLE ListenFileHandle, IN PFILE_OBJECT ListenFileObject, IN ULONG ListenSocketIndex, IN PLPX_ADDRESS RemoteAddress ) { PLIST_ENTRY listEntry; PPRIMARY_SESSION newPrimarySession; KIRQL oldIrql; newPrimarySession = PrimarySession_Create( Primary, ListenFileHandle, ListenFileObject, ListenSocketIndex, RemoteAddress ); if(newPrimarySession == NULL) { LpxTdiDisconnect(ListenFileObject, 0); LpxTdiDisassociateAddress(ListenFileObject); LpxTdiCloseConnection( ListenFileHandle, ListenFileObject ); } KeAcquireSpinLock(&Primary->SpinLock, &oldIrql); listEntry = Primary->PrimarySessionQueue[ListenSocketIndex].Flink; while(listEntry != &Primary->PrimarySessionQueue[ListenSocketIndex]) { PPRIMARY_SESSION primarySession; primarySession = CONTAINING_RECORD (listEntry, PRIMARY_SESSION, ListEntry); listEntry = listEntry->Flink; if(primarySession->ThreadFlags & PRIMARY_SESSION_THREAD_TERMINATED || primarySession->State == SESSION_CLOSED) { KeReleaseSpinLock(&Primary->SpinLock, oldIrql); PrimarySession_Close(primarySession); KeAcquireSpinLock(&Primary->SpinLock, &oldIrql); } } KeReleaseSpinLock(&Primary->SpinLock, oldIrql); return; }
PPRIMARY_SESSION PrimarySession_Create ( IN PPRIMARY Primary, IN HANDLE ListenFileHandle, IN PFILE_OBJECT ListenFileObject, IN PLPXTDI_OVERLAPPED_CONTEXT ListenOverlapped, IN ULONG ListenSocketIndex, IN PLPX_ADDRESS RemoteAddress ) { PPRIMARY_SESSION primarySession; OBJECT_ATTRIBUTES objectAttributes; NTSTATUS status; LARGE_INTEGER timeOut; NDAS_ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL ); Primary_Reference( Primary ); primarySession = FsRtlAllocatePoolWithTag( NonPagedPool, sizeof(PRIMARY_SESSION), LFS_ALLOC_TAG ); if (primarySession == NULL) { NDAS_ASSERT( NDAS_ASSERT_INSUFFICIENT_RESOURCES ); Primary_Dereference( Primary ); return NULL; } try { RtlZeroMemory( primarySession, sizeof(PRIMARY_SESSION) ); primarySession->Flags = PRIMARY_SESSION_FLAG_INITIALIZING; primarySession->ReferenceCount = 1; primarySession->Primary = Primary; ExInitializeFastMutex( &primarySession->FastMutex ); InitializeListHead( &primarySession->ListEntry ); KeInitializeEvent( &primarySession->ReadyEvent, NotificationEvent, FALSE ); InitializeListHead( &primarySession->RequestQueue ); KeInitializeSpinLock( &primarySession->RequestQSpinLock ); KeInitializeEvent( &primarySession->RequestEvent, NotificationEvent, FALSE ); InitializeListHead( &primarySession->NetdiskPartitionListEntry ); primarySession->ThreadHandle = 0; primarySession->ThreadObject = NULL; NdasFcInitialize( &primarySession->SendNdasFcStatistics ); NdasFcInitialize( &primarySession->RecvNdasFcStatistics ); primarySession->ConnectionFileHandle = ListenFileHandle; primarySession->ConnectionFileObject = ListenFileObject; LpxTdiV2MoveOverlappedContext( &primarySession->ReceiveOverlapped, ListenOverlapped ); RtlCopyMemory( &primarySession->RemoteAddress, RemoteAddress, sizeof(LPX_ADDRESS) ); primarySession->IsLocalAddress = Lfs_IsLocalAddress(RemoteAddress); SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_TRACE, ("primarySession->ConnectionFileHandle = %p\n", primarySession->ConnectionFileHandle) ); primarySession->Thread.SessionState = SESSION_CLOSE; primarySession->SessionContext.SessionKey = (UINT32)PtrToUlong(primarySession); primarySession->SessionContext.PrimaryMaxDataSize = (LfsRegistry.MaxDataTransferPri < DEFAULT_MAX_DATA_SIZE) ? LfsRegistry.MaxDataTransferPri:DEFAULT_MAX_DATA_SIZE; primarySession->SessionContext.SecondaryMaxDataSize = (LfsRegistry.MaxDataTransferSec < DEFAULT_MAX_DATA_SIZE) ? LfsRegistry.MaxDataTransferSec:DEFAULT_MAX_DATA_SIZE; // // Initialize transport context for traffic control // InitTransCtx( &primarySession->Thread.TransportCtx, primarySession->SessionContext.SecondaryMaxDataSize ); SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_TRACE, ("PrimarySession_Create: PriMaxData:%08u SecMaxData:%08u\n", primarySession->SessionContext.PrimaryMaxDataSize, primarySession->SessionContext.SecondaryMaxDataSize) ); ExAcquireFastMutex( &GlobalLfs.FastMutex ); primarySession->SessionContext.Uid = GlobalLfs.Uid++; ExReleaseFastMutex( &GlobalLfs.FastMutex ); InitializeObjectAttributes( &objectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL ); status = PsCreateSystemThread( &primarySession->ThreadHandle, THREAD_ALL_ACCESS, &objectAttributes, NULL, NULL, PrimarySessionThreadProc, primarySession ); if (!NT_SUCCESS(status)) { leave; } status = ObReferenceObjectByHandle( primarySession->ThreadHandle, FILE_READ_DATA, NULL, KernelMode, &primarySession->ThreadObject, NULL ); if (!NT_SUCCESS(status)) { leave; } timeOut.QuadPart = -LFS_TIME_OUT; status = KeWaitForSingleObject( &primarySession->ReadyEvent, Executive, KernelMode, FALSE, &timeOut ); if (!NT_SUCCESS(status)) { leave; } KeClearEvent( &primarySession->ReadyEvent ); ExInterlockedInsertTailList( &Primary->PrimarySessionQueue[ListenSocketIndex], &primarySession->ListEntry, &Primary->PrimarySessionQSpinLock[ListenSocketIndex] ); SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_TRACE, ("PrimarySession_Create: The primary thread are ready\n") ); SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_TRACE, ("Fat PrimarySession_Create: primarySession = %p\n", primarySession) ); } finally { if (AbnormalTermination()) { status = STATUS_UNSUCCESSFUL; } if (!NT_SUCCESS(status)) { ASSERT( LFS_UNEXPECTED ); PrimarySession_Close( primarySession ); primarySession = NULL; } } return primarySession; }
VOID Primary_Close ( IN PPRIMARY Primary ) { ULONG listenSocketIndex; SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_INFO, ("Primary_Close: Entered primary = %p\n", Primary)); for(listenSocketIndex=0; listenSocketIndex<MAX_SOCKETLPX_INTERFACE; listenSocketIndex++) { PLIST_ENTRY primarySessionListEntry; BOOLEAN found = FALSE; if(Primary->Agent.ListenSocket[listenSocketIndex].Active != TRUE) continue; while(primarySessionListEntry = ExInterlockedRemoveHeadList( &Primary->PrimarySessionQueue[listenSocketIndex], &Primary->PrimarySessionQSpinLock[listenSocketIndex] ) ) { PPRIMARY_SESSION primarySession; primarySession = CONTAINING_RECORD (primarySessionListEntry, PRIMARY_SESSION, ListEntry); InitializeListHead(primarySessionListEntry); PrimarySession_Close(primarySession); } } if(Primary->Agent.ThreadHandle == NULL) { ASSERT(LFS_BUG); Primary_Dereference(Primary); return; } ASSERT(Primary->Agent.ThreadObject != NULL); if(Primary->Agent.Flags & PRIMARY_AGENT_TERMINATED) { ObDereferenceObject(Primary->Agent.ThreadObject); Primary->Agent.ThreadHandle = NULL; Primary->Agent.ThreadObject = NULL; } else { PPRIMARY_AGENT_REQUEST primaryAgentRequest; NTSTATUS ntStatus; LARGE_INTEGER timeOut; primaryAgentRequest = AllocPrimaryAgentRequest(FALSE); primaryAgentRequest->RequestType = PRIMARY_AGENT_REQ_DISCONNECT; QueueingPrimaryAgentRequest( Primary, primaryAgentRequest ); primaryAgentRequest = AllocPrimaryAgentRequest (FALSE); primaryAgentRequest->RequestType = PRIMARY_AGENT_REQ_DOWN; QueueingPrimaryAgentRequest( Primary, primaryAgentRequest ); timeOut.QuadPart = - LFS_TIME_OUT; // 10 sec ntStatus = KeWaitForSingleObject( Primary->Agent.ThreadObject, Executive, KernelMode, FALSE, &timeOut ); ASSERT(ntStatus == STATUS_SUCCESS); if(ntStatus == STATUS_SUCCESS) { SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_INFO, ("Primary_Close: thread stoped\n")); ObDereferenceObject(Primary->Agent.ThreadObject); Primary->Agent.ThreadHandle = NULL; Primary->Agent.ThreadObject = NULL; } else { ASSERT(LFS_BUG); return; } } Primary_Dereference(Primary); return; }
PPRIMARY_SESSION PrimarySession_Create ( IN PIRP_CONTEXT IrpContext, IN PVOLUME_DEVICE_OBJECT VolDo, IN PSESSION_INFORMATION SessionInformation, IN PIRP Irp ) { PPRIMARY_SESSION primarySession; OBJECT_ATTRIBUTES objectAttributes; NTSTATUS status; LARGE_INTEGER timeOut; ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL ); VolDo_Reference( VolDo ); primarySession = FsRtlAllocatePoolWithTag( NonPagedPool, sizeof(PRIMARY_SESSION), NDFAT_ALLOC_TAG ); if (primarySession == NULL) { ASSERT( NDASFAT_INSUFFICIENT_RESOURCES ); VolDo_Dereference( VolDo ); return NULL; } try { RtlZeroMemory( primarySession, sizeof(PRIMARY_SESSION) ); primarySession->Flags = PRIMARY_SESSION_FLAG_INITIALIZING; primarySession->ReferenceCount = 1; primarySession->VolDo = VolDo; ExInitializeFastMutex( &primarySession->FastMutex ) InitializeListHead( &primarySession->ListEntry ); primarySession->NetdiskPartitionInformation = SessionInformation->NetdiskPartitionInformation; RtlInitEmptyUnicodeString( &primarySession->NetdiskPartitionInformation.VolumeName, primarySession->NetdiskPartitionInformation.VolumeNameBuffer, sizeof(primarySession->NetdiskPartitionInformation.VolumeNameBuffer) ); if (RtlAppendUnicodeStringToString( &primarySession->NetdiskPartitionInformation.VolumeName, &SessionInformation->NetdiskPartitionInformation.VolumeName) != STATUS_SUCCESS) { ASSERT( NDASFAT_UNEXPECTED ); } ASSERT( primarySession->NetdiskPartitionInformation.VolumeName.Buffer == primarySession->NetdiskPartitionInformation.VolumeNameBuffer ); primarySession->ConnectionFileHandle = SessionInformation->ConnectionFileHandle; primarySession->ConnectionFileObject = SessionInformation->ConnectionFileObject; primarySession->RemoteAddress = SessionInformation->RemoteAddress; primarySession->IsLocalAddress = SessionInformation->IsLocalAddress; primarySession->Irp = Irp; primarySession->SessionContext = SessionInformation->SessionContext; primarySession->SessionContext.PrimaryMaxDataSize = DEFAULT_NDAS_MAX_DATA_SIZE; //SessionInformation->PrimaryMaxDataSize; primarySession->SessionContext.SecondaryMaxDataSize = DEFAULT_NDAS_MAX_DATA_SIZE; // SessionInformation->SecondaryMaxDataSize; DebugTrace2( 0, Dbg2, ("primarySession->ConnectionFileHandle = %x " "primarySession->SessionContext.PrimaryMaxDataSize = %x primarySession->SessionContext.SecondaryMaxDataSize = %x\n", primarySession->ConnectionFileHandle, primarySession->SessionContext.PrimaryMaxDataSize, primarySession->SessionContext.SecondaryMaxDataSize) ); KeInitializeEvent( &primarySession->ReadyEvent, NotificationEvent, FALSE ); InitializeListHead( &primarySession->RequestQueue ); KeInitializeSpinLock( &primarySession->RequestQSpinLock ); KeInitializeEvent( &primarySession->RequestEvent, NotificationEvent, FALSE ); primarySession->ThreadHandle = 0; primarySession->ThreadObject = NULL; primarySession->Thread.TdiReceiveContext.Irp = NULL; KeInitializeEvent( &primarySession->Thread.TdiReceiveContext.CompletionEvent, NotificationEvent, FALSE ); InitializeObjectAttributes( &objectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL ); primarySession->Thread.SessionState = SESSION_TREE_CONNECT; ExInterlockedInsertTailList( &VolDo->PrimarySessionQueue, &primarySession->ListEntry, &VolDo->PrimarySessionQSpinLock ); status = PsCreateSystemThread( &primarySession->ThreadHandle, THREAD_ALL_ACCESS, &objectAttributes, NULL, NULL, PrimarySessionThreadProc, primarySession ); if (!NT_SUCCESS(status)) { leave; } status = ObReferenceObjectByHandle( primarySession->ThreadHandle, FILE_READ_DATA, NULL, KernelMode, &primarySession->ThreadObject, NULL ); if (!NT_SUCCESS(status)) { leave; } timeOut.QuadPart = -NDASFAT_TIME_OUT; status = KeWaitForSingleObject( &primarySession->ReadyEvent, Executive, KernelMode, FALSE, &timeOut ); if (!NT_SUCCESS(status)) { leave; } KeClearEvent( &primarySession->ReadyEvent ); DebugTrace2( 0, Dbg, ("PrimarySession_Create: The primary thread are ready\n") ); DebugTrace2( 0, Dbg2, ("Fat PrimarySession_Create: primarySession = %p\n", primarySession) ); } finally { if (AbnormalTermination()) { status = IrpContext->ExceptionStatus; } if (!NT_SUCCESS(status)) { ASSERT( NDASFAT_UNEXPECTED ); PrimarySession_Close( primarySession ); primarySession = NULL; } } return primarySession; }