mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
817 lines
20 KiB
817 lines
20 KiB
/*++
|
|
|
|
Copyright (c) 1987-1993 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
marshall.c
|
|
|
|
Abstract:
|
|
|
|
Contains the functions that are required to marshall/unmarshall
|
|
message buffer.
|
|
|
|
Author:
|
|
|
|
11/08/91 (madana)
|
|
initial coding.
|
|
|
|
Environment:
|
|
|
|
Contains NT-specific code.
|
|
Requires ANSI C extensions: slash-slash comments, long external names.
|
|
|
|
Revision History:
|
|
|
|
19-Dec-1991 JohnRo
|
|
Made changes suggested by PC-LINT.
|
|
16-Jan-1992 JohnRo
|
|
Avoid using private logon functions.
|
|
23-Jan-1992 JohnRo
|
|
Avoid compiler warnings if MIN_GUARD is zero.
|
|
28-Jan-1992 JohnRo
|
|
Changed to use LPTSTR etc. Also moved RANGECHECK to NetLib.h and
|
|
renamed it IN_RANGE().
|
|
05-Mar-1992 JohnRo
|
|
A few more changes suggested by PC-LINT.
|
|
24-Mar-1992 JohnRo
|
|
Fixed bug dealing with pulse value in sync msg.
|
|
Added more debug output.
|
|
Correct some character types.
|
|
Use integrity and extent equates in <lmrepl.h>.
|
|
08-Apr-1992 JohnRo
|
|
Fixed UNICODE handling.
|
|
11-Feb-1993 JohnRo
|
|
RAID 10716: msg timing and checksum problems (also downlevel msg bug).
|
|
Use PREFIX_ equates.
|
|
|
|
--*/
|
|
|
|
#include <windows.h>
|
|
|
|
#include <align.h>
|
|
#include <lmcons.h>
|
|
#include <netdebug.h> // DBGSTATIC, NetDbgHexDump(), etc.
|
|
#include <netlib.h> // IN_RANGE(), etc.
|
|
#include <prefix.h> // PREFIX_ equates.
|
|
#include <smbgtpt.h>
|
|
#include <string.h> // strcpy(), strlen().
|
|
#include <tstring.h> // NetpCopy{type}ToUnalignedWStr(), etc.
|
|
#include <stdlib.h>
|
|
|
|
|
|
// repl headers
|
|
|
|
#include <repldefs.h> // IF_DEBUG(), etc.
|
|
#include <replpack.h>
|
|
#include <iniparm.h>
|
|
|
|
#define NOT_NET_VERSION 0
|
|
#define NT_VERSION 1
|
|
|
|
|
|
#ifdef UNICODE
|
|
|
|
DBGSTATIC VOID
|
|
ReplGetUnicodeName(
|
|
OUT LPWSTR WhereDst,
|
|
IN LPBYTE WhereSrc
|
|
);
|
|
|
|
#define ReplGetNeutralName ReplGetUnicodeName
|
|
|
|
#else // ndef UNICODE
|
|
|
|
DBGSTATIC VOID
|
|
ReplGetNeutralName(
|
|
OUT LPTSTR WhereDst,
|
|
IN LPBYTE WhereSrc
|
|
);
|
|
|
|
#endif // ndef UNICODE
|
|
|
|
|
|
#define REPORT_BAD_INCOMING_MSG( bufStart, bufSize, explanation ) \
|
|
{ \
|
|
NetpKdPrint(( PREFIX_REPL_CLIENT "BAD INCOMING MSG (" \
|
|
explanation ")\n" )); \
|
|
NetpDbgHexDump( bufStart, bufSize ); \
|
|
}
|
|
|
|
|
|
NET_API_STATUS
|
|
ReplMarshallQueryMsg(
|
|
IN PBYTE InBuf,
|
|
OUT PBYTE OutBuf,
|
|
IN LPDWORD BytesRead
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Marshall QUERY type message. The marshalled data buffer will look like as
|
|
follows:
|
|
|
|
PACK_QUERY_MSG
|
|
PACK_HEADER
|
|
WORD msg_type;
|
|
CHAR sender[LM20_CNLEN+1];
|
|
CHAR senders_domain[LM20_DNLEN+1];
|
|
CHAR dir_name[LM20_PATHLEN]; // ASCIIZ dir/tree name.
|
|
WCHAR unicode_sender[];
|
|
WCHAR unicode_senders_domain[];
|
|
WCHAR unicode_dir_name[];
|
|
DWORD NT_TOKEN; // unaligned
|
|
|
|
Arguments:
|
|
|
|
InBuf : input buffer that contains QUERY_MSG data structure.
|
|
OutBuf : output buffer that will have the marshalled data.
|
|
BytesRead : length of the marshalled data
|
|
|
|
Return Value:
|
|
|
|
NERR_Success : if successfully unmarshall/validate the message.
|
|
error code : otherwise
|
|
|
|
NOTE : OutBuf is assumed big enough to fit the entire marshalled data.
|
|
|
|
--*/
|
|
{
|
|
|
|
PQUERY_MSG QueryMsg;
|
|
PPACK_QUERY_MSG PackQueryMsg;
|
|
DWORD Len, Token, TotalSize;
|
|
LPBYTE Where;
|
|
|
|
NetpAssert( InBuf != NULL );
|
|
NetpAssert( OutBuf != NULL );
|
|
|
|
QueryMsg = (PQUERY_MSG) InBuf;
|
|
PackQueryMsg = (PPACK_QUERY_MSG) OutBuf;
|
|
|
|
// copy header info.
|
|
|
|
SmbPutUshort( (LPWORD) &(PackQueryMsg->header.msg_type),
|
|
(WORD) QueryMsg->header.msg_type );
|
|
|
|
#if defined(DBCS) && defined(UNICODE) // ReplMarshallQueryMsg()
|
|
NetpCopyWStrToStrDBCS(
|
|
PackQueryMsg->header.sender, // dest
|
|
QueryMsg->header.sender ); // src
|
|
|
|
NetpCopyWStrToStrDBCS(
|
|
PackQueryMsg->header.senders_domain, // dest
|
|
QueryMsg->header.senders_domain ); // src
|
|
|
|
NetpCopyWStrToStrDBCS(
|
|
PackQueryMsg->dir_name, // dest
|
|
QueryMsg->dir_name ); // src
|
|
#else
|
|
NetpCopyTStrToStr(
|
|
PackQueryMsg->header.sender, // dest
|
|
QueryMsg->header.sender ); // src
|
|
|
|
NetpCopyTStrToStr(
|
|
PackQueryMsg->header.senders_domain, // dest
|
|
QueryMsg->header.senders_domain ); // src
|
|
|
|
NetpCopyTStrToStr(
|
|
PackQueryMsg->dir_name, // dest
|
|
QueryMsg->dir_name ); // src
|
|
#endif // DBCS
|
|
|
|
|
|
// copy unicode names
|
|
|
|
Where = OutBuf + sizeof(PACK_QUERY_MSG);
|
|
|
|
Len = ( STRLEN( QueryMsg->header.sender ) + 1 ) * sizeof( WCHAR );
|
|
|
|
NetpCopyTStrToUnalignedWStr( Where, QueryMsg->header.sender );
|
|
|
|
Where += Len;
|
|
|
|
Len = ( STRLEN( QueryMsg->header.senders_domain ) + 1 ) * sizeof( WCHAR );
|
|
|
|
NetpCopyTStrToUnalignedWStr( Where, QueryMsg->header.senders_domain );
|
|
|
|
Where += Len;
|
|
|
|
Len = ( STRLEN( QueryMsg->dir_name ) + 1 ) * sizeof( WCHAR );
|
|
|
|
NetpCopyTStrToUnalignedWStr( Where, QueryMsg->dir_name );
|
|
|
|
Where += Len;
|
|
|
|
// add token
|
|
|
|
Token = NT_MSG_TOKEN;
|
|
|
|
NetpMoveMemory( Where, &Token, sizeof( DWORD ));
|
|
|
|
Where += sizeof( DWORD );
|
|
|
|
TotalSize = (DWORD) (Where - OutBuf);
|
|
NetpAssert( TotalSize != 0 );
|
|
*BytesRead = TotalSize;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
|
|
NET_API_STATUS
|
|
ReplUnmarshallMessage(
|
|
IN PBYTE InBuf,
|
|
IN DWORD InBufLen,
|
|
OUT PBYTE OutBuf,
|
|
IN DWORD OutBufLen,
|
|
OUT LPDWORD BytesRead
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Unmarshall a message buffer. This function determines the message version
|
|
(NT/DOWNLEVEL), message type and unmarshalls it accordingly. This
|
|
function also validates the messsage fields.
|
|
|
|
Arguments:
|
|
|
|
InBuf : incoming message buffer that contains marshalled data.
|
|
InBufLen : length of input buffer.
|
|
OutBuf : unmarshalled message buffer.
|
|
OutBufLen : unmarshall buffer length.
|
|
BytesRead : unmarshalled message length.
|
|
|
|
Return Value:
|
|
|
|
NO_ERROR : if successfully unmarshall/validate the message.
|
|
error code : otherwise
|
|
|
|
--*/
|
|
{
|
|
|
|
DWORD MsgType;
|
|
|
|
// get message type.
|
|
|
|
MsgType = (DWORD) SmbGetUshort( (LPWORD)InBuf );
|
|
|
|
switch ( MsgType ) {
|
|
|
|
case SYNC_MSG : /*FALLTHROUGH*/
|
|
case GUARD_MSG : /*FALLTHROUGH*/
|
|
case PULSE_MSG :
|
|
|
|
return( ReplUnmarshallSyncMsg(InBuf,
|
|
InBufLen,
|
|
OutBuf,
|
|
OutBufLen,
|
|
BytesRead) );
|
|
|
|
case IS_DIR_SUPPORTED : /*FALLTHROUGH*/
|
|
case IS_MASTER : /*FALLTHROUGH*/
|
|
case DIR_NOT_SUPPORTED : /*FALLTHROUGH*/
|
|
case DIR_SUPPORTED : /*FALLTHROUGH*/
|
|
case NOT_MASTER_DIR : /*FALLTHROUGH*/
|
|
case MASTER_DIR : /*FALLTHROUGH*/
|
|
case DIR_COLLIDE :
|
|
|
|
return( ReplUnmarshallQueryMsg(InBuf,
|
|
InBufLen,
|
|
OutBuf,
|
|
OutBufLen,
|
|
BytesRead) );
|
|
|
|
default :
|
|
|
|
REPORT_BAD_INCOMING_MSG( InBuf, InBufLen, "bad msg type" );
|
|
return ERROR_INVALID_DATA;
|
|
|
|
}
|
|
/*NOTREACHED*/
|
|
|
|
}
|
|
|
|
NET_API_STATUS
|
|
ReplUnmarshallSyncMsg(
|
|
IN PBYTE InBuf,
|
|
IN DWORD InBufLen,
|
|
OUT PBYTE OutBuf,
|
|
IN DWORD OutBufLen,
|
|
OUT LPDWORD BytesRead
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Unmarshall SYNC/PULSE/GUARD type message buffer. The input buffer contains
|
|
packed PACK_SYNGMSG and PACK_MSG_STATUS_REC as defined in replpack.h and
|
|
as marshalled in puls_msg.c.
|
|
|
|
Arguments:
|
|
|
|
InBuf : incoming message buffer that contains marshalled data.
|
|
InBufLen : length of input buffer.
|
|
OutBuf : unmarshalled message buffer.
|
|
OutBufLen : unmarshall buffer length.
|
|
BytesRead : unmarshalled message length.
|
|
|
|
Return Value:
|
|
|
|
NO_ERROR : if successfully unmarshall/validate the message.
|
|
error code : otherwise
|
|
|
|
--*/
|
|
{
|
|
DWORD MsgToken;
|
|
DWORD Version;
|
|
DWORD i;
|
|
|
|
PSYNCMSG SyncMsg;
|
|
PPACK_SYNCMSG PackSyncMsg;
|
|
|
|
LPWSTR UnicodeName;
|
|
DWORD UpdateCount;
|
|
|
|
PMSG_STATUS_REC UpdateRec;
|
|
PPACK_MSG_STATUS_REC PackUpdateRec;
|
|
|
|
PBYTE WhereSrc;
|
|
PBYTE WhereDst;
|
|
|
|
DWORD Len;
|
|
|
|
*BytesRead = 0;
|
|
|
|
MsgToken = SmbGetUlong( (LPBYTE) (InBuf + InBufLen - sizeof(DWORD)) );
|
|
|
|
Version = (MsgToken == NT_MSG_TOKEN) ? NT_VERSION : NOT_NET_VERSION;
|
|
|
|
// copy header info.
|
|
|
|
SyncMsg = (PSYNCMSG) OutBuf;
|
|
|
|
PackSyncMsg = (PPACK_SYNCMSG) InBuf;
|
|
|
|
SyncMsg->header.msg_type =
|
|
(DWORD) SmbGetUshort( (LPBYTE) &(PackSyncMsg->header.msg_type) );
|
|
|
|
// msg_type is checked already in the main unmarshall routine
|
|
|
|
UpdateCount = SyncMsg->update_count =
|
|
(DWORD) SmbGetUshort( (LPWORD) &(PackSyncMsg->update_count));
|
|
|
|
// do sanity check on UpdateCount
|
|
|
|
if( InBufLen < ( sizeof( PACK_SYNCMSG ) +
|
|
UpdateCount * sizeof( PACK_MSG_STATUS_REC ) ) ) {
|
|
|
|
// bogus message, message size is not sufficient even to fit
|
|
// fix portion.
|
|
|
|
REPORT_BAD_INCOMING_MSG( InBuf, InBufLen, "sync msg too small" );
|
|
return ERROR_INVALID_DATA;
|
|
|
|
}
|
|
|
|
if( OutBufLen < ( sizeof(SYNCMSG) ) ) {
|
|
|
|
// output buffer is too small
|
|
|
|
REPORT_BAD_INCOMING_MSG( InBuf, InBufLen,
|
|
"sync buffer too small for fixed" );
|
|
return ERROR_INSUFFICIENT_BUFFER;
|
|
|
|
}
|
|
|
|
if( Version != NT_VERSION ) {
|
|
|
|
// sanity check on ANSI names
|
|
|
|
if( ( strlen((LPSTR) PackSyncMsg->header.sender) > LM20_CNLEN ) ||
|
|
( strlen( (LPSTR)PackSyncMsg->header.senders_domain ) >
|
|
LM20_DNLEN ) ) {
|
|
|
|
REPORT_BAD_INCOMING_MSG( InBuf, InBufLen,
|
|
"sync msg ANSI names too long" );
|
|
return ERROR_INVALID_DATA;
|
|
|
|
}
|
|
|
|
// copy neutral names from ansi strings
|
|
|
|
NetpCopyStrToTStr (
|
|
SyncMsg->header.sender, // dest
|
|
PackSyncMsg->header.sender ); // src
|
|
|
|
NetpCopyStrToTStr (
|
|
SyncMsg->header.senders_domain, // dest
|
|
PackSyncMsg->header.senders_domain ); // src
|
|
|
|
} else {
|
|
|
|
// copy neutral names from unicode strings
|
|
|
|
WhereSrc = (PBYTE) (InBuf +
|
|
sizeof(PACK_SYNCMSG) +
|
|
UpdateCount * sizeof(PACK_MSG_STATUS_REC)) ;
|
|
|
|
ReplGetNeutralName(SyncMsg->header.sender, WhereSrc);
|
|
|
|
WhereSrc += ( ( STRLEN(SyncMsg->header.sender) + 1 ) * sizeof(WCHAR) );
|
|
|
|
ReplGetNeutralName(SyncMsg->header.senders_domain, WhereSrc);
|
|
|
|
// sanity check on UNICODE names
|
|
|
|
if( ( STRLEN( SyncMsg->header.sender ) > CNLEN ) ||
|
|
( STRLEN( SyncMsg->header.senders_domain ) > DNLEN ) ) {
|
|
|
|
REPORT_BAD_INCOMING_MSG( InBuf, InBufLen,
|
|
"sync msg UNICODE names too long" );
|
|
return ERROR_INVALID_DATA;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
SyncMsg->info.random =
|
|
(DWORD) SmbGetUshort( (LPWORD) &(PackSyncMsg->info.random));
|
|
|
|
if( !ReplIsRandomValid( SyncMsg->info.random ) ) {
|
|
|
|
REPORT_BAD_INCOMING_MSG( InBuf, InBufLen, "sync msg bad RANDOM value" );
|
|
return ERROR_INVALID_DATA;
|
|
}
|
|
|
|
{
|
|
DWORD SyncRate;
|
|
|
|
SyncRate =
|
|
(DWORD) SmbGetUshort( (LPWORD) &(PackSyncMsg->info.sync_rate));
|
|
SyncMsg->info.sync_rate = SyncRate;
|
|
|
|
if ( !ReplIsIntervalValid( SyncRate ) ) {
|
|
|
|
REPORT_BAD_INCOMING_MSG( InBuf, InBufLen,
|
|
"sync msg bad SYNC value" );
|
|
return ERROR_INVALID_DATA;
|
|
}
|
|
|
|
// Get pulse rate (pulse * sync time):
|
|
SyncMsg->info.pulse_rate =
|
|
(DWORD) SmbGetUshort( (LPWORD) &(PackSyncMsg->info.pulse_rate));
|
|
|
|
if ( !IN_RANGE( SyncMsg->info.pulse_rate,
|
|
(MIN_PULSE*SyncRate),
|
|
(MAX_PULSE*SyncRate) ) ) {
|
|
|
|
REPORT_BAD_INCOMING_MSG( InBuf, InBufLen,
|
|
"sync msg bad PULSE value" );
|
|
return ERROR_INVALID_DATA;
|
|
}
|
|
}
|
|
|
|
SyncMsg->info.guard_time =
|
|
(DWORD) SmbGetUshort( (LPWORD) &(PackSyncMsg->info.guard_time));
|
|
|
|
if( !ReplIsGuardTimeValid( SyncMsg->info.guard_time ) ) {
|
|
|
|
REPORT_BAD_INCOMING_MSG( InBuf, InBufLen, "sync msg bad GUARD value" );
|
|
return ERROR_INVALID_DATA;
|
|
}
|
|
|
|
UpdateRec = (PMSG_STATUS_REC) (LPVOID) (SyncMsg + 1);
|
|
|
|
PackUpdateRec = (PPACK_MSG_STATUS_REC) (LPVOID) (PackSyncMsg + 1);
|
|
|
|
WhereDst = (PBYTE) ( OutBuf +
|
|
sizeof(SYNCMSG) +
|
|
UpdateCount * sizeof(MSG_STATUS_REC) );
|
|
|
|
// align to WCHAR boundary
|
|
|
|
WhereDst = ROUND_UP_POINTER( WhereDst, ALIGN_WCHAR );
|
|
|
|
for( i = 0;
|
|
i < UpdateCount;
|
|
i++, UpdateRec++, PackUpdateRec++ ) {
|
|
|
|
UpdateRec->dir_name_offset = (DWORD) (WhereDst - OutBuf);
|
|
if (UpdateRec->dir_name_offset > OutBufLen) {
|
|
|
|
// output buffer is too small
|
|
|
|
REPORT_BAD_INCOMING_MSG( InBuf, InBufLen,
|
|
"sync name offset too large" );
|
|
return ERROR_INSUFFICIENT_BUFFER;
|
|
|
|
}
|
|
|
|
|
|
WhereSrc = InBuf +
|
|
(DWORD) SmbGetUshort( (LPWORD) &(PackUpdateRec->dir_name_offset));
|
|
|
|
if( Version == NT_VERSION ) {
|
|
|
|
// skip ansi dir name.
|
|
|
|
WhereSrc += (DWORD) ( strlen( (LPSTR) WhereSrc) + 1 );
|
|
|
|
ReplGetNeutralName( (LPTSTR) WhereDst, WhereSrc );
|
|
|
|
if( ( Len = wcslen((LPWSTR) WhereDst) ) > PATHLEN ) {
|
|
|
|
REPORT_BAD_INCOMING_MSG( InBuf, InBufLen,
|
|
"sync NT name too long" );
|
|
return ERROR_INVALID_DATA;
|
|
|
|
}
|
|
} else {
|
|
|
|
// copy unicode dir name from ansi string
|
|
|
|
UnicodeName = NetpAllocWStrFromStr( (LPSTR) WhereSrc );
|
|
|
|
if( UnicodeName == NULL ) {
|
|
|
|
// no memory.
|
|
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
}
|
|
|
|
(void) wcscpy( (LPWSTR) WhereDst, UnicodeName );
|
|
|
|
NetpMemoryFree( UnicodeName );
|
|
|
|
if( ( Len = wcslen((LPWSTR) WhereDst) ) > LM20_PATHLEN ) {
|
|
|
|
REPORT_BAD_INCOMING_MSG( InBuf, InBufLen,
|
|
"sync non-NT name too long" );
|
|
return ERROR_INVALID_DATA;
|
|
|
|
}
|
|
}
|
|
|
|
WhereDst += ( ( Len + 1 ) * sizeof(WCHAR) );
|
|
|
|
UpdateRec->opcode =
|
|
(DWORD) SmbGetUshort( (LPWORD) &(PackUpdateRec->opcode));
|
|
|
|
UpdateRec->checksum =
|
|
SmbGetUlong( (LPDWORD) &(PackUpdateRec->checksum));
|
|
|
|
UpdateRec->count =
|
|
(DWORD) SmbGetUshort( (LPWORD) &(PackUpdateRec->count));
|
|
|
|
UpdateRec->integrity =
|
|
(DWORD) SmbGetUshort( (LPWORD) &(PackUpdateRec->integrity));
|
|
|
|
UpdateRec->extent =
|
|
(DWORD) SmbGetUshort( (LPWORD) &(PackUpdateRec->extent));
|
|
|
|
if( !IN_RANGE( UpdateRec->opcode, START, GUARD ) ||
|
|
!ReplIsIntegrityValid( UpdateRec->integrity ) ||
|
|
!ReplIsExtentValid( UpdateRec->extent ) ) {
|
|
|
|
REPORT_BAD_INCOMING_MSG( InBuf, InBufLen,
|
|
"sync RANGE/INTEGRITY/EXTENT invalid" );
|
|
return ERROR_INVALID_DATA;
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
// set total bytes read in the output buffer.
|
|
|
|
*BytesRead = (DWORD) (WhereDst - OutBuf);
|
|
|
|
return NO_ERROR;
|
|
|
|
}
|
|
|
|
NET_API_STATUS
|
|
ReplUnmarshallQueryMsg(
|
|
IN PBYTE InBuf,
|
|
IN DWORD InBufLen,
|
|
OUT PBYTE OutBuf,
|
|
IN DWORD OutBufLen,
|
|
OUT LPDWORD BytesRead
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Unmarshall QUERY type message buffer.
|
|
|
|
Arguments:
|
|
|
|
InBuf : incoming message buffer that contains marshalled data.
|
|
InBufLen : length of input buffer.
|
|
OutBuf : unmarshalled message buffer.
|
|
OutBufLen : unmarshall buffer length.
|
|
BytesRead : unmarshalled message length.
|
|
|
|
Return Value:
|
|
|
|
NO_ERROR : if successfully unmarshall/validate the message.
|
|
error code : otherwise
|
|
|
|
--*/
|
|
{
|
|
DWORD MsgToken;
|
|
DWORD Version;
|
|
|
|
PQUERY_MSG QueryMsg;
|
|
PPACK_QUERY_MSG PackQueryMsg;
|
|
|
|
PBYTE WhereSrc;
|
|
|
|
*BytesRead = 0;
|
|
|
|
// sanity check input message length
|
|
|
|
if( InBufLen < sizeof(PACK_QUERY_MSG) ) {
|
|
|
|
REPORT_BAD_INCOMING_MSG( InBuf, InBufLen, "query msg too small" );
|
|
return ERROR_INVALID_DATA;
|
|
|
|
}
|
|
|
|
MsgToken = SmbGetUlong( (LPBYTE) (InBuf + InBufLen - sizeof(DWORD)));
|
|
|
|
if( (MsgToken == NT_MSG_TOKEN) && (InBufLen != sizeof(PACK_QUERY_MSG)) ) {
|
|
|
|
Version = NT_VERSION;
|
|
|
|
} else {
|
|
|
|
Version = NOT_NET_VERSION;
|
|
|
|
}
|
|
|
|
if( OutBufLen < sizeof(QUERY_MSG) ) {
|
|
|
|
// output buffer is too small
|
|
|
|
REPORT_BAD_INCOMING_MSG( InBuf, InBufLen,
|
|
"query output buffer too small" );
|
|
return ERROR_INSUFFICIENT_BUFFER;
|
|
|
|
}
|
|
|
|
// copy header info.
|
|
|
|
QueryMsg = (PQUERY_MSG) OutBuf;
|
|
|
|
PackQueryMsg = (PPACK_QUERY_MSG) InBuf;
|
|
|
|
QueryMsg->header.msg_type =
|
|
(DWORD) SmbGetUshort( (LPBYTE) &(PackQueryMsg->header.msg_type) );
|
|
|
|
// msg_type value is already validated in the main unmarshall routine ..
|
|
|
|
if( Version != NT_VERSION ) {
|
|
|
|
// validate ansi names ..
|
|
|
|
if( ( strlen( (LPSTR) PackQueryMsg->header.sender ) > LM20_CNLEN ) ||
|
|
( strlen( (LPSTR)PackQueryMsg->header.senders_domain) >
|
|
LM20_DNLEN )) {
|
|
|
|
REPORT_BAD_INCOMING_MSG( InBuf, InBufLen,
|
|
"query ANSI names too long" );
|
|
return ERROR_INVALID_DATA;
|
|
|
|
}
|
|
|
|
// copy neutral names from ansi strings
|
|
|
|
NetpCopyStrToTStr (
|
|
QueryMsg->header.sender, // dest
|
|
(LPSTR) PackQueryMsg->header.sender ); // src
|
|
|
|
|
|
NetpCopyStrToTStr (
|
|
QueryMsg->header.senders_domain, // dest
|
|
(LPSTR)PackQueryMsg->header.senders_domain ); // src
|
|
|
|
} else {
|
|
|
|
// copy unicode names from unicode strings
|
|
|
|
WhereSrc = (PBYTE) (InBuf + sizeof(PACK_QUERY_MSG) );
|
|
|
|
ReplGetNeutralName(QueryMsg->header.sender, WhereSrc);
|
|
|
|
WhereSrc += ( ( STRLEN(QueryMsg->header.sender) + 1 ) * sizeof(WCHAR) );
|
|
|
|
ReplGetNeutralName(QueryMsg->header.senders_domain, WhereSrc);
|
|
|
|
// validate unicode names ..
|
|
|
|
if( ( STRLEN( QueryMsg->header.sender ) > CNLEN ) ||
|
|
( STRLEN( QueryMsg->header.senders_domain) > DNLEN )) {
|
|
|
|
REPORT_BAD_INCOMING_MSG( InBuf, InBufLen,
|
|
"query UNICODE names too long" );
|
|
return ERROR_INVALID_DATA;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*BytesRead = sizeof(QUERY_MSG);
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
#ifndef UNICODE
|
|
|
|
DBGSTATIC VOID
|
|
ReplGetNeutralName(
|
|
OUT LPTSTR NeutralName,
|
|
IN LPBYTE UnicodeRaw
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Copy an unaligned Unicode string to aligned buffer.
|
|
|
|
Arguments:
|
|
|
|
NeutralName : TCHAR aligned buffer.
|
|
UnicodeRaw : unaligned buffer with unicode name in it.
|
|
|
|
Return Value:
|
|
|
|
none
|
|
|
|
--*/
|
|
{
|
|
|
|
TCHAR NeutralChar;
|
|
WCHAR UnicodeChar;
|
|
|
|
do {
|
|
|
|
UnicodeChar = (WCHAR) SmbGetUshort ( UnicodeRaw );
|
|
|
|
NeutralChar = (TCHAR) UnicodeChar; // BUGBUG: Wrong!!
|
|
|
|
*NeutralName++ = NeutralChar;
|
|
|
|
UnicodeRaw += sizeof(WCHAR);
|
|
|
|
} while (UnicodeChar != L'\0' );
|
|
|
|
} // ReplGetNeutralName
|
|
|
|
|
|
#else // def UNICODE
|
|
|
|
|
|
DBGSTATIC VOID
|
|
ReplGetUnicodeName(
|
|
OUT LPWSTR UnicodeName,
|
|
IN LPBYTE UnicodeRaw
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Copy a unaligned Unicode string to aligned buffer.
|
|
|
|
Arguments:
|
|
|
|
UnicodeName : WCHAR aligned buffer.
|
|
UnicodeRaw : unaligned buffer with unicode name in it.
|
|
|
|
Return Value:
|
|
|
|
none
|
|
|
|
--*/
|
|
{
|
|
|
|
WCHAR UnicodeChar;
|
|
|
|
do {
|
|
|
|
UnicodeChar = (WCHAR) SmbGetUshort ( UnicodeRaw );
|
|
|
|
*UnicodeName++ = UnicodeChar;
|
|
|
|
UnicodeRaw += sizeof(WCHAR);
|
|
|
|
} while (UnicodeChar != L'\0' );
|
|
|
|
} // ReplGetUnicodeName
|
|
|
|
#endif // def UNICODE
|