Esempio n. 1
0
/*
 * 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;
}
Esempio n. 2
0
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));
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
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);
}
Esempio n. 5
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);
}
Esempio n. 6
0
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));
}
Esempio n. 7
0
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;
}
Esempio n. 8
0
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;
	
}
Esempio n. 9
0
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));
}
Esempio n. 10
0
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);
}
Esempio n. 11
0
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;
}
Esempio n. 12
0
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 );
}
Esempio n. 14
0
// .Dispatch -- Define function code handler method ----------------------------------DdmOsServices-
//
STATUS DdmOsServices::DispatchRequest(REQUESTCODE _reqCode, RequestCallback mcMethod) {
	return DispatchRequest(_reqCode,this,mcMethod);
}