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); } } }
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; } }
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; }