001: /* jcifs smb client library in Java
002: * Copyright (C) 2000 "Michael B. Allen" <jcifs at samba dot org>
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2.1 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: */
018:
019: package com.knowgate.jcifs.smb;
020:
021: import java.util.Enumeration;
022: import com.knowgate.jcifs.Config;
023: import com.knowgate.misc.Gadgets;
024:
025: abstract class SmbComTransaction extends ServerMessageBlock implements
026: Enumeration {
027:
028: private static final int DEFAULT_MAX_DATA_COUNT = Config.getInt(
029: "jcifs.smb.client.transaction_buf_size",
030: SmbComTransaction.TRANSACTION_BUF_SIZE) - 512;
031:
032: // relative to headerStart
033: private static final int PRIMARY_SETUP_OFFSET = 61;
034: private static final int SECONDARY_PARAMETER_OFFSET = 51;
035:
036: private static final int DISCONNECT_TID = 0x01;
037: private static final int ONE_WAY_TRANSACTION = 0x02;
038:
039: private static final int PADDING_SIZE = 2;
040:
041: private int flags = 0x00;
042: private int parameterCount;
043: private int parameterOffset;
044: private int parameterDisplacement;
045: private int dataCount;
046: private int dataOffset;
047: private int dataDisplacement;
048: private int fid;
049: private int pad = 0;
050: private int pad1 = 0;
051: private boolean hasMore = true;
052: private boolean isPrimary = true;
053: private int bufParameterOffset;
054: private int bufDataOffset;
055:
056: static final int TRANSACTION_BUF_SIZE = 0xFFFF;
057:
058: static final byte TRANS2_FIND_FIRST2 = (byte) 0x01;
059: static final byte TRANS2_FIND_NEXT2 = (byte) 0x02;
060: static final byte TRANS2_QUERY_FS_INFORMATION = (byte) 0x03;
061: static final byte TRANS2_QUERY_PATH_INFORMATION = (byte) 0x05;
062: static final byte TRANS2_GET_DFS_REFERRAL = (byte) 0x10;
063: static final byte TRANS2_SET_FILE_INFORMATION = (byte) 0x08;
064:
065: static final int NET_SHARE_ENUM = 0x0000;
066: static final int NET_SERVER_ENUM2 = 0x0068;
067: static final int NET_SERVER_ENUM3 = 0x00D7;
068:
069: static final byte TRANS_PEEK_NAMED_PIPE = (byte) 0x23;
070: static final byte TRANS_WAIT_NAMED_PIPE = (byte) 0x53;
071: static final byte TRANS_CALL_NAMED_PIPE = (byte) 0x54;
072: static final byte TRANS_TRANSACT_NAMED_PIPE = (byte) 0x26;
073:
074: int totalParameterCount;
075: int totalDataCount;
076: int maxParameterCount;
077: int maxDataCount = DEFAULT_MAX_DATA_COUNT;
078: byte maxSetupCount;
079: int timeout = 0;
080: int setupCount = 1;
081: byte subCommand;
082: String name = "";
083: int maxBufferSize; // set in SmbTransport.sendTransaction() before nextElement called
084:
085: byte[] txn_buf;
086:
087: SmbComTransaction() {
088: maxParameterCount = 1024;
089: }
090:
091: void reset() {
092: isPrimary = hasMore = true;
093: }
094:
095: void reset(int key, String lastName) {
096: reset();
097: }
098:
099: public boolean hasMoreElements() {
100: return hasMore;
101: }
102:
103: public Object nextElement() {
104: if (isPrimary) {
105: isPrimary = false;
106:
107: parameterOffset = PRIMARY_SETUP_OFFSET + (setupCount * 2)
108: + 2;
109: if (command == SMB_COM_TRANSACTION && isResponse() == false) {
110: parameterOffset += stringWireLength(name,
111: parameterOffset);
112: }
113: pad = parameterOffset % PADDING_SIZE;
114: pad = pad == 0 ? 0 : PADDING_SIZE - pad;
115: parameterOffset += pad;
116:
117: totalParameterCount = writeParametersWireFormat(txn_buf,
118: bufParameterOffset);
119: bufDataOffset = totalParameterCount; // data comes right after data
120:
121: int available = maxBufferSize - parameterOffset;
122: parameterCount = Math.min(totalParameterCount, available);
123: available -= parameterCount;
124:
125: dataOffset = parameterOffset + parameterCount;
126: pad1 = dataOffset % PADDING_SIZE;
127: pad1 = pad1 == 0 ? 0 : PADDING_SIZE - pad1;
128: dataOffset += pad1;
129:
130: totalDataCount = writeDataWireFormat(txn_buf, bufDataOffset);
131:
132: dataCount = Math.min(totalDataCount, available);
133: } else {
134: command = SMB_COM_TRANSACTION_SECONDARY;
135: // totalParameterCount and totalDataCount are set ok from primary
136:
137: parameterOffset = SECONDARY_PARAMETER_OFFSET;
138: if ((totalParameterCount - parameterDisplacement) > 0) {
139: pad = parameterOffset % PADDING_SIZE;
140: pad = pad == 0 ? 0 : PADDING_SIZE - pad;
141: parameterOffset += pad;
142: }
143:
144: // caclulate parameterDisplacement before calculating new parameterCount
145: parameterDisplacement += parameterCount;
146:
147: int available = maxBufferSize - parameterOffset - pad;
148: parameterCount = Math.min(totalParameterCount
149: - parameterDisplacement, available);
150: available -= parameterCount;
151:
152: dataOffset = parameterOffset + parameterCount;
153: pad1 = dataOffset % PADDING_SIZE;
154: pad1 = pad1 == 0 ? 0 : PADDING_SIZE - pad1;
155: dataOffset += pad1;
156:
157: dataDisplacement += dataCount;
158:
159: available -= pad1;
160: dataCount = Math.min(totalDataCount - dataDisplacement,
161: available);
162: }
163: if ((parameterDisplacement + parameterCount) >= totalParameterCount
164: && (dataDisplacement + dataCount) >= totalDataCount) {
165: hasMore = false;
166: }
167: return this ;
168: }
169:
170: int writeParameterWordsWireFormat(byte[] dst, int dstIndex) {
171: int start = dstIndex;
172:
173: writeInt2(totalParameterCount, dst, dstIndex);
174: dstIndex += 2;
175: writeInt2(totalDataCount, dst, dstIndex);
176: dstIndex += 2;
177: if (command != SMB_COM_TRANSACTION_SECONDARY) {
178: writeInt2(maxParameterCount, dst, dstIndex);
179: dstIndex += 2;
180: writeInt2(maxDataCount, dst, dstIndex);
181: dstIndex += 2;
182: dst[dstIndex++] = maxSetupCount;
183: dst[dstIndex++] = (byte) 0x00; // Reserved1
184: writeInt2(flags, dst, dstIndex);
185: dstIndex += 2;
186: writeInt4(timeout, dst, dstIndex);
187: dstIndex += 4;
188: dst[dstIndex++] = (byte) 0x00; // Reserved2
189: dst[dstIndex++] = (byte) 0x00;
190: }
191: writeInt2(parameterCount, dst, dstIndex);
192: dstIndex += 2;
193: writeInt2((parameterCount == 0 ? 0 : parameterOffset), dst,
194: dstIndex);
195: dstIndex += 2;
196: if (command == SMB_COM_TRANSACTION_SECONDARY) {
197: writeInt2(parameterDisplacement, dst, dstIndex);
198: dstIndex += 2;
199: }
200: writeInt2(dataCount, dst, dstIndex);
201: dstIndex += 2;
202: writeInt2((dataCount == 0 ? 0 : dataOffset), dst, dstIndex);
203: dstIndex += 2;
204: if (command == SMB_COM_TRANSACTION_SECONDARY) {
205: writeInt2(dataDisplacement, dst, dstIndex);
206: dstIndex += 2;
207: } else {
208: dst[dstIndex++] = (byte) setupCount;
209: dst[dstIndex++] = (byte) 0x00; // Reserved3
210: dstIndex += writeSetupWireFormat(dst, dstIndex);
211: }
212:
213: return dstIndex - start;
214: }
215:
216: int writeBytesWireFormat(byte[] dst, int dstIndex) {
217: int start = dstIndex;
218: int p = pad;
219:
220: if (command == SMB_COM_TRANSACTION && isResponse() == false) {
221: dstIndex += writeString(name, dst, dstIndex);
222: }
223:
224: if (parameterCount > 0) {
225: while (p-- > 0) {
226: dst[dstIndex++] = (byte) 0x00; // Pad
227: }
228:
229: System.arraycopy(txn_buf, bufParameterOffset, dst,
230: dstIndex, parameterCount);
231: dstIndex += parameterCount;
232: }
233:
234: if (dataCount > 0) {
235: p = pad1;
236: while (p-- > 0) {
237: dst[dstIndex++] = (byte) 0x00; // Pad1
238: }
239: System.arraycopy(txn_buf, bufDataOffset, dst, dstIndex,
240: dataCount);
241: bufDataOffset += dataCount;
242: dstIndex += dataCount;
243: }
244:
245: return dstIndex - start;
246: }
247:
248: int readParameterWordsWireFormat(byte[] buffer, int bufferIndex) {
249: return 0;
250: }
251:
252: int readBytesWireFormat(byte[] buffer, int bufferIndex) {
253: return 0;
254: }
255:
256: abstract int writeSetupWireFormat(byte[] dst, int dstIndex);
257:
258: abstract int writeParametersWireFormat(byte[] dst, int dstIndex);
259:
260: abstract int writeDataWireFormat(byte[] dst, int dstIndex);
261:
262: abstract int readSetupWireFormat(byte[] buffer, int bufferIndex,
263: int len);
264:
265: abstract int readParametersWireFormat(byte[] buffer,
266: int bufferIndex, int len);
267:
268: abstract int readDataWireFormat(byte[] buffer, int bufferIndex,
269: int len);
270:
271: public String toString() {
272: return new String(super .toString() + ",totalParameterCount="
273: + totalParameterCount + ",totalDataCount="
274: + totalDataCount + ",maxParameterCount="
275: + maxParameterCount + ",maxDataCount=" + maxDataCount
276: + ",maxSetupCount=" + (int) maxSetupCount + ",flags=0x"
277: + Gadgets.toHexString(flags, 2) + ",timeout=" + timeout
278: + ",parameterCount=" + parameterCount
279: + ",parameterOffset=" + parameterOffset
280: + ",parameterDisplacement=" + parameterDisplacement
281: + ",dataCount=" + dataCount + ",dataOffset="
282: + dataOffset + ",dataDisplacement=" + dataDisplacement
283: + ",setupCount=" + setupCount + ",pad=" + pad
284: + ",pad1=" + pad1);
285: }
286: }
|