VOID Primary_FileSystemShutdown ( IN PPRIMARY Primary ) { ULONG listenSocketIndex; Primary_Reference(Primary); SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_ERROR, ("Primary_FileSystemShutdown: Entered primary = %p\n", Primary)); do { if(Primary->Agent.ThreadHandle == NULL) { ASSERT(LFS_BUG); break; } ASSERT(Primary->Agent.ThreadObject != NULL); if(Primary->Agent.Flags & PRIMARY_AGENT_TERMINATED) { break; } else { PPRIMARY_AGENT_REQUEST primaryAgentRequest; NTSTATUS ntStatus; LARGE_INTEGER timeOut; primaryAgentRequest = AllocPrimaryAgentRequest(TRUE); primaryAgentRequest->RequestType = PRIMARY_AGENT_REQ_SHUTDOWN; QueueingPrimaryAgentRequest( Primary, primaryAgentRequest ); timeOut.QuadPart = - LFS_TIME_OUT; // 10 sec ntStatus = KeWaitForSingleObject( &primaryAgentRequest->CompleteEvent, Executive, KernelMode, FALSE, &timeOut ); ASSERT(ntStatus == STATUS_SUCCESS); KeClearEvent(&primaryAgentRequest->CompleteEvent); if(ntStatus == STATUS_SUCCESS) { SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_INFO, ("Primary_FileSystemShutdown: thread shutdown\n")); } else { ASSERT(LFS_BUG); break; } } }while(0); for(listenSocketIndex=0; listenSocketIndex<MAX_SOCKETLPX_INTERFACE; listenSocketIndex++) { if(Primary->Agent.ListenSocket[listenSocketIndex].Active != TRUE) continue; while(1) { KIRQL oldIrql; BOOLEAN found; PLIST_ENTRY primarySessionListEntry; KeAcquireSpinLock(&Primary->PrimarySessionQSpinLock[listenSocketIndex], &oldIrql); found = FALSE; for (primarySessionListEntry = Primary->PrimarySessionQueue[listenSocketIndex].Flink; primarySessionListEntry != &Primary->PrimarySessionQueue[listenSocketIndex]; primarySessionListEntry = primarySessionListEntry->Flink) { PPRIMARY_SESSION primarySession; primarySession = CONTAINING_RECORD (primarySessionListEntry, PRIMARY_SESSION, ListEntry); //if(primarySession->LfsDeviceExt && primarySession->LfsDeviceExt->FileSystemType == FileSystemType) //{ RemoveEntryList(primarySessionListEntry); KeReleaseSpinLock(&Primary->PrimarySessionQSpinLock[listenSocketIndex], oldIrql); InitializeListHead(primarySessionListEntry); PrimarySession_FileSystemShutdown(primarySession); found = TRUE; break; //} } if(found == FALSE) { KeReleaseSpinLock(&Primary->PrimarySessionQSpinLock[listenSocketIndex], oldIrql); break; } } } Primary_Dereference(Primary); 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; }