/* * Copyright (C) 2005 Alfresco, Inc. * * Licensed under the Mozilla Public License version 1.1 * with a permitted attribution clause. You may obtain a * copy of the License at * * http://www.alfresco.org/legal/license.txt * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific * language governing permissions and limitations under the * License. */ package org.alfresco.filesys.smb.server; import org.alfresco.filesys.netbios.RFCNetBIOSProtocol; import org.alfresco.filesys.smb.PacketType; import org.alfresco.filesys.util.DataPacker; /** * NT Transaction Packet Class */ public class NTTransPacket extends SMBSrvPacket { // Define the number of standard parameter words/bytes private static final int StandardParams = 19; private static final int ParameterBytes = 36; // 8 x 32bit params + max setup count byte + // setup count byte + reserved word // Standard reply word count private static final int ReplyParams = 18; // Offset to start of NT parameters from start of packet private static final int NTMaxSetupCount = SMBPacket.PARAMWORDS; private static final int NTParams = SMBPacket.PARAMWORDS + 3; private static final int NTSetupCount = NTParams + 32; private static final int NTFunction = NTSetupCount + 1; // Default return parameter/data byte counts private static final int DefaultReturnParams = 4; private static final int DefaultReturnData = 1024; /** * Default constructor */ public NTTransPacket() { super(); } /** * Class constructor * * @param buf byte[] */ public NTTransPacket(byte[] buf) { super(buf); } /** * Copy constructor * * @param pkt NTTransPacket */ public NTTransPacket(NTTransPacket pkt) { super(pkt); } /** * Return the data block size * * @return Data block size in bytes */ public final int getDataLength() { return getNTParameter(6); } /** * Return the data block offset * * @return Data block offset within the SMB packet. */ public final int getDataOffset() { return getNTParameter(7) + RFCNetBIOSProtocol.HEADER_LEN; } /** * Unpack the parameter block * * @return int[] */ public final int[] getParameterBlock() { // Get the parameter count and allocate the parameter buffer int prmcnt = getParameterBlockCount() / 4; // convert to number of ints if (prmcnt <= 0) return null; int[] prmblk = new int[prmcnt]; // Get the offset to the parameter words, add the NetBIOS header length // to the offset. int pos = getParameterBlockOffset(); // Unpack the parameter ints setBytePointer(pos, getByteCount()); for (int idx = 0; idx < prmcnt; idx++) { // Unpack the current parameter value prmblk[idx] = unpackInt(); } // Return the parameter block return prmblk; } /** * Return the total parameter count * * @return int */ public final int getTotalParameterCount() { return getNTParameter(0); } /** * Return the total data count * * @return int */ public final int getTotalDataCount() { return getNTParameter(1); } /** * Return the maximum parameter block length to be returned * * @return int */ public final int getMaximumParameterReturn() { return getNTParameter(2); } /** * Return the maximum data block length to be returned * * @return int */ public final int getMaximumDataReturn() { return getNTParameter(3); } /** * Return the parameter block count * * @return int */ public final int getParameterBlockCount() { return getNTParameter(getCommand() == PacketType.NTTransact ? 4 : 2); } /** * Return the parameter block offset * * @return int */ public final int getParameterBlockOffset() { return getNTParameter(getCommand() == PacketType.NTTransact ? 5 : 3) + RFCNetBIOSProtocol.HEADER_LEN; } /** * Return the paramater block displacement * * @return int */ public final int getParameterBlockDisplacement() { return getNTParameter(4); } /** * Return the data block count * * @return int */ public final int getDataBlockCount() { return getNTParameter(getCommand() == PacketType.NTTransact ? 6 : 5); } /** * Return the data block offset * * @return int */ public final int getDataBlockOffset() { return getNTParameter(getCommand() == PacketType.NTTransact ? 7 : 6) + RFCNetBIOSProtocol.HEADER_LEN; } /** * Return the data block displacment * * @return int */ public final int getDataBlockDisplacement() { return getNTParameter(7); } /** * Get an NT parameter (32bit) * * @param idx int * @return int */ protected final int getNTParameter(int idx) { int pos = NTParams + (4 * idx); return DataPacker.getIntelInt(getBuffer(), pos); } /** * Get the setup parameter count * * @return int */ public final int getSetupCount() { byte[] buf = getBuffer(); return (int) buf[NTSetupCount] & 0xFF; } /** * Return the offset to the setup words data * * @return int */ public final int getSetupOffset() { return NTFunction + 2; } /** * Get the NT transaction function code * * @return int */ public final int getNTFunction() { byte[] buf = getBuffer(); return DataPacker.getIntelShort(buf, NTFunction); } /** * Initialize the transact SMB packet * * @param func NT transaction function code * @param paramblk Parameter block data bytes * @param plen Parameter block data length * @param datablk Data block data bytes * @param dlen Data block data length * @param setupcnt Number of setup parameters */ public final void initTransact(int func, byte[] paramblk, int plen, byte[] datablk, int dlen, int setupcnt) { initTransact(func, paramblk, plen, datablk, dlen, setupcnt, DefaultReturnParams, DefaultReturnData); } /** * Initialize the transact SMB packet * * @param func NT transaction function code * @param paramblk Parameter block data bytes * @param plen Parameter block data length * @param datablk Data block data bytes * @param dlen Data block data length * @param setupcnt Number of setup parameters * @param maxPrm Maximum parameter bytes to return * @param maxData Maximum data bytes to return */ public final void initTransact(int func, byte[] paramblk, int plen, byte[] datablk, int dlen, int setupcnt, int maxPrm, int maxData) { // Set the SMB command and parameter count setCommand(PacketType.NTTransact); setParameterCount(StandardParams + setupcnt); // Initialize the parameters setTotalParameterCount(plen); setTotalDataCount(dlen); setMaximumParameterReturn(maxPrm); setMaximumDataReturn(maxData); setParameterCount(plen); setParameterBlockOffset(0); setDataBlockCount(dlen); setDataBlockOffset(0); setSetupCount(setupcnt); setNTFunction(func); resetBytePointerAlign(); // Pack the parameter block if (paramblk != null) { // Set the parameter block offset, from the start of the SMB packet setParameterBlockOffset(getPosition()); // Pack the parameter block packBytes(paramblk, plen); } // Pack the data block if (datablk != null) { // Align the byte area offset and set the data block offset in the request alignBytePointer(); setDataBlockOffset(getPosition()); // Pack the data block packBytes(datablk, dlen); } // Set the byte count for the SMB packet setByteCount(); } /** * Initialize the NT transaction reply * * @param paramblk Parameter block data bytes * @param plen Parameter block data length * @param datablk Data block data bytes * @param dlen Data block data length */ public final void initTransactReply(byte[] paramblk, int plen, byte[] datablk, int dlen) { // Set the parameter count setParameterCount(ReplyParams); setSetupCount(0); // Initialize the parameters setTotalParameterCount(plen); setTotalDataCount(dlen); setReplyParameterCount(plen); setReplyParameterOffset(0); setReplyParameterDisplacement(0); setReplyDataCount(dlen); setDataBlockOffset(0); setReplyDataDisplacement(0); setSetupCount(0); resetBytePointerAlign(); // Pack the parameter block if (paramblk != null) { // Set the parameter block offset, from the start of the SMB packet setReplyParameterOffset(getPosition() - 4); // Pack the parameter block packBytes(paramblk, plen); } // Pack the data block if (datablk != null) { // Align the byte area offset and set the data block offset in the request alignBytePointer(); setReplyDataOffset(getPosition() - 4); // Pack the data block packBytes(datablk, dlen); } // Set the byte count for the SMB packet setByteCount(); } /** * Initialize the NT transaction reply * * @param paramblk Parameter block data bytes * @param plen Parameter block data length * @param datablk Data block data bytes * @param dlen Data block data length * @param setupCnt Number of setup parameter */ public final void initTransactReply(byte[] paramblk, int plen, byte[] datablk, int dlen, int setupCnt) { // Set the parameter count, add the setup parameter count setParameterCount(ReplyParams + setupCnt); setSetupCount(setupCnt); // Initialize the parameters setTotalParameterCount(plen); setTotalDataCount(dlen); setReplyParameterCount(plen); setReplyParameterOffset(0); setReplyParameterDisplacement(0); setReplyDataCount(dlen); setDataBlockOffset(0); setReplyDataDisplacement(0); setSetupCount(setupCnt); resetBytePointerAlign(); // Pack the parameter block if (paramblk != null) { // Set the parameter block offset, from the start of the SMB packet setReplyParameterOffset(getPosition() - 4); // Pack the parameter block packBytes(paramblk, plen); } // Pack the data block if (datablk != null) { // Align the byte area offset and set the data block offset in the request alignBytePointer(); setReplyDataOffset(getPosition() - 4); // Pack the data block packBytes(datablk, dlen); } // Set the byte count for the SMB packet setByteCount(); } /** * Set the total parameter count * * @param cnt int */ public final void setTotalParameterCount(int cnt) { setNTParameter(0, cnt); } /** * Set the total data count * * @param cnt int */ public final void setTotalDataCount(int cnt) { setNTParameter(1, cnt); } /** * Set the maximum return parameter count * * @param cnt int */ public final void setMaximumParameterReturn(int cnt) { setNTParameter(2, cnt); } /** * Set the maximum return data count * * @param cnt int */ public final void setMaximumDataReturn(int cnt) { setNTParameter(3, cnt); } /** * Set the paramater block count * * @param disp int */ public final void setTransactParameterCount(int cnt) { setNTParameter(4, cnt); } /** * Set the reply parameter byte count * * @param cnt int */ public final void setReplyParameterCount(int cnt) { setNTParameter(2, cnt); } /** * Set the reply parameter offset * * @param off int */ public final void setReplyParameterOffset(int off) { setNTParameter(3, off); } /** * Set the reply parameter bytes displacement * * @param disp int */ public final void setReplyParameterDisplacement(int disp) { setNTParameter(4, disp); } /** * Set the reply data byte count * * @param cnt int */ public final void setReplyDataCount(int cnt) { setNTParameter(5, cnt); } /** * Set the reply data offset * * @param off int */ public final void setReplyDataOffset(int off) { setNTParameter(6, off); } /** * Set the reply data bytes displacement * * @param disp int */ public final void setReplyDataDisplacement(int disp) { setNTParameter(7, disp); } /** * Set the parameter block offset within the packet * * @param off int */ public final void setParameterBlockOffset(int off) { setNTParameter(5, off != 0 ? off - RFCNetBIOSProtocol.HEADER_LEN : 0); } /** * Set the data block count * * @param cnt int */ public final void setDataBlockCount(int cnt) { setNTParameter(6, cnt); } /** * Set the data block offset * * @param disp int */ public final void setDataBlockOffset(int off) { setNTParameter(7, off != 0 ? off - RFCNetBIOSProtocol.HEADER_LEN : 0); } /** * Set an NT parameter (32bit) * * @param idx int * @param val int */ public final void setNTParameter(int idx, int val) { int pos = NTParams + (4 * idx); DataPacker.putIntelInt(val, getBuffer(), pos); } /** * Set the maximum setup parameter count * * @param cnt Maximum count of setup paramater words */ public final void setMaximumSetupCount(int cnt) { byte[] buf = getBuffer(); buf[NTMaxSetupCount] = (byte) cnt; } /** * Set the setup parameter count * * @param cnt Count of setup paramater words */ public final void setSetupCount(int cnt) { byte[] buf = getBuffer(); buf[NTSetupCount] = (byte) cnt; } /** * Set the specified setup parameter * * @param setupIdx Setup parameter index * @param setupVal Setup parameter value */ public final void setSetupParameter(int setupIdx, int setupVal) { int pos = NTSetupCount + 1 + (setupIdx * 2); DataPacker.putIntelShort(setupVal, getBuffer(), pos); } /** * Set the NT transaction function code * * @param func int */ public final void setNTFunction(int func) { byte[] buf = getBuffer(); DataPacker.putIntelShort(func, buf, NTFunction); } /** * Reset the byte/parameter pointer area for packing/unpacking setup paramaters items to the * packet */ public final void resetSetupPointer() { m_pos = NTFunction + 2; m_endpos = m_pos; } /** * Reset the byte/parameter pointer area for packing/unpacking the transaction data block */ public final void resetDataBlockPointer() { m_pos = getDataBlockOffset(); m_endpos = m_pos; } /** * Reset the byte/parameter pointer area for packing/unpacking the transaction paramater block */ public final void resetParameterBlockPointer() { m_pos = getParameterBlockOffset(); m_endpos = m_pos; } }