Пример #1
0
void main(void)
{
	char* messages[12];
	int i;
	unsigned key;    // User keypress
	tcp_Socket tcpSock;
	int respond;

	respond = 0;

	// Initialize the message array
	for (i = 0; i < 12; i++) {
		messages[i] = "";
	}

	// Define messages here--note that you only need define the messages
	// you will actually use.
	messages[0] = "I hear ya";
	messages[1] = "Hello, there";
	messages[2] = "I'm here";
	messages[3] = "This Rabbit is fast!";
   messages[6] = "That's right, Charlie!";
   messages[7] = "Daisy, Daisy, Give me your answer, do.";

	brdInit();
	sock_init();

	// Configure the upper row of keys on the keypad, in order from left
	// to right
	for (i = 0; i < 6; i++) {
		// Only enable a key if there is a corresponding message
		if (strcmp(messages[i], "") != 0) {
			keyConfig ( 5-i, i+1, 0, 0, 0, 0, 0 );
		} else {
			keyConfig ( 5-i, IGNORE, 0, 0, 0, 0, 0 );
		}
	}
	// Configure the lower row of keys on the keypad, in order from left
	// to right
	for (i = 6; i < 12; i++) {
		// Only enable a key if there is a corresponding message
		if (strcmp(messages[i], "") != 0) {
			keyConfig ( 19-i, i+1, 0, 0, 0, 0, 0 );
		} else {
			keyConfig ( 19-i, IGNORE, 0, 0, 0, 0, 0 );
		}
	}

	while (1) {
		costate {								//	Process Keypad Press/Hold/Release
			keyProcess ();
			waitfor ( DelayMs(10) );
		}

		costate {								//	Process Keypad Press/Hold/Release
			waitfor ( key = keyGet() );	//	Wait for Keypress
			// Only handle the keypress if it corresponds to a message and if
			// a response is currently needed
			if ((key != IGNORE) && (respond == 1)) {
				SendMessage(&tcpSock, key, messages);
				respond = 0;
			}
		}

		// Receive a message.  RecvMessage() will block until something comes in.
		if (respond == 0) {
			RecvMessage(&tcpSock, &respond);
		}
	}
}
Пример #2
0
NTSTATUS
ReceiveNtfsWinxpMessage (
	IN  PPRIMARY_SESSION	PrimarySession,
	IN  UINT16				Mid
	)
{
	PNDFS_REQUEST_HEADER		ndfsRequestHeader = (PNDFS_REQUEST_HEADER)PrimarySession->Thread.SessionSlot[Mid].RequestMessageBuffer;
	PNDFS_WINXP_REQUEST_HEADER	ndfsWinxpRequestHeader;
	UINT8							*cryptWinxpRequestMessage;

	NTSTATUS					tdiStatus;
	//int						desResult;


	cryptWinxpRequestMessage = PrimarySession->Thread.SessionSlot[Mid].CryptWinxpMessageBuffer;	

	//
	// If the request is not split, receive the request at a time
	//	and return to the caller.
	//

	if (ndfsRequestHeader->Splitted == 0) {

		ASSERT( NTOHL(ndfsRequestHeader->MessageSize4) <= PrimarySession->Thread.SessionSlot[Mid].RequestMessageBufferLength );

		ndfsWinxpRequestHeader = (PNDFS_WINXP_REQUEST_HEADER)(ndfsRequestHeader+1);
	

		//
		// Receive non-encrypted request at a time and return to the caller.
		//

		if (ndfsRequestHeader->MessageSecurity == 0) {

			tdiStatus = RecvMessage( PrimarySession->ConnectionFileObject,
									 &PrimarySession->RecvNdasFcStatistics,
									 NULL,
									 (UINT8 *)ndfsWinxpRequestHeader,
									 NTOHL(ndfsRequestHeader->MessageSize4) - sizeof(NDFS_REQUEST_HEADER) );
	
			PrimarySession->Thread.SessionSlot[Mid].NdfsWinxpRequestHeader = ndfsWinxpRequestHeader;
	
			return tdiStatus;
		}

		ASSERT( FALSE );
#if 0
		//
		//  Receive encrypted WinXP request header
		//	and return to the caller
		//

		ASSERT(ndfsRequestHeader->MessageSecurity == 1);
		
		tdiStatus = RecvMessage(
						PrimarySession->ConnectionFileObject,
						cryptWinxpRequestMessage,
							sizeof(NDFS_WINXP_REQUEST_HEADER),
							NULL
							);
			if(tdiStatus != STATUS_SUCCESS)
			{
			return tdiStatus;
			}

		RtlZeroMemory(&PrimarySession->DesCbcContext, sizeof(PrimarySession->DesCbcContext));
		RtlZeroMemory(PrimarySession->Iv, sizeof(PrimarySession->Iv));
		DES_CBCInit(&PrimarySession->DesCbcContext,
					PrimarySession->NetdiskPartition->NetdiskPartitionInformation.NetdiskInformation.Password,
					PrimarySession->Iv,
					DES_DECRYPT);
		desResult = DES_CBCUpdate(&PrimarySession->DesCbcContext,
								(UINT8 *)ndfsWinxpRequestHeader,
								cryptWinxpRequestMessage,
								sizeof(NDFS_WINXP_REQUEST_HEADER));
		ASSERT(desResult == IDOK);

		//
		//  Receive encrypted WinXP request data
		//

		ASSERT(ndfsRequestHeader->MessageSize >= sizeof(NDFS_REQUEST_HEADER) + sizeof(NDFS_WINXP_REQUEST_HEADER));

		if(ndfsRequestHeader->MessageSize - sizeof(NDFS_REQUEST_HEADER) - sizeof(NDFS_WINXP_REQUEST_HEADER))
		{
			if(ndfsWinxpRequestHeader->IrpMajorFunction == IRP_MJ_WRITE && ndfsRequestHeader->RwDataSecurity == 0)
			{
				tdiStatus = RecvMessage(
								PrimarySession->ConnectionFileObject,
								(UINT8 *)(ndfsWinxpRequestHeader+1),
								ndfsRequestHeader->MessageSize - sizeof(NDFS_REQUEST_HEADER) - sizeof(NDFS_WINXP_REQUEST_HEADER),
								NULL
								);
				if(tdiStatus != STATUS_SUCCESS)
				{
					return tdiStatus;
				}
			}
			else
			{
				tdiStatus = RecvMessage(
								PrimarySession->ConnectionFileObject,
								cryptWinxpRequestMessage,
								ndfsRequestHeader->MessageSize - sizeof(NDFS_REQUEST_HEADER) - sizeof(NDFS_WINXP_REQUEST_HEADER),
								NULL
								);
				if(tdiStatus != STATUS_SUCCESS)
				{
					return tdiStatus;
				}

				desResult = DES_CBCUpdate(&PrimarySession->DesCbcContext, (UINT8 *)(ndfsWinxpRequestHeader+1), cryptWinxpRequestMessage, ndfsRequestHeader->MessageSize - sizeof(NDFS_REQUEST_HEADER) - sizeof(NDFS_WINXP_REQUEST_HEADER));
				ASSERT(desResult == IDOK);
			}
		}

		PrimarySession->Thread.SessionSlot[Mid].NdfsWinxpRequestHeader = ndfsWinxpRequestHeader;


		//
		//	return to the caller
		//

		return STATUS_SUCCESS;

#endif
	}

	ASSERT( ndfsRequestHeader->Splitted == 1 );

	//
	//	Allocate memory for extended WinXP header
	//

//	if(ndfsRequestHeader->MessageSize > (PrimarySession->RequestMessageBufferLength - sizeof(NDFS_REQUEST_HEADER) - sizeof(NDFS_WINXP_REQUEST_HEADER)))
	{
		ASSERT( PrimarySession->Thread.SessionSlot[Mid].ExtendWinxpRequestMessagePool == NULL );
		
		PrimarySession->Thread.SessionSlot[Mid].ExtendWinxpRequestMessagePoolLength = 
			NTOHL(ndfsRequestHeader->MessageSize4) - sizeof(NDFS_REQUEST_HEADER);
		PrimarySession->Thread.SessionSlot[Mid].ExtendWinxpRequestMessagePool = 
			ExAllocatePoolWithTag( NonPagedPool,
								   PrimarySession->Thread.SessionSlot[Mid].ExtendWinxpRequestMessagePoolLength,
								   PRIMARY_SESSION_BUFFERE_TAG );

		ASSERT( PrimarySession->Thread.SessionSlot[Mid].ExtendWinxpRequestMessagePool );

		if (PrimarySession->Thread.SessionSlot[Mid].ExtendWinxpRequestMessagePool == NULL) {
		
			SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_ERROR,	("ReceiveNtfsWinxpMessage: failed to allocate ExtendWinxpRequestMessagePool\n") );
			return STATUS_INSUFFICIENT_RESOURCES;
		}

		ndfsWinxpRequestHeader = (PNDFS_WINXP_REQUEST_HEADER)(PrimarySession->Thread.SessionSlot[Mid].ExtendWinxpRequestMessagePool);
	}
//	else
//		ndfsWinxpRequestHeader = (PNDFS_WINXP_REQUEST_HEADER)(ndfsRequestHeader+1);

	//
	//  Receive WinXP request header
	//

	if (ndfsRequestHeader->MessageSecurity == 0) {

		tdiStatus = RecvMessage( PrimarySession->ConnectionFileObject,
								 &PrimarySession->RecvNdasFcStatistics,
								 NULL,
								 (UINT8 *)ndfsWinxpRequestHeader,
								 sizeof(NDFS_WINXP_REQUEST_HEADER) );

		if (tdiStatus != STATUS_SUCCESS) {

			return tdiStatus;
		}
	}

#if 0

	else
	{
		tdiStatus = RecvMessage(
						PrimarySession->ConnectionFileObject,
						cryptWinxpRequestMessage,
						sizeof(NDFS_WINXP_REQUEST_HEADER),
						NULL
						);

		if(tdiStatus != STATUS_SUCCESS)
		{
			return tdiStatus;
		}
		RtlZeroMemory(&PrimarySession->DesCbcContext, sizeof(PrimarySession->DesCbcContext));
		RtlZeroMemory(PrimarySession->Iv, sizeof(PrimarySession->Iv));
		DES_CBCInit(&PrimarySession->DesCbcContext, PrimarySession->NetdiskPartition->NetdiskPartitionInformation.NetdiskInformation.Password, PrimarySession->Iv, DES_DECRYPT);
		desResult = DES_CBCUpdate(&PrimarySession->DesCbcContext, (UINT8 *)ndfsWinxpRequestHeader, cryptWinxpRequestMessage, sizeof(NDFS_WINXP_REQUEST_HEADER));
		ASSERT(desResult == IDOK);
	}

#endif

	//
	//	Receive a pair of NDFS request header and data
	//

	while (1) {

		PNDFS_REQUEST_HEADER	splitNdfsRequestHeader = &PrimarySession->Thread.SessionSlot[Mid].SplitNdfsRequestHeader;

		//
		//	Receive NDFS request
		//

		tdiStatus = RecvMessage( PrimarySession->ConnectionFileObject,
								 &PrimarySession->RecvNdasFcStatistics,
								 NULL,
								 (UINT8 *)splitNdfsRequestHeader,
								 sizeof(NDFS_REQUEST_HEADER) );

		if (tdiStatus != STATUS_SUCCESS)
			return tdiStatus;

		if (!(NTOHS(ndfsRequestHeader->Uid2) == PrimarySession->SessionContext.Uid &&
			  NTOHS(ndfsRequestHeader->Tid2) == PrimarySession->SessionContext.Tid)) {

			ASSERT( LFS_BUG );
			return STATUS_UNSUCCESSFUL;
		}

		//
		// receive a part of data
		//

		if (ndfsRequestHeader->MessageSecurity == 0) {

			tdiStatus = RecvMessage( PrimarySession->ConnectionFileObject,
									 &PrimarySession->RecvNdasFcStatistics,
									 NULL,
									 (UINT8 *)ndfsWinxpRequestHeader + NTOHL(ndfsRequestHeader->MessageSize4) - NTOHL(splitNdfsRequestHeader->MessageSize4),
									 splitNdfsRequestHeader->Splitted ? 
										PrimarySession->SessionContext.PrimaryMaxDataSize : (NTOHL(splitNdfsRequestHeader->MessageSize4) - sizeof(NDFS_REQUEST_HEADER)) );

			if (tdiStatus != STATUS_SUCCESS)
				return tdiStatus;
		}
#if 0
		else
		{
			tdiStatus = RecvMessage(
							PrimarySession->ConnectionFileObject,
							cryptWinxpRequestMessage,
							splitNdfsRequestHeader->Splitted 
								? PrimarySession->SessionContext.PrimaryMaxDataSize
								: (splitNdfsRequestHeader->MessageSize - sizeof(NDFS_REQUEST_HEADER)),
							NULL
							);
			if(tdiStatus != STATUS_SUCCESS)
				return tdiStatus;

			desResult = DES_CBCUpdate(
							&PrimarySession->DesCbcContext, 
							(UINT8 *)ndfsWinxpRequestHeader + ndfsRequestHeader->MessageSize - splitNdfsRequestHeader->MessageSize, 
		 					cryptWinxpRequestMessage, 
							splitNdfsRequestHeader->Splitted 
								? PrimarySession->SessionContext.PrimaryMaxDataSize
								: (splitNdfsRequestHeader->MessageSize - sizeof(NDFS_REQUEST_HEADER))
								);
			ASSERT(desResult == IDOK);
		}
#endif
		if (splitNdfsRequestHeader->Splitted)
			continue;

		PrimarySession->Thread.SessionSlot[Mid].NdfsWinxpRequestHeader = ndfsWinxpRequestHeader;

		return STATUS_SUCCESS;
	}
}
Пример #3
0
NTSTATUS
ReceiveNdfsWinxpMessage (
	IN  PPRIMARY_SESSION	PrimarySession,
	IN  _U16				Mid
	)
{
	PNDFS_REQUEST_HEADER		ndfsRequestHeader = (PNDFS_REQUEST_HEADER)PrimarySession->Thread.SessionSlot[Mid].RequestMessageBuffer;
	PNDFS_WINXP_REQUEST_HEADER	ndfsWinxpRequestHeader;
	_U8							*cryptWinxpRequestMessage;

	NTSTATUS					tdiStatus;
#if __NDAS_FAT_DES__
	int							desResult;
#endif

	cryptWinxpRequestMessage = PrimarySession->Thread.SessionSlot[Mid].CryptWinxpMessageBuffer;	
	//ASSERT(ndfsRequestHeader->Splitted == 0 && ndfsRequestHeader->MessageSecurity == 0);
		
	if (ndfsRequestHeader->Splitted == 0) {

		ASSERT( ndfsRequestHeader->MessageSize <= PrimarySession->Thread.SessionSlot[Mid].RequestMessageBufferLength );

		ndfsWinxpRequestHeader = (PNDFS_WINXP_REQUEST_HEADER)(ndfsRequestHeader+1);
	
		if (ndfsRequestHeader->MessageSecurity == 0) {

			tdiStatus = RecvMessage( PrimarySession->ConnectionFileObject,
									 (_U8 *)ndfsWinxpRequestHeader,
									 ndfsRequestHeader->MessageSize - sizeof(NDFS_REQUEST_HEADER),
									 NULL );
	
			PrimarySession->Thread.SessionSlot[Mid].NdfsWinxpRequestHeader = ndfsWinxpRequestHeader;
	
			return tdiStatus;
		}

		ASSERT(ndfsRequestHeader->MessageSecurity == 1);
		
		tdiStatus = RecvMessage( PrimarySession->ConnectionFileObject,
								 cryptWinxpRequestMessage,
								 sizeof(NDFS_WINXP_REQUEST_HEADER),
								 NULL );

			if (tdiStatus != STATUS_SUCCESS) {

				return tdiStatus;
			}

#if __NDAS_FAT_DES__

		RtlZeroMemory(&PrimarySession->DesCbcContext, sizeof(PrimarySession->DesCbcContext));
		RtlZeroMemory(PrimarySession->Iv, sizeof(PrimarySession->Iv));
		//DES_CBCInit(&PrimarySession->DesCbcContext, PrimarySession->NetdiskPartition->NetdiskPartitionInformation.NetdiskInformation.Password, PrimarySession->Iv, DES_DECRYPT);
		DES_CBCInit(&PrimarySession->DesCbcContext, PrimarySession->NetdiskPartitionInformation.NetdiskInformation.Password, PrimarySession->Iv, DES_DECRYPT);
		desResult = DES_CBCUpdate(&PrimarySession->DesCbcContext, (_U8 *)ndfsWinxpRequestHeader, cryptWinxpRequestMessage, sizeof(NDFS_WINXP_REQUEST_HEADER));
		ASSERT(desResult == IDOK);
#endif
		if (ndfsRequestHeader->MessageSize - sizeof(NDFS_REQUEST_HEADER) - sizeof(NDFS_WINXP_REQUEST_HEADER)) {

			if (ndfsWinxpRequestHeader->IrpMajorFunction == IRP_MJ_WRITE && ndfsRequestHeader->RwDataSecurity == 0) {

				tdiStatus = RecvMessage( PrimarySession->ConnectionFileObject,
										 (_U8 *)(ndfsWinxpRequestHeader+1),
										 ndfsRequestHeader->MessageSize - sizeof(NDFS_REQUEST_HEADER) - sizeof(NDFS_WINXP_REQUEST_HEADER),
										 NULL );

				if (tdiStatus != STATUS_SUCCESS) {

					return tdiStatus;
				}
			
			} else {

				tdiStatus = RecvMessage( PrimarySession->ConnectionFileObject,
										 cryptWinxpRequestMessage,
										 ndfsRequestHeader->MessageSize - sizeof(NDFS_REQUEST_HEADER) - sizeof(NDFS_WINXP_REQUEST_HEADER),
										 NULL );

				if (tdiStatus != STATUS_SUCCESS) {

					return tdiStatus;
				}

#if __NDAS_FAT_DES__
				desResult = DES_CBCUpdate(&PrimarySession->DesCbcContext, (_U8 *)(ndfsWinxpRequestHeader+1), cryptWinxpRequestMessage, ndfsRequestHeader->MessageSize - sizeof(NDFS_REQUEST_HEADER) - sizeof(NDFS_WINXP_REQUEST_HEADER));
				ASSERT(desResult == IDOK);
#endif
			}
		}

		PrimarySession->Thread.SessionSlot[Mid].NdfsWinxpRequestHeader = ndfsWinxpRequestHeader;

		return STATUS_SUCCESS;
	}

	ASSERT( ndfsRequestHeader->Splitted == 1 );

//	if (ndfsRequestHeader->MessageSize > (PrimarySession->RequestMessageBufferLength - sizeof(NDFS_REQUEST_HEADER) - sizeof(NDFS_WINXP_REQUEST_HEADER)))
	{
		PrimarySession->Thread.SessionSlot[Mid].ExtendWinxpRequestMessagePoolLength = ndfsRequestHeader->MessageSize - sizeof(NDFS_REQUEST_HEADER);
		PrimarySession->Thread.SessionSlot[Mid].ExtendWinxpRequestMessagePool 
			= ExAllocatePoolWithTag(
				NonPagedPool,
				PrimarySession->Thread.SessionSlot[Mid].ExtendWinxpRequestMessagePoolLength,
				PRIMARY_SESSION_BUFFERE_TAG
				);
		ASSERT(PrimarySession->Thread.SessionSlot[Mid].ExtendWinxpRequestMessagePool);
		if (PrimarySession->Thread.SessionSlot[Mid].ExtendWinxpRequestMessagePool == NULL) {
			DebugTrace2( 0, Dbg,	("ReceiveNdfsWinxpMessage: failed to allocate ExtendWinxpRequestMessagePool\n"));
			return STATUS_INSUFFICIENT_RESOURCES;
		}
		ndfsWinxpRequestHeader = (PNDFS_WINXP_REQUEST_HEADER)(PrimarySession->Thread.SessionSlot[Mid].ExtendWinxpRequestMessagePool);
	}
//	else
//		ndfsWinxpRequestHeader = (PNDFS_WINXP_REQUEST_HEADER)(ndfsRequestHeader+1);

	if (ndfsRequestHeader->MessageSecurity == 0)
	{
		tdiStatus = RecvMessage(
						PrimarySession->ConnectionFileObject,
						(_U8 *)ndfsWinxpRequestHeader,
						sizeof(NDFS_WINXP_REQUEST_HEADER),
						NULL
						);
		if (tdiStatus != STATUS_SUCCESS)
		{
			return tdiStatus;
		}
	}
	else
	{
		tdiStatus = RecvMessage(
						PrimarySession->ConnectionFileObject,
						cryptWinxpRequestMessage,
						sizeof(NDFS_WINXP_REQUEST_HEADER),
						NULL
						);

		if (tdiStatus != STATUS_SUCCESS)
		{
			return tdiStatus;
		}
#if __NDAS_FAT_DES__
		RtlZeroMemory(&PrimarySession->DesCbcContext, sizeof(PrimarySession->DesCbcContext));
		RtlZeroMemory(PrimarySession->Iv, sizeof(PrimarySession->Iv));
		//DES_CBCInit(&PrimarySession->DesCbcContext, PrimarySession->NetdiskPartition->NetdiskPartitionInformation.NetdiskInformation.Password, PrimarySession->Iv, DES_DECRYPT);
		DES_CBCInit(&PrimarySession->DesCbcContext, PrimarySession->NetdiskPartitionInformation.NetdiskInformation.Password, PrimarySession->Iv, DES_DECRYPT);
		desResult = DES_CBCUpdate(&PrimarySession->DesCbcContext, (_U8 *)ndfsWinxpRequestHeader, cryptWinxpRequestMessage, sizeof(NDFS_WINXP_REQUEST_HEADER));
		ASSERT(desResult == IDOK);
#endif
	}

	while(1)
	{
		PNDFS_REQUEST_HEADER	splitNdfsRequestHeader = &PrimarySession->Thread.SessionSlot[Mid].SplitNdfsRequestHeader;


		tdiStatus = RecvMessage(
						PrimarySession->ConnectionFileObject,
						(_U8 *)splitNdfsRequestHeader,
						sizeof(NDFS_REQUEST_HEADER),
						NULL
						);
		if (tdiStatus != STATUS_SUCCESS)
			return tdiStatus;

		if (!(
			PrimarySession->Thread.SessionState == SESSION_SETUP
			&& ndfsRequestHeader->Uid == PrimarySession->SessionContext.Uid
			&& ndfsRequestHeader->Tid == PrimarySession->SessionContext.Tid
			))
		{
			ASSERT(NDASFAT_BUG);
			return STATUS_UNSUCCESSFUL;
		}

		if (ndfsRequestHeader->MessageSecurity == 0)
		{
			tdiStatus = RecvMessage(
							PrimarySession->ConnectionFileObject,
							(_U8 *)ndfsWinxpRequestHeader + ndfsRequestHeader->MessageSize - splitNdfsRequestHeader->MessageSize,
							splitNdfsRequestHeader->Splitted 
								? PrimarySession->SessionContext.PrimaryMaxDataSize
								: (splitNdfsRequestHeader->MessageSize - sizeof(NDFS_REQUEST_HEADER)),
							NULL
								);
			if (tdiStatus != STATUS_SUCCESS)
				return tdiStatus;
		}
		else
		{
			tdiStatus = RecvMessage(
							PrimarySession->ConnectionFileObject,
							cryptWinxpRequestMessage,
							splitNdfsRequestHeader->Splitted 
								? PrimarySession->SessionContext.PrimaryMaxDataSize
								: (splitNdfsRequestHeader->MessageSize - sizeof(NDFS_REQUEST_HEADER)),
							NULL
							);
			if (tdiStatus != STATUS_SUCCESS)
				return tdiStatus;
#if __NDAS_FAT_DES__

			desResult = DES_CBCUpdate(
							&PrimarySession->DesCbcContext, 
							(_U8 *)ndfsWinxpRequestHeader + ndfsRequestHeader->MessageSize - splitNdfsRequestHeader->MessageSize, 
							cryptWinxpRequestMessage, 
							splitNdfsRequestHeader->Splitted 
								? PrimarySession->SessionContex.PrimaryMaxDataSize
								: (splitNdfsRequestHeader->MessageSize - sizeof(NDFS_REQUEST_HEADER))
								);
			ASSERT(desResult == IDOK);
#endif
		}

		if (splitNdfsRequestHeader->Splitted)
			continue;

		PrimarySession->Thread.SessionSlot[Mid].NdfsWinxpRequestHeader = ndfsWinxpRequestHeader;

		return STATUS_SUCCESS;
	}
}
NTSTATUS
DispatchRequest(
	IN PPRIMARY_SESSION	PrimarySession
	)
{
	NTSTATUS				status;
	IN PNDFS_REQUEST_HEADER	ndfsRequestHeader;


	ASSERT( PrimarySession->Thread.NdfsRequestHeader.Mid < PrimarySession->SessionContext.SessionSlotCount );
	ASSERT( PrimarySession->Thread.SessionSlot[PrimarySession->Thread.NdfsRequestHeader.Mid].State == SLOT_WAIT );
	ASSERT( PrimarySession->Thread.TdiReceiveContext.Result == sizeof(NDFS_REQUEST_HEADER) );

	RtlCopyMemory( PrimarySession->Thread.SessionSlot[PrimarySession->Thread.NdfsRequestHeader.Mid].RequestMessageBuffer,
				   &PrimarySession->Thread.NdfsRequestHeader,
				   sizeof(NDFS_REQUEST_HEADER) );

	ndfsRequestHeader = (PNDFS_REQUEST_HEADER)PrimarySession->Thread.SessionSlot[PrimarySession->Thread.NdfsRequestHeader.Mid].RequestMessageBuffer;
   
    DebugTrace( 0, Dbg,
				("DispatchRequest: ndfsRequestHeader->Command = %d\n", 
				ndfsRequestHeader->Command) );

	switch (ndfsRequestHeader->Command) {

	case NDFS_COMMAND_LOGOFF: {

		PNDFS_REQUEST_LOGOFF	ndfsRequestLogoff;
		PNDFS_REPLY_HEADER		ndfsReplyHeader;
		PNDFS_REPLY_LOGOFF		ndfsReplyLogoff;
		

		if (PrimarySession->Thread.SessionState != SESSION_TREE_CONNECT) {

			ASSERT(NDNTFS_BUG);
			status = STATUS_UNSUCCESSFUL;
			break;
		}

		if (!(ndfsRequestHeader->Uid == PrimarySession->SessionContext.Uid && ndfsRequestHeader->Tid == PrimarySession->SessionContext.Tid)) {

			ASSERT(NDNTFS_BUG);
			status = STATUS_UNSUCCESSFUL;
			break;
		}
		
		ASSERT( ndfsRequestHeader->MessageSize == sizeof(NDFS_REQUEST_HEADER) + sizeof(NDFS_REQUEST_LOGOFF) );

		ndfsRequestLogoff = (PNDFS_REQUEST_LOGOFF)(ndfsRequestHeader+1);
		
		status = RecvMessage( PrimarySession->ConnectionFileObject,
							 (_U8 *)ndfsRequestLogoff,
							 sizeof(NDFS_REQUEST_LOGOFF),
							 NULL );
	
		if (status != STATUS_SUCCESS) {

			ASSERT(NDNTFS_BUG);
			break;
		}

		ndfsReplyHeader = (PNDFS_REPLY_HEADER)(ndfsRequestLogoff+1);

		RtlCopyMemory( ndfsReplyHeader->Protocol, NDFS_PROTOCOL, sizeof(ndfsReplyHeader->Protocol) );
		ndfsReplyHeader->Status		= NDFS_SUCCESS;
		ndfsReplyHeader->Flags	    = 0;
		ndfsReplyHeader->Uid		= PrimarySession->SessionContext.Uid;
		ndfsReplyHeader->Tid		= 0;
		ndfsReplyHeader->Mid		= 0;
		ndfsReplyHeader->MessageSize = sizeof(NDFS_REPLY_HEADER)+sizeof(NDFS_REPLY_LOGOFF);

		ndfsReplyLogoff = (PNDFS_REPLY_LOGOFF)(ndfsReplyHeader+1);

		if(ndfsRequestLogoff->SessionKey != PrimarySession->SessionContext.SessionKey) {

			ndfsReplyLogoff->Status = NDFS_LOGOFF_UNSUCCESSFUL;
		
		} else {

			ndfsReplyLogoff->Status = NDFS_LOGOFF_SUCCESS;
		}

		status = SendMessage( PrimarySession->ConnectionFileObject,
							  (_U8 *)ndfsReplyHeader,
							  ndfsReplyHeader->MessageSize,
							  NULL );

		if (status != STATUS_SUCCESS) {

			break;
		}

		PrimarySession->Thread.SessionState = SESSION_CLOSE;
		LpxTdiDisconnect( PrimarySession->ConnectionFileObject, 0 );
		SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_DISCONNECTED );

		status = STATUS_SUCCESS;

		break;
	}

	case NDFS_COMMAND_EXECUTE: {

		_U16	slotIndex;

		if(PrimarySession->Thread.SessionState != SESSION_TREE_CONNECT) {

			ASSERT(NDNTFS_BUG);
			status = STATUS_UNSUCCESSFUL;
			break;
		}

		if (!(ndfsRequestHeader->Uid == PrimarySession->SessionContext.Uid && ndfsRequestHeader->Tid == PrimarySession->SessionContext.Tid)) {

			ASSERT(NDNTFS_BUG);
			status = STATUS_UNSUCCESSFUL;
			break;
		}

		slotIndex = ndfsRequestHeader->Mid;

		PrimarySession->Thread.SessionSlot[slotIndex].RequestMessageBufferLength = sizeof(NDFS_REQUEST_HEADER) + sizeof(NDFS_WINXP_REQUEST_HEADER) + DEFAULT_MAX_DATA_SIZE;
		
		RtlZeroMemory( &PrimarySession->Thread.SessionSlot[slotIndex].RequestMessageBuffer[sizeof(NDFS_REQUEST_HEADER)], 
					   PrimarySession->Thread.SessionSlot[slotIndex].RequestMessageBufferLength - sizeof(NDFS_REQUEST_HEADER) );

		PrimarySession->Thread.SessionSlot[slotIndex].ReplyMessageBufferLength = sizeof(NDFS_REPLY_HEADER) + sizeof(NDFS_WINXP_REPLY_HEADER) + DEFAULT_MAX_DATA_SIZE;
		
		RtlZeroMemory(PrimarySession->Thread.SessionSlot[slotIndex].ReplyMessageBuffer, PrimarySession->Thread.SessionSlot[slotIndex].ReplyMessageBufferLength);

		ASSERT( ndfsRequestHeader->MessageSize >= sizeof(NDFS_REQUEST_HEADER) + sizeof(NDFS_WINXP_REQUEST_HEADER) );
		status = ReceiveNtfsWinxpMessage( PrimarySession, slotIndex );

		if(status != STATUS_SUCCESS)
			break;

		if(PrimarySession->Thread.SessionSlot[slotIndex].State != SLOT_WAIT) {

			break;
		}
	
		PrimarySession->Thread.SessionSlot[slotIndex].State = SLOT_EXECUTING;
		PrimarySession->Thread.IdleSlotCount --;

		if(slotIndex == 0)
			ExInitializeWorkItem( &PrimarySession->Thread.SessionSlot[slotIndex].WorkQueueItem,
								  DispatchWinXpRequestWorker0,
								  PrimarySession );
		if(slotIndex == 1)
			ExInitializeWorkItem( &PrimarySession->Thread.SessionSlot[slotIndex].WorkQueueItem,
								  DispatchWinXpRequestWorker1,
								  PrimarySession );
		if(slotIndex == 2)
			ExInitializeWorkItem( &PrimarySession->Thread.SessionSlot[slotIndex].WorkQueueItem,
								  DispatchWinXpRequestWorker2,
								  PrimarySession );
		if(slotIndex == 3)
			ExInitializeWorkItem( &PrimarySession->Thread.SessionSlot[slotIndex].WorkQueueItem,
								  DispatchWinXpRequestWorker3,
								  PrimarySession );

		ExQueueWorkItem( &PrimarySession->Thread.SessionSlot[slotIndex].WorkQueueItem, DelayedWorkQueue );	
		status = STATUS_PENDING;

		break;
	}

	default:

		ASSERT(NDNTFS_LPX_BUG);
		status = STATUS_UNSUCCESSFUL;
		
		break;
	}

	return status;
}
NTSTATUS
DispatchRequest (
	IN PPRIMARY_SESSION	PrimarySession
	)
{
	NTSTATUS				status;
	IN PNDFS_REQUEST_HEADER	ndfsRequestHeader;


	ASSERT( NTOHS(PrimarySession->Thread.NdfsRequestHeader.Mid2) < PrimarySession->SessionContext.SessionSlotCount );
	ASSERT( PrimarySession->Thread.SessionSlot[NTOHS(PrimarySession->Thread.NdfsRequestHeader.Mid2)].State == SLOT_WAIT );
	ASSERT( PrimarySession->Thread.ReceiveOverlapped.Request[0].IoStatusBlock.Information == sizeof(NDFS_REQUEST_HEADER) );

	RtlCopyMemory( PrimarySession->Thread.SessionSlot[NTOHS(PrimarySession->Thread.NdfsRequestHeader.Mid2)].RequestMessageBuffer,
				   &PrimarySession->Thread.NdfsRequestHeader,
				   sizeof(NDFS_REQUEST_HEADER) );

	ndfsRequestHeader = (PNDFS_REQUEST_HEADER)PrimarySession->Thread.SessionSlot[NTOHS(PrimarySession->Thread.NdfsRequestHeader.Mid2)].RequestMessageBuffer;
   
    DebugTrace2( 0, Dbg,
				("DispatchRequest: ndfsRequestHeader->Command = %d\n", 
				ndfsRequestHeader->Command) );

	switch (ndfsRequestHeader->Command) {

	case NDFS_COMMAND_LOGOFF: {

		PNDFS_REQUEST_LOGOFF	ndfsRequestLogoff;
		PNDFS_REPLY_HEADER		ndfsReplyHeader;
		PNDFS_REPLY_LOGOFF		ndfsReplyLogoff;
		

		if (PrimarySession->Thread.SessionState != SESSION_TREE_CONNECT) {

			ASSERT(NDASFAT_BUG);
			status = STATUS_UNSUCCESSFUL;
			break;
		}

		if (!(NTOHS(ndfsRequestHeader->Uid2) == PrimarySession->SessionContext.Uid && 
			 NTOHS(ndfsRequestHeader->Tid2) == PrimarySession->SessionContext.Tid)) {

			ASSERT(NDASFAT_BUG);
			status = STATUS_UNSUCCESSFUL;
			break;
		}
		
		ASSERT( NTOHL(ndfsRequestHeader->MessageSize4) == sizeof(NDFS_REQUEST_HEADER) + sizeof(NDFS_REQUEST_LOGOFF) );

		ndfsRequestLogoff = (PNDFS_REQUEST_LOGOFF)(ndfsRequestHeader+1);
		
		status = RecvMessage( PrimarySession->ConnectionFileObject,
							  &PrimarySession->RecvNdasFcStatistics,
							  NULL,
							  (UINT8 *)ndfsRequestLogoff,
							  sizeof(NDFS_REQUEST_LOGOFF) );
	
		if (status != STATUS_SUCCESS) {

			ASSERT(NDASFAT_BUG);
			break;
		}

		ndfsReplyHeader = (PNDFS_REPLY_HEADER)(ndfsRequestLogoff+1);

		RtlCopyMemory( ndfsReplyHeader->Protocol, NDFS_PROTOCOL, sizeof(ndfsReplyHeader->Protocol) );
		ndfsReplyHeader->Status		= NDFS_SUCCESS;
		ndfsReplyHeader->Flags	    = 0;
		ndfsReplyHeader->Uid2		= HTONS(PrimarySession->SessionContext.Uid);
		ndfsReplyHeader->Tid2		= 0;
		ndfsReplyHeader->Mid2		= 0;
		ndfsReplyHeader->MessageSize4 = HTONL((UINT32)(sizeof(NDFS_REPLY_HEADER)+sizeof(NDFS_REPLY_LOGOFF)));

		ndfsReplyLogoff = (PNDFS_REPLY_LOGOFF)(ndfsReplyHeader+1);

		if (NTOHL(ndfsRequestLogoff->SessionKey4) != PrimarySession->SessionContext.SessionKey) {

			ndfsReplyLogoff->Status = NDFS_LOGOFF_UNSUCCESSFUL;
		
		} else {

			ndfsReplyLogoff->Status = NDFS_LOGOFF_SUCCESS;
		}

		status = SendMessage( PrimarySession->ConnectionFileObject,
							  &PrimarySession->SendNdasFcStatistics,
							  NULL,
							  (UINT8 *)ndfsReplyHeader,
							  NTOHL(ndfsReplyHeader->MessageSize4) );

		if (status != STATUS_SUCCESS) {

			break;
		}

		PrimarySession->Thread.SessionState = SESSION_CLOSED;

		status = STATUS_SUCCESS;

		break;
	}

	case NDFS_COMMAND_EXECUTE: {

		UINT16	mid;

		if(PrimarySession->SessionContext.NdfsMinorVersion == NDFS_PROTOCOL_MINOR_0) {

			if (PrimarySession->Thread.SessionState != SESSION_TREE_CONNECT) {

				ASSERT( NDASFAT_BUG );
				status = STATUS_UNSUCCESSFUL;
				break;
			}
		}

		if (!(NTOHS(ndfsRequestHeader->Uid2) == PrimarySession->SessionContext.Uid && 
			NTOHS(ndfsRequestHeader->Tid2) == PrimarySession->SessionContext.Tid)) {

			ASSERT( NDASFAT_BUG );
			status = STATUS_UNSUCCESSFUL;

			break;
		}

		mid = NTOHS(ndfsRequestHeader->Mid2);

		PrimarySession->Thread.SessionSlot[mid].RequestMessageBufferLength = sizeof(NDFS_REQUEST_HEADER) + sizeof(NDFS_WINXP_REQUEST_HEADER) + DEFAULT_NDAS_MAX_DATA_SIZE;
		RtlZeroMemory( &PrimarySession->Thread.SessionSlot[mid].RequestMessageBuffer[sizeof(NDFS_REQUEST_HEADER)], 
					   PrimarySession->Thread.SessionSlot[mid].RequestMessageBufferLength - sizeof(NDFS_REQUEST_HEADER) );

		PrimarySession->Thread.SessionSlot[mid].ReplyMessageBufferLength = sizeof(NDFS_REPLY_HEADER) + sizeof(NDFS_WINXP_REPLY_HEADER) + DEFAULT_NDAS_MAX_DATA_SIZE;
		RtlZeroMemory( PrimarySession->Thread.SessionSlot[mid].ReplyMessageBuffer, 
					   PrimarySession->Thread.SessionSlot[mid].ReplyMessageBufferLength );

		ASSERT( NTOHL(ndfsRequestHeader->MessageSize4) >= sizeof(NDFS_REQUEST_HEADER) + sizeof(NDFS_WINXP_REQUEST_HEADER) );

		status = ReceiveNdfsWinxpMessage( PrimarySession, mid );

		if (status != STATUS_SUCCESS)
			break;

		if (PrimarySession->Thread.SessionSlot[mid].State != SLOT_WAIT) {

			break;
		}
	
		PrimarySession->Thread.SessionSlot[mid].State = SLOT_EXECUTING;
		PrimarySession->Thread.IdleSlotCount --;

		if (PrimarySession->SessionContext.SessionSlotCount == 1) {

			ASSERT( mid == 0 );

			DispatchWinXpRequestWorker( PrimarySession, mid );

			PrimarySession->Thread.SessionSlot[mid].State = SLOT_WAIT;
			PrimarySession->Thread.IdleSlotCount ++;

			if (PrimarySession->Thread.SessionSlot[mid].Status == STATUS_SUCCESS) {

				PNDFS_REPLY_HEADER		ndfsReplyHeader;

				ndfsReplyHeader = (PNDFS_REPLY_HEADER)PrimarySession->Thread.SessionSlot[mid].ReplyMessageBuffer;
				
				PrimarySession->Thread.SessionSlot[mid].Status = 
					SendNdfsWinxpMessage( PrimarySession,
										  ndfsReplyHeader,
										  PrimarySession->Thread.SessionSlot[mid].NdfsWinxpReplyHeader,
										  PrimarySession->Thread.SessionSlot[mid].ReplyDataSize,
										  mid );

			}
	
			if (PrimarySession->Thread.SessionSlot[mid].ExtendWinxpRequestMessagePool) {

				ExFreePool( PrimarySession->Thread.SessionSlot[mid].ExtendWinxpRequestMessagePool );	
				PrimarySession->Thread.SessionSlot[mid].ExtendWinxpRequestMessagePool = NULL;
				PrimarySession->Thread.SessionSlot[mid].ExtendWinxpReplyMessagePoolLength = 0;
			}
		
			if (PrimarySession->Thread.SessionSlot[mid].ExtendWinxpReplyMessagePool) {

				ExFreePool( PrimarySession->Thread.SessionSlot[mid].ExtendWinxpReplyMessagePool );	
				PrimarySession->Thread.SessionSlot[mid].ExtendWinxpReplyMessagePool = NULL;
				PrimarySession->Thread.SessionSlot[mid].ExtendWinxpReplyMessagePoolLength = 0;
			}

			NDAS_ASSERT( PrimarySession->Thread.SessionSlot[mid].Status != STATUS_PENDING );
			
			if (PrimarySession->Thread.SessionSlot[mid].Status != STATUS_SUCCESS) {

				SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_ERROR );
										
				status = PrimarySession->Thread.SessionSlot[mid].Status;
				break;		
			}
				
			status = STATUS_SUCCESS;
			break;
		}

		if (mid == 0)
			ExInitializeWorkItem( &PrimarySession->Thread.SessionSlot[mid].WorkQueueItem,
								  DispatchWinXpRequestWorker0,
								  PrimarySession );
		
		if (mid == 1)
			ExInitializeWorkItem( &PrimarySession->Thread.SessionSlot[mid].WorkQueueItem,
								  DispatchWinXpRequestWorker1,
								  PrimarySession );
		
		if (mid == 2)
			ExInitializeWorkItem( &PrimarySession->Thread.SessionSlot[mid].WorkQueueItem,
								  DispatchWinXpRequestWorker2,
								  PrimarySession );

		
		if (mid == 3)
			ExInitializeWorkItem( &PrimarySession->Thread.SessionSlot[mid].WorkQueueItem,
								  DispatchWinXpRequestWorker3,
								  PrimarySession );

		ExQueueWorkItem( &PrimarySession->Thread.SessionSlot[mid].WorkQueueItem, DelayedWorkQueue );	

		status = STATUS_PENDING;
		break;
	}

	default:

		NDAS_ASSERT( FALSE );			
		status = STATUS_UNSUCCESSFUL;
		
		break;
	}

	return status;
}
NTSTATUS
DispatchRequest (
	IN PPRIMARY_SESSION	PrimarySession
	)
{
	NTSTATUS				status;
	IN PNDFS_REQUEST_HEADER	ndfsRequestHeader;


	ASSERT( NTOHS(PrimarySession->Thread.NdfsRequestHeader.Mid2) < PrimarySession->SessionContext.SessionSlotCount );

	RtlCopyMemory( PrimarySession->Thread.SessionSlot[NTOHS(PrimarySession->Thread.NdfsRequestHeader.Mid2)].RequestMessageBuffer,
				   &PrimarySession->Thread.NdfsRequestHeader,
				   sizeof(NDFS_REQUEST_HEADER) );

	ndfsRequestHeader 
		= (PNDFS_REQUEST_HEADER)PrimarySession->Thread.SessionSlot[NTOHS(PrimarySession->Thread.NdfsRequestHeader.Mid2)].RequestMessageBuffer;
   
	ASSERT (PrimarySession->ReceiveOverlapped.Request[0].IoStatusBlock.Information == sizeof(NDFS_REQUEST_HEADER) );

    SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_NOISE,
				   ("DispatchRequest: PrimarySession = %p, ndfsRequestHeader->Command = %d\n", 
				   PrimarySession, ndfsRequestHeader->Command) );

	
	switch (ndfsRequestHeader->Command) {

	case NDFS_COMMAND_NEGOTIATE: {

		PNDFS_REQUEST_NEGOTIATE	ndfsRequestNegotiate;
		PNDFS_REPLY_HEADER		ndfsReplyHeader;
		PNDFS_REPLY_NEGOTIATE	ndfsReplyNegotiate;
		
		
		if (PrimarySession->Thread.SessionState != SESSION_CLOSE) {

			ASSERT( LFS_BUG );
			status = STATUS_UNSUCCESSFUL;

			break;
		}
		
		ASSERT( NTOHL(ndfsRequestHeader->MessageSize4) == sizeof(NDFS_REQUEST_HEADER) + sizeof(NDFS_REQUEST_NEGOTIATE) );
		ndfsRequestNegotiate = (PNDFS_REQUEST_NEGOTIATE)(ndfsRequestHeader+1);
	
		status = RecvMessage( PrimarySession->ConnectionFileObject,
							  &PrimarySession->RecvNdasFcStatistics,
							  NULL,
							  (UINT8 *)ndfsRequestNegotiate,
							  sizeof(NDFS_REQUEST_NEGOTIATE) );
	

		if (status != STATUS_SUCCESS) {

			ASSERT( LFS_BUG );

			break;
		}

		PrimarySession->SessionContext.Flags = ndfsRequestNegotiate->Flags;
		ndfsReplyHeader = (PNDFS_REPLY_HEADER)(ndfsRequestNegotiate+1);

		RtlCopyMemory( ndfsReplyHeader->Protocol, NDFS_PROTOCOL, sizeof(ndfsReplyHeader->Protocol) );
		ndfsReplyHeader->Status		= NDFS_SUCCESS;
		ndfsReplyHeader->Flags	    = PrimarySession->SessionContext.Flags;
		ndfsReplyHeader->Uid2		= 0;
		ndfsReplyHeader->Tid2		= 0;
		ndfsReplyHeader->Mid2		= 0;
		ndfsReplyHeader->MessageSize4 = HTONL((UINT32)(sizeof(NDFS_REPLY_HEADER)+sizeof(NDFS_REPLY_NEGOTIATE)));

		ndfsReplyNegotiate = (PNDFS_REPLY_NEGOTIATE)(ndfsReplyHeader+1);

		if (NTOHS(ndfsRequestNegotiate->NdfsMajorVersion2) == NDFS_PROTOCOL_MAJOR_3 && 
			NTOHS(ndfsRequestNegotiate->NdfsMinorVersion2) == NDFS_PROTOCOL_MINOR_0 && 
			NTOHS(ndfsRequestNegotiate->OsMajorType2) == OS_TYPE_WINDOWS			&& 
			NTOHS(ndfsRequestNegotiate->OsMinorType2) == OS_TYPE_WINXP) {

			PrimarySession->SessionContext.NdfsMajorVersion = NTOHS(ndfsRequestNegotiate->NdfsMajorVersion2);
			PrimarySession->SessionContext.NdfsMinorVersion = NTOHS(ndfsRequestNegotiate->NdfsMinorVersion2);

			ndfsReplyNegotiate->Status = NDFS_NEGOTIATE_SUCCESS;
			ndfsReplyNegotiate->NdfsMajorVersion2 = HTONS(PrimarySession->SessionContext.NdfsMajorVersion);
			ndfsReplyNegotiate->NdfsMinorVersion2 = HTONS(PrimarySession->SessionContext.NdfsMinorVersion);
			ndfsReplyNegotiate->OsMajorType2 = HTONS(OS_TYPE_WINDOWS);	
			ndfsReplyNegotiate->OsMinorType2 = HTONS(OS_TYPE_WINXP);
			ndfsReplyNegotiate->SessionKey4 = HTONL(PrimarySession->SessionContext.SessionKey);
			ndfsReplyNegotiate->MaxBufferSize4 = HTONL(PrimarySession->SessionContext.PrimaryMaxDataSize);

			RtlCopyMemory( ndfsReplyNegotiate->ChallengeBuffer,
						   &PrimarySession,
						   sizeof(PPRIMARY_SESSION) );

			ndfsReplyNegotiate->ChallengeLength2 = HTONS((UINT16)(sizeof(PPRIMARY_SESSION)));

			PrimarySession->Thread.SessionState = SESSION_NEGOTIATE;
		
		} else {

			ndfsReplyNegotiate->Status = NDFS_NEGOTIATE_UNSUCCESSFUL;
		}

		status = SendMessage( PrimarySession->ConnectionFileObject,
							  &PrimarySession->SendNdasFcStatistics,
							  NULL,
							  (UINT8 *)ndfsReplyHeader,
							  NTOHL(ndfsReplyHeader->MessageSize4) );

		if (status != STATUS_SUCCESS) {

			break;
		}

		break;
	
	}

	case NDFS_COMMAND_SETUP: {

		PNDFS_REQUEST_SETUP	ndfsRequestSetup;
		PNDFS_REPLY_HEADER	ndfsReplyHeader;
		PNDFS_REPLY_SETUP	ndfsReplySetup;

		UINT8					ndfsReplySetupStatus;

		unsigned char		idData[1];
		MD5_CTX				context;
		UINT8				responseBuffer[16]; 
		
		
		if (PrimarySession->Thread.SessionState != SESSION_NEGOTIATE) {

			ASSERT( LFS_BUG );
			status = STATUS_UNSUCCESSFUL;

			break;
		}
		
		ASSERT( NTOHL(ndfsRequestHeader->MessageSize4) == sizeof(NDFS_REQUEST_HEADER) + sizeof(NDFS_REQUEST_SETUP) );
		ndfsRequestSetup = (PNDFS_REQUEST_SETUP)(ndfsRequestHeader+1);

		status = RecvMessage( PrimarySession->ConnectionFileObject,
							  &PrimarySession->RecvNdasFcStatistics,
							  NULL,
							  (UINT8 *)ndfsRequestSetup,
							  sizeof(NDFS_REQUEST_SETUP) );
	
		if (status != STATUS_SUCCESS) {

			ASSERT( LFS_BUG );

			break;
		}
	
		do {

			ASSERT( PrimarySession->NetdiskPartition == NULL );

			if (NTOHL(ndfsRequestSetup->SessionKey4) != PrimarySession->SessionContext.SessionKey) {

				ndfsReplySetupStatus = NDFS_SETUP_UNSUCCESSFUL;				
				break;
			}

			RtlCopyMemory( PrimarySession->NetDiskAddress.Node,
						   ndfsRequestSetup->NetdiskNode,
						   6 );
			
			PrimarySession->NetDiskAddress.Port = ndfsRequestSetup->NetdiskPort2;//HTONS(ndfsRequestSetup->NetDiskPort);
			PrimarySession->UnitDiskNo = NTOHS(ndfsRequestSetup->UnitDiskNo2);
			RtlCopyMemory( PrimarySession->NdscId, ndfsRequestSetup->NdscId, NDSC_ID_LENGTH);
				
			if (PrimarySession->SessionContext.NdfsMinorVersion == NDFS_PROTOCOL_MINOR_0) {

				status = NetdiskManager_GetPrimaryPartition( GlobalLfs.NetdiskManager,
															 PrimarySession,
															 &PrimarySession->NetDiskAddress,
															 PrimarySession->UnitDiskNo,
															 PrimarySession->NdscId,
															 NULL,
															 PrimarySession->IsLocalAddress,
															 &PrimarySession->NetdiskPartition,
															 &PrimarySession->NetdiskPartitionInformation,
															 &PrimarySession->FileSystemType );

				SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_INFO,
							   ("PRIM:SETUP:MIN1 PrimarySession->NetdiskPartition = %p netDiskPartitionInfo.StartingOffset = %I64x\n",
								 PrimarySession->NetdiskPartition, PrimarySession->StartingOffset.QuadPart) );

				if (status != STATUS_SUCCESS) {

					ndfsReplySetupStatus = NDFS_SETUP_UNSUCCESSFUL;
					break;
				}
			
			} else {

				NDAS_BUGON( FALSE );
			}

			
			MD5Init( &context );

			/* id byte */
			idData[0] = (unsigned char)PrimarySession->SessionContext.SessionKey;
			
			MD5Update( &context, idData, 1 );

			MD5Update( &context, 
					   PrimarySession->NetdiskPartitionInformation.NetdiskInformation.Password, 
					   8 );

			MD5Update( &context, &(UCHAR)PrimarySession, sizeof(PPRIMARY_SESSION) );
			MD5Final( responseBuffer, &context );

			if (!RtlEqualMemory(ndfsRequestSetup->ResponseBuffer,
								responseBuffer,
								16)) {

				NDAS_BUGON( LFS_BUG );
				ndfsReplySetupStatus = NDFS_SETUP_UNSUCCESSFUL;				
				break;
			}

			ndfsReplySetupStatus = NDFS_SETUP_SUCCESS;
		
		} while(0);

		ndfsReplyHeader = (PNDFS_REPLY_HEADER)(ndfsRequestSetup+1);
			
		RtlCopyMemory( ndfsReplyHeader->Protocol, NDFS_PROTOCOL, sizeof(ndfsReplyHeader->Protocol) );
		
		ndfsReplyHeader->Status		= NDFS_SUCCESS;
		ndfsReplyHeader->Flags	    = 0;
		ndfsReplyHeader->Uid2		= 0;
		ndfsReplyHeader->Tid2		= 0;
		ndfsReplyHeader->Mid2		= 0;
		ndfsReplyHeader->MessageSize4 = HTONL((UINT32)(sizeof(NDFS_REPLY_HEADER)+sizeof(NDFS_REPLY_SETUP)));

		if (ndfsReplySetupStatus == NDFS_SETUP_SUCCESS) {

			if (NTOHL(ndfsRequestSetup->MaxBufferSize4)) {

				if (PrimarySession->NetdiskPartition->FileSystemType == LFS_FILE_SYSTEM_NDAS_NTFS ||
					GlobalLfs.NdasFatRwIndirect == FALSE && PrimarySession->NetdiskPartition->FileSystemType == LFS_FILE_SYSTEM_NDAS_FAT ||
					GlobalLfs.NdasNtfsRwIndirect == FALSE && PrimarySession->NetdiskPartition->FileSystemType == LFS_FILE_SYSTEM_NDAS_NTFS) {

					PrimarySession->SessionContext.SecondaryMaxDataSize = NTOHL(ndfsRequestSetup->MaxBufferSize4);
				
				} else {

					PrimarySession->SessionContext.SecondaryMaxDataSize = 
						(NTOHL(ndfsRequestSetup->MaxBufferSize4) <= PrimarySession->SessionContext.SecondaryMaxDataSize) ? 
							   NTOHL(ndfsRequestSetup->MaxBufferSize4) : PrimarySession->SessionContext.SecondaryMaxDataSize;
				}

				//
				//	Initialize transport context for traffic control
				//

				InitTransCtx(&PrimarySession->Thread.TransportCtx, PrimarySession->SessionContext.SecondaryMaxDataSize);
			}

			SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_INFO,
						   ("NDFS_COMMAND_SETUP: PrimarySession->NetdiskPartition->FileSystemType = %d "  
						    "ndfsRequestSetup->MaxBufferSize = %x PrimaryMaxDataSize:%x SecondaryMaxDataSize:%x \n",
							PrimarySession->NetdiskPartition->FileSystemType, NTOHL(ndfsRequestSetup->MaxBufferSize4), 
							PrimarySession->SessionContext.PrimaryMaxDataSize,
							PrimarySession->SessionContext.SecondaryMaxDataSize) );

			ndfsReplyHeader->Uid2 = HTONS(PrimarySession->SessionContext.Uid);
			ndfsReplyHeader->Tid2 = HTONS(PrimarySession->SessionContext.Tid);
		
		} else {

			if (PrimarySession->NetdiskPartition) {

				NetdiskManager_ReturnPrimaryPartition( GlobalLfs.NetdiskManager, 
													   PrimarySession,
													   PrimarySession->NetdiskPartition, 
													   PrimarySession->IsLocalAddress );

				PrimarySession->NetdiskPartition = NULL;
			}
		}

		ndfsReplySetup = (PNDFS_REPLY_SETUP)(ndfsReplyHeader+1);
		ndfsReplySetup->Status = ndfsReplySetupStatus;

		status = SendMessage( PrimarySession->ConnectionFileObject,
							  &PrimarySession->SendNdasFcStatistics,
							  NULL,
							  (UINT8 *)ndfsReplyHeader,
							  NTOHL(ndfsReplyHeader->MessageSize4) );

		if (status != STATUS_SUCCESS) {

			break;
		}

		if (ndfsReplySetupStatus == NDFS_SETUP_SUCCESS)
			PrimarySession->Thread.SessionState = SESSION_SETUP;
		
		break;
	}

	case NDFS_COMMAND_TREE_CONNECT:{

		PNDFS_REQUEST_TREE_CONNECT	ndfsRequestTreeConnect;
		PNDFS_REPLY_HEADER			ndfsReplyHeader;
		PNDFS_REPLY_TREE_CONNECT	ndfsReplyTreeConnect;
	
		UINT8							ndfsReplyTreeConnectStatus;
		
		
		if (!(PrimarySession->Thread.SessionState == SESSION_SETUP && \
			  NTOHS(ndfsRequestHeader->Uid2) == PrimarySession->SessionContext.Uid)) {

			ASSERT( LFS_BUG );
			status = STATUS_UNSUCCESSFUL;

			break;
		}
		
		ASSERT( NTOHL(ndfsRequestHeader->MessageSize4) == sizeof(NDFS_REQUEST_HEADER) + sizeof(NDFS_REQUEST_TREE_CONNECT) );
		ndfsRequestTreeConnect = (PNDFS_REQUEST_TREE_CONNECT)(ndfsRequestHeader+1);

		status = RecvMessage( PrimarySession->ConnectionFileObject,
							  &PrimarySession->RecvNdasFcStatistics,
							  NULL,
							  (UINT8 *)ndfsRequestTreeConnect,
							  sizeof(NDFS_REQUEST_TREE_CONNECT) );
	
		if (status != STATUS_SUCCESS) {

			ASSERT( LFS_BUG );

			break;
		}
		
		do {

			NTSTATUS			getVolumeInformationStatus;
			PNETDISK_PARTITION	netdiskPartition;


			ndfsReplyHeader = (PNDFS_REPLY_HEADER)(ndfsRequestTreeConnect+1);

			RtlCopyMemory( ndfsReplyHeader->Protocol, NDFS_PROTOCOL, sizeof(ndfsReplyHeader->Protocol) );

			ndfsReplyHeader->Status		= NDFS_SUCCESS;
			ndfsReplyHeader->Flags	    = 0;
			ndfsReplyHeader->Uid2		= HTONS(PrimarySession->SessionContext.Uid);
			ndfsReplyHeader->Tid2		= 0;
			ndfsReplyHeader->Mid2		= 0;
			ndfsReplyHeader->MessageSize4 = HTONL((UINT32)(sizeof(NDFS_REPLY_HEADER)+sizeof(NDFS_REPLY_TREE_CONNECT)));

			PrimarySession->StartingOffset.QuadPart = NTOHLL(ndfsRequestTreeConnect->StartingOffset8);

			status = NetdiskManager_GetPrimaryPartition( GlobalLfs.NetdiskManager,
														 PrimarySession,
														 &PrimarySession->NetDiskAddress,
														 PrimarySession->UnitDiskNo,
														 PrimarySession->NdscId,
														 &PrimarySession->StartingOffset,
														 PrimarySession->IsLocalAddress,
														 &netdiskPartition,
														 &PrimarySession->NetdiskPartitionInformation,
														 &PrimarySession->FileSystemType );

			SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_TRACE,
						   ("PRIM:TREE_CONNECT: netdiskPartition = %p netDiskPartitionInfo.StartingOffset = %I64x\n", 
						    netdiskPartition, PrimarySession->StartingOffset.QuadPart) );

			if (status != STATUS_SUCCESS) {
				
				if (status == STATUS_UNRECOGNIZED_VOLUME) {

					SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_TRACE,
								   ("PRIM:TREE_CONNECT: Partition is not available\n") );

					ndfsReplyTreeConnectStatus = NDFS_TREE_CONNECT_NO_PARTITION;				
				
				} else {

					ndfsReplyTreeConnectStatus = NDFS_TREE_CONNECT_UNSUCCESSFUL;
				}
			
				break;
			}

			if (FlagOn(netdiskPartition->Flags, NETDISK_PARTITION_FLAG_MOUNT_CORRUPTED)) {

				ndfsReplyTreeConnectStatus = NDFS_TREE_CORRUPTED;

				NetdiskManager_ReturnPrimaryPartition( GlobalLfs.NetdiskManager, 
													   PrimarySession,
													   netdiskPartition, 
													   PrimarySession->IsLocalAddress );
				break;
			}

			if (netdiskPartition->FileSystemType == LFS_FILE_SYSTEM_NTFS && IS_WINDOWSXP_OR_LATER()) {

				getVolumeInformationStatus = 
					GetVolumeInformation( PrimarySession, 
										  &netdiskPartition->NetdiskPartitionInformation.VolumeName );
		
				SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_TRACE,
							   ("PRIM:TREE_CONNECT: getVolumeInformationStatus = %x\n", 
								getVolumeInformationStatus) );

				if (getVolumeInformationStatus != STATUS_SUCCESS) {

					NetdiskManager_ReturnPrimaryPartition( GlobalLfs.NetdiskManager, 
														   PrimarySession,
														   netdiskPartition, 
														   PrimarySession->IsLocalAddress );

					ndfsReplyTreeConnectStatus = NDFS_TREE_CONNECT_UNSUCCESSFUL;				
					break;
				}
			}

			if (PrimarySession->NetdiskPartition) { 

				NetdiskManager_ReturnPrimaryPartition( GlobalLfs.NetdiskManager, 
													   PrimarySession,
													   PrimarySession->NetdiskPartition, 
													   PrimarySession->IsLocalAddress );
			
				PrimarySession->NetdiskPartition = NULL;
			
			} else {

				NDAS_BUGON( FALSE );
			}

			PrimarySession->NetdiskPartition = netdiskPartition;

			PrimarySession->SessionContext.Tid  = PrimarySession->NetdiskPartition->Tid;
			ndfsReplyHeader->Tid2 = HTONS(PrimarySession->SessionContext.Tid);

			ndfsReplyTreeConnectStatus = NDFS_TREE_CONNECT_SUCCESS;				
		
		} while(0);
		
		ndfsReplyTreeConnect = (PNDFS_REPLY_TREE_CONNECT)(ndfsReplyHeader+1);
		ndfsReplyTreeConnect->Status = ndfsReplyTreeConnectStatus;
		
		ndfsReplyTreeConnect->SessionSlotCount = SESSION_SLOT_COUNT;
		
		ndfsReplyTreeConnect->BytesPerFileRecordSegment4	= HTONL(PrimarySession->Thread.BytesPerFileRecordSegment);
		ndfsReplyTreeConnect->BytesPerSector4			= HTONL(PrimarySession->Thread.BytesPerSector);
		ndfsReplyTreeConnect->BytesPerCluster4			= HTONL(PrimarySession->Thread.BytesPerCluster);

		status = SendMessage( PrimarySession->ConnectionFileObject,
							  &PrimarySession->SendNdasFcStatistics,
							  NULL,
							  (UINT8 *)ndfsReplyHeader,
							  NTOHL(ndfsReplyHeader->MessageSize4) );

		if (status != STATUS_SUCCESS) {
		
			break;
		}

		if (ndfsReplyTreeConnectStatus == NDFS_TREE_CONNECT_SUCCESS) {

			status = PrimarySessionTakeOver( PrimarySession );

			if (status == STATUS_INVALID_DEVICE_REQUEST) {

				PrimarySession->Thread.SessionState = SESSION_TREE_CONNECT;
			
			} else {
				
				SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_INFO,
						   ("PrimarySessionTakeOver: Success PrimarySession = %p status = %x\n", 
						    PrimarySession, status) );

				if (PrimarySession->NetdiskPartition) {

					NetdiskManager_ReturnPrimaryPartition( GlobalLfs.NetdiskManager,
														   PrimarySession,
														   PrimarySession->NetdiskPartition, 
														   PrimarySession->IsLocalAddress );	

					PrimarySession->NetdiskPartition = NULL;
				}
						
				if (status == STATUS_SUCCESS) {

					PrimarySession->ConnectionFileHandle = NULL;
					PrimarySession->ConnectionFileObject = NULL;
					
				} else {

					DisconnectFromSecondary( PrimarySession );
				} 

				SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_DISCONNECTED );

				PrimarySession->Thread.SessionState = SESSION_CLOSED;
			}
		}

		status = STATUS_SUCCESS;

		break;
	}

	case NDFS_COMMAND_LOGOFF: {

		PNDFS_REQUEST_LOGOFF	ndfsRequestLogoff;
		PNDFS_REPLY_HEADER		ndfsReplyHeader;
		PNDFS_REPLY_LOGOFF		ndfsReplyLogoff;
		

		if(PrimarySession->SessionContext.NdfsMinorVersion == NDFS_PROTOCOL_MINOR_0) {

			if(PrimarySession->Thread.SessionState != SESSION_TREE_CONNECT) {

				ASSERT( LFS_BUG );
				status = STATUS_UNSUCCESSFUL;
				break;
			}
		}

		if (!(NTOHS(ndfsRequestHeader->Uid2) == PrimarySession->SessionContext.Uid && 
			  NTOHS(ndfsRequestHeader->Tid2) == PrimarySession->SessionContext.Tid)) {

			ASSERT( LFS_BUG );
			status = STATUS_UNSUCCESSFUL;

			break;
		}
		
		ASSERT( NTOHL(ndfsRequestHeader->MessageSize4) == sizeof(NDFS_REQUEST_HEADER) + sizeof(NDFS_REQUEST_LOGOFF) );

		ndfsRequestLogoff = (PNDFS_REQUEST_LOGOFF)(ndfsRequestHeader+1);

		status = RecvMessage( PrimarySession->ConnectionFileObject,
							  &PrimarySession->RecvNdasFcStatistics,
							  NULL,
							  (UINT8 *)ndfsRequestLogoff,
							  sizeof(NDFS_REQUEST_LOGOFF) );
	

		if (status != STATUS_SUCCESS) {

			//ASSERT( LFS_BUG );

			break;
		}

		ndfsReplyHeader = (PNDFS_REPLY_HEADER)(ndfsRequestLogoff+1);

		RtlCopyMemory( ndfsReplyHeader->Protocol, NDFS_PROTOCOL, sizeof(ndfsReplyHeader->Protocol) );

		ndfsReplyHeader->Status		= NDFS_SUCCESS;
		ndfsReplyHeader->Flags	    = 0;
		ndfsReplyHeader->Uid2		= HTONS(PrimarySession->SessionContext.Uid);
		ndfsReplyHeader->Tid2		= 0;
		ndfsReplyHeader->Mid2		= 0;
		ndfsReplyHeader->MessageSize4 = HTONL((UINT32)(sizeof(NDFS_REPLY_HEADER)+sizeof(NDFS_REPLY_LOGOFF)));

		ndfsReplyLogoff = (PNDFS_REPLY_LOGOFF)(ndfsReplyHeader+1);

		if (NTOHL(ndfsRequestLogoff->SessionKey4) != PrimarySession->SessionContext.SessionKey) {

			ndfsReplyLogoff->Status = NDFS_LOGOFF_UNSUCCESSFUL;
		
		} else {

			ndfsReplyLogoff->Status = NDFS_LOGOFF_SUCCESS;
		}

		status = SendMessage( PrimarySession->ConnectionFileObject,
							  &PrimarySession->SendNdasFcStatistics,
							  NULL,
							  (UINT8 *)ndfsReplyHeader,
							  NTOHL(ndfsReplyHeader->MessageSize4) );

		if (status != STATUS_SUCCESS) {

			break;
		}

		PrimarySession->Thread.SessionState = SESSION_CLOSED;
		break;
	}

	case NDFS_COMMAND_EXECUTE: {

		UINT16	mid;

		if(PrimarySession->SessionContext.NdfsMinorVersion == NDFS_PROTOCOL_MINOR_0) {

			if (PrimarySession->Thread.SessionState != SESSION_TREE_CONNECT) {

				ASSERT( LFS_BUG );
				status = STATUS_UNSUCCESSFUL;
				break;
			}
		}

		if (!(NTOHS(ndfsRequestHeader->Uid2) == PrimarySession->SessionContext.Uid && 
			NTOHS(ndfsRequestHeader->Tid2) == PrimarySession->SessionContext.Tid)) {

			ASSERT( LFS_BUG );
			status = STATUS_UNSUCCESSFUL;

			break;
		}

		mid = NTOHS(ndfsRequestHeader->Mid2);

		PrimarySession->Thread.SessionSlot[mid].RequestMessageBufferLength = sizeof(NDFS_REQUEST_HEADER) + sizeof(NDFS_WINXP_REQUEST_HEADER) + DEFAULT_MAX_DATA_SIZE;
		RtlZeroMemory( &PrimarySession->Thread.SessionSlot[mid].RequestMessageBuffer[sizeof(NDFS_REQUEST_HEADER)], 
					   PrimarySession->Thread.SessionSlot[mid].RequestMessageBufferLength - sizeof(NDFS_REQUEST_HEADER) );

		PrimarySession->Thread.SessionSlot[mid].ReplyMessageBufferLength = sizeof(NDFS_REPLY_HEADER) + sizeof(NDFS_WINXP_REPLY_HEADER) + DEFAULT_MAX_DATA_SIZE;
		RtlZeroMemory( PrimarySession->Thread.SessionSlot[mid].ReplyMessageBuffer, 
					   PrimarySession->Thread.SessionSlot[mid].ReplyMessageBufferLength );

		ASSERT( NTOHL(ndfsRequestHeader->MessageSize4) >= sizeof(NDFS_REQUEST_HEADER) + sizeof(NDFS_WINXP_REQUEST_HEADER) );

		status = ReceiveNtfsWinxpMessage(PrimarySession, mid );

		if (status != STATUS_SUCCESS)
			break;

		if (PrimarySession->Thread.SessionSlot[mid].State != SLOT_WAIT) {

			break;
		}
	
		PrimarySession->Thread.SessionSlot[mid].State = SLOT_EXECUTING;
		PrimarySession->Thread.IdleSlotCount --;

		if (PrimarySession->SessionContext.SessionSlotCount == 1) {

			ASSERT( mid == 0 );

			DispatchWinXpRequestWorker( PrimarySession, mid );

			PrimarySession->Thread.SessionSlot[mid].State = SLOT_WAIT;
			PrimarySession->Thread.IdleSlotCount ++;

			if (PrimarySession->Thread.SessionSlot[mid].Status == STATUS_SUCCESS) {

				PNDFS_REPLY_HEADER		ndfsReplyHeader;

				ndfsReplyHeader = (PNDFS_REPLY_HEADER)PrimarySession->Thread.SessionSlot[mid].ReplyMessageBuffer;
										
				PrimarySession->Thread.SessionSlot[mid].Status = 
					SendNdfsWinxpMessage( PrimarySession,
										  ndfsReplyHeader,
										  PrimarySession->Thread.SessionSlot[mid].NdfsWinxpReplyHeader,
										  PrimarySession->Thread.SessionSlot[mid].ReplyDataSize,
										  mid );

			}
	
			if (PrimarySession->Thread.SessionSlot[mid].ExtendWinxpRequestMessagePool) {

				ExFreePool( PrimarySession->Thread.SessionSlot[mid].ExtendWinxpRequestMessagePool );	
				PrimarySession->Thread.SessionSlot[mid].ExtendWinxpRequestMessagePool = NULL;
				PrimarySession->Thread.SessionSlot[mid].ExtendWinxpReplyMessagePoolLength = 0;
			}
		
			if (PrimarySession->Thread.SessionSlot[mid].ExtendWinxpReplyMessagePool) {

				ExFreePool( PrimarySession->Thread.SessionSlot[mid].ExtendWinxpReplyMessagePool );	
				PrimarySession->Thread.SessionSlot[mid].ExtendWinxpReplyMessagePool = NULL;
				PrimarySession->Thread.SessionSlot[mid].ExtendWinxpReplyMessagePoolLength = 0;
			}

			if (PrimarySession->Thread.SessionSlot[mid].Status == STATUS_PENDING)
				NDAS_BUGON( FALSE );			
			
			if (PrimarySession->Thread.SessionSlot[mid].Status != STATUS_SUCCESS) {

				SetFlag( PrimarySession->Thread.Flags, PRIMARY_SESSION_THREAD_FLAG_ERROR );
										
				status = PrimarySession->Thread.SessionSlot[mid].Status;
				break;		
			}
				
			status = STATUS_SUCCESS;
			break;
		}

		NDAS_BUGON( FALSE );

		if (mid == 0)
			ExInitializeWorkItem( &PrimarySession->Thread.SessionSlot[mid].WorkQueueItem,
								  DispatchWinXpRequestWorker0,
								  PrimarySession );
		
		if (mid == 1)
			ExInitializeWorkItem( &PrimarySession->Thread.SessionSlot[mid].WorkQueueItem,
								  DispatchWinXpRequestWorker1,
								  PrimarySession );
		
		if (mid == 2)
			ExInitializeWorkItem( &PrimarySession->Thread.SessionSlot[mid].WorkQueueItem,
								  DispatchWinXpRequestWorker2,
								  PrimarySession );

		
		if (mid == 3)
			ExInitializeWorkItem( &PrimarySession->Thread.SessionSlot[mid].WorkQueueItem,
								  DispatchWinXpRequestWorker3,
								  PrimarySession );

		ExQueueWorkItem( &PrimarySession->Thread.SessionSlot[mid].WorkQueueItem, DelayedWorkQueue );	

		status = STATUS_PENDING;
		break;
	}

	default:

		ASSERT( LFS_LPX_BUG );
		status = STATUS_UNSUCCESSFUL;
		
		break;
	}

	return status;
}