KickJava   Java API By Example, From Geeks To Geeks.

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


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.NetBIOSSocket;
23 import org.alfresco.filesys.netbios.win32.WinsockError;
24 import org.alfresco.filesys.netbios.win32.WinsockNetBIOSException;
25 import org.alfresco.filesys.smb.server.PacketHandler;
26 import org.alfresco.filesys.smb.server.SMBSrvPacket;
27
28 /**
29  * Winsock NetBIOS Packet Handler Class
30  *
31  * <p>Uses a Windows Winsock NetBIOS socket to provide the low level session layer for better integration
32  * with Windows.
33  *
34  * @author GKSpencer
35  */

36 public class WinsockNetBIOSPacketHandler extends PacketHandler
37 {
38     // Constants
39
//
40
// Receive error indicating a receive buffer error
41

42     private static final int ReceiveBufferSizeError = 0x80000000;
43     
44     // Network LAN adapter to use
45

46     private int m_lana;
47
48     // NetBIOS session socket
49

50     private NetBIOSSocket m_sessSock;
51     
52     /**
53      * Class constructor
54      *
55      * @param lana int
56      * @param sock NetBIOSSocket
57      */

58     public WinsockNetBIOSPacketHandler(int lana, NetBIOSSocket sock)
59     {
60         super(SMBSrvPacket.PROTOCOL_WIN32NETBIOS, "WinsockNB", "WSNB", sock.getName().getName());
61
62         m_lana = lana;
63         m_sessSock = sock;
64     }
65     
66     /**
67      * Return the LANA number
68      *
69      * @return int
70      */

71     public final int getLANA()
72     {
73         return m_lana;
74     }
75
76     /**
77      * Return the NetBIOS socket
78      *
79      * @return NetBIOSSocket
80      */

81     public final NetBIOSSocket getSocket()
82     {
83         return m_sessSock;
84     }
85
86     /**
87      * Read a packet from the client
88      *
89      * @param pkt SMBSrvPacket
90      * @return int
91      * @throws IOException
92      */

93     public int readPacket(SMBSrvPacket pkt) throws IOException JavaDoc
94     {
95         // Receive an SMB/CIFS request packet via the Winsock NetBIOS socket
96

97         int rxlen = 0;
98         
99         try {
100             
101             // Read a pakcet of data
102

103             rxlen = m_sessSock.read(pkt.getBuffer(), 4, pkt.getBufferLength() - 4);
104             
105             // Check if the buffer is not big enough to receive the entire packet, extend the buffer
106
// and read the remaining part of the packet
107

108             if (rxlen == ReceiveBufferSizeError)
109             {
110                 
111                 // Check if the packet buffer is already at the maximum size (we assume the maximum
112
// size is the maximum that RFC NetBIOS can send which is 17bits)
113

114                 if (pkt.getBuffer().length < RFCNetBIOSProtocol.MaxPacketSize)
115                 {
116                     // Set the initial receive size, assume a full read
117

118                     rxlen = pkt.getBufferLength() - 4;
119                     
120                     // Allocate a new buffer, copy the existing data to the new buffer
121

122                     byte[] newbuf = new byte[RFCNetBIOSProtocol.MaxPacketSize];
123                     System.arraycopy(pkt.getBuffer(), 4, newbuf, 4, rxlen);
124                     pkt.setBuffer( newbuf);
125
126                     // Receive the packet
127

128                     int rxlen2 = m_sessSock.read(pkt.getBuffer(), rxlen + 4, pkt.getBufferLength() - (rxlen + 4));
129
130                     if ( rxlen2 == ReceiveBufferSizeError)
131                         throw new WinsockNetBIOSException(WinsockError.WsaEMsgSize);
132
133                     rxlen += rxlen2;
134                 }
135                 else
136                     throw new WinsockNetBIOSException(WinsockError.WsaEMsgSize);
137             }
138         }
139         catch ( WinsockNetBIOSException ex)
140         {
141             // Check if the remote client has closed the socket
142

143             if ( ex.getErrorCode() == WinsockError.WsaEConnReset)
144             {
145                 // Indicate that the socket has been closed
146

147                 rxlen = -1;
148             }
149             else
150             {
151                 // Rethrow the exception
152

153                 throw ex;
154             }
155         }
156         
157         // Return the received packet length
158

159         return rxlen;
160     }
161
162     /**
163      * Write a packet to the client
164      *
165      * @param pkt SMBSrvPacket
166      * @param len int
167      * @throws IOException
168      */

169     public void writePacket(SMBSrvPacket pkt, int len) throws IOException JavaDoc
170     {
171         // Output the packet via the Winsock NetBIOS socket
172
//
173
// As Windows is handling the NetBIOS session layer we do not send the 4 byte header that is
174
// used by the NetBIOS over TCP/IP and native SMB packet handlers.
175

176         int txlen = m_sessSock.write(pkt.getBuffer(), 4, len);
177
178         // Do not check the status, if the session has been closed the next receive will fail
179
}
180     
181     /**
182      * Close the Winsock NetBIOS packet handler.
183      */

184     public void closeHandler()
185     {
186         super.closeHandler();
187
188         // Close the session socket
189

190         if ( m_sessSock != null)
191             m_sessSock.closeSocket();
192     }
193 }
194
Popular Tags