📄 servermessageblock.java
字号:
String readString(byte[] src, int srcIndex, int srcEnd, int maxLen, boolean useUnicode) {
int len = 0;
String str = null;
try {
if (useUnicode) {
// Unicode requires word alignment
if (((srcIndex - headerStart) % 2) != 0) {
srcIndex++;
}
for (len = 0; (srcIndex + len + 1) < srcEnd; len += 2) {
if (src[srcIndex + len] == (byte)0x00 && src[srcIndex + len + 1] == (byte)0x00) {
break;
}
if (len > maxLen) {
if (log.level > 0)
Hexdump.hexdump(System.err, src, srcIndex, maxLen < 128 ? maxLen + 8 : 128);
throw new RuntimeException("zero termination not found");
}
}
str = new String(src, srcIndex, len, "UnicodeLittleUnmarked");
} else {
for (len = 0; srcIndex < srcEnd; len++) {
if (src[srcIndex + len] == (byte)0x00) {
break;
}
if (len > maxLen) {
if (log.level > 0)
Hexdump.hexdump(System.err, src, srcIndex, maxLen < 128 ? maxLen + 8 : 128);
throw new RuntimeException("zero termination not found");
}
}
str = new String(src, srcIndex, len, OEM_ENCODING);
}
} catch( UnsupportedEncodingException uee ) {
if( log.level > 1 )
uee.printStackTrace( log );
}
return str;
}
int stringWireLength( String str, int offset ) {
int len = str.length() + 1;
if( useUnicode ) {
len = str.length() * 2 + 2;
len = ( offset % 2 ) != 0 ? len + 1 : len;
}
return len;
}
int readStringLength( byte[] src, int srcIndex, int max ) {
int len = 0;
while( src[srcIndex + len] != (byte)0x00 ) {
if( len++ > max ) {
throw new RuntimeException( "zero termination not found: " + this );
}
}
return len;
}
int encode( byte[] dst, int dstIndex ) {
int start = headerStart = dstIndex;
dstIndex += writeHeaderWireFormat( dst, dstIndex );
wordCount = writeParameterWordsWireFormat( dst, dstIndex + 1 );
dst[dstIndex++] = (byte)(( wordCount / 2 ) & 0xFF );
dstIndex += wordCount;
wordCount /= 2;
byteCount = writeBytesWireFormat( dst, dstIndex + 2 );
dst[dstIndex++] = (byte)( byteCount & 0xFF );
dst[dstIndex++] = (byte)(( byteCount >> 8 ) & 0xFF );
dstIndex += byteCount;
length = dstIndex - start;
if( digest != null ) {
digest.sign( dst, headerStart, length, this, response );
}
return length;
}
int decode( byte[] buffer, int bufferIndex ) {
int start = headerStart = bufferIndex;
bufferIndex += readHeaderWireFormat( buffer, bufferIndex );
wordCount = buffer[bufferIndex++];
if( wordCount != 0 ) {
int n;
if(( n = readParameterWordsWireFormat( buffer, bufferIndex )) != wordCount * 2 ) {
if( log.level >= 5 ) {
log.println( "wordCount * 2=" + ( wordCount * 2 ) +
" but readParameterWordsWireFormat returned " + n );
}
}
bufferIndex += wordCount * 2;
}
byteCount = readInt2( buffer, bufferIndex );
bufferIndex += 2;
if( byteCount != 0 ) {
int n;
if(( n = readBytesWireFormat( buffer, bufferIndex )) != byteCount ) {
if( log.level >= 5 ) {
log.println( "byteCount=" + byteCount +
" but readBytesWireFormat returned " + n );
}
}
// Don't think we can rely on n being correct here. Must use byteCount.
// Last paragraph of section 3.13.3 eludes to this.
bufferIndex += byteCount;
}
length = bufferIndex - start;
return length;
}
int writeHeaderWireFormat( byte[] dst, int dstIndex ) {
System.arraycopy( header, 0, dst, dstIndex, header.length );
dst[dstIndex + CMD_OFFSET] = command;
dst[dstIndex + FLAGS_OFFSET] = flags;
writeInt2( flags2, dst, dstIndex + FLAGS_OFFSET + 1 );
dstIndex += TID_OFFSET;
writeInt2( tid, dst, dstIndex );
writeInt2( pid, dst, dstIndex + 2 );
writeInt2( uid, dst, dstIndex + 4 );
writeInt2( mid, dst, dstIndex + 6 );
return HEADER_LENGTH;
}
int readHeaderWireFormat( byte[] buffer, int bufferIndex ) {
command = buffer[bufferIndex + CMD_OFFSET];
errorCode = readInt4( buffer, bufferIndex + ERROR_CODE_OFFSET );
flags = buffer[bufferIndex + FLAGS_OFFSET];
flags2 = readInt2( buffer, bufferIndex + FLAGS_OFFSET + 1 );
tid = readInt2( buffer, bufferIndex + TID_OFFSET );
pid = readInt2( buffer, bufferIndex + TID_OFFSET + 2 );
uid = readInt2( buffer, bufferIndex + TID_OFFSET + 4 );
mid = readInt2( buffer, bufferIndex + TID_OFFSET + 6 );
return HEADER_LENGTH;
}
boolean isResponse() {
return ( flags & FLAGS_RESPONSE ) == FLAGS_RESPONSE;
}
/*
* For this packet deconstruction technique to work for
* other networking protocols the InputStream may need
* to be passed to the readXxxWireFormat methods. This is
* actually purer. However, in the case of smb we know the
* wordCount and byteCount. And since every subclass of
* ServerMessageBlock would have to perform the same read
* operation on the input stream, we might as will pull that
* common functionality into the superclass and read wordCount
* and byteCount worth of data.
*
* We will still use the readXxxWireFormat return values to
* indicate how many bytes(note: readParameterWordsWireFormat
* returns bytes read and not the number of words(but the
* wordCount member DOES store the number of words)) we
* actually read. Incedentally this is important to the
* AndXServerMessageBlock class that needs to potentially
* read in another smb's parameter words and bytes based on
* information in it's andxCommand, andxOffset, ...etc.
*/
abstract int writeParameterWordsWireFormat( byte[] dst, int dstIndex );
abstract int writeBytesWireFormat( byte[] dst, int dstIndex );
abstract int readParameterWordsWireFormat( byte[] buffer, int bufferIndex );
abstract int readBytesWireFormat( byte[] buffer, int bufferIndex );
public int hashCode() {
return mid;
}
public boolean equals( Object obj ) {
return obj instanceof ServerMessageBlock && ((ServerMessageBlock)obj).mid == mid;
}
public String toString() {
String c;
switch( command ) {
case SMB_COM_NEGOTIATE:
c = "SMB_COM_NEGOTIATE";
break;
case SMB_COM_SESSION_SETUP_ANDX:
c = "SMB_COM_SESSION_SETUP_ANDX";
break;
case SMB_COM_TREE_CONNECT_ANDX:
c = "SMB_COM_TREE_CONNECT_ANDX";
break;
case SMB_COM_QUERY_INFORMATION:
c = "SMB_COM_QUERY_INFORMATION";
break;
case SMB_COM_CHECK_DIRECTORY:
c = "SMB_COM_CHECK_DIRECTORY";
break;
case SMB_COM_TRANSACTION:
c = "SMB_COM_TRANSACTION";
break;
case SMB_COM_TRANSACTION2:
c = "SMB_COM_TRANSACTION2";
break;
case SMB_COM_TRANSACTION_SECONDARY:
c = "SMB_COM_TRANSACTION_SECONDARY";
break;
case SMB_COM_FIND_CLOSE2:
c = "SMB_COM_FIND_CLOSE2";
break;
case SMB_COM_TREE_DISCONNECT:
c = "SMB_COM_TREE_DISCONNECT";
break;
case SMB_COM_LOGOFF_ANDX:
c = "SMB_COM_LOGOFF_ANDX";
break;
case SMB_COM_ECHO:
c = "SMB_COM_ECHO";
break;
case SMB_COM_MOVE:
c = "SMB_COM_MOVE";
break;
case SMB_COM_RENAME:
c = "SMB_COM_RENAME";
break;
case SMB_COM_DELETE:
c = "SMB_COM_DELETE";
break;
case SMB_COM_DELETE_DIRECTORY:
c = "SMB_COM_DELETE_DIRECTORY";
break;
case SMB_COM_NT_CREATE_ANDX:
c = "SMB_COM_NT_CREATE_ANDX";
break;
case SMB_COM_OPEN_ANDX:
c = "SMB_COM_OPEN_ANDX";
break;
case SMB_COM_READ_ANDX:
c = "SMB_COM_READ_ANDX";
break;
case SMB_COM_CLOSE:
c = "SMB_COM_CLOSE";
break;
case SMB_COM_WRITE_ANDX:
c = "SMB_COM_WRITE_ANDX";
break;
case SMB_COM_CREATE_DIRECTORY:
c = "SMB_COM_CREATE_DIRECTORY";
break;
case SMB_COM_NT_TRANSACT:
c = "SMB_COM_NT_TRANSACT";
break;
case SMB_COM_NT_TRANSACT_SECONDARY:
c = "SMB_COM_NT_TRANSACT_SECONDARY";
break;
default:
c = "UNKNOWN";
}
String str = errorCode == 0 ? "0" : SmbException.getMessageByCode( errorCode );
return new String(
"command=" + c +
",received=" + received +
",errorCode=" + str +
",flags=0x" + Hexdump.toHexString( flags & 0xFF, 4 ) +
",flags2=0x" + Hexdump.toHexString( flags2, 4 ) +
",signSeq=" + signSeq +
",tid=" + tid +
",pid=" + pid +
",uid=" + uid +
",mid=" + mid +
",wordCount=" + wordCount +
",byteCount=" + byteCount );
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -