📄 servermessageblock.java
字号:
/* jcifs smb client library in Java
* Copyright (C) 2000 "Michael B. Allen" <jcifs at samba dot org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcifs.smb;
import jcifs.Config;
import java.io.InputStream;
import java.io.PushbackInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Calendar;
import java.util.Date;
import jcifs.util.Hexdump;
import jcifs.util.LogStream;
import jcifs.util.transport.*;
abstract class ServerMessageBlock extends Response implements Request, SmbConstants {
static LogStream log = LogStream.getInstance();
static final byte[] header = {
(byte)0xFF, (byte)'S', (byte)'M', (byte)'B',
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00
};
static void writeInt2( long val, byte[] dst, int dstIndex ) {
dst[dstIndex] = (byte)(val);
dst[++dstIndex] = (byte)(val >> 8);
}
static void writeInt4( long val, byte[] dst, int dstIndex ) {
dst[dstIndex] = (byte)(val);
dst[++dstIndex] = (byte)(val >>= 8);
dst[++dstIndex] = (byte)(val >>= 8);
dst[++dstIndex] = (byte)(val >> 8);
}
static int readInt2( byte[] src, int srcIndex ) {
return ( src[srcIndex] & 0xFF ) +
(( src[srcIndex + 1] & 0xFF ) << 8 );
}
static int readInt4( byte[] src, int srcIndex ) {
return ( src[srcIndex] & 0xFF ) +
(( src[srcIndex + 1] & 0xFF ) << 8 ) +
(( src[srcIndex + 2] & 0xFF ) << 16 ) +
(( src[srcIndex + 3] & 0xFF ) << 24 );
}
static long readInt8( byte[] src, int srcIndex ) {
return (readInt4( src, srcIndex ) & 0xFFFFFFFFL) +
((long)(readInt4( src, srcIndex + 4 )) << 32);
}
static void writeInt8( long val, byte[] dst, int dstIndex ) {
dst[dstIndex] = (byte)(val);
dst[++dstIndex] = (byte)(val >>= 8);
dst[++dstIndex] = (byte)(val >>= 8);
dst[++dstIndex] = (byte)(val >>= 8);
dst[++dstIndex] = (byte)(val >>= 8);
dst[++dstIndex] = (byte)(val >>= 8);
dst[++dstIndex] = (byte)(val >>= 8);
dst[++dstIndex] = (byte)(val >> 8);
}
static long readTime( byte[] src, int srcIndex ) {
int low = readInt4( src, srcIndex );
int hi = readInt4( src, srcIndex + 4 );
long t = ((long)hi << 32L ) | (low & 0xFFFFFFFFL);
t = ( t / 10000L - MILLISECONDS_BETWEEN_1970_AND_1601 );
return t;
}
static void writeTime( long t, byte[] dst, int dstIndex ) {
if( t != 0L ) {
t = (t + MILLISECONDS_BETWEEN_1970_AND_1601) * 10000L;
}
writeInt8( t, dst, dstIndex );
}
static long readUTime( byte[] buffer, int bufferIndex ) {
return readInt4( buffer, bufferIndex ) * 1000L;
}
static void writeUTime( long t, byte[] dst, int dstIndex ) {
if( t == 0L || t == 0xFFFFFFFFFFFFFFFFL ) {
writeInt4( 0xFFFFFFFF, dst, dstIndex );
return;
}
synchronized( TZ ) {
if( TZ.inDaylightTime( new Date() )) {
// in DST
if( TZ.inDaylightTime( new Date( t ))) {
// t also in DST so no correction
} else {
// t not in DST so subtract 1 hour
t -= 3600000;
}
} else {
// not in DST
if( TZ.inDaylightTime( new Date( t ))) {
// t is in DST so add 1 hour
t += 3600000;
} else {
// t isn't in DST either
}
}
}
writeInt4( (int)(t / 1000L), dst, dstIndex );
}
/*
* These are all the smbs supported by this library. This includes requests
* and well as their responses for each type however the actuall implementations
* of the readXxxWireFormat and writeXxxWireFormat methods may not be in
* place. For example at the time of this writing the readXxxWireFormat
* for requests and the writeXxxWireFormat for responses are not implemented
* and simply return 0. These would need to be completed for a server
* implementation.
*/
static final byte SMB_COM_CREATE_DIRECTORY = (byte)0x00;
static final byte SMB_COM_DELETE_DIRECTORY = (byte)0x01;
static final byte SMB_COM_CLOSE = (byte)0x04;
static final byte SMB_COM_DELETE = (byte)0x06;
static final byte SMB_COM_RENAME = (byte)0x07;
static final byte SMB_COM_QUERY_INFORMATION = (byte)0x08;
static final byte SMB_COM_WRITE = (byte)0x0B;
static final byte SMB_COM_CHECK_DIRECTORY = (byte)0x10;
static final byte SMB_COM_TRANSACTION = (byte)0x25;
static final byte SMB_COM_TRANSACTION_SECONDARY = (byte)0x26;
static final byte SMB_COM_MOVE = (byte)0x2A;
static final byte SMB_COM_ECHO = (byte)0x2B;
static final byte SMB_COM_OPEN_ANDX = (byte)0x2D;
static final byte SMB_COM_READ_ANDX = (byte)0x2E;
static final byte SMB_COM_WRITE_ANDX = (byte)0x2F;
static final byte SMB_COM_TRANSACTION2 = (byte)0x32;
static final byte SMB_COM_FIND_CLOSE2 = (byte)0x34;
static final byte SMB_COM_TREE_DISCONNECT = (byte)0x71;
static final byte SMB_COM_NEGOTIATE = (byte)0x72;
static final byte SMB_COM_SESSION_SETUP_ANDX = (byte)0x73;
static final byte SMB_COM_LOGOFF_ANDX = (byte)0x74;
static final byte SMB_COM_TREE_CONNECT_ANDX = (byte)0x75;
static final byte SMB_COM_NT_TRANSACT = (byte)0xA0;
static final byte SMB_COM_NT_TRANSACT_SECONDARY = (byte)0xA1;
static final byte SMB_COM_NT_CREATE_ANDX = (byte)0xA2;
/*
* Some fields specify the offset from the beginning of the header. This
* field should be used for calculating that. This would likely be zero
* but an implemantation that encorporates the transport header(for
* efficiency) might use a different initial bufferIndex. For example,
* to eliminate copying data when writing NbtSession data one might
* manage that 4 byte header specifically and therefore the initial
* bufferIndex, and thus headerStart, would be 4).(NOTE: If one where
* looking for a way to improve perfomance this is precisly what you
* would want to do as the jcifs.netbios.SocketXxxputStream classes
* arraycopy all data read or written into a new buffer shifted over 4!)
*/
byte command, flags;
int headerStart,
length,
batchLevel,
errorCode,
flags2,
tid, pid, uid, mid,
wordCount, byteCount;
boolean useUnicode, received, extendedSecurity;
long responseTimeout = 1;
int signSeq;
boolean verifyFailed;
NtlmPasswordAuthentication auth = null;
String path;
SigningDigest digest = null;
ServerMessageBlock response;
ServerMessageBlock() {
flags = (byte)( FLAGS_PATH_NAMES_CASELESS | FLAGS_PATH_NAMES_CANONICALIZED );
pid = PID;
batchLevel = 0;
}
void reset() {
flags = (byte)( FLAGS_PATH_NAMES_CASELESS | FLAGS_PATH_NAMES_CANONICALIZED );
flags2 = 0;
errorCode = 0;
received = false;
digest = null;
}
int writeString( String str, byte[] dst, int dstIndex ) {
return writeString( str, dst, dstIndex, useUnicode );
}
int writeString( String str, byte[] dst, int dstIndex, boolean useUnicode ) {
int start = dstIndex;
try {
if( useUnicode ) {
// Unicode requires word alignment
if((( dstIndex - headerStart ) % 2 ) != 0 ) {
dst[dstIndex++] = (byte)'\0';
}
System.arraycopy( str.getBytes( "UnicodeLittleUnmarked" ), 0,
dst, dstIndex, str.length() * 2 );
dstIndex += str.length() * 2;
dst[dstIndex++] = (byte)'\0';
dst[dstIndex++] = (byte)'\0';
} else {
byte[] b = str.getBytes( OEM_ENCODING );
System.arraycopy( b, 0, dst, dstIndex, b.length );
dstIndex += b.length;
dst[dstIndex++] = (byte)'\0';
}
} catch( UnsupportedEncodingException uee ) {
if( log.level > 1 )
uee.printStackTrace( log );
}
return dstIndex - start;
}
String readString( byte[] src, int srcIndex ) {
return readString( src, srcIndex, 256, useUnicode );
}
String readString( byte[] src, int srcIndex, int maxLen, boolean useUnicode ) {
int len = 0;
String str = null;
try {
if( useUnicode ) {
// Unicode requires word alignment
if((( srcIndex - headerStart ) % 2 ) != 0 ) {
srcIndex++;
}
while( src[srcIndex + len] != (byte)0x00 ||
src[srcIndex + len + 1] != (byte)0x00 ) {
len += 2;
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 {
while( src[srcIndex + len] != (byte)0x00 ) {
len++;
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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -