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.io.IOException;
022: import java.net.UnknownHostException;
023:
024: import com.knowgate.jcifs.UniAddress;
025: import com.knowgate.jcifs.netbios.NbtAddress;
026: import com.knowgate.jcifs.Config;
027:
028: import com.knowgate.debug.DebugFile;
029:
030: class SmbTree {
031:
032: private static final String DEFAULT_SERVICE = Config.getProperty(
033: "jcifs.smb.client.serviceType", "?????");
034:
035: private int tid;
036: private String share;
037:
038: String service = DEFAULT_SERVICE;
039: SmbSession session;
040: boolean treeConnected, inDfs;
041:
042: SmbTree(SmbSession session, String share, String service) {
043: this .session = session;
044: this .share = share.toUpperCase();
045: if (service != null && service.startsWith("??") == false) {
046: this .service = service;
047: }
048: }
049:
050: boolean matches(String share, String service) {
051: return this .share.equalsIgnoreCase(share)
052: && (service == null || service.startsWith("??") || this .service
053: .equalsIgnoreCase(service));
054: }
055:
056: void sendTransaction(SmbComTransaction request,
057: SmbComTransactionResponse response) throws SmbException {
058: // transactions are not batchable
059: treeConnect(null, null);
060: if (service.equals("A:") == false) {
061: switch (((SmbComTransaction) request).subCommand & 0xFF) {
062: case SmbComTransaction.NET_SHARE_ENUM:
063: case SmbComTransaction.NET_SERVER_ENUM2:
064: case SmbComTransaction.NET_SERVER_ENUM3:
065: case SmbComTransaction.TRANS_PEEK_NAMED_PIPE:
066: case SmbComTransaction.TRANS_WAIT_NAMED_PIPE:
067: case SmbComTransaction.TRANS_CALL_NAMED_PIPE:
068: case SmbComTransaction.TRANS_TRANSACT_NAMED_PIPE:
069: case SmbComTransaction.TRANS2_GET_DFS_REFERRAL:
070: break;
071: default:
072: throw new SmbException("Invalid operation for "
073: + service + " service");
074: }
075: }
076: request.tid = tid;
077: if (inDfs && request.path != null && request.path.length() > 0) {
078: request.path = '\\' + session.transport().tconHostName
079: + '\\' + share + request.path;
080: }
081: session.sendTransaction(request, response);
082: }
083:
084: void send(ServerMessageBlock request, ServerMessageBlock response)
085: throws SmbException {
086: if (response != null) {
087: response.received = false;
088: }
089: treeConnect(request, response);
090: if (request == null || (response != null && response.received)) {
091: return;
092: }
093: if (service.equals("A:") == false) {
094: switch (request.command) {
095: case ServerMessageBlock.SMB_COM_OPEN_ANDX:
096: case ServerMessageBlock.SMB_COM_NT_CREATE_ANDX:
097: case ServerMessageBlock.SMB_COM_READ_ANDX:
098: case ServerMessageBlock.SMB_COM_WRITE_ANDX:
099: case ServerMessageBlock.SMB_COM_CLOSE:
100: case ServerMessageBlock.SMB_COM_TREE_DISCONNECT:
101: break;
102: default:
103: throw new SmbException("Invalid operation for "
104: + service + " service");
105: }
106: }
107: request.tid = tid;
108: if (inDfs && request.path != null && request.path.length() > 0) {
109: request.flags2 = ServerMessageBlock.FLAGS2_RESOLVE_PATHS_IN_DFS;
110: request.path = '\\' + session.transport().tconHostName
111: + '\\' + share + request.path;
112: }
113: session.send(request, response);
114: }
115:
116: void treeConnect(ServerMessageBlock andx,
117: ServerMessageBlock andxResponse) throws SmbException {
118: String unc;
119: synchronized (session.transport()) {
120:
121: if (treeConnected) {
122: return;
123: }
124:
125: /* The hostname to use in the path is only known for
126: * sure if the NetBIOS session has been successfully
127: * established.
128: */
129:
130: session.transport.negotiate();
131:
132: unc = "\\\\" + session.transport.tconHostName + '\\'
133: + share;
134:
135: /*
136: * Tree Connect And X Request / Response
137: */
138:
139: if (DebugFile.trace)
140: DebugFile.writeln("treeConnect: unc=" + unc
141: + ",service=" + service);
142:
143: SmbComTreeConnectAndXResponse response = new SmbComTreeConnectAndXResponse(
144: andxResponse);
145: SmbComTreeConnectAndX request = new SmbComTreeConnectAndX(
146: session, unc, service, andx);
147: session.send(request, response);
148:
149: tid = response.tid;
150: service = response.service;
151: inDfs = response.shareIsInDfs;
152: treeConnected = true;
153: }
154: }
155:
156: void treeDisconnect(boolean inError) {
157: synchronized (session.transport) {
158: if (treeConnected == false) {
159: return;
160: }
161: if (!inError) {
162: try {
163: send(new SmbComTreeDisconnect(), null);
164: } catch (SmbException se) {
165: }
166: }
167: treeConnected = false;
168: }
169: }
170:
171: public String toString() {
172: return "SmbTree[share=" + share + ",service=" + service
173: + ",tid=" + tid + ",inDfs=" + inDfs + ",treeConnected="
174: + treeConnected + "]";
175: }
176: }
|