jcifs.internal.smb1.trans.SmbComTransaction Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jcifs-ng Show documentation
Show all versions of jcifs-ng Show documentation
A pure-java CIFS/SMB client library
/* jcifs smb client library in Java
* Copyright (C) 2000 "Michael B. Allen"
*
* 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.internal.smb1.trans;
import java.util.Enumeration;
import jcifs.Configuration;
import jcifs.internal.smb1.ServerMessageBlock;
import jcifs.internal.util.SMBUtil;
import jcifs.util.Hexdump;
/**
*
*/
public abstract class SmbComTransaction extends ServerMessageBlock implements Enumeration {
// relative to headerStart
private static final int PRIMARY_SETUP_OFFSET = 61;
private static final int SECONDARY_PARAMETER_OFFSET = 51;
static final int DISCONNECT_TID = 0x01;
static final int ONE_WAY_TRANSACTION = 0x02;
static final int PADDING_SIZE = 4;
private int tflags = 0x00;
private int pad1 = 0;
private int pad2 = 0;
private boolean hasMore = true;
private boolean isPrimary = true;
private int bufParameterOffset;
private int bufDataOffset;
static final int TRANSACTION_BUF_SIZE = 0xFFFF;
/**
*
*/
public static final byte TRANS2_FIND_FIRST2 = (byte) 0x01;
/**
*
*/
public static final byte TRANS2_FIND_NEXT2 = (byte) 0x02;
/**
*
*/
public static final byte TRANS2_QUERY_FS_INFORMATION = (byte) 0x03;
/**
*
*/
public static final byte TRANS2_QUERY_PATH_INFORMATION = (byte) 0x05;
/**
*
*/
public static final byte TRANS2_GET_DFS_REFERRAL = (byte) 0x10;
/**
*
*/
public static final byte TRANS2_QUERY_FILE_INFORMATION = (byte) 0x07;
/**
*
*/
public static final byte TRANS2_SET_FILE_INFORMATION = (byte) 0x08;
/**
*
*/
public static final byte NET_SHARE_ENUM = (byte) 0x00;
/**
*
*/
public static final byte NET_SERVER_ENUM2 = (byte) 0x68;
/**
*
*/
public static final byte NET_SERVER_ENUM3 = (byte) 0xD7;
/**
*
*/
public static final byte TRANS_PEEK_NAMED_PIPE = (byte) 0x23;
/**
*
*/
public static final byte TRANS_WAIT_NAMED_PIPE = (byte) 0x53;
/**
*
*/
public static final byte TRANS_CALL_NAMED_PIPE = (byte) 0x54;
/**
*
*/
public static final byte TRANS_TRANSACT_NAMED_PIPE = (byte) 0x26;
protected int primarySetupOffset;
protected int secondaryParameterOffset;
protected int parameterCount;
protected int parameterOffset;
protected int parameterDisplacement;
protected int dataCount;
protected int dataOffset;
protected int dataDisplacement;
protected int totalParameterCount;
protected int totalDataCount;
protected int maxParameterCount;
protected int maxDataCount;
protected byte maxSetupCount;
protected int timeout = 0;
protected int setupCount = 1;
private byte subCommand;
protected String name = "";
protected int maxBufferSize; // set in SmbTransport.sendTransaction() before nextElement called
private byte[] txn_buf;
protected SmbComTransaction ( Configuration config, byte command, byte subCommand ) {
super(config, command);
this.subCommand = subCommand;
this.maxDataCount = config.getTransactionBufferSize() - 512;
this.maxParameterCount = 1024;
this.primarySetupOffset = PRIMARY_SETUP_OFFSET;
this.secondaryParameterOffset = SECONDARY_PARAMETER_OFFSET;
}
/**
* @param maxBufferSize
* the maxBufferSize to set
*/
public final void setMaxBufferSize ( int maxBufferSize ) {
this.maxBufferSize = maxBufferSize;
}
/**
* @param maxDataCount
* the maxDataCount to set
*/
public final void setMaxDataCount ( int maxDataCount ) {
this.maxDataCount = maxDataCount;
}
/**
* @param buffer
*/
public void setBuffer ( byte[] buffer ) {
this.txn_buf = buffer;
}
/**
* @return the txn_buf
*/
public byte[] releaseBuffer () {
byte[] buf = this.txn_buf;
this.txn_buf = null;
return buf;
}
/**
* @return the subCommand
*/
public final byte getSubCommand () {
return this.subCommand;
}
/**
* @param subCommand
* the subCommand to set
*/
public final void setSubCommand ( byte subCommand ) {
this.subCommand = subCommand;
}
@Override
public void reset () {
super.reset();
this.isPrimary = this.hasMore = true;
}
protected void reset ( int key, String lastName ) {
reset();
}
@Override
public boolean hasMoreElements () {
return this.hasMore;
}
@Override
public SmbComTransaction nextElement () {
if ( this.isPrimary ) {
this.isPrimary = false;
// primarySetupOffset
// SMB_COM_TRANSACTION: 61 = 32 SMB header + 1 (word count) + 28 (fixed words)
// SMB_COM_NT_TRANSACTION: 69 = 32 SMB header + 1 (word count) + 38 (fixed words)
this.parameterOffset = this.primarySetupOffset;
// 2* setupCount
this.parameterOffset += this.setupCount * 2;
this.parameterOffset += 2; // ByteCount
if ( this.getCommand() == SMB_COM_TRANSACTION && isResponse() == false ) {
this.parameterOffset += stringWireLength(this.name, this.parameterOffset);
}
this.pad1 = pad(this.parameterOffset);
this.parameterOffset += this.pad1;
this.totalParameterCount = writeParametersWireFormat(this.txn_buf, this.bufParameterOffset);
this.bufDataOffset = this.totalParameterCount; // data comes right after data
int available = this.maxBufferSize - this.parameterOffset;
this.parameterCount = Math.min(this.totalParameterCount, available);
available -= this.parameterCount;
this.dataOffset = this.parameterOffset + this.parameterCount;
this.pad2 = this.pad(this.dataOffset);
this.dataOffset += this.pad2;
this.totalDataCount = writeDataWireFormat(this.txn_buf, this.bufDataOffset);
this.dataCount = Math.min(this.totalDataCount, available);
}
else {
if ( this.getCommand() != SMB_COM_NT_TRANSACT ) {
this.setCommand(SMB_COM_TRANSACTION_SECONDARY);
}
else {
this.setCommand(SMB_COM_NT_TRANSACT_SECONDARY);
}
// totalParameterCount and totalDataCount are set ok from primary
this.parameterOffset = SECONDARY_PARAMETER_OFFSET;
if ( ( this.totalParameterCount - this.parameterDisplacement ) > 0 ) {
this.pad1 = this.pad(this.parameterOffset);
this.parameterOffset += this.pad1;
}
// caclulate parameterDisplacement before calculating new parameterCount
this.parameterDisplacement += this.parameterCount;
int available = this.maxBufferSize - this.parameterOffset - this.pad1;
this.parameterCount = Math.min(this.totalParameterCount - this.parameterDisplacement, available);
available -= this.parameterCount;
this.dataOffset = this.parameterOffset + this.parameterCount;
this.pad2 = this.pad(this.dataOffset);
this.dataOffset += this.pad2;
this.dataDisplacement += this.dataCount;
available -= this.pad2;
this.dataCount = Math.min(this.totalDataCount - this.dataDisplacement, available);
}
if ( ( this.parameterDisplacement + this.parameterCount ) >= this.totalParameterCount
&& ( this.dataDisplacement + this.dataCount ) >= this.totalDataCount ) {
this.hasMore = false;
}
return this;
}
/**
* @return
*/
protected int pad ( int offset ) {
int p = offset % getPadding();
if ( p == 0 ) {
return 0;
}
return getPadding() - p;
}
/**
*
* @return padding size
*/
public int getPadding () {
return PADDING_SIZE;
}
@Override
protected int writeParameterWordsWireFormat ( byte[] dst, int dstIndex ) {
int start = dstIndex;
SMBUtil.writeInt2(this.totalParameterCount, dst, dstIndex);
dstIndex += 2;
SMBUtil.writeInt2(this.totalDataCount, dst, dstIndex);
dstIndex += 2;
if ( this.getCommand() != SMB_COM_TRANSACTION_SECONDARY ) {
SMBUtil.writeInt2(this.maxParameterCount, dst, dstIndex);
dstIndex += 2;
SMBUtil.writeInt2(this.maxDataCount, dst, dstIndex);
dstIndex += 2;
dst[ dstIndex++ ] = this.maxSetupCount;
dst[ dstIndex++ ] = (byte) 0x00; // Reserved1
SMBUtil.writeInt2(this.tflags, dst, dstIndex);
dstIndex += 2;
SMBUtil.writeInt4(this.timeout, dst, dstIndex);
dstIndex += 4;
dst[ dstIndex++ ] = (byte) 0x00; // Reserved2
dst[ dstIndex++ ] = (byte) 0x00;
}
SMBUtil.writeInt2(this.parameterCount, dst, dstIndex);
dstIndex += 2;
// writeInt2(( parameterCount == 0 ? 0 : parameterOffset ), dst, dstIndex );
SMBUtil.writeInt2(this.parameterOffset, dst, dstIndex);
dstIndex += 2;
if ( this.getCommand() == SMB_COM_TRANSACTION_SECONDARY ) {
SMBUtil.writeInt2(this.parameterDisplacement, dst, dstIndex);
dstIndex += 2;
}
SMBUtil.writeInt2(this.dataCount, dst, dstIndex);
dstIndex += 2;
SMBUtil.writeInt2( ( this.dataCount == 0 ? 0 : this.dataOffset ), dst, dstIndex);
dstIndex += 2;
if ( this.getCommand() == SMB_COM_TRANSACTION_SECONDARY ) {
SMBUtil.writeInt2(this.dataDisplacement, dst, dstIndex);
dstIndex += 2;
}
else {
dst[ dstIndex++ ] = (byte) this.setupCount;
dst[ dstIndex++ ] = (byte) 0x00; // Reserved3
dstIndex += writeSetupWireFormat(dst, dstIndex);
}
return dstIndex - start;
}
@Override
protected int writeBytesWireFormat ( byte[] dst, int dstIndex ) {
int start = dstIndex;
if ( this.getCommand() == SMB_COM_TRANSACTION && isResponse() == false ) {
dstIndex += writeString(this.name, dst, dstIndex);
}
int end = dstIndex + this.pad1;
if ( this.parameterCount > 0 ) {
System.arraycopy(this.txn_buf, this.bufParameterOffset, dst, this.headerStart + this.parameterOffset, this.parameterCount);
end = Math.max(end, this.headerStart + this.parameterOffset + this.parameterCount + this.pad2);
}
if ( this.dataCount > 0 ) {
System.arraycopy(this.txn_buf, this.bufDataOffset, dst, this.headerStart + this.dataOffset, this.dataCount);
this.bufDataOffset += this.dataCount;
end = Math.max(end, this.headerStart + this.dataOffset + this.dataCount);
}
return end - start;
}
@Override
protected int readParameterWordsWireFormat ( byte[] buffer, int bufferIndex ) {
return 0;
}
@Override
protected int readBytesWireFormat ( byte[] buffer, int bufferIndex ) {
return 0;
}
protected abstract int writeSetupWireFormat ( byte[] dst, int dstIndex );
protected abstract int writeParametersWireFormat ( byte[] dst, int dstIndex );
protected abstract int writeDataWireFormat ( byte[] dst, int dstIndex );
protected abstract int readSetupWireFormat ( byte[] buffer, int bufferIndex, int len );
protected abstract int readParametersWireFormat ( byte[] buffer, int bufferIndex, int len );
protected abstract int readDataWireFormat ( byte[] buffer, int bufferIndex, int len );
@Override
public String toString () {
return new String(
super.toString() + ",totalParameterCount=" + this.totalParameterCount + ",totalDataCount=" + this.totalDataCount + ",maxParameterCount="
+ this.maxParameterCount + ",maxDataCount=" + this.maxDataCount + ",maxSetupCount=" + (int) this.maxSetupCount + ",flags=0x"
+ Hexdump.toHexString(this.tflags, 2) + ",timeout=" + this.timeout + ",parameterCount=" + this.parameterCount
+ ",parameterOffset=" + this.parameterOffset + ",parameterDisplacement=" + this.parameterDisplacement + ",dataCount="
+ this.dataCount + ",dataOffset=" + this.dataOffset + ",dataDisplacement=" + this.dataDisplacement + ",setupCount="
+ this.setupCount + ",pad=" + this.pad1 + ",pad1=" + this.pad2);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy