KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > alfresco > filesys > smb > server > win32 > Win32NetBIOSPacketHandler


1 /*
2  * Copyright (C) 2005 Alfresco, Inc.
3  *
4  * Licensed under the Mozilla Public License version 1.1
5  * with a permitted attribution clause. You may obtain a
6  * copy of the License at
7  *
8  * http://www.alfresco.org/legal/license.txt
9  *
10  * Unless required by applicable law or agreed to in writing,
11  * software distributed under the License is distributed on an
12  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13  * either express or implied. See the License for the specific
14  * language governing permissions and limitations under the
15  * License.
16  */

17 package org.alfresco.filesys.smb.server.win32;
18
19 import java.io.IOException JavaDoc;
20
21 import org.alfresco.filesys.netbios.RFCNetBIOSProtocol;
22 import org.alfresco.filesys.netbios.win32.NetBIOS;
23 import org.alfresco.filesys.netbios.win32.Win32NetBIOS;
24 import org.alfresco.filesys.smb.server.PacketHandler;
25 import org.alfresco.filesys.smb.server.SMBSrvPacket;
26
27 /**
28  * Win32 NetBIOS Packet Handler Class
29  *
30  * <p>Uses the Win32 Netbios() call to provide the low level session layer for better integration with
31  * Windows.
32  *
33  * @author GKSpencer
34  */

35 public class Win32NetBIOSPacketHandler extends PacketHandler
36 {
37
38     // Constants
39
//
40
// Receive error encoding and length masks
41

42     private static final int ReceiveErrorMask = 0xFF000000;
43     private static final int ReceiveLengthMask = 0x0000FFFF;
44
45     // Network LAN adapter to use
46

47     private int m_lana;
48
49     // NetBIOS session id
50

51     private int m_lsn;
52
53     /**
54      * Class constructor
55      *
56      * @param lana int
57      * @param lsn int
58      * @param callerName String
59      */

60     public Win32NetBIOSPacketHandler(int lana, int lsn, String JavaDoc callerName)
61     {
62         super(SMBSrvPacket.PROTOCOL_WIN32NETBIOS, "Win32NB", "WNB", callerName);
63
64         m_lana = lana;
65         m_lsn = lsn;
66     }
67
68     /**
69      * Return the LANA number
70      *
71      * @return int
72      */

73     public final int getLANA()
74     {
75         return m_lana;
76     }
77
78     /**
79      * Return the NetBIOS session id
80      *
81      * @return int
82      */

83     public final int getLSN()
84     {
85         return m_lsn;
86     }
87
88     /**
89      * Read a packet from the client
90      *
91      * @param pkt SMBSrvPacket
92      * @return int
93      * @throws IOException
94      */

95     public int readPacket(SMBSrvPacket pkt) throws IOException JavaDoc
96     {
97
98         // Wait for a packet on the Win32 NetBIOS session
99
//
100
// As Windows is handling the NetBIOS session layer we only receive the SMB packet. In order
101
// to be compatible with the other packet handlers we allow for the 4 byte header.
102

103         int pktLen = pkt.getBuffer().length;
104         if (pktLen > NetBIOS.MaxReceiveSize)
105             pktLen = NetBIOS.MaxReceiveSize;
106
107         int rxLen = Win32NetBIOS.Receive(m_lana, m_lsn, pkt.getBuffer(), 4, pktLen - 4);
108
109         if ((rxLen & ReceiveErrorMask) != 0)
110         {
111
112             // Check for an incomplete message status code
113

114             int sts = (rxLen & ReceiveErrorMask) >> 24;
115
116             if (sts == NetBIOS.NRC_Incomp)
117             {
118
119                 // Check if the packet buffer is already at the maximum size (we assume the maximum
120
// size is the maximum that RFC NetBIOS can send which is 17bits)
121

122                 if (pkt.getBuffer().length < RFCNetBIOSProtocol.MaxPacketSize)
123                 {
124
125                     // Allocate a new buffer
126

127                     byte[] newbuf = new byte[RFCNetBIOSProtocol.MaxPacketSize];
128
129                     // Copy the first part of the received data to the new buffer
130

131                     System.arraycopy(pkt.getBuffer(), 4, newbuf, 4, pktLen - 4);
132
133                     // Move the new buffer in as the main packet buffer
134

135                     pkt.setBuffer(newbuf);
136
137                     // DEBUG
138

139                     // Debug.println("readPacket() extended buffer to " + pkt.getBuffer().length);
140
}
141
142                 // Set the original receive size
143

144                 rxLen = (rxLen & ReceiveLengthMask);
145
146                 // Receive the remaining data
147
//
148
// Note: If the second read request is issued with a size of 64K or 64K-4 it returns
149
// with another incomplete status and returns no data.
150

151                 int rxLen2 = Win32NetBIOS.Receive(m_lana, m_lsn, pkt.getBuffer(), rxLen + 4, 32768);
152
153                 if ((rxLen2 & ReceiveErrorMask) != 0)
154                 {
155                     sts = (rxLen2 & ReceiveErrorMask) >> 24;
156                     throw new IOException JavaDoc("Win32 NetBIOS multi-part receive failed, sts=0x" + sts + ", err="
157                             + NetBIOS.getErrorString(sts));
158                 }
159
160                 // Set the total received data length
161

162                 rxLen += rxLen2;
163             }
164             else
165             {
166
167                 // Indicate that the session has closed
168

169                 return -1;
170             }
171         }
172
173         // Return the received data length
174

175         return rxLen;
176     }
177
178     /**
179      * Write a packet to the client
180      *
181      * @param pkt SMBSrvPacket
182      * @param len int
183      * @throws IOException
184      */

185     public void writePacket(SMBSrvPacket pkt, int len) throws IOException JavaDoc
186     {
187
188         // Output the packet on the Win32 NetBIOS session
189
//
190
// As Windows is handling the NetBIOS session layer we do not send the 4 byte header that is
191
// used by the NetBIOS over TCP/IP and native SMB packet handlers.
192

193         int sts = Win32NetBIOS.Send(m_lana, m_lsn, pkt.getBuffer(), 4, len);
194
195         // Do not check the status, if the session has been closed the next receive will fail
196
}
197
198     /**
199      * Close the Win32 NetBIOS packet handler. Hangup the NetBIOS session
200      */

201     public void closeHandler()
202     {
203         super.closeHandler();
204
205         // Hangup the Win32 NetBIOS session
206

207         Win32NetBIOS.Hangup(m_lana, m_lsn);
208     }
209 }
210
Popular Tags