/* * Handle a setfilter response */ void DmxTriWidgetImpl::HandleSetFilterResponse(uint8_t return_code, const uint8_t *data, unsigned int length) { if (!m_pending_request) { OLA_WARN << "Set filter response but no RDM message to send!"; return; } ola::rdm::RDMCallback *callback = m_rdm_request_callback; m_rdm_request_callback = NULL; const ola::rdm::RDMRequest *request = m_pending_request; m_pending_request = NULL; if (return_code == EC_NO_ERROR) { m_last_esta_id = request->DestinationUID().ManufacturerId(); DispatchRequest(request, callback); } else { OLA_WARN << "SetFilter returned " << static_cast<int>(return_code) << ", we have no option but to drop the rdm request"; delete request; if (callback) { std::vector<string> packets; callback->Run(ola::rdm::RDM_FAILED_TO_SEND, NULL, packets); } } (void) data; (void) length; }
HRESULT NamedPipeChannel::TransactAsync(const void* input, int input_length, void* output, int output_length, Listener* listener) { if (input == nullptr && input_length != 0 || input_length < 0 || output == nullptr && output_length != 0 || output_length < 0 || listener == nullptr) return E_INVALIDARG; auto request = std::make_unique<Request>(); if (request == nullptr) return E_OUTOFMEMORY; memset(request.get(), 0, sizeof(*request)); request->command = Command::kTransactAsync; request->input = const_cast<void*>(input); request->input_length = input_length; request->output = output; request->output_length = output_length; request->listener = listener; base::AutoLock guard(lock_); if (!IsValid()) return E_HANDLE; return DispatchRequest(std::move(request)); }
PipeStream::AsyncContext* PipeStream::BeginTransactData(void* write_buffer, DWORD write_length, void* read_buffer, DWORD read_length, HANDLE event) { if (event == NULL) return nullptr; if (!IsValid()) return nullptr; auto context = CreateContext<AsyncContext>( PipeRequest::Transact, write_buffer, write_length, nullptr); if (context == nullptr) return nullptr; context->hEvent = event; context->buffer2 = read_buffer; context->length2 = read_length; auto pointer = context.get(); HRESULT result = DispatchRequest(std::move(context)); if (FAILED(result)) return nullptr; return pointer; }
void PipeStream::TransactDataAsync(void* write_buffer, DWORD write_length, void* read_buffer, DWORD read_length, Listener* listener) { HRESULT result = S_OK; if (listener == nullptr) result = E_INVALIDARG; else if (!IsValid()) result = E_HANDLE; if (SUCCEEDED(result)) { auto context = CreateContext<AsyncContext>( PipeRequest::Transact, write_buffer, write_length, listener); if (context != nullptr) { context->buffer2 = read_buffer; context->length2 = read_length; result = DispatchRequest(std::move(context)); } else { result = E_OUTOFMEMORY; } } if (FAILED(result)) listener->OnTransacted(this, result, 0); }
STATUS SSD_Ddm::Initialize(Message *pMsg) // virtual { // Tell Chaos what messages to send us. DispatchRequest(BSA_BLOCK_READ, (RequestCallback) &Process_Read); // Tell Chaos what signals we are using. DispatchSignal(0 /* signal number */, (SignalCallback) &Signal_Request_Complete); // We are finished initializing. Tell Chaos. return Ddm::Initialize(pMsg); }
HRESULT NamedPipe::Write(const void* buffer, DWORD size, Listener* listener) { if (buffer == nullptr || listener == nullptr) return E_INVALIDARG; auto request = CreateRequest(Command::kWrite, listener); if (request == nullptr) return E_OUTOFMEMORY; request->InternalHigh = size; request->buffer = const_cast<void*>(buffer); return DispatchRequest(std::move(request)); }
void NamedPipeChannel::OnCompleted(OVERLAPPED* overlapped, ULONG error, ULONG_PTR bytes) { auto request = base::WrapUnique(static_cast<Request*>(overlapped)); request->completed_command = request->command; request->result = HRESULT_FROM_WIN32(error); request->length = static_cast<int>(bytes); request->command = Command::kNotify; base::AutoLock guard(lock_); auto result = DispatchRequest(std::move(request)); LOG_IF(FATAL, FAILED(result)) << "Unrecoverable Error: 0x" << std::hex << result; }
STATUS DdmTestSample::Initialize(Message *pMsg) { Tracef("DdmTestSample::Initialize()\n"); Tracef("Registering as DID %d\n", GetDid()); TestMsgRegister *pTestMsg = new TestMsgRegister("TestSample\0", "0d\0", GetDid()); Send(pTestMsg, NULL, REPLYCALLBACK(DdmTestSample, Registered)); DispatchRequest(REQ_TEST_RUN, REQUESTCALLBACK(DdmTestSample, TestProc)); Reply(pMsg, OK); return OK; }
HRESULT NamedPipeChannel::ConnectAsync(Listener* listener) { if (listener == nullptr) return E_INVALIDARG; auto request = std::make_unique<Request>(); if (request == nullptr) return E_OUTOFMEMORY; memset(request.get(), 0, sizeof(*request)); request->command = Command::kConnectAsync; request->listener = listener; base::AutoLock guard(lock_); if (end_point_ != EndPoint::kServer) return E_HANDLE; return DispatchRequest(std::move(request)); }
void PipeStream::WaitForConnectionAsync(Listener* listener) { HRESULT result = S_OK; if (listener == nullptr) result = E_INVALIDARG; else if (!IsValid()) result = E_HANDLE; if (SUCCEEDED(result)) { auto context = CreateContext<AsyncContext>(PipeRequest::WaitForConnection, nullptr, 0, listener); if (context != nullptr) result = DispatchRequest(std::move(context)); else result = E_OUTOFMEMORY; } if (FAILED(result)) listener->OnConnected(this, result); }
PipeStream::AsyncContext* PipeStream::BeginWaitForConnection(HANDLE event) { if (event == NULL) return nullptr; if (!IsValid()) return nullptr; auto context = CreateContext<AsyncContext>(PipeRequest::WaitForConnection, nullptr, 0, nullptr); if (context == nullptr) return nullptr; context->hEvent = event; auto pointer = context.get(); HRESULT result = DispatchRequest(std::move(context)); if (FAILED(result)) return nullptr; return pointer; }
HRESULT NamedPipeChannel::WriteAsync(const void* buffer, int length, Channel::Listener* listener) { if (buffer == nullptr && length != 0 || length < 0 || listener == nullptr) return E_INVALIDARG; auto request = std::make_unique<Request>(); if (request == nullptr) return E_OUTOFMEMORY; memset(request.get(), 0, sizeof(*request)); request->command = Command::kWriteAsync; request->input = const_cast<void*>(buffer); request->input_length = length; request->channel_listener = listener; base::AutoLock guard(lock_); if (!IsValid()) return E_HANDLE; return DispatchRequest(std::move(request)); }
VOID PrimarySessionThreadProc ( IN PPRIMARY_SESSION PrimarySession ) { BOOLEAN primarySessionTerminate = FALSE; NTSTATUS status; UINT16 slotIndex; PLIST_ENTRY primarySessionRequestEntry; ASSERT( SESSION_SLOT_COUNT == 1 ); ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL ); SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_INFO, ("PrimarySessionThreadProc: Start PrimarySession = %p\n", PrimarySession) ); PrimarySession_Reference( PrimarySession ); SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_INITIALIZING ); InitializeListHead( &PrimarySession->Thread.OpenedFileQueue ); KeInitializeSpinLock( &PrimarySession->Thread.OpenedFileQSpinLock ); KeInitializeEvent( &PrimarySession->Thread.WorkCompletionEvent, NotificationEvent, FALSE ); PrimarySession->SessionContext.SessionSlotCount = SESSION_SLOT_COUNT; for (slotIndex = 0; slotIndex < PrimarySession->SessionContext.SessionSlotCount; slotIndex ++) { PrimarySession->Thread.SessionSlot[slotIndex].State = SLOT_WAIT; PrimarySession->Thread.IdleSlotCount ++; } ClearFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_INITIALIZING ); SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_START ); SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_CONNECTED ); KeSetEvent( &PrimarySession->ReadyEvent, IO_DISK_INCREMENT, FALSE ); status = LpxTdiV2Recv( PrimarySession->ConnectionFileObject, (PUCHAR)&PrimarySession->Thread.NdfsRequestHeader, sizeof(NDFS_REQUEST_HEADER), 0, NULL, &PrimarySession->ReceiveOverlapped, 0, NULL ); if (!NT_SUCCESS(status)) { LpxTdiV2CompleteRequest( &PrimarySession->ReceiveOverlapped, 0 ); ASSERT( LFS_BUG ); SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_ERROR ); primarySessionTerminate = TRUE; } while (primarySessionTerminate == FALSE) { PKEVENT events[3]; LONG eventCount; NTSTATUS eventStatus; LARGE_INTEGER timeOut; NDAS_ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL ); eventCount = 0; events[eventCount++] = &PrimarySession->RequestEvent; if (!FlagOn(PrimarySession->Flags, PRIMARY_SESSION_FLAG_STOPPING)) { events[eventCount++] = &PrimarySession->Thread.WorkCompletionEvent; if (FlagOn(PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_SHUTDOWN)) { if (PrimarySession->Thread.IdleSlotCount == PrimarySession->SessionContext.SessionSlotCount) { CloseOpenFiles( PrimarySession, TRUE ); KeSetEvent( &PrimarySession->Thread.ShutdownPrimarySessionRequest->CompleteEvent, IO_DISK_INCREMENT, FALSE ); SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_SHUTDOWN_WAIT ); ClearFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_SHUTDOWN ); } } if (!FlagOn(PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_SHUTDOWN_WAIT)) { if (LpxTdiV2IsRequestPending(&PrimarySession->ReceiveOverlapped, 0)) { ASSERT( PrimarySession->Thread.IdleSlotCount != 0 ); events[eventCount++] = &PrimarySession->ReceiveOverlapped.Request[0].CompletionEvent; } } ASSERT( eventCount <= THREAD_WAIT_OBJECTS ); } timeOut.QuadPart = -5*NANO100_PER_SEC; eventStatus = KeWaitForMultipleObjects( eventCount, events, WaitAny, Executive, KernelMode, TRUE, &timeOut, NULL ); if (!FlagOn(PrimarySession->Flags, PRIMARY_SESSION_FLAG_STOPPING)) { if (eventStatus == STATUS_TIMEOUT || eventStatus == 2) { if (PrimarySession->Thread.SessionState == SESSION_TREE_CONNECT) { ASSERT( PrimarySession->NetdiskPartition ); if (!(PrimarySession->NetdiskPartition->NetdiskVolume[NETDISK_PRIMARY].VolumeState == VolumeMounted || PrimarySession->NetdiskPartition->NetdiskVolume[NETDISK_SECONDARY2PRIMARY].VolumeState == VolumeMounted)) { SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_INFO, ("Netdisk Volume is unmounted\n") ); if (!FlagOn(PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_SHUTDOWN_WAIT)) primarySessionTerminate = TRUE; continue; } } } } if (eventStatus == STATUS_TIMEOUT) { continue; } if (!NT_SUCCESS(eventStatus) || eventStatus >= eventCount) { NDAS_ASSERT( FALSE ); SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_ERROR ); primarySessionTerminate = TRUE; continue; } if (eventStatus == 0) { KeClearEvent( events[eventStatus] ); while (primarySessionRequestEntry = ExInterlockedRemoveHeadList( &PrimarySession->RequestQueue, &PrimarySession->RequestQSpinLock)) { PPRIMARY_SESSION_REQUEST primarySessionRequest; primarySessionRequest = CONTAINING_RECORD( primarySessionRequestEntry, PRIMARY_SESSION_REQUEST, ListEntry ); if (primarySessionRequest->RequestType == PRIMARY_SESSION_REQ_DISCONNECT || primarySessionRequest->RequestType == PRIMARY_SESSION_REQ_DISCONNECT_AND_TERMINATE) { SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_INFO, ((primarySessionRequest->RequestType == PRIMARY_SESSION_REQ_DISCONNECT) ? ("PRIMARY_SESSION_REQ_DISCONNECT: DisconnectFromSecondary\n") : ("PRIMARY_SESSION_REQ_DISCONNECT_AND_TERMINATE: DisconnectFromSecondary\n")) ); if (!FlagOn(PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_DISCONNECTED)) { DisconnectFromSecondary( PrimarySession ); ClearFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_CONNECTED ); SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_DISCONNECTED ); } if (primarySessionRequest->RequestType == PRIMARY_SESSION_REQ_DISCONNECT_AND_TERMINATE) primarySessionTerminate = TRUE; if (primarySessionRequest->Synchronous == TRUE) KeSetEvent( &primarySessionRequest->CompleteEvent, IO_DISK_INCREMENT, FALSE ); else DereferencePrimarySessionRequest( primarySessionRequest ); } else if (primarySessionRequest->RequestType == PRIMARY_SESSION_REQ_DOWN) { SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_STOPED ); primarySessionTerminate = TRUE; if (primarySessionRequest->Synchronous == TRUE) KeSetEvent( &primarySessionRequest->CompleteEvent, IO_DISK_INCREMENT, FALSE ); else DereferencePrimarySessionRequest( primarySessionRequest ); } else if (primarySessionRequest->RequestType == PRIMARY_SESSION_REQ_SHUTDOWN) { SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_TRACE, ("PrimarySessionThreadProc: PRIMARY_SESSION_THREAD_FLAG_SHUTDOWN\n") ); SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_SHUTDOWN ); ASSERT (primarySessionRequest->Synchronous == TRUE); PrimarySession->Thread.ShutdownPrimarySessionRequest = primarySessionRequest; if (!FlagOn(PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_DISCONNECTED)) { DisconnectFromSecondary( PrimarySession ); ClearFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_CONNECTED ); SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_DISCONNECTED ); } } else if (primarySessionRequest->RequestType == PRIMARY_SESSION_REQ_STOPPING) { SetFlag( PrimarySession->Flags, PRIMARY_SESSION_FLAG_STOPPING ); if (PrimarySession->IsLocalAddress == FALSE) { #if __NDAS_FS_PRIMARY_DISMOUNT__ CloseOpenFiles( PrimarySession, FALSE ); #endif } ExAcquireFastMutexUnsafe( &PrimarySession->FastMutex ); if (primarySessionRequest->Synchronous == TRUE) { primarySessionRequest->ExecuteStatus = STATUS_SUCCESS; KeSetEvent( &primarySessionRequest->CompleteEvent, IO_DISK_INCREMENT, FALSE ); } else { DereferencePrimarySessionRequest( primarySessionRequest ); } ExReleaseFastMutexUnsafe( &PrimarySession->FastMutex ); } else if (primarySessionRequest->RequestType == PRIMARY_SESSION_REQ_CANCEL_STOPPING) { ClearFlag( PrimarySession->Flags, PRIMARY_SESSION_FLAG_STOPPING ); if (primarySessionRequest->Synchronous == TRUE) KeSetEvent( &primarySessionRequest->CompleteEvent, IO_DISK_INCREMENT, FALSE ); else DereferencePrimarySessionRequest( primarySessionRequest ); } else { ASSERT( LFS_BUG ); SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_ERROR ); } } continue; } else if (eventStatus == 1) { KeClearEvent( events[eventStatus] ); while (TRUE) { for (slotIndex = 0; slotIndex < PrimarySession->SessionContext.SessionSlotCount; slotIndex ++) { if (PrimarySession->Thread.SessionSlot[slotIndex].State == SLOT_FINISH) break; } if (slotIndex == PrimarySession->SessionContext.SessionSlotCount) break; PrimarySession->Thread.SessionSlot[slotIndex].State = SLOT_WAIT; PrimarySession->Thread.IdleSlotCount ++; if (PrimarySession->Thread.SessionSlot[slotIndex].Status == STATUS_SUCCESS) { PNDFS_REPLY_HEADER ndfsReplyHeader; ndfsReplyHeader = (PNDFS_REPLY_HEADER)PrimarySession->Thread.SessionSlot[slotIndex].ReplyMessageBuffer; PrimarySession->Thread.SessionSlot[slotIndex].Status = SendNdfsWinxpMessage( PrimarySession, ndfsReplyHeader, PrimarySession->Thread.SessionSlot[slotIndex].NdfsWinxpReplyHeader, PrimarySession->Thread.SessionSlot[slotIndex].ReplyDataSize, slotIndex ); } if (PrimarySession->Thread.SessionSlot[slotIndex].ExtendWinxpRequestMessagePool) { ExFreePool(PrimarySession->Thread.SessionSlot[slotIndex].ExtendWinxpRequestMessagePool); PrimarySession->Thread.SessionSlot[slotIndex].ExtendWinxpRequestMessagePool = NULL; PrimarySession->Thread.SessionSlot[slotIndex].ExtendWinxpReplyMessagePoolLength = 0; } if (PrimarySession->Thread.SessionSlot[slotIndex].ExtendWinxpReplyMessagePool) { ExFreePool(PrimarySession->Thread.SessionSlot[slotIndex].ExtendWinxpReplyMessagePool); PrimarySession->Thread.SessionSlot[slotIndex].ExtendWinxpReplyMessagePool = NULL; PrimarySession->Thread.SessionSlot[slotIndex].ExtendWinxpReplyMessagePoolLength = 0; } if (!(PrimarySession->Thread.SessionSlot[slotIndex].Status == STATUS_SUCCESS || PrimarySession->Thread.SessionSlot[slotIndex].Status == STATUS_PENDING)) { SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_ERROR ); if (PrimarySession->NetdiskPartition) { NetdiskManager_ReturnPrimaryPartition( GlobalLfs.NetdiskManager, PrimarySession, PrimarySession->NetdiskPartition, PrimarySession->IsLocalAddress ); PrimarySession->NetdiskPartition = NULL; } primarySessionTerminate = TRUE; break; } if (PrimarySession->Thread.SessionState == SESSION_CLOSED) { if (PrimarySession->NetdiskPartition) { NetdiskManager_ReturnPrimaryPartition( GlobalLfs.NetdiskManager, PrimarySession, PrimarySession->NetdiskPartition, PrimarySession->IsLocalAddress ); PrimarySession->NetdiskPartition = NULL; } primarySessionTerminate = TRUE; break; } if (PrimarySession->Thread.SessionSlot[slotIndex].Status == STATUS_SUCCESS) { if (!LpxTdiV2IsRequestPending(&PrimarySession->ReceiveOverlapped, 0)) { status = LpxTdiV2Recv( PrimarySession->ConnectionFileObject, (PUCHAR)&PrimarySession->Thread.NdfsRequestHeader, sizeof(NDFS_REQUEST_HEADER), 0, NULL, &PrimarySession->ReceiveOverlapped, 0, NULL ); if (!NT_SUCCESS(status)) { ASSERT( LFS_BUG ); LpxTdiV2CompleteRequest( &PrimarySession->ReceiveOverlapped, 0 ); SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_ERROR ); primarySessionTerminate = TRUE; break; } } } } continue; } else { NDAS_ASSERT( eventStatus == 2 ); // Receive Event ASSERT( !FlagOn(PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_SHUTDOWN_WAIT) && !FlagOn(PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_SHUTDOWN) ); LpxTdiV2CompleteRequest( &PrimarySession->ReceiveOverlapped, 0 ); if (PrimarySession->ReceiveOverlapped.Request[0].IoStatusBlock.Status != STATUS_SUCCESS || PrimarySession->ReceiveOverlapped.Request[0].IoStatusBlock.Information != sizeof(NDFS_REQUEST_HEADER)) { SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_TRACE, ("DispatchRequest: Disconnected, PrimarySession = Data received:%d\n", PrimarySession->ReceiveOverlapped.Request[0].IoStatusBlock.Information) ); SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_DISCONNECTED ); primarySessionTerminate = TRUE; continue; } #if 0 if (PrimarySession->NetdiskPartition) { PENABLED_NETDISK EnabledNetdisk = PrimarySession->NetdiskPartition->EnabledNetdisk; ASSERT( EnabledNetdisk ); if (NetdiskManager_IsStoppedNetdisk(GlobalLfs.NetdiskManager, EnabledNetdisk)) { SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_ERROR, ("PrimarySessionThread: %p Netdisk is stopped\n", PrimarySession) ); SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_ERROR, ("DispatchWinXpRequest: Netdisk is stopped.\n") ); if (!FlagOn(PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_DISCONNECTED)) { // no other way to notify secondary about unmount without break backward compatability. SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_INFO, ("IsStoppedNetdisk: DisconnectFromSecondary\n") ); DisconnectFromSecondary( PrimarySession ); ClearFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_CONNECTED ); SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_DISCONNECTED ); } primarySessionTerminate = TRUE; continue; } } #endif status = DispatchRequest( PrimarySession ); if (!(status == STATUS_SUCCESS || status == STATUS_PENDING)) { primarySessionTerminate = TRUE; continue; } if (PrimarySession->Thread.SessionState == SESSION_CLOSED) { primarySessionTerminate = TRUE; continue; } if (status == STATUS_SUCCESS) { if (!LpxTdiV2IsRequestPending(&PrimarySession->ReceiveOverlapped, 0)) { status = LpxTdiV2Recv( PrimarySession->ConnectionFileObject, (PUCHAR)&PrimarySession->Thread.NdfsRequestHeader, sizeof(NDFS_REQUEST_HEADER), 0, NULL, &PrimarySession->ReceiveOverlapped, 0, NULL ); if (!NT_SUCCESS(status)) { LpxTdiV2CompleteRequest( &PrimarySession->ReceiveOverlapped, 0 ); SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_ERROR ); primarySessionTerminate = TRUE; } } } continue; } } ExAcquireFastMutexUnsafe( &PrimarySession->FastMutex ); SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_STOPED ); ExReleaseFastMutexUnsafe( &PrimarySession->FastMutex ); while (TRUE) { LARGE_INTEGER timeOut; NTSTATUS eventStatus; if (PrimarySession->Thread.IdleSlotCount == PrimarySession->SessionContext.SessionSlotCount) break; timeOut.QuadPart = -10*NANO100_PER_SEC; eventStatus = KeWaitForSingleObject( &PrimarySession->Thread.WorkCompletionEvent, Executive, KernelMode, FALSE, &timeOut ); KeClearEvent( &PrimarySession->Thread.WorkCompletionEvent ); if (eventStatus == STATUS_TIMEOUT) { ASSERT( LFS_UNEXPECTED ); continue; } while (TRUE) { for (slotIndex = 0; slotIndex < PrimarySession->SessionContext.SessionSlotCount; slotIndex++) { if (PrimarySession->Thread.SessionSlot[slotIndex].State == SLOT_FINISH) break; } if (slotIndex == PrimarySession->SessionContext.SessionSlotCount) break; SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_TRACE, ("PrimarySessionThreadProc: eventStatus = %d\n", eventStatus) ); PrimarySession->Thread.SessionSlot[slotIndex].State = SLOT_WAIT; PrimarySession->Thread.IdleSlotCount++; if (PrimarySession->Thread.SessionSlot[slotIndex].ExtendWinxpRequestMessagePool) { ExFreePool( PrimarySession->Thread.SessionSlot[slotIndex].ExtendWinxpRequestMessagePool ); PrimarySession->Thread.SessionSlot[slotIndex].ExtendWinxpRequestMessagePool = NULL; PrimarySession->Thread.SessionSlot[slotIndex].ExtendWinxpReplyMessagePoolLength = 0; } if (PrimarySession->Thread.SessionSlot[slotIndex].ExtendWinxpReplyMessagePool) { ExFreePool( PrimarySession->Thread.SessionSlot[slotIndex].ExtendWinxpReplyMessagePool ); PrimarySession->Thread.SessionSlot[slotIndex].ExtendWinxpReplyMessagePool = NULL; PrimarySession->Thread.SessionSlot[slotIndex].ExtendWinxpReplyMessagePoolLength = 0; } } } if (!FlagOn(PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_DISCONNECTED)) { SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_INFO, ("PsTerminateSystemThread: DisconnectFromSecondary\n") ); DisconnectFromSecondary( PrimarySession ); ClearFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_CONNECTED ); SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_DISCONNECTED ); } CloseOpenFiles( PrimarySession, TRUE ); while (primarySessionRequestEntry = ExInterlockedRemoveHeadList( &PrimarySession->RequestQueue, &PrimarySession->RequestQSpinLock)) { PPRIMARY_SESSION_REQUEST primarySessionRequest; primarySessionRequest = CONTAINING_RECORD( primarySessionRequestEntry, PRIMARY_SESSION_REQUEST, ListEntry ); if (primarySessionRequest->Synchronous == TRUE) KeSetEvent( &primarySessionRequest->CompleteEvent, IO_DISK_INCREMENT, FALSE ); else DereferencePrimarySessionRequest( primarySessionRequest ); } if (PrimarySession->NetdiskPartition) { NetdiskManager_ReturnPrimaryPartition( GlobalLfs.NetdiskManager, PrimarySession, PrimarySession->NetdiskPartition, PrimarySession->IsLocalAddress ); PrimarySession->NetdiskPartition = NULL; } SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_INFO, ("PrimarySessionThreadProc: PsTerminateSystemThread PrimarySession = %p\n", PrimarySession) ); SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_TERMINATED ); PrimarySession_Dereference ( PrimarySession ); NDAS_ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL ); PsTerminateSystemThread( STATUS_SUCCESS ); }
// .Dispatch -- Define function code handler method ----------------------------------DdmOsServices- // STATUS DdmOsServices::DispatchRequest(REQUESTCODE _reqCode, RequestCallback mcMethod) { return DispatchRequest(_reqCode,this,mcMethod); }