KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > alfresco > filesys > smb > server > CoreProtocolHandler


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;
18
19 import java.io.IOException JavaDoc;
20
21 import org.alfresco.filesys.netbios.RFCNetBIOSProtocol;
22 import org.alfresco.filesys.server.auth.InvalidUserException;
23 import org.alfresco.filesys.server.auth.SrvAuthenticator;
24 import org.alfresco.filesys.server.core.InvalidDeviceInterfaceException;
25 import org.alfresco.filesys.server.core.ShareType;
26 import org.alfresco.filesys.server.core.SharedDevice;
27 import org.alfresco.filesys.server.filesys.AccessDeniedException;
28 import org.alfresco.filesys.server.filesys.AccessMode;
29 import org.alfresco.filesys.server.filesys.DirectoryNotEmptyException;
30 import org.alfresco.filesys.server.filesys.DiskDeviceContext;
31 import org.alfresco.filesys.server.filesys.DiskInterface;
32 import org.alfresco.filesys.server.filesys.FileAccess;
33 import org.alfresco.filesys.server.filesys.FileAction;
34 import org.alfresco.filesys.server.filesys.FileAttribute;
35 import org.alfresco.filesys.server.filesys.FileExistsException;
36 import org.alfresco.filesys.server.filesys.FileInfo;
37 import org.alfresco.filesys.server.filesys.FileName;
38 import org.alfresco.filesys.server.filesys.FileOpenParams;
39 import org.alfresco.filesys.server.filesys.FileSharingException;
40 import org.alfresco.filesys.server.filesys.FileStatus;
41 import org.alfresco.filesys.server.filesys.NetworkFile;
42 import org.alfresco.filesys.server.filesys.SearchContext;
43 import org.alfresco.filesys.server.filesys.SrvDiskInfo;
44 import org.alfresco.filesys.server.filesys.TooManyConnectionsException;
45 import org.alfresco.filesys.server.filesys.TooManyFilesException;
46 import org.alfresco.filesys.server.filesys.TreeConnection;
47 import org.alfresco.filesys.server.filesys.VolumeInfo;
48 import org.alfresco.filesys.smb.Capability;
49 import org.alfresco.filesys.smb.DataType;
50 import org.alfresco.filesys.smb.InvalidUNCPathException;
51 import org.alfresco.filesys.smb.PCShare;
52 import org.alfresco.filesys.smb.PacketType;
53 import org.alfresco.filesys.smb.SMBDate;
54 import org.alfresco.filesys.smb.SMBStatus;
55 import org.alfresco.filesys.util.DataPacker;
56 import org.alfresco.filesys.util.WildCard;
57 import org.apache.commons.logging.Log;
58 import org.apache.commons.logging.LogFactory;
59
60 /**
61  * Core SMB protocol handler class.
62  */

63 class CoreProtocolHandler extends ProtocolHandler
64 {
65
66     // Debug logging
67

68     private static final Log logger = LogFactory.getLog("org.alfresco.smb.protocol");
69
70     // Special resume ids for '.' and '..' pseudo directories
71

72     private static final int RESUME_START = 0x00008003;
73     private static final int RESUME_DOT = 0x00008002;
74     private static final int RESUME_DOTDOT = 0x00008001;
75
76     // Maximum value that can be stored in a parameter word
77

78     private static final int MaxWordValue = 0x0000FFFF;
79
80     // SMB packet class
81

82     protected SMBSrvPacket m_smbPkt;
83
84     /**
85      * Create a new core SMB protocol handler.
86      */

87     protected CoreProtocolHandler()
88     {
89     }
90
91     /**
92      * Class constructor
93      *
94      * @param sess SMBSrvSession
95      */

96     protected CoreProtocolHandler(SMBSrvSession sess)
97     {
98         super(sess);
99     }
100
101     /**
102      * Return the protocol name
103      *
104      * @return String
105      */

106     public String JavaDoc getName()
107     {
108         return "Core Protocol";
109     }
110
111     /**
112      * Map a Java exception class to an SMB error code, and return an error response to the caller.
113      *
114      * @param ex java.lang.Exception
115      */

116     protected final void MapExceptionToSMBError(Exception JavaDoc ex)
117     {
118
119     }
120
121     /**
122      * Pack file information for a search into the specified buffer.
123      *
124      * @param buf byte[] Buffer to store data.
125      * @param bufpos int Position to start storing data.
126      * @param searchStr Search context string.
127      * @param resumeId int Resume id
128      * @param searchId Search context id
129      * @param info File data to be packed.
130      * @return int Next available buffer position.
131      */

132     protected final int packSearchInfo(byte[] buf, int bufPos, String JavaDoc searchStr, int resumeId, int searchId,
133             FileInfo info)
134     {
135
136         // Pack the resume key
137

138         CoreResumeKey.putResumeKey(buf, bufPos, searchStr, resumeId + (searchId << 16));
139         bufPos += CoreResumeKey.LENGTH;
140
141         // Pack the file information
142

143         buf[bufPos++] = (byte) (info.getFileAttributes() & 0x00FF);
144
145         SMBDate dateTime = new SMBDate(info.getModifyDateTime());
146         if (dateTime != null)
147         {
148             DataPacker.putIntelShort(dateTime.asSMBTime(), buf, bufPos);
149             DataPacker.putIntelShort(dateTime.asSMBDate(), buf, bufPos + 2);
150         }
151         else
152         {
153             DataPacker.putIntelShort(0, buf, bufPos);
154             DataPacker.putIntelShort(0, buf, bufPos + 2);
155         }
156         bufPos += 4;
157
158         DataPacker.putIntelInt((int) info.getSize(), buf, bufPos);
159         bufPos += 4;
160
161         StringBuffer JavaDoc strBuf = new StringBuffer JavaDoc();
162         strBuf.append(info.getFileName());
163
164         while (strBuf.length() < 13)
165             strBuf.append('\0');
166
167         if (strBuf.length() > 12)
168             strBuf.setLength(12);
169
170         DataPacker.putString(strBuf.toString().toUpperCase(), buf, bufPos, true);
171         bufPos += 13;
172
173         // Return the new buffer position
174

175         return bufPos;
176     }
177
178     /**
179      * Check if the specified path exists, and is a directory.
180      *
181      * @param outPkt SMBSrvPacket
182      * @exception java.io.IOException If an I/O error occurs
183      * @exception SMBSrvException if an SMB protocol error occurs
184      */

185     protected void procCheckDirectory(SMBSrvPacket outPkt) throws java.io.IOException JavaDoc, SMBSrvException
186     {
187
188         // Check that the received packet looks like a valid check directory request
189

190         if (m_smbPkt.checkPacketIsValid(0, 2) == false)
191         {
192             m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv);
193             return;
194         }
195
196         // Get the tree id from the received packet and validate that it is a valid
197
// connection id.
198

199         int treeId = m_smbPkt.getTreeId();
200         TreeConnection conn = m_sess.findConnection(treeId);
201
202         if (conn == null)
203         {
204             m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos);
205             return;
206         }
207
208         // Check if the user has the required access permission
209

210         if (conn.hasReadAccess() == false)
211         {
212
213             // User does not have the required access rights
214

215             m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
216             return;
217         }
218
219         // Get the data bytes position and length
220

221         int dataPos = m_smbPkt.getByteOffset();
222         int dataLen = m_smbPkt.getByteCount();
223         byte[] buf = m_smbPkt.getBuffer();
224
225         // Extract the directory name
226

227         String JavaDoc dirName = DataPacker.getDataString(DataType.ASCII, buf, dataPos, dataLen, m_smbPkt.isUnicode());
228         if (dirName == null)
229         {
230             m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos);
231             return;
232         }
233
234         // Debug
235

236         if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE))
237             logger.debug("Directory Check [" + treeId + "] name=" + dirName);
238
239         // Access the disk interface and check for the directory
240

241         try
242         {
243
244             // Access the disk interface that is associated with the shared device
245

246             DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface();
247
248             // Check that the specified path exists, and it is a directory
249

250             if (disk.fileExists(m_sess, conn, dirName) == FileStatus.DirectoryExists)
251             {
252
253                 // The path exists and is a directory, build the valid path response.
254

255                 outPkt.setParameterCount(0);
256                 outPkt.setByteCount(0);
257
258                 // Send the response packet
259

260                 m_sess.sendResponseSMB(outPkt);
261             }
262             else
263             {
264
265                 // The path does not exist, or is not a directory.
266
//
267
// DOS clients depend on the 'Directory Invalid' (SMB_ERR_BAD_PATH) message being
268
// returned.
269

270                 m_sess.sendErrorResponseSMB(SMBStatus.DOSDirectoryInvalid, SMBStatus.ErrDos);
271             }
272         }
273         catch (InvalidDeviceInterfaceException ex)
274         {
275
276             // Failed to get/initialize the disk interface
277

278             m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos);
279             return;
280         }
281         catch (java.io.IOException JavaDoc ex)
282         {
283
284             // Failed to delete the directory
285

286             m_sess.sendErrorResponseSMB(SMBStatus.DOSDirectoryInvalid, SMBStatus.ErrDos);
287             return;
288         }
289     }
290
291     /**
292      * Close a file that has been opened on the server.
293      *
294      * @param outPkt Response SMB packet.
295      * @exception java.io.IOException If an I/O error occurs
296      * @exception SMBSrvException If an SMB protocol error occurs
297      */

298     protected void procCloseFile(SMBSrvPacket outPkt) throws java.io.IOException JavaDoc, SMBSrvException
299     {
300
301         // Check that the received packet looks like a valid file close request
302

303         if (m_smbPkt.checkPacketIsValid(3, 0) == false)
304         {
305             m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv);
306             return;
307         }
308
309         // Get the tree id from the received packet and validate that it is a valid
310
// connection id.
311

312         int treeId = m_smbPkt.getTreeId();
313         TreeConnection conn = m_sess.findConnection(treeId);
314
315         if (conn == null)
316         {
317             m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos);
318             return;
319         }
320
321         // Check if the user has the required access permission
322

323         if (conn.hasReadAccess() == false)
324         {
325
326             // User does not have the required access rights
327

328             m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
329             return;
330         }
331
332         // Get the file id from the request
333

334         int fid = m_smbPkt.getParameter(0);
335         int ftime = m_smbPkt.getParameter(1);
336         int fdate = m_smbPkt.getParameter(2);
337
338         NetworkFile netFile = conn.findFile(fid);
339
340         if (netFile == null)
341         {
342             m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos);
343             return;
344         }
345
346         // Debug
347

348         if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE))
349             logger.debug("File close [" + treeId + "] fid=" + fid);
350
351         // Close the file
352

353         try
354         {
355
356             // Access the disk interface that is associated with the shared device
357

358             DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface();
359
360             // Close the file
361
//
362
// The disk interface may be null if the file is a named pipe file
363

364             if (disk != null)
365                 disk.closeFile(m_sess, conn, netFile);
366
367             // Indicate that the file has been closed
368

369             netFile.setClosed(true);
370         }
371         catch (InvalidDeviceInterfaceException ex)
372         {
373
374             // Failed to get/initialize the disk interface
375

376             m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos);
377             return;
378         }
379         catch (java.io.IOException JavaDoc ex)
380         {
381         }
382
383         // Remove the file from the connections list of open files
384

385         conn.removeFile(fid, getSession());
386
387         // Build the close file response
388

389         outPkt.setParameterCount(0);
390         outPkt.setByteCount(0);
391
392         // Send the response packet
393

394         m_sess.sendResponseSMB(outPkt);
395     }
396
397     /**
398      * Create a new directory.
399      *
400      * @param outPkt SMBSrvPacket
401      * @exception java.io.IOException If an I/O error occurs
402      * @exception SMBSrvException If an SMB protocol error occurs
403      */

404     protected void procCreateDirectory(SMBSrvPacket outPkt) throws java.io.IOException JavaDoc, SMBSrvException
405     {
406
407         // Check that the received packet looks like a valid create directory request
408

409         if (m_smbPkt.checkPacketIsValid(0, 2) == false)
410         {
411             m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv);
412             return;
413         }
414
415         // Get the tree id from the received packet and validate that it is a valid
416
// connection id.
417

418         int treeId = m_smbPkt.getTreeId();
419         TreeConnection conn = m_sess.findConnection(treeId);
420
421         if (conn == null)
422         {
423             m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos);
424             return;
425         }
426
427         // Check if the user has the required access permission
428

429         if (conn.hasWriteAccess() == false)
430         {
431
432             // User does not have the required access rights
433

434             m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
435             return;
436         }
437
438         // Get the data bytes position and length
439

440         int dataPos = m_smbPkt.getByteOffset();
441         int dataLen = m_smbPkt.getByteCount();
442         byte[] buf = m_smbPkt.getBuffer();
443
444         // Extract the directory name
445

446         String JavaDoc dirName = DataPacker.getDataString(DataType.ASCII, buf, dataPos, dataLen, m_smbPkt.isUnicode());
447         if (dirName == null)
448         {
449             m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos);
450             return;
451         }
452
453         // Debug
454

455         if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE))
456             logger.debug("Directory Create [" + treeId + "] name=" + dirName);
457
458         // Access the disk interface and create the new directory
459

460         try
461         {
462
463             // Access the disk interface that is associated with the shared device
464

465             DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface();
466
467             // Directory creation parameters
468

469             FileOpenParams params = new FileOpenParams(dirName, FileAction.CreateNotExist, AccessMode.ReadWrite,
470                     FileAttribute.NTDirectory);
471
472             // Create the new directory
473

474             disk.createDirectory(m_sess, conn, params);
475         }
476         catch (InvalidDeviceInterfaceException ex)
477         {
478
479             // Failed to get/initialize the disk interface
480

481             m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos);
482             return;
483         }
484         catch (FileExistsException ex)
485         {
486
487             // Failed to create the directory
488

489             m_sess.sendErrorResponseSMB(SMBStatus.NTObjectNameCollision, SMBStatus.DOSFileAlreadyExists,
490                     SMBStatus.ErrDos);
491             return;
492         }
493         catch (AccessDeniedException ex)
494         {
495
496             // Not allowed to create directory
497

498             m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos);
499             return;
500         }
501         catch (java.io.IOException JavaDoc ex)
502         {
503
504             // Failed to create the directory
505

506             m_sess.sendErrorResponseSMB(SMBStatus.DOSDirectoryInvalid, SMBStatus.ErrDos);
507             return;
508         }
509
510         // Build the create directory response
511

512         outPkt.setParameterCount(0);
513         outPkt.setByteCount(0);
514
515         // Send the response packet
516

517         m_sess.sendResponseSMB(outPkt);
518     }
519
520     /**
521      * Create a new file on the server.
522      *
523      * @param outPkt SMBSrvPacket
524      * @exception java.io.IOException If an I/O error occurs
525      * @exception SMBSrvException If an SMB protocol error occurs
526      */

527     protected void procCreateFile(SMBSrvPacket outPkt) throws java.io.IOException JavaDoc, SMBSrvException
528     {
529
530         // Check that the received packet looks like a valid file create request
531

532         if (m_smbPkt.checkPacketIsValid(3, 2) == false)
533         {
534             m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv);
535             return;
536         }
537
538         // Get the tree id from the received packet and validate that it is a valid
539
// connection id.
540

541         int treeId = m_smbPkt.getTreeId();
542         TreeConnection conn = m_sess.findConnection(treeId);
543
544         if (conn == null)
545         {
546             m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos);
547             return;
548         }
549
550         // Check if the user has the required access permission
551

552         if (conn.hasWriteAccess() == false)
553         {
554
555             // User does not have the required access rights
556

557             m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
558             return;
559         }
560
561         // Get the data bytes position and length
562

563         int dataPos = m_smbPkt.getByteOffset();
564         int dataLen = m_smbPkt.getByteCount();
565         byte[] buf = m_smbPkt.getBuffer();
566
567         // Extract the file name
568

569         String JavaDoc fileName = DataPacker.getDataString(DataType.ASCII, buf, dataPos, dataLen, m_smbPkt.isUnicode());
570         if (fileName == null)
571         {
572             m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos);
573             return;
574         }
575
576         // Get the required file attributes for the new file
577

578         int attr = m_smbPkt.getParameter(0);
579
580         // Create the file parameters to be passed to the disk interface
581

582         FileOpenParams params = new FileOpenParams(fileName, FileAction.CreateNotExist, AccessMode.ReadWrite, attr);
583
584         // Debug
585

586         if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE))
587             logger.debug("File Create [" + treeId + "] params=" + params);
588
589         // Access the disk interface and create the new file
590

591         int fid;
592         NetworkFile netFile = null;
593
594         try
595         {
596
597             // Access the disk interface that is associated with the shared device
598

599             DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface();
600
601             // Create the new file
602

603             netFile = disk.createFile(m_sess, conn, params);
604
605             // Add the file to the list of open files for this tree connection
606

607             fid = conn.addFile(netFile, getSession());
608         }
609         catch (InvalidDeviceInterfaceException ex)
610         {
611
612             // Failed to get/initialize the disk interface
613

614             m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos);
615             return;
616         }
617         catch (TooManyFilesException ex)
618         {
619
620             // Too many files are open on this connection, cannot open any more files.
621

622             m_sess.sendErrorResponseSMB(SMBStatus.DOSTooManyOpenFiles, SMBStatus.ErrDos);
623             return;
624         }
625         catch (FileExistsException ex)
626         {
627
628             // File with the requested name already exists
629

630             m_sess.sendErrorResponseSMB(SMBStatus.DOSFileAlreadyExists, SMBStatus.ErrDos);
631             return;
632         }
633         catch (java.io.IOException JavaDoc ex)
634         {
635
636             // Failed to open the file
637

638             m_sess.sendErrorResponseSMB(SMBStatus.DOSFileNotFound, SMBStatus.ErrDos);
639             return;
640         }
641
642         // Build the create file response
643

644         outPkt.setParameterCount(1);
645         outPkt.setParameter(0, fid);
646         outPkt.setByteCount(0);
647
648         // Send the response packet
649

650         m_sess.sendResponseSMB(outPkt);
651     }
652
653     /**
654      * Create a temporary file.
655      *
656      * @param outPkt SMBSrvPacket
657      * @exception java.io.IOException If an I/O error occurs
658      * @exception SMBSrvException If an SMB protocol error occurs
659      */

660     protected void procCreateTemporaryFile(SMBSrvPacket outPkt) throws java.io.IOException JavaDoc, SMBSrvException
661     {
662
663     }
664
665     /**
666      * Delete a directory.
667      *
668      * @param outPkt SMBSrvPacket
669      * @exception java.io.IOException If an I/O error occurs
670      * @exception SMBSrvException If an SMB protocol error occurs
671      */

672     protected void procDeleteDirectory(SMBSrvPacket outPkt) throws java.io.IOException JavaDoc, SMBSrvException
673     {
674
675         // Check that the received packet looks like a valid delete directory request
676

677         if (m_smbPkt.checkPacketIsValid(0, 2) == false)
678         {
679             m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv);
680             return;
681         }
682
683         // Get the tree id from the received packet and validate that it is a valid
684
// connection id.
685

686         int treeId = m_smbPkt.getTreeId();
687         TreeConnection conn = m_sess.findConnection(treeId);
688
689         if (conn == null)
690         {
691             m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos);
692             return;
693         }
694
695         // Check if the user has the required access permission
696

697         if (conn.hasWriteAccess() == false)
698         {
699
700             // User does not have the required access rights
701

702             m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
703             return;
704         }
705
706         // Get the data bytes position and length
707

708         int dataPos = m_smbPkt.getByteOffset();
709         int dataLen = m_smbPkt.getByteCount();
710         byte[] buf = m_smbPkt.getBuffer();
711
712         // Extract the directory name
713

714         String JavaDoc dirName = DataPacker.getDataString(DataType.ASCII, buf, dataPos, dataLen, m_smbPkt.isUnicode());
715
716         if (dirName == null)
717         {
718             m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos);
719             return;
720         }
721
722         // Debug
723

724         if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE))
725             logger.debug("Directory Delete [" + treeId + "] name=" + dirName);
726
727         // Access the disk interface and delete the directory
728

729         try
730         {
731
732             // Access the disk interface that is associated with the shared device
733

734             DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface();
735
736             // Delete the directory
737

738             disk.deleteDirectory(m_sess, conn, dirName);
739         }
740         catch (InvalidDeviceInterfaceException ex)
741         {
742
743             // Failed to get/initialize the disk interface
744

745             m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos);
746             return;
747         }
748         catch (AccessDeniedException ex)
749         {
750
751             // Not allowed to delete the directory
752

753             m_sess.sendErrorResponseSMB(SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
754             return;
755         }
756         catch (DirectoryNotEmptyException ex)
757         {
758
759             // Directory not empty
760

761             m_sess.sendErrorResponseSMB(SMBStatus.DOSDirectoryNotEmpty, SMBStatus.ErrDos);
762             return;
763         }
764         catch (java.io.IOException JavaDoc ex)
765         {
766
767             // Failed to delete the directory
768

769             m_sess.sendErrorResponseSMB(SMBStatus.DOSDirectoryInvalid, SMBStatus.ErrDos);
770             return;
771         }
772
773         // Build the delete directory response
774

775         outPkt.setParameterCount(0);
776         outPkt.setByteCount(0);
777
778         // Send the response packet
779

780         m_sess.sendResponseSMB(outPkt);
781     }
782
783     /**
784      * Delete a file.
785      *
786      * @param outPkt SMBSrvPacket
787      * @exception java.io.IOException If an I/O error occurs
788      * @exception SMBSrvException If an SMB protocol error occurs
789      */

790     protected void procDeleteFile(SMBSrvPacket outPkt) throws java.io.IOException JavaDoc, SMBSrvException
791     {
792
793         // Check that the received packet looks like a valid file delete request
794

795         if (m_smbPkt.checkPacketIsValid(1, 2) == false)
796         {
797             m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv);
798             return;
799         }
800
801         // Get the tree id from the received packet and validate that it is a valid
802
// connection id.
803

804         int treeId = m_smbPkt.getTreeId();
805         TreeConnection conn = m_sess.findConnection(treeId);
806
807         if (conn == null)
808         {
809             m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos);
810             return;
811         }
812
813         // Check if the user has the required access permission
814

815         if (conn.hasWriteAccess() == false)
816         {
817
818             // User does not have the required access rights
819

820             m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
821             return;
822         }
823
824         // Get the data bytes position and length
825

826         int dataPos = m_smbPkt.getByteOffset();
827         int dataLen = m_smbPkt.getByteCount();
828         byte[] buf = m_smbPkt.getBuffer();
829
830         // Extract the file name
831

832         String JavaDoc fileName = DataPacker.getDataString(DataType.ASCII, buf, dataPos, dataLen, m_smbPkt.isUnicode());
833         if (fileName == null)
834         {
835             m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos);
836             return;
837         }
838
839         // Debug
840

841         if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE))
842             logger.debug("File Delete [" + treeId + "] name=" + fileName);
843
844         // Access the disk interface and delete the file(s)
845

846         int fid;
847         NetworkFile netFile = null;
848
849         try
850         {
851
852             // Access the disk interface that is associated with the shared device
853

854             DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface();
855
856             // Delete file(s)
857

858             disk.deleteFile(m_sess, conn, fileName);
859         }
860         catch (InvalidDeviceInterfaceException ex)
861         {
862
863             // Failed to get/initialize the disk interface
864

865             m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos);
866             return;
867         }
868         catch (java.io.IOException JavaDoc ex)
869         {
870
871             // Failed to open the file
872

873             m_sess.sendErrorResponseSMB(SMBStatus.DOSFileNotFound, SMBStatus.ErrDos);
874             return;
875         }
876
877         // Build the delete file response
878

879         outPkt.setParameterCount(0);
880         outPkt.setByteCount(0);
881
882         // Send the response packet
883

884         m_sess.sendResponseSMB(outPkt);
885     }
886
887     /**
888      * Get disk attributes processing.
889      *
890      * @param outPkt Response SMB packet.
891      * @exception java.io.IOException If an I/O error occurs
892      * @exception SMBSrvException If an SMB protocol error occurs
893      */

894     protected void procDiskAttributes(SMBSrvPacket outPkt) throws java.io.IOException JavaDoc, SMBSrvException
895     {
896
897         // Debug
898

899         if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_INFO))
900             logger.debug("Get disk attributes");
901
902         // Parameter and byte count should be zero
903

904         if (m_smbPkt.getParameterCount() != 0 && m_smbPkt.getByteCount() != 0)
905         {
906
907             // Send an error response
908

909             m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos);
910             return;
911         }
912
913         // Get the tree connection details
914

915         int treeId = m_smbPkt.getTreeId();
916         TreeConnection conn = m_sess.findConnection(treeId);
917
918         if (conn == null)
919         {
920             m_sess.sendErrorResponseSMB(SMBStatus.SRVInvalidTID, SMBStatus.ErrSrv);
921             return;
922         }
923
924         // Check if the user has the required access permission
925

926         if (conn.hasReadAccess() == false)
927         {
928
929             // User does not have the required access rights
930

931             m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
932             return;
933         }
934
935         // Get the disk interface from the shared device
936

937         DiskInterface disk = null;
938         DiskDeviceContext diskCtx = null;
939
940         try
941         {
942             disk = (DiskInterface) conn.getSharedDevice().getInterface();
943             diskCtx = (DiskDeviceContext) conn.getContext();
944         }
945         catch (InvalidDeviceInterfaceException ex)
946         {
947
948             // Failed to get/initialize the disk interface
949

950             m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos);
951             return;
952         }
953
954         // Create a disk information object and ask the disk interface to fill in the details
955

956         SrvDiskInfo diskInfo = getDiskInformation(disk, diskCtx);
957
958         // Debug
959

960         if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_INFO))
961             logger.debug(" Disk info - total=" + diskInfo.getTotalUnits() + ", free=" + diskInfo.getFreeUnits()
962                     + ", blocksPerUnit=" + diskInfo.getBlocksPerAllocationUnit() + ", blockSize="
963                     + diskInfo.getBlockSize());
964
965         // Check if the disk size information needs scaling to fit into 16bit values
966

967         long totUnits = diskInfo.getTotalUnits();
968         long freeUnits = diskInfo.getFreeUnits();
969         int blocksUnit = diskInfo.getBlocksPerAllocationUnit();
970
971         while (totUnits > MaxWordValue && blocksUnit <= MaxWordValue)
972         {
973
974             // Increase the blocks per unit and decrease the total/free units
975

976             blocksUnit *= 2;
977
978             totUnits = totUnits / 2L;
979             freeUnits = freeUnits / 2L;
980         }
981
982         // Check if the total/free units fit into a 16bit value
983

984         if (totUnits > MaxWordValue || blocksUnit > MaxWordValue)
985         {
986
987             // Just use dummy values, cannot fit the disk size into 16bits
988

989             totUnits = MaxWordValue;
990
991             if (freeUnits > MaxWordValue)
992                 freeUnits = MaxWordValue / 2;
993
994             if (blocksUnit > MaxWordValue)
995                 blocksUnit = MaxWordValue;
996         }
997
998         // Build the reply SMB
999

1000        outPkt.setParameterCount(5);
1001
1002        outPkt.setParameter(0, (int) totUnits);
1003        outPkt.setParameter(1, blocksUnit);
1004        outPkt.setParameter(2, diskInfo.getBlockSize());
1005        outPkt.setParameter(3, (int) freeUnits);
1006        outPkt.setParameter(4, 0);
1007
1008        outPkt.setByteCount(0);
1009
1010        // Send the response packet
1011

1012        m_sess.sendResponseSMB(outPkt);
1013    }
1014
1015    /**
1016     * Echo packet request.
1017     *
1018     * @param outPkt SMBSrvPacket
1019     * @exception java.io.IOException If an I/O error occurs
1020     * @exception SMBSrvException If an SMB protocol error occurs
1021     */

1022    protected void procEcho(SMBSrvPacket outPkt) throws java.io.IOException JavaDoc, SMBSrvException
1023    {
1024
1025        // Check that the received packet looks like a valid echo request
1026

1027        if (m_smbPkt.checkPacketIsValid(1, 0) == false)
1028        {
1029            m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv);
1030            return;
1031        }
1032
1033        // Get the echo count from the request
1034

1035        int echoCnt = m_smbPkt.getParameter(0);
1036
1037        // Debug
1038

1039        if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_ECHO))
1040            logger.debug("Echo - Count = " + echoCnt);
1041
1042        // Loop until all echo packets have been sent
1043

1044        int echoSeq = 1;
1045
1046        while (echoCnt > 0)
1047        {
1048
1049            // Set the echo response sequence number
1050

1051            outPkt.setParameter(0, echoSeq++);
1052
1053            // Echo the received packet
1054

1055            m_sess.sendResponseSMB(outPkt);
1056            echoCnt--;
1057
1058            // Debug
1059

1060            if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_ECHO))
1061                logger.debug("Echo Packet, Seq = " + echoSeq);
1062        }
1063    }
1064
1065    /**
1066     * Flush the specified file.
1067     *
1068     * @param outPkt SMBSrvPacket
1069     * @exception java.io.IOException If an I/O error occurs
1070     * @exception SMBSrvException If an SMB protocol error occurs
1071     */

1072    protected void procFlushFile(SMBSrvPacket outPkt) throws java.io.IOException JavaDoc, SMBSrvException
1073    {
1074
1075        // Check that the received packet looks like a valid file flush request
1076

1077        if (m_smbPkt.checkPacketIsValid(1, 0) == false)
1078        {
1079            m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv);
1080            return;
1081        }
1082
1083        // Get the tree id from the received packet and validate that it is a valid
1084
// connection id.
1085

1086        int treeId = m_smbPkt.getTreeId();
1087        TreeConnection conn = m_sess.findConnection(treeId);
1088
1089        if (conn == null)
1090        {
1091            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos);
1092            return;
1093        }
1094
1095        // Check if the user has the required access permission
1096

1097        if (conn.hasWriteAccess() == false)
1098        {
1099
1100            // User does not have the required access rights
1101

1102            m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
1103            return;
1104        }
1105
1106        // Get the file id from the request
1107

1108        int fid = m_smbPkt.getParameter(0);
1109
1110        NetworkFile netFile = conn.findFile(fid);
1111
1112        if (netFile == null)
1113        {
1114            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos);
1115            return;
1116        }
1117
1118        // Debug
1119

1120        if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE))
1121            logger.debug("File Flush [" + netFile.getFileId() + "]");
1122
1123        // Flush the file
1124

1125        try
1126        {
1127
1128            // Access the disk interface that is associated with the shared device
1129

1130            DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface();
1131
1132            // Flush the file
1133

1134            disk.flushFile(m_sess, conn, netFile);
1135        }
1136        catch (InvalidDeviceInterfaceException ex)
1137        {
1138
1139            // Failed to get/initialize the disk interface
1140

1141            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos);
1142            return;
1143        }
1144        catch (java.io.IOException JavaDoc ex)
1145        {
1146
1147            // Debug
1148

1149            if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE))
1150                logger.debug("File Flush Error [" + netFile.getFileId() + "] : " + ex.toString());
1151
1152            // Failed to read the file
1153

1154            m_sess.sendErrorResponseSMB(SMBStatus.HRDWriteFault, SMBStatus.ErrHrd);
1155            return;
1156        }
1157
1158        // Send the flush response
1159

1160        outPkt.setParameterCount(0);
1161        outPkt.setByteCount(0);
1162
1163        m_sess.sendResponseSMB(outPkt);
1164    }
1165
1166    /**
1167     * Get the file attributes for the specified file.
1168     *
1169     * @param outPkt Response SMB packet.
1170     * @exception java.io.IOException If an I/O error occurs
1171     * @exception SMBSrvException If an SMB protocol error occurs
1172     */

1173    protected void procGetFileAttributes(SMBSrvPacket outPkt) throws java.io.IOException JavaDoc, SMBSrvException
1174    {
1175
1176        // Check that the received packet looks like a valid query file information request
1177

1178        if (m_smbPkt.checkPacketIsValid(0, 2) == false)
1179        {
1180            m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv);
1181            return;
1182        }
1183
1184        // Get the tree id from the received packet and validate that it is a valid
1185
// connection id.
1186

1187        int treeId = m_smbPkt.getTreeId();
1188        TreeConnection conn = m_sess.findConnection(treeId);
1189
1190        if (conn == null)
1191        {
1192            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos);
1193            return;
1194        }
1195
1196        // Check if the user has the required access permission
1197

1198        if (conn.hasReadAccess() == false)
1199        {
1200
1201            // User does not have the required access rights
1202

1203            m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
1204            return;
1205        }
1206
1207        // Get the data bytes position and length
1208

1209        int dataPos = m_smbPkt.getByteOffset();
1210        int dataLen = m_smbPkt.getByteCount();
1211        byte[] buf = m_smbPkt.getBuffer();
1212
1213        // Extract the file name
1214

1215        String JavaDoc fileName = DataPacker.getDataString(DataType.ASCII, buf, dataPos, dataLen, m_smbPkt.isUnicode());
1216        if (fileName == null)
1217        {
1218            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos);
1219            return;
1220        }
1221
1222        // Debug
1223

1224        if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE))
1225            logger.debug("Get File Information [" + treeId + "] name=" + fileName);
1226
1227        // Access the disk interface and get the file information
1228

1229        try
1230        {
1231
1232            // Access the disk interface that is associated with the shared device
1233

1234            DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface();
1235
1236            // Get the file information for the specified file/directory
1237

1238            FileInfo finfo = disk.getFileInformation(m_sess, conn, fileName);
1239            if (finfo != null)
1240            {
1241
1242                // Check if the share is read-only, if so then force the read-only flag for the file
1243

1244                if (conn.getSharedDevice().isReadOnly() && finfo.isReadOnly() == false)
1245                {
1246
1247                    // Make sure the read-only attribute is set
1248

1249                    finfo.setFileAttributes(finfo.getFileAttributes() + FileAttribute.ReadOnly);
1250                }
1251
1252                // Return the file information
1253

1254                outPkt.setParameterCount(10);
1255                outPkt.setParameter(0, finfo.getFileAttributes());
1256                if (finfo.getModifyDateTime() != 0L)
1257                {
1258                    SMBDate dateTime = new SMBDate(finfo.getModifyDateTime());
1259                    outPkt.setParameter(1, dateTime.asSMBTime());
1260                    outPkt.setParameter(2, dateTime.asSMBDate());
1261                }
1262                else
1263                {
1264                    outPkt.setParameter(1, 0);
1265                    outPkt.setParameter(2, 0);
1266                }
1267                outPkt.setParameter(3, (int) finfo.getSize() & 0x0000FFFF);
1268                outPkt.setParameter(4, (int) (finfo.getSize() & 0xFFFF0000) >> 16);
1269
1270                for (int i = 5; i < 10; i++)
1271                    outPkt.setParameter(i, 0);
1272
1273                outPkt.setByteCount(0);
1274
1275                // Send the response packet
1276

1277                m_sess.sendResponseSMB(outPkt);
1278                return;
1279            }
1280        }
1281        catch (InvalidDeviceInterfaceException ex)
1282        {
1283
1284            // Failed to get/initialize the disk interface
1285

1286            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos);
1287            return;
1288        }
1289        catch (java.io.IOException JavaDoc ex)
1290        {
1291        }
1292
1293        // Failed to get the file information
1294

1295        m_sess.sendErrorResponseSMB(SMBStatus.DOSFileNotFound, SMBStatus.ErrDos);
1296    }
1297
1298    /**
1299     * Get file information.
1300     *
1301     * @param outPkt SMBSrvPacket
1302     * @exception java.io.IOException If an I/O error occurs
1303     * @exception SMBSrvException If an SMB protocol error occurs
1304     */

1305    protected void procGetFileInformation(SMBSrvPacket outPkt) throws java.io.IOException JavaDoc, SMBSrvException
1306    {
1307
1308        // Check that the received packet looks like a valid query file information2 request
1309

1310        if (m_smbPkt.checkPacketIsValid(1, 0) == false)
1311        {
1312            m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv);
1313            return;
1314        }
1315
1316        // Get the tree id from the received packet and validate that it is a valid
1317
// connection id.
1318

1319        int treeId = m_smbPkt.getTreeId();
1320        TreeConnection conn = m_sess.findConnection(treeId);
1321
1322        if (conn == null)
1323        {
1324            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos);
1325            return;
1326        }
1327
1328        // Check if the user has the required access permission
1329

1330        if (conn.hasReadAccess() == false)
1331        {
1332
1333            // User does not have the required access rights
1334

1335            m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
1336            return;
1337        }
1338
1339        // Get the file id from the request
1340

1341        int fid = m_smbPkt.getParameter(0);
1342        NetworkFile netFile = conn.findFile(fid);
1343
1344        if (netFile == null)
1345        {
1346            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos);
1347            return;
1348        }
1349
1350        // Debug
1351

1352        if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE))
1353            logger.debug("Get File Information 2 [" + netFile.getFileId() + "]");
1354
1355        // Access the disk interface and get the file information
1356

1357        try
1358        {
1359
1360            // Access the disk interface that is associated with the shared device
1361

1362            DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface();
1363
1364            // Get the file information for the specified file/directory
1365

1366            FileInfo finfo = disk.getFileInformation(m_sess, conn, netFile.getFullName());
1367            if (finfo != null)
1368            {
1369
1370                // Check if the share is read-only, if so then force the read-only flag for the file
1371

1372                if (conn.getSharedDevice().isReadOnly() && finfo.isReadOnly() == false)
1373                {
1374
1375                    // Make sure the read-only attribute is set
1376

1377                    finfo.setFileAttributes(finfo.getFileAttributes() + FileAttribute.ReadOnly);
1378                }
1379
1380                // Initialize the return packet, no data bytes
1381

1382                outPkt.setParameterCount(11);
1383                outPkt.setByteCount(0);
1384
1385                // Return the file information
1386
//
1387
// Creation date/time
1388

1389                SMBDate dateTime = new SMBDate(0);
1390
1391                if (finfo.getCreationDateTime() != 0L)
1392                {
1393                    dateTime.setTime(finfo.getCreationDateTime());
1394                    outPkt.setParameter(0, dateTime.asSMBDate());
1395                    outPkt.setParameter(1, dateTime.asSMBTime());
1396                }
1397                else
1398                {
1399                    outPkt.setParameter(0, 0);
1400                    outPkt.setParameter(1, 0);
1401                }
1402
1403                // Access date/time
1404

1405                if (finfo.getAccessDateTime() != 0L)
1406                {
1407                    dateTime.setTime(finfo.getAccessDateTime());
1408                    outPkt.setParameter(2, dateTime.asSMBDate());
1409                    outPkt.setParameter(3, dateTime.asSMBTime());
1410                }
1411                else
1412                {
1413                    outPkt.setParameter(2, 0);
1414                    outPkt.setParameter(3, 0);
1415                }
1416
1417                // Modify date/time
1418

1419                if (finfo.getModifyDateTime() != 0L)
1420                {
1421                    dateTime.setTime(finfo.getModifyDateTime());
1422                    outPkt.setParameter(4, dateTime.asSMBDate());
1423                    outPkt.setParameter(5, dateTime.asSMBTime());
1424                }
1425                else
1426                {
1427                    outPkt.setParameter(4, 0);
1428                    outPkt.setParameter(5, 0);
1429                }
1430
1431                // File data size
1432

1433                outPkt.setParameter(6, (int) finfo.getSize() & 0x0000FFFF);
1434                outPkt.setParameter(7, (int) (finfo.getSize() & 0xFFFF0000) >> 16);
1435
1436                // File allocation size
1437

1438                outPkt.setParameter(8, (int) finfo.getSize() & 0x0000FFFF);
1439                outPkt.setParameter(9, (int) (finfo.getSize() & 0xFFFF0000) >> 16);
1440
1441                // File attributes
1442

1443                outPkt.setParameter(10, finfo.getFileAttributes());
1444
1445                // Send the response packet
1446

1447                m_sess.sendResponseSMB(outPkt);
1448                return;
1449            }
1450        }
1451        catch (InvalidDeviceInterfaceException ex)
1452        {
1453
1454            // Failed to get/initialize the disk interface
1455

1456            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos);
1457            return;
1458        }
1459        catch (java.io.IOException JavaDoc ex)
1460        {
1461        }
1462
1463        // Failed to get the file information
1464

1465        m_sess.sendErrorResponseSMB(SMBStatus.DOSFileNotFound, SMBStatus.ErrDos);
1466    }
1467
1468    /**
1469     * @param outPkt SMBSrvPacket
1470     * @exception java.io.IOException If an I/O error occurs
1471     * @exception SMBSrvException If an SMB protocol error occurs
1472     */

1473    protected void procLockFile(SMBSrvPacket outPkt) throws java.io.IOException JavaDoc, SMBSrvException
1474    {
1475
1476        // Check that the received packet looks like a valid lock file request
1477

1478        if (m_smbPkt.checkPacketIsValid(5, 0) == false)
1479        {
1480            m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv);
1481            return;
1482        }
1483
1484        // Get the tree id from the received packet and validate that it is a valid
1485
// connection id.
1486

1487        int treeId = m_smbPkt.getTreeId();
1488        TreeConnection conn = m_sess.findConnection(treeId);
1489
1490        if (conn == null)
1491        {
1492            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos);
1493            return;
1494        }
1495
1496        // Check if the user has the required access permission
1497

1498        if (conn.hasReadAccess() == false)
1499        {
1500
1501            // User does not have the required access rights
1502

1503            m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
1504            return;
1505        }
1506
1507        // Get the file id from the request
1508

1509        int fid = m_smbPkt.getParameter(0);
1510        long lockcnt = m_smbPkt.getParameterLong(1);
1511        long lockoff = m_smbPkt.getParameterLong(3);
1512
1513        NetworkFile netFile = conn.findFile(fid);
1514
1515        if (netFile == null)
1516        {
1517            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos);
1518            return;
1519        }
1520
1521        // Debug
1522

1523        if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILEIO))
1524            logger.debug("File Lock [" + netFile.getFileId() + "] : Offset=" + lockoff + " ,Count=" + lockcnt);
1525
1526        // ***** Always return a success status, simulated locking ****
1527
//
1528
// Build the lock file response
1529

1530        outPkt.setParameterCount(0);
1531        outPkt.setByteCount(0);
1532
1533        // Send the response packet
1534

1535        m_sess.sendResponseSMB(outPkt);
1536    }
1537
1538    /**
1539     * Open a file on the server.
1540     *
1541     * @param outPkt Response SMB packet.
1542     * @exception java.io.IOException If an I/O error occurs
1543     * @exception SMBSrvException If an SMB protocol error occurs
1544     */

1545    protected void procOpenFile(SMBSrvPacket outPkt) throws IOException JavaDoc, SMBSrvException
1546    {
1547
1548        // Check that the received packet looks like a valid file open request
1549

1550        if (m_smbPkt.checkPacketIsValid(2, 2) == false)
1551        {
1552            m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv);
1553            return;
1554        }
1555
1556        // Get the tree id from the received packet and validate that it is a valid
1557
// connection id.
1558

1559        int treeId = m_smbPkt.getTreeId();
1560        TreeConnection conn = m_sess.findConnection(treeId);
1561
1562        if (conn == null)
1563        {
1564            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos);
1565            return;
1566        }
1567
1568        // Check if the user has the required access permission
1569

1570        if (conn.hasReadAccess() == false)
1571        {
1572
1573            // User does not have the required access rights
1574

1575            m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
1576            return;
1577        }
1578
1579        // Get the data bytes position and length
1580

1581        int dataPos = m_smbPkt.getByteOffset();
1582        int dataLen = m_smbPkt.getByteCount();
1583        byte[] buf = m_smbPkt.getBuffer();
1584
1585        // Extract the file name
1586

1587        String JavaDoc fileName = DataPacker.getDataString(DataType.ASCII, buf, dataPos, dataLen, m_smbPkt.isUnicode());
1588        if (fileName == null)
1589        {
1590            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos);
1591            return;
1592        }
1593
1594        // Get the required access mode and the file attributes
1595

1596        int mode = m_smbPkt.getParameter(0);
1597        int attr = m_smbPkt.getParameter(1);
1598
1599        // Create the file open parameters to be passed to the disk interface
1600

1601        FileOpenParams params = new FileOpenParams(fileName, mode, AccessMode.ReadWrite, attr);
1602        // Debug
1603

1604        if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE))
1605            logger.debug("File Open [" + treeId + "] params=" + params);
1606
1607        // Access the disk interface and open the requested file
1608

1609        int fid;
1610        NetworkFile netFile = null;
1611
1612        try
1613        {
1614
1615            // Access the disk interface that is associated with the shared device
1616

1617            DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface();
1618
1619            // Open the requested file
1620

1621            netFile = disk.openFile(m_sess, conn, params);
1622
1623            // Add the file to the list of open files for this tree connection
1624

1625            fid = conn.addFile(netFile, getSession());
1626        }
1627        catch (InvalidDeviceInterfaceException ex)
1628        {
1629
1630            // Failed to get/initialize the disk interface
1631

1632            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos);
1633            return;
1634        }
1635        catch (TooManyFilesException ex)
1636        {
1637
1638            // Too many files are open on this connection, cannot open any more files.
1639

1640            m_sess.sendErrorResponseSMB(SMBStatus.DOSTooManyOpenFiles, SMBStatus.ErrDos);
1641            return;
1642        }
1643        catch (AccessDeniedException ex)
1644        {
1645
1646            // File is not accessible, or file is actually a directory
1647

1648            m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
1649            return;
1650        }
1651        catch (FileSharingException ex)
1652        {
1653
1654            // Return a sharing violation error
1655

1656            m_sess.sendErrorResponseSMB(SMBStatus.DOSFileSharingConflict, SMBStatus.ErrDos);
1657            return;
1658        }
1659        catch (java.io.IOException JavaDoc ex)
1660        {
1661
1662            // Failed to open the file
1663

1664            m_sess.sendErrorResponseSMB(SMBStatus.DOSFileNotFound, SMBStatus.ErrDos);
1665            return;
1666        }
1667
1668        // Build the open file response
1669

1670        outPkt.setParameterCount(7);
1671
1672        outPkt.setParameter(0, fid);
1673        outPkt.setParameter(1, 0); // file attributes
1674

1675        if (netFile.hasModifyDate())
1676        {
1677            outPkt.setParameterLong(2, (int) (netFile.getModifyDate() / 1000L));
1678
1679            // SMBDate smbDate = new SMBDate(netFile.getModifyDate());
1680
// outPkt.setParameter(2, smbDate.asSMBTime()); // last write time
1681
// outPkt.setParameter(3, smbDate.asSMBDate()); // last write date
1682
}
1683        else
1684            outPkt.setParameterLong(2, 0);
1685
1686        outPkt.setParameterLong(4, netFile.getFileSizeInt()); // file size
1687
outPkt.setParameter(6, netFile.getGrantedAccess());
1688
1689        outPkt.setByteCount(0);
1690
1691        // Send the response packet
1692

1693        m_sess.sendResponseSMB(outPkt);
1694    }
1695
1696    /**
1697     * Process exit, close all open files.
1698     *
1699     * @param outPkt SMBSrvPacket
1700     * @exception java.io.IOException If an I/O error occurs
1701     * @exception SMBSrvException If an SMB protocol error occurs
1702     */

1703    protected void procProcessExit(SMBSrvPacket outPkt) throws java.io.IOException JavaDoc, SMBSrvException
1704    {
1705
1706        // Check that the received packet looks like a valid process exit request
1707

1708        if (m_smbPkt.checkPacketIsValid(0, 0) == false)
1709        {
1710            m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv);
1711            return;
1712        }
1713
1714        // Get the tree id from the received packet and validate that it is a valid
1715
// connection id.
1716

1717        int treeId = m_smbPkt.getTreeId();
1718        TreeConnection conn = m_sess.findConnection(treeId);
1719
1720        if (conn == null)
1721        {
1722            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos);
1723            return;
1724        }
1725
1726        // Debug
1727

1728        if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE))
1729            logger.debug("Process Exit - Open files = " + conn.openFileCount());
1730
1731        // Close all open files
1732

1733        if (conn.openFileCount() > 0)
1734        {
1735
1736            // Close all files on the connection
1737

1738            conn.closeConnection(getSession());
1739        }
1740
1741        // Build the process exit response
1742

1743        outPkt.setParameterCount(0);
1744        outPkt.setByteCount(0);
1745
1746        // Send the response packet
1747

1748        m_sess.sendResponseSMB(outPkt);
1749    }
1750
1751    /**
1752     * Read from a file that has been opened on the server.
1753     *
1754     * @param outPkt Response SMB packet.
1755     * @exception java.io.IOException If an I/O error occurs
1756     * @exception SMBSrvException If an SMB protocol error occurs
1757     */

1758    protected void procReadFile(SMBSrvPacket outPkt) throws java.io.IOException JavaDoc, SMBSrvException
1759    {
1760
1761        // Check that the received packet looks like a valid file read request
1762

1763        if (m_smbPkt.checkPacketIsValid(5, 0) == false)
1764        {
1765            m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv);
1766            return;
1767        }
1768
1769        // Get the tree id from the received packet and validate that it is a valid
1770
// connection id.
1771

1772        int treeId = m_smbPkt.getTreeId();
1773        TreeConnection conn = m_sess.findConnection(treeId);
1774
1775        if (conn == null)
1776        {
1777            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos);
1778            return;
1779        }
1780
1781        // Check if the user has the required access permission
1782

1783        if (conn.hasReadAccess() == false)
1784        {
1785
1786            // User does not have the required access rights
1787

1788            m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
1789            return;
1790        }
1791
1792        // Get the file id from the request
1793

1794        int fid = m_smbPkt.getParameter(0);
1795        int reqcnt = m_smbPkt.getParameter(1);
1796        int reqoff = m_smbPkt.getParameter(2) + (m_smbPkt.getParameter(3) << 16);
1797
1798        NetworkFile netFile = conn.findFile(fid);
1799
1800        if (netFile == null)
1801        {
1802            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos);
1803            return;
1804        }
1805
1806        // Debug
1807

1808        if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILEIO))
1809            logger.debug("File Read [" + netFile.getFileId() + "] : Size=" + reqcnt + " ,Pos=" + reqoff);
1810
1811        // Read data from the file
1812

1813        byte[] buf = outPkt.getBuffer();
1814        int rdlen = 0;
1815
1816        try
1817        {
1818
1819            // Access the disk interface that is associated with the shared device
1820

1821            DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface();
1822
1823            // Check if the required read size will fit into the reply packet
1824

1825            int dataOff = outPkt.getByteOffset() + 3;
1826            int availCnt = buf.length - dataOff;
1827            if (m_sess.hasClientCapability(Capability.LargeRead) == false)
1828                availCnt = m_sess.getClientMaximumBufferSize() - dataOff;
1829
1830            if (availCnt < reqcnt)
1831            {
1832
1833                // Limit the file read size
1834

1835                reqcnt = availCnt;
1836
1837                // Debug
1838

1839                if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILEIO))
1840                    logger.debug("File Read [" + netFile.getFileId() + "] Limited to " + availCnt);
1841            }
1842
1843            // Read from the file
1844

1845            rdlen = disk.readFile(m_sess, conn, netFile, buf, outPkt.getByteOffset() + 3, reqcnt, reqoff);
1846        }
1847        catch (InvalidDeviceInterfaceException ex)
1848        {
1849
1850            // Failed to get/initialize the disk interface
1851

1852            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos);
1853            return;
1854        }
1855        catch (java.io.IOException JavaDoc ex)
1856        {
1857
1858            // Debug
1859

1860            if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILEIO))
1861                logger.debug("File Read Error [" + netFile.getFileId() + "] : " + ex.toString());
1862
1863            // Failed to read the file
1864

1865            m_sess.sendErrorResponseSMB(SMBStatus.HRDReadFault, SMBStatus.ErrHrd);
1866            return;
1867        }
1868
1869        // Return the data block
1870

1871        int bytOff = outPkt.getByteOffset();
1872        buf[bytOff] = (byte) DataType.DataBlock;
1873        DataPacker.putIntelShort(rdlen, buf, bytOff + 1);
1874        outPkt.setByteCount(rdlen + 3); // data type + 16bit length
1875

1876        outPkt.setParameter(0, rdlen);
1877        outPkt.setParameter(1, 0);
1878        outPkt.setParameter(2, 0);
1879        outPkt.setParameter(3, 0);
1880        outPkt.setParameter(4, 0);
1881
1882        // Send the read response
1883

1884        m_sess.sendResponseSMB(outPkt);
1885    }
1886
1887    /**
1888     * Rename a file.
1889     *
1890     * @param outPkt SMBSrvPacket
1891     * @exception java.io.IOException If an I/O error occurs
1892     * @exception SMBSrvException If an SMB protocol error occurs
1893     */

1894    protected void procRenameFile(SMBSrvPacket outPkt) throws java.io.IOException JavaDoc, SMBSrvException
1895    {
1896
1897        // Check that the received packet looks like a valid rename file request
1898

1899        if (m_smbPkt.checkPacketIsValid(1, 4) == false)
1900        {
1901            m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv);
1902            return;
1903        }
1904
1905        // Get the tree id from the received packet and validate that it is a valid
1906
// connection id.
1907

1908        int treeId = m_smbPkt.getTreeId();
1909        TreeConnection conn = m_sess.findConnection(treeId);
1910
1911        if (conn == null)
1912        {
1913            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos);
1914            return;
1915        }
1916
1917        // Check if the user has the required access permission
1918

1919        if (conn.hasWriteAccess() == false)
1920        {
1921
1922            // User does not have the required access rights
1923

1924            m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
1925            return;
1926        }
1927
1928        // Get the data bytes position and length
1929

1930        int dataPos = m_smbPkt.getByteOffset();
1931        int dataLen = m_smbPkt.getByteCount();
1932        byte[] buf = m_smbPkt.getBuffer();
1933
1934        // Extract the old file name
1935

1936        boolean isUni = m_smbPkt.isUnicode();
1937        String JavaDoc oldName = DataPacker.getDataString(DataType.ASCII, buf, dataPos, dataLen, isUni);
1938        if (oldName == null)
1939        {
1940            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos);
1941            return;
1942        }
1943
1944        // Update the data position
1945

1946        if (isUni)
1947        {
1948            int len = (oldName.length() * 2) + 2;
1949            dataPos = DataPacker.wordAlign(dataPos + 1) + len;
1950            dataLen -= len;
1951        }
1952        else
1953        {
1954            dataPos += oldName.length() + 2; // string length + null + data type
1955
dataLen -= oldName.length() + 2;
1956        }
1957
1958        // Extract the new file name
1959

1960        String JavaDoc newName = DataPacker.getDataString(DataType.ASCII, buf, dataPos, dataLen, isUni);
1961        if (newName == null)
1962        {
1963            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos);
1964            return;
1965        }
1966
1967        // Debug
1968

1969        if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE))
1970            logger.debug("File Rename [" + treeId + "] old name=" + oldName + ", new name=" + newName);
1971
1972        // Access the disk interface and rename the requested file
1973

1974        int fid;
1975        NetworkFile netFile = null;
1976
1977        try
1978        {
1979
1980            // Access the disk interface that is associated with the shared device
1981

1982            DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface();
1983
1984            // Rename the requested file
1985

1986            disk.renameFile(m_sess, conn, oldName, newName);
1987        }
1988        catch (InvalidDeviceInterfaceException ex)
1989        {
1990
1991            // Failed to get/initialize the disk interface
1992

1993            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos);
1994            return;
1995        }
1996        catch (java.io.IOException JavaDoc ex)
1997        {
1998
1999            // Failed to open the file
2000

2001            m_sess.sendErrorResponseSMB(SMBStatus.DOSFileNotFound, SMBStatus.ErrDos);
2002            return;
2003        }
2004
2005        // Build the rename file response
2006

2007        outPkt.setParameterCount(0);
2008        outPkt.setByteCount(0);
2009
2010        // Send the response packet
2011

2012        m_sess.sendResponseSMB(outPkt);
2013    }
2014
2015    /**
2016     * Start/continue a directory search operation.
2017     *
2018     * @param outPkt Response SMB packet.
2019     * @exception java.io.IOException If an I/O error occurs
2020     * @exception SMBSrvException If an SMB protocol error occurs
2021     */

2022    protected final void procSearch(SMBSrvPacket outPkt) throws java.io.IOException JavaDoc, SMBSrvException
2023    {
2024
2025        // Check that the received packet looks like a valid search request
2026

2027        if (m_smbPkt.checkPacketIsValid(2, 5) == false)
2028        {
2029            m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv);
2030            return;
2031        }
2032
2033        // Get the tree connection details
2034

2035        int treeId = m_smbPkt.getTreeId();
2036        TreeConnection conn = m_sess.findConnection(treeId);
2037
2038        if (conn == null)
2039        {
2040            m_sess.sendErrorResponseSMB(SMBStatus.SRVInvalidTID, SMBStatus.ErrSrv);
2041            return;
2042        }
2043
2044        // Check if the user has the required access permission
2045

2046        if (conn.hasReadAccess() == false)
2047        {
2048
2049            // User does not have the required access rights
2050

2051            m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
2052            return;
2053        }
2054
2055        // Get the maximum number of entries to return and the search file attributes
2056

2057        int maxFiles = m_smbPkt.getParameter(0);
2058        int srchAttr = m_smbPkt.getParameter(1);
2059
2060        // Check if this is a volume label request
2061

2062        if ((srchAttr & FileAttribute.Volume) != 0)
2063        {
2064
2065            // Process the volume label request
2066

2067            procSearchVolumeLabel(outPkt);
2068            return;
2069        }
2070
2071        // Get the data bytes position and length
2072

2073        int dataPos = m_smbPkt.getByteOffset();
2074        int dataLen = m_smbPkt.getByteCount();
2075        byte[] buf = m_smbPkt.getBuffer();
2076
2077        // Extract the search file name
2078

2079        String JavaDoc srchPath = DataPacker.getDataString(DataType.ASCII, buf, dataPos, dataLen, m_smbPkt.isUnicode());
2080
2081        if (srchPath == null)
2082        {
2083            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidFunc, SMBStatus.ErrDos);
2084            return;
2085        }
2086
2087        // Update the received data position
2088

2089        dataPos += srchPath.length() + 2;
2090        dataLen -= srchPath.length() + 2;
2091
2092        int resumeLen = 0;
2093
2094        if (buf[dataPos++] == DataType.VariableBlock)
2095        {
2096
2097            // Extract the resume key length
2098

2099            resumeLen = DataPacker.getIntelShort(buf, dataPos);
2100
2101            // Adjust remaining the data length and position
2102

2103            dataLen -= 3; // block type + resume key length short
2104
dataPos += 2; // resume key length short
2105

2106            // Check that we received enough data
2107

2108            if (resumeLen > dataLen)
2109            {
2110                m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos);
2111                return;
2112            }
2113        }
2114
2115        // Access the shared devices disk interface
2116

2117        SearchContext ctx = null;
2118        DiskInterface disk = null;
2119
2120        try
2121        {
2122            disk = (DiskInterface) conn.getSharedDevice().getInterface();
2123        }
2124        catch (InvalidDeviceInterfaceException ex)
2125        {
2126
2127            // Failed to get/initialize the disk interface
2128

2129            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos);
2130            return;
2131        }
2132
2133        // Check if this is the start of a new search
2134

2135        byte[] resumeKey = null;
2136        int searchId = -1;
2137
2138        // Default resume point is at the start of the directory, at the '.' directory if
2139
// directories are
2140
// being returned.
2141

2142        int resumeId = RESUME_START;
2143
2144        if (resumeLen == 0 && srchPath.length() > 0)
2145        {
2146
2147            // Allocate a search slot for the new search
2148

2149            searchId = m_sess.allocateSearchSlot();
2150            if (searchId == -1)
2151            {
2152
2153                // Try and find any 'leaked' searches, ie. searches that have been started but not
2154
// closed.
2155
//
2156
// Windows Explorer seems to leak searches after a new folder has been created, a
2157
// search for '????????.???'
2158
// is started but never continued.
2159

2160                int idx = 0;
2161                ctx = m_sess.getSearchContext(idx);
2162
2163                while (ctx != null && searchId == -1)
2164                {
2165
2166                    // Check if the current search context looks like a leaked search.
2167

2168                    if (ctx.getSearchString().compareTo("????????.???") == 0)
2169                    {
2170
2171                        // Debug
2172

2173                        if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH))
2174                            logger.debug("Release leaked search [" + idx + "]");
2175
2176                        // Deallocate the search context
2177

2178                        m_sess.deallocateSearchSlot(idx);
2179
2180                        // Allocate the slot for the new search
2181

2182                        searchId = m_sess.allocateSearchSlot();
2183                    }
2184                    else
2185                    {
2186
2187                        // Update the search index and get the next search context
2188

2189                        ctx = m_sess.getSearchContext(++idx);
2190                    }
2191                }
2192
2193                // Check if we freed up a search slot
2194

2195                if (searchId == -1)
2196                {
2197
2198                    // Failed to allocate a slot for the new search
2199

2200                    m_sess.sendErrorResponseSMB(SMBStatus.SRVNoResourcesAvailable, SMBStatus.ErrSrv);
2201                    return;
2202                }
2203            }
2204
2205            // Debug
2206

2207            if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH))
2208                logger.debug("Start search [" + searchId + "] - " + srchPath + ", attr=0x"
2209                        + Integer.toHexString(srchAttr) + ", maxFiles=" + maxFiles);
2210
2211            // Start a new search
2212

2213            ctx = disk.startSearch(m_sess, conn, srchPath, srchAttr);
2214            if (ctx != null)
2215            {
2216
2217                // Store details of the search in the context
2218

2219                ctx.setTreeId(treeId);
2220                ctx.setMaximumFiles(maxFiles);
2221            }
2222
2223            // Save the search context
2224

2225            m_sess.setSearchContext(searchId, ctx);
2226        }
2227        else
2228        {
2229
2230            // Take a copy of the resume key
2231

2232            resumeKey = new byte[CoreResumeKey.LENGTH];
2233            CoreResumeKey.getResumeKey(buf, dataPos, resumeKey);
2234
2235            // Get the search context slot id from the resume key, and get the search context.
2236

2237            int id = CoreResumeKey.getServerArea(resumeKey, 0);
2238            searchId = (id & 0xFFFF0000) >> 16;
2239            ctx = m_sess.getSearchContext(searchId);
2240
2241            // Check if the search context is valid
2242

2243            if (ctx == null)
2244            {
2245                m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos);
2246                return;
2247            }
2248
2249            // Get the resume id from the resume key
2250

2251            resumeId = id & 0x0000FFFF;
2252
2253            // Restart the search at the resume point, check if the resume point is already set, ie.
2254
// we are just continuing the search.
2255

2256            if (resumeId < RESUME_DOTDOT && ctx.getResumeId() != resumeId)
2257            {
2258
2259                // Debug
2260

2261                if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH))
2262                    logger.debug("Search resume at " + resumeId);
2263
2264                // Restart the search at the specified point
2265

2266                if (ctx.restartAt(resumeId) == false)
2267                {
2268
2269                    // Debug
2270

2271                    if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH))
2272                        logger.debug("Search restart failed");
2273
2274                    // Failed to restart the search
2275

2276                    m_sess.sendErrorResponseSMB(SMBStatus.DOSNoMoreFiles, SMBStatus.ErrDos);
2277
2278                    // Release the search context
2279

2280                    m_sess.deallocateSearchSlot(searchId);
2281                    return;
2282                }
2283            }
2284        }
2285
2286        // Check if the search context is valid
2287

2288        if (ctx == null)
2289        {
2290            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos);
2291            return;
2292        }
2293
2294        // Check that the search context and tree connection match
2295

2296        if (ctx.getTreeId() != treeId)
2297        {
2298            m_sess.sendErrorResponseSMB(SMBStatus.SRVInvalidTID, SMBStatus.ErrSrv);
2299            return;
2300        }
2301
2302        // Start building the search response packet
2303

2304        outPkt.setParameterCount(1);
2305        int bufPos = outPkt.getByteOffset();
2306        buf[bufPos] = (byte) DataType.VariableBlock;
2307        bufPos += 3; // save two bytes for the actual block length
2308
int fileCnt = 0;
2309
2310        // Check if this is the start of a wildcard search and includes directories
2311

2312        if ((srchAttr & FileAttribute.Directory) != 0 && resumeId >= RESUME_DOTDOT
2313                && WildCard.containsWildcards(srchPath))
2314        {
2315
2316            // The first entries in the search should be the '.' and '..' entries for the
2317
// current/parent
2318
// directories.
2319
//
2320
// Remove the file name from the search path, and get the file information for the
2321
// search
2322
// directory.
2323

2324            String JavaDoc workDir = FileName.removeFileName(srchPath);
2325            FileInfo dirInfo = disk.getFileInformation(m_sess, conn, workDir);
2326
2327            // Check if we have valid information for the working directory
2328

2329            if (dirInfo != null)
2330                dirInfo = new FileInfo(".", 0, FileAttribute.Directory);
2331
2332            // Debug
2333

2334            if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH))
2335                logger.debug("Search adding . and .. entries: " + dirInfo.toString());
2336
2337            // Reset the file name to '.' and pack the directory information
2338

2339            if (resumeId == RESUME_START)
2340            {
2341
2342                // Pack the '.' file information
2343

2344                dirInfo.setFileName(".");
2345                resumeId = RESUME_DOT;
2346                bufPos = packSearchInfo(buf, bufPos, ctx.getSearchString(), RESUME_DOT, searchId, dirInfo);
2347
2348                // Update the file count
2349

2350                fileCnt++;
2351            }
2352
2353            // Reset the file name to '..' and pack the directory information
2354

2355            if (resumeId == RESUME_DOT)
2356            {
2357
2358                // Pack the '..' file information
2359

2360                dirInfo.setFileName("..");
2361                bufPos = packSearchInfo(buf, bufPos, ctx.getSearchString(), RESUME_DOTDOT, searchId, dirInfo);
2362
2363                // Update the file count
2364

2365                fileCnt++;
2366            }
2367        }
2368
2369        // Get files from the search and pack into the return packet
2370

2371        FileInfo fileInfo = new FileInfo();
2372
2373        while (fileCnt < ctx.getMaximumFiles() && ctx.nextFileInfo(fileInfo) == true)
2374        {
2375
2376            // Check for . files, ignore them.
2377
//
2378
// ** Should check for . and .. file names **
2379

2380            if (fileInfo.getFileName().startsWith("."))
2381                continue;
2382
2383            // Get the resume id for the current file/directory
2384

2385            resumeId = ctx.getResumeId();
2386
2387            // Debug
2388

2389            if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH))
2390                logger.debug("Search return file " + fileInfo.toString() + ", resumeId=" + resumeId);
2391
2392            // Check if the share is read-only, if so then force the read-only flag for the file
2393

2394            if (conn.getSharedDevice().isReadOnly() && fileInfo.isReadOnly() == false)
2395            {
2396
2397                // Make sure the read-only attribute is set
2398

2399                fileInfo.setFileAttributes(fileInfo.getFileAttributes() + FileAttribute.ReadOnly);
2400            }
2401
2402            // Pack the file information
2403

2404            bufPos = packSearchInfo(buf, bufPos, ctx.getSearchString(), resumeId, searchId, fileInfo);
2405
2406            // Update the file count, reset the current file information
2407

2408            fileCnt++;
2409            fileInfo.resetInfo();
2410        }
2411
2412        // Check if any files were found
2413

2414        if (fileCnt == 0)
2415        {
2416
2417            // Send a repsonse that indicates that the search has finished
2418

2419            outPkt.setParameterCount(1);
2420            outPkt.setParameter(0, 0);
2421            outPkt.setByteCount(0);
2422
2423            outPkt.setErrorClass(SMBStatus.ErrDos);
2424            outPkt.setErrorCode(SMBStatus.DOSNoMoreFiles);
2425
2426            m_sess.sendResponseSMB(outPkt);
2427
2428            // Debug
2429

2430            if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH))
2431                logger.debug("End search [" + searchId + "]");
2432
2433            // Release the search context
2434

2435            m_sess.deallocateSearchSlot(searchId);
2436        }
2437        else
2438        {
2439
2440            // Set the actual data length
2441

2442            dataLen = bufPos - outPkt.getByteOffset();
2443            outPkt.setByteCount(dataLen);
2444
2445            // Set the variable data block length and returned file count parameter
2446

2447            bufPos = outPkt.getByteOffset() + 1;
2448            DataPacker.putIntelShort(dataLen - 3, buf, bufPos);
2449            outPkt.setParameter(0, fileCnt);
2450
2451            // Send the search response packet
2452

2453            m_sess.sendResponseSMB(outPkt);
2454
2455            // Check if the search string contains wildcards and this is the start of a new search,
2456
// if not then
2457
// release the search context now as the client will not continue the search.
2458

2459            if (fileCnt == 1 && resumeLen == 0 && WildCard.containsWildcards(srchPath) == false)
2460            {
2461
2462                // Debug
2463

2464                if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH))
2465                    logger.debug("End search [" + searchId + "] (Not wildcard)");
2466
2467                // Release the search context
2468

2469                m_sess.deallocateSearchSlot(searchId);
2470            }
2471        }
2472    }
2473
2474    /**
2475     * Process a search request that is for the volume label.
2476     *
2477     * @param outPkt SMBSrvPacket
2478     */

2479    protected final void procSearchVolumeLabel(SMBSrvPacket outPkt) throws IOException JavaDoc, SMBSrvException
2480    {
2481
2482        // Get the tree connection details
2483

2484        int treeId = m_smbPkt.getTreeId();
2485        TreeConnection conn = m_sess.findConnection(treeId);
2486
2487        if (conn == null)
2488        {
2489            m_sess.sendErrorResponseSMB(SMBStatus.SRVInvalidTID, SMBStatus.ErrSrv);
2490            return;
2491        }
2492
2493        // Check if the user has the required access permission
2494

2495        if (conn.hasReadAccess() == false)
2496        {
2497
2498            // User does not have the required access rights
2499

2500            m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
2501            return;
2502        }
2503
2504        // Debug
2505

2506        if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH))
2507            logger.debug("Start Search - Volume Label");
2508
2509        // Access the shared devices disk interface
2510

2511        DiskInterface disk = null;
2512        DiskDeviceContext diskCtx = null;
2513
2514        try
2515        {
2516            disk = (DiskInterface) conn.getSharedDevice().getInterface();
2517            diskCtx = (DiskDeviceContext) conn.getContext();
2518        }
2519        catch (InvalidDeviceInterfaceException ex)
2520        {
2521
2522            // Failed to get/initialize the disk interface
2523

2524            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos);
2525            return;
2526        }
2527
2528        // Get the volume label
2529

2530        VolumeInfo volInfo = diskCtx.getVolumeInformation();
2531        String JavaDoc volLabel = "";
2532        if (volInfo != null)
2533            volLabel = volInfo.getVolumeLabel();
2534
2535        // Start building the search response packet
2536

2537        outPkt.setParameterCount(1);
2538        int bufPos = outPkt.getByteOffset();
2539        byte[] buf = outPkt.getBuffer();
2540        buf[bufPos++] = (byte) DataType.VariableBlock;
2541
2542        // Calculate the data length
2543

2544        int dataLen = CoreResumeKey.LENGTH + 22;
2545        DataPacker.putIntelShort(dataLen, buf, bufPos);
2546        bufPos += 2;
2547
2548        // Pack the resume key
2549

2550        CoreResumeKey.putResumeKey(buf, bufPos, volLabel, -1);
2551        bufPos += CoreResumeKey.LENGTH;
2552
2553        // Pack the file information
2554

2555        buf[bufPos++] = (byte) (FileAttribute.Volume & 0x00FF);
2556
2557        // Zero the date/time and file length fields
2558

2559        for (int i = 0; i < 8; i++)
2560            buf[bufPos++] = (byte) 0;
2561
2562        StringBuffer JavaDoc volBuf = new StringBuffer JavaDoc();
2563        volBuf.append(volLabel);
2564
2565        while (volBuf.length() < 13)
2566            volBuf.append(" ");
2567
2568        if (volBuf.length() > 12)
2569            volBuf.setLength(12);
2570
2571        bufPos = DataPacker.putString(volBuf.toString().toUpperCase(), buf, bufPos, true);
2572
2573        // Set the actual data length
2574

2575        dataLen = bufPos - m_smbPkt.getByteOffset();
2576        outPkt.setByteCount(dataLen);
2577
2578        // Send the search response packet
2579

2580        m_sess.sendResponseSMB(outPkt);
2581
2582        // Debug
2583

2584        if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_SEARCH))
2585            logger.debug("Volume label for " + conn.toString() + " is " + volLabel);
2586        return;
2587    }
2588
2589    /**
2590     * Seek to the specified file position within the open file.
2591     *
2592     * @param pkt SMBSrvPacket
2593     */

2594    protected final void procSeekFile(SMBSrvPacket outPkt) throws java.io.IOException JavaDoc, SMBSrvException
2595    {
2596
2597        // Check that the received packet looks like a valid file seek request
2598

2599        if (m_smbPkt.checkPacketIsValid(4, 0) == false)
2600        {
2601            m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv);
2602            return;
2603        }
2604
2605        // Get the tree id from the received packet and validate that it is a valid
2606
// connection id.
2607

2608        int treeId = m_smbPkt.getTreeId();
2609        TreeConnection conn = m_sess.findConnection(treeId);
2610
2611        if (conn == null)
2612        {
2613            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos);
2614            return;
2615        }
2616
2617        // Check if the user has the required access permission
2618

2619        if (conn.hasReadAccess() == false)
2620        {
2621
2622            // User does not have the required access rights
2623

2624            m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
2625            return;
2626        }
2627
2628        // Get the file id from the request
2629

2630        int fid = m_smbPkt.getParameter(0);
2631        int seekMode = m_smbPkt.getParameter(1);
2632        long seekPos = (long) m_smbPkt.getParameterLong(2);
2633
2634        NetworkFile netFile = conn.findFile(fid);
2635
2636        if (netFile == null)
2637        {
2638            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos);
2639            return;
2640        }
2641
2642        // Debug
2643

2644        if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE))
2645            logger.debug("File Seek [" + netFile.getFileId() + "] : Mode = " + seekMode + ", Pos = " + seekPos);
2646
2647        // Seek to the specified position within the file
2648

2649        byte[] buf = outPkt.getBuffer();
2650        long pos = 0;
2651
2652        try
2653        {
2654
2655            // Access the disk interface that is associated with the shared device
2656

2657            DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface();
2658
2659            // Seek to the file position
2660

2661            pos = disk.seekFile(m_sess, conn, netFile, seekPos, seekMode);
2662        }
2663        catch (InvalidDeviceInterfaceException ex)
2664        {
2665
2666            // Failed to get/initialize the disk interface
2667

2668            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos);
2669            return;
2670        }
2671        catch (java.io.IOException JavaDoc ex)
2672        {
2673
2674            // Debug
2675

2676            if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE))
2677                logger.debug("File Seek Error [" + netFile.getFileId() + "] : " + ex.toString());
2678
2679            // Failed to seek the file
2680

2681            m_sess.sendErrorResponseSMB(SMBStatus.HRDReadFault, SMBStatus.ErrHrd);
2682            return;
2683        }
2684
2685        // Return the new file position
2686

2687        outPkt.setParameterCount(2);
2688        outPkt.setParameterLong(0, (int) (pos & 0x0FFFFFFFFL));
2689        outPkt.setByteCount(0);
2690
2691        // Send the seek response
2692

2693        m_sess.sendResponseSMB(outPkt);
2694    }
2695
2696    /**
2697     * Process the SMB session setup request.
2698     *
2699     * @param outPkt Response SMB packet.
2700     */

2701
2702    protected void procSessionSetup(SMBSrvPacket outPkt) throws SMBSrvException, IOException JavaDoc,
2703            TooManyConnectionsException
2704    {
2705
2706        // Build the session setup response SMB
2707

2708        outPkt.setParameterCount(3);
2709        outPkt.setParameter(0, 0);
2710        outPkt.setParameter(1, 0);
2711        outPkt.setParameter(2, 8192);
2712        outPkt.setByteCount(0);
2713
2714        outPkt.setTreeId(0);
2715        outPkt.setUserId(0);
2716
2717        // Pack the OS, dialect and domain name strings.
2718

2719        int pos = outPkt.getByteOffset();
2720        byte[] buf = outPkt.getBuffer();
2721
2722        pos = DataPacker.putString("Java", buf, pos, true);
2723        pos = DataPacker.putString("JLAN Server " + m_sess.getServer().isVersion(), buf, pos, true);
2724        pos = DataPacker.putString(m_sess.getServer().getConfiguration().getDomainName(), buf, pos, true);
2725
2726        outPkt.setByteCount(pos - outPkt.getByteOffset());
2727
2728        // Send the negotiate response
2729

2730        m_sess.sendResponseSMB(outPkt);
2731
2732        // Update the session state
2733

2734        m_sess.setState(SMBSrvSessionState.SMBSESSION);
2735    }
2736
2737    /**
2738     * Set the file attributes for a file.
2739     *
2740     * @param outPkt SMBSrvPacket
2741     * @exception java.io.IOException If an I/O error occurs
2742     * @exception SMBSrvException If an SMB protocol error occurs
2743     */

2744    protected void procSetFileAttributes(SMBSrvPacket outPkt) throws java.io.IOException JavaDoc, SMBSrvException
2745    {
2746
2747        // Check that the received packet looks like a valid set file attributes request
2748

2749        if (m_smbPkt.checkPacketIsValid(8, 0) == false)
2750        {
2751            m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv);
2752            return;
2753        }
2754
2755        // Get the tree id from the received packet and validate that it is a valid
2756
// connection id.
2757

2758        int treeId = m_smbPkt.getTreeId();
2759        TreeConnection conn = m_sess.findConnection(treeId);
2760
2761        if (conn == null)
2762        {
2763            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos);
2764            return;
2765        }
2766
2767        // Check if the user has the required access permission
2768

2769        if (conn.hasWriteAccess() == false)
2770        {
2771
2772            // User does not have the required access rights
2773

2774            m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
2775            return;
2776        }
2777
2778        // Get the data bytes position and length
2779

2780        int dataPos = m_smbPkt.getByteOffset();
2781        int dataLen = m_smbPkt.getByteCount();
2782        byte[] buf = m_smbPkt.getBuffer();
2783
2784        // Extract the file name
2785

2786        String JavaDoc fileName = DataPacker.getDataString(DataType.ASCII, buf, dataPos, dataLen, m_smbPkt.isUnicode());
2787        if (fileName == null)
2788        {
2789            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos);
2790            return;
2791        }
2792
2793        // Get the file attributes
2794

2795        int fattr = m_smbPkt.getParameter(0);
2796        int setFlags = FileInfo.SetAttributes;
2797
2798        FileInfo finfo = new FileInfo(fileName, 0, fattr);
2799
2800        int fdate = m_smbPkt.getParameter(1);
2801        int ftime = m_smbPkt.getParameter(2);
2802
2803        if (fdate != 0 && ftime != 0)
2804        {
2805            finfo.setModifyDateTime(new SMBDate(fdate, ftime).getTime());
2806            setFlags += FileInfo.SetModifyDate;
2807        }
2808
2809        // Debug
2810

2811        if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE))
2812            logger.debug("Set File Attributes [" + treeId + "] name=" + fileName + ", attr=0x"
2813                    + Integer.toHexString(fattr) + ", fdate=" + fdate + ", ftime=" + ftime);
2814
2815        // Access the disk interface and set the file attributes
2816

2817        try
2818        {
2819
2820            // Access the disk interface that is associated with the shared device
2821

2822            DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface();
2823
2824            // Get the file information for the specified file/directory
2825

2826            finfo.setFileInformationFlags(setFlags);
2827            disk.setFileInformation(m_sess, conn, fileName, finfo);
2828        }
2829        catch (InvalidDeviceInterfaceException ex)
2830        {
2831
2832            // Failed to get/initialize the disk interface
2833

2834            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos);
2835            return;
2836        }
2837        catch (java.io.IOException JavaDoc ex)
2838        {
2839        }
2840
2841        // Return the set file attributes response
2842

2843        outPkt.setParameterCount(0);
2844        outPkt.setByteCount(0);
2845
2846        // Send the response packet
2847

2848        m_sess.sendResponseSMB(outPkt);
2849    }
2850
2851    /**
2852     * Set file information.
2853     *
2854     * @param outPkt SMBSrvPacket
2855     * @exception java.io.IOException If an I/O error occurs
2856     * @exception SMBSrvException If an SMB protocol error occurs
2857     */

2858    protected void procSetFileInformation(SMBSrvPacket outPkt) throws java.io.IOException JavaDoc, SMBSrvException
2859    {
2860
2861        // Check that the received packet looks like a valid set file information2 request
2862

2863        if (m_smbPkt.checkPacketIsValid(7, 0) == false)
2864        {
2865            m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv);
2866            return;
2867        }
2868
2869        // Get the tree id from the received packet and validate that it is a valid
2870
// connection id.
2871

2872        int treeId = m_smbPkt.getTreeId();
2873        TreeConnection conn = m_sess.findConnection(treeId);
2874
2875        if (conn == null)
2876        {
2877            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos);
2878            return;
2879        }
2880
2881        // Check if the user has the required access permission
2882

2883        if (conn.hasWriteAccess() == false)
2884        {
2885
2886            // User does not have the required access rights
2887

2888            m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
2889            return;
2890        }
2891
2892        // Get the file id from the request, and get the network file details.
2893

2894        int fid = m_smbPkt.getParameter(0);
2895        NetworkFile netFile = conn.findFile(fid);
2896
2897        if (netFile == null)
2898        {
2899            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos);
2900            return;
2901        }
2902
2903        // Get the creation date/time from the request
2904

2905        int setFlags = 0;
2906        FileInfo finfo = new FileInfo(netFile.getName(), 0, 0);
2907
2908        int fdate = m_smbPkt.getParameter(1);
2909        int ftime = m_smbPkt.getParameter(2);
2910
2911        if (fdate != 0 && ftime != 0)
2912        {
2913            finfo.setCreationDateTime(new SMBDate(fdate, ftime).getTime());
2914            setFlags += FileInfo.SetCreationDate;
2915        }
2916
2917        // Get the last access date/time from the request
2918

2919        fdate = m_smbPkt.getParameter(3);
2920        ftime = m_smbPkt.getParameter(4);
2921
2922        if (fdate != 0 && ftime != 0)
2923        {
2924            finfo.setAccessDateTime(new SMBDate(fdate, ftime).getTime());
2925            setFlags += FileInfo.SetAccessDate;
2926        }
2927
2928        // Get the last write date/time from the request
2929

2930        fdate = m_smbPkt.getParameter(5);
2931        ftime = m_smbPkt.getParameter(6);
2932
2933        if (fdate != 0 && ftime != 0)
2934        {
2935            finfo.setModifyDateTime(new SMBDate(fdate, ftime).getTime());
2936            setFlags += FileInfo.SetModifyDate;
2937        }
2938
2939        // Debug
2940

2941        if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILE))
2942            logger.debug("Set File Information 2 [" + netFile.getFileId() + "] " + finfo.toString());
2943
2944        // Access the disk interface and set the file information
2945

2946        try
2947        {
2948
2949            // Access the disk interface that is associated with the shared device
2950

2951            DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface();
2952
2953            // Get the file information for the specified file/directory
2954

2955            finfo.setFileInformationFlags(setFlags);
2956            disk.setFileInformation(m_sess, conn, netFile.getFullName(), finfo);
2957        }
2958        catch (InvalidDeviceInterfaceException ex)
2959        {
2960
2961            // Failed to get/initialize the disk interface
2962

2963            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos);
2964            return;
2965        }
2966        catch (java.io.IOException JavaDoc ex)
2967        {
2968        }
2969
2970        // Return the set file information response
2971

2972        outPkt.setParameterCount(0);
2973        outPkt.setByteCount(0);
2974
2975        // Send the response packet
2976

2977        m_sess.sendResponseSMB(outPkt);
2978    }
2979
2980    /**
2981     * Process the SMB tree connect request.
2982     *
2983     * @param outPkt Response SMB packet.
2984     * @exception java.io.IOException If an I/O error occurs
2985     * @exception SMBSrvException If an SMB protocol error occurs
2986     * @exception TooManyConnectionsException Too many concurrent connections on this session.
2987     */

2988
2989    protected void procTreeConnect(SMBSrvPacket outPkt) throws SMBSrvException, TooManyConnectionsException,
2990            java.io.IOException JavaDoc
2991    {
2992
2993        // Check that the received packet looks like a valid tree connect request
2994

2995        if (m_smbPkt.checkPacketIsValid(0, 4) == false)
2996        {
2997            m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv);
2998            return;
2999        }
3000
3001        // Get the data bytes position and length
3002

3003        int dataPos = m_smbPkt.getByteOffset();
3004        int dataLen = m_smbPkt.getByteCount();
3005        byte[] buf = m_smbPkt.getBuffer();
3006
3007        // Extract the requested share name, as a UNC path
3008

3009        boolean isUni = m_smbPkt.isUnicode();
3010        String JavaDoc uncPath = DataPacker.getDataString(DataType.ASCII, buf, dataPos, dataLen, isUni);
3011        if (uncPath == null)
3012        {
3013            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos);
3014            return;
3015        }
3016
3017        // Extract the password string
3018

3019        if (isUni)
3020        {
3021            dataPos = DataPacker.wordAlign(dataPos + 1) + (uncPath.length() * 2) + 2;
3022            dataLen -= (uncPath.length() * 2) + 2;
3023        }
3024        else
3025        {
3026            dataPos += uncPath.length() + 2;
3027            dataLen -= uncPath.length() + 2;
3028        }
3029
3030        String JavaDoc pwd = DataPacker.getDataString(DataType.ASCII, buf, dataPos, dataLen, isUni);
3031        if (pwd == null)
3032        {
3033            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos);
3034            return;
3035        }
3036
3037        // Extract the service type string
3038

3039        if (isUni)
3040        {
3041            dataPos = DataPacker.wordAlign(dataPos + 1) + (pwd.length() * 2) + 2;
3042            dataLen -= (pwd.length() * 2) + 2;
3043        }
3044        else
3045        {
3046            dataPos += pwd.length() + 2;
3047            dataLen -= pwd.length() + 2;
3048        }
3049
3050        String JavaDoc service = DataPacker.getDataString(DataType.ASCII, buf, dataPos, dataLen, isUni);
3051        if (service == null)
3052        {
3053            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos);
3054            return;
3055        }
3056
3057        // Convert the service type to a shared device type
3058

3059        int servType = ShareType.ServiceAsType(service);
3060        if (servType == ShareType.UNKNOWN)
3061        {
3062            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos);
3063            return;
3064        }
3065
3066        // Debug
3067

3068        if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TREE))
3069            logger.debug("Tree connect - " + uncPath + ", " + service);
3070
3071        // Parse the requested share name
3072

3073        PCShare share = null;
3074
3075        try
3076        {
3077            share = new PCShare(uncPath);
3078        }
3079        catch (InvalidUNCPathException ex)
3080        {
3081            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos);
3082            return;
3083        }
3084
3085        // Map the IPC$ share to the admin pipe type
3086

3087        if (servType == ShareType.NAMEDPIPE && share.getShareName().compareTo("IPC$") == 0)
3088            servType = ShareType.ADMINPIPE;
3089
3090        // Find the requested shared device
3091

3092        SharedDevice shareDev = null;
3093
3094        try
3095        {
3096
3097            // Get/create the shared device
3098

3099            shareDev = m_sess.getSMBServer().findShare(share.getNodeName(), share.getShareName(), servType,
3100                    getSession(), true);
3101        }
3102        catch (InvalidUserException ex)
3103        {
3104
3105            // Return a logon failure status
3106

3107            m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
3108            return;
3109        }
3110        catch (Exception JavaDoc ex)
3111        {
3112
3113            // Return a general status, bad network name
3114

3115            m_sess.sendErrorResponseSMB(SMBStatus.SRVInvalidNetworkName, SMBStatus.ErrSrv);
3116            return;
3117        }
3118
3119        // Check if the share is valid
3120

3121        if (shareDev == null || shareDev.getType() != servType)
3122        {
3123            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos);
3124            return;
3125        }
3126
3127        // Allocate a tree id for the new connection
3128

3129        int treeId = m_sess.addConnection(shareDev);
3130
3131        // Authenticate the share connection depending upon the security mode the server is running
3132
// under
3133

3134        SrvAuthenticator auth = getSession().getSMBServer().getAuthenticator();
3135        int filePerm = FileAccess.Writeable;
3136
3137        if (auth != null)
3138        {
3139
3140            // Validate the share connection
3141

3142            filePerm = auth.authenticateShareConnect(m_sess.getClientInformation(), shareDev, pwd, m_sess);
3143            if (filePerm < 0)
3144            {
3145
3146                // Invalid share connection request
3147

3148                m_sess.sendErrorResponseSMB(SMBStatus.SRVNoAccessRights, SMBStatus.ErrSrv);
3149                return;
3150            }
3151        }
3152
3153        // Set the file permission that this user has been granted for this share
3154

3155        TreeConnection tree = m_sess.findConnection(treeId);
3156        tree.setPermission(filePerm);
3157
3158        // Build the tree connect response
3159

3160        outPkt.setParameterCount(2);
3161
3162        outPkt.setParameter(0, buf.length - RFCNetBIOSProtocol.HEADER_LEN);
3163        outPkt.setParameter(1, treeId);
3164        outPkt.setByteCount(0);
3165
3166        // Clear any chained request
3167

3168        outPkt.setAndXCommand(0xFF);
3169        m_sess.sendResponseSMB(outPkt);
3170
3171        // Inform the driver that a connection has been opened
3172

3173        if (tree.getInterface() != null)
3174            tree.getInterface().treeOpened(m_sess, tree);
3175    }
3176
3177    /**
3178     * Process the SMB tree disconnect request.
3179     *
3180     * @param outPkt Response SMB packet.
3181     * @exception java.io.IOException If an I/O error occurs
3182     * @exception SMBSrvException If an SMB protocol error occurs
3183     */

3184    protected void procTreeDisconnect(SMBSrvPacket outPkt) throws java.io.IOException JavaDoc, SMBSrvException
3185    {
3186
3187        // Check that the received packet looks like a valid tree disconnect request
3188

3189        if (m_smbPkt.checkPacketIsValid(0, 0) == false)
3190        {
3191            m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv);
3192            return;
3193        }
3194
3195        // Get the tree id from the received packet and validate that it is a valid
3196
// connection id.
3197

3198        int treeId = m_smbPkt.getTreeId();
3199        TreeConnection conn = m_sess.findConnection(treeId);
3200
3201        if (conn == null)
3202        {
3203            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos);
3204            return;
3205        }
3206
3207        // Debug
3208

3209        if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TREE))
3210            logger.debug("Tree disconnect - " + treeId + ", " + conn.toString());
3211
3212        // Remove the specified connection from the session
3213

3214        m_sess.removeConnection(treeId);
3215
3216        // Build the tree disconnect response
3217

3218        outPkt.setParameterCount(0);
3219        outPkt.setByteCount(0);
3220
3221        m_sess.sendResponseSMB(outPkt);
3222
3223        // Inform the driver that a connection has been closed
3224

3225        if (conn.getInterface() != null)
3226            conn.getInterface().treeClosed(m_sess, conn);
3227    }
3228
3229    /**
3230     * Unlock a byte range in the specified file.
3231     *
3232     * @param outPkt SMBSrvPacket
3233     * @exception java.io.IOException If an I/O error occurs
3234     * @exception SMBSrvException If an SMB protocol error occurs
3235     */

3236    protected void procUnLockFile(SMBSrvPacket outPkt) throws java.io.IOException JavaDoc, SMBSrvException
3237    {
3238
3239        // Check that the received packet looks like a valid unlock file request
3240

3241        if (m_smbPkt.checkPacketIsValid(5, 0) == false)
3242        {
3243            m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv);
3244            return;
3245        }
3246
3247        // Get the tree id from the received packet and validate that it is a valid
3248
// connection id.
3249

3250        int treeId = m_smbPkt.getTreeId();
3251        TreeConnection conn = m_sess.findConnection(treeId);
3252
3253        if (conn == null)
3254        {
3255            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos);
3256            return;
3257        }
3258
3259        // Check if the user has the required access permission
3260

3261        if (conn.hasReadAccess() == false)
3262        {
3263
3264            // User does not have the required access rights
3265

3266            m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
3267            return;
3268        }
3269
3270        // Get the file id from the request
3271

3272        int fid = m_smbPkt.getParameter(0);
3273        long lockcnt = m_smbPkt.getParameterLong(1);
3274        long lockoff = m_smbPkt.getParameterLong(3);
3275
3276        NetworkFile netFile = conn.findFile(fid);
3277
3278        if (netFile == null)
3279        {
3280            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos);
3281            return;
3282        }
3283
3284        // Debug
3285

3286        if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILEIO))
3287            logger.debug("File UnLock [" + netFile.getFileId() + "] : Offset=" + lockoff + " ,Count=" + lockcnt);
3288
3289        // ***** Always return a success status, simulated locking ****
3290
//
3291
// Build the unlock file response
3292

3293        outPkt.setParameterCount(0);
3294        outPkt.setByteCount(0);
3295
3296        // Send the response packet
3297

3298        m_sess.sendResponseSMB(outPkt);
3299    }
3300
3301    /**
3302     * Unsupported SMB procesing.
3303     *
3304     * @param outPkt SMBSrvPacket
3305     * @exception java.io.IOException If an I/O error occurs
3306     * @exception SMBSrvException If an SMB protocol error occurs
3307     */

3308    protected final void procUnsupported(SMBSrvPacket outPkt) throws java.io.IOException JavaDoc, SMBSrvException
3309    {
3310
3311        // Send an unsupported error response
3312

3313        m_sess.sendErrorResponseSMB(SMBStatus.SRVNotSupported, SMBStatus.ErrSrv);
3314    }
3315
3316    /**
3317     * Write to a file.
3318     *
3319     * @param outPkt SMBSrvPacket
3320     * @exception java.io.IOException If an I/O error occurs
3321     * @exception SMBSrvException If an SMB protocol error occurs
3322     */

3323    protected void procWriteFile(SMBSrvPacket outPkt) throws java.io.IOException JavaDoc, SMBSrvException
3324    {
3325
3326        // Check that the received packet looks like a valid file write request
3327

3328        if (m_smbPkt.checkPacketIsValid(5, 0) == false)
3329        {
3330            m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv);
3331            return;
3332        }
3333
3334        // Get the tree id from the received packet and validate that it is a valid
3335
// connection id.
3336

3337        int treeId = m_smbPkt.getTreeId();
3338        TreeConnection conn = m_sess.findConnection(treeId);
3339
3340        if (conn == null)
3341        {
3342            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos);
3343            return;
3344        }
3345
3346        // Check if the user has the required access permission
3347

3348        if (conn.hasWriteAccess() == false)
3349        {
3350
3351            // User does not have the required access rights
3352

3353            m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
3354            return;
3355        }
3356
3357        // Get the file id from the request
3358

3359        int fid = m_smbPkt.getParameter(0);
3360        int wrtcnt = m_smbPkt.getParameter(1);
3361        long wrtoff = (m_smbPkt.getParameter(2) + (m_smbPkt.getParameter(3) << 16)) & 0xFFFFFFFFL;
3362
3363        NetworkFile netFile = conn.findFile(fid);
3364
3365        if (netFile == null)
3366        {
3367            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos);
3368            return;
3369        }
3370
3371        // Debug
3372

3373        if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILEIO))
3374            logger.debug("File Write [" + netFile.getFileId() + "] : Size=" + wrtcnt + " ,Pos=" + wrtoff);
3375
3376        // Write data to the file
3377

3378        byte[] buf = m_smbPkt.getBuffer();
3379        int pos = m_smbPkt.getByteOffset();
3380        int wrtlen = 0;
3381
3382        // Check that the data block is valid
3383

3384        if (buf[pos] != DataType.DataBlock)
3385        {
3386            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos);
3387            return;
3388        }
3389
3390        try
3391        {
3392
3393            // Access the disk interface that is associated with the shared device
3394

3395            DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface();
3396
3397            // Update the buffer position to the start of the data to be written
3398

3399            pos += 3;
3400
3401            // Check for a zero length write, this should truncate/extend the file to the write
3402
// offset position
3403

3404            if (wrtcnt == 0)
3405            {
3406
3407                // Truncate/extend the file to the write offset
3408

3409                disk.truncateFile(m_sess, conn, netFile, wrtoff);
3410            }
3411            else
3412            {
3413
3414                // Write to the file
3415

3416                wrtlen = disk.writeFile(m_sess, conn, netFile, buf, pos, wrtcnt, wrtoff);
3417            }
3418        }
3419        catch (InvalidDeviceInterfaceException ex)
3420        {
3421
3422            // Failed to get/initialize the disk interface
3423

3424            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos);
3425            return;
3426        }
3427        catch (java.io.IOException JavaDoc ex)
3428        {
3429
3430            // Debug
3431

3432            if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILEIO))
3433                logger.debug("File Write Error [" + netFile.getFileId() + "] : " + ex.toString());
3434
3435            // Failed to read the file
3436

3437            m_sess.sendErrorResponseSMB(SMBStatus.HRDWriteFault, SMBStatus.ErrHrd);
3438            return;
3439        }
3440
3441        // Return the count of bytes actually written
3442

3443        outPkt.setParameterCount(1);
3444        outPkt.setParameter(0, wrtlen);
3445        outPkt.setByteCount(0);
3446
3447        // Send the write response
3448

3449        m_sess.sendResponseSMB(outPkt);
3450    }
3451
3452    /**
3453     * Write to a file then close the file.
3454     *
3455     * @param outPkt SMBSrvPacket
3456     * @exception java.io.IOException If an I/O error occurs
3457     * @exception SMBSrvException If an SMB protocol error occurs
3458     */

3459    protected void procWriteAndCloseFile(SMBSrvPacket outPkt) throws java.io.IOException JavaDoc, SMBSrvException
3460    {
3461
3462        // Check that the received packet looks like a valid file write and close request
3463

3464        if (m_smbPkt.checkPacketIsValid(6, 0) == false)
3465        {
3466            m_sess.sendErrorResponseSMB(SMBStatus.SRVUnrecognizedCommand, SMBStatus.ErrSrv);
3467            return;
3468        }
3469
3470        // Get the tree id from the received packet and validate that it is a valid
3471
// connection id.
3472

3473        int treeId = m_smbPkt.getTreeId();
3474        TreeConnection conn = m_sess.findConnection(treeId);
3475
3476        if (conn == null)
3477        {
3478            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos);
3479            return;
3480        }
3481
3482        // Check if the user has the required access permission
3483

3484        if (conn.hasWriteAccess() == false)
3485        {
3486
3487            // User does not have the required access rights
3488

3489            m_sess.sendErrorResponseSMB(SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
3490            return;
3491        }
3492
3493        // Get the file id from the request
3494

3495        int fid = m_smbPkt.getParameter(0);
3496        int wrtcnt = m_smbPkt.getParameter(1);
3497        int wrtoff = m_smbPkt.getParameterLong(2);
3498
3499        NetworkFile netFile = conn.findFile(fid);
3500
3501        if (netFile == null)
3502        {
3503            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos);
3504            return;
3505        }
3506
3507        // Debug
3508

3509        if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILEIO))
3510            logger.debug("File Write And Close [" + netFile.getFileId() + "] : Size=" + wrtcnt + " ,Pos=" + wrtoff);
3511
3512        // Write data to the file
3513

3514        byte[] buf = m_smbPkt.getBuffer();
3515        int pos = m_smbPkt.getByteOffset() + 1; // word align
3516
int wrtlen = 0;
3517
3518        try
3519        {
3520
3521            // Access the disk interface that is associated with the shared device
3522

3523            DiskInterface disk = (DiskInterface) conn.getSharedDevice().getInterface();
3524
3525            // Write to the file
3526

3527            wrtlen = disk.writeFile(m_sess, conn, netFile, buf, pos, wrtcnt, wrtoff);
3528
3529            // Close the file
3530
//
3531
// The disk interface may be null if the file is a named pipe file
3532

3533            if (disk != null)
3534                disk.closeFile(m_sess, conn, netFile);
3535
3536            // Indicate that the file has been closed
3537

3538            netFile.setClosed(true);
3539        }
3540        catch (InvalidDeviceInterfaceException ex)
3541        {
3542
3543            // Failed to get/initialize the disk interface
3544

3545            m_sess.sendErrorResponseSMB(SMBStatus.DOSInvalidData, SMBStatus.ErrDos);
3546            return;
3547        }
3548        catch (java.io.IOException JavaDoc ex)
3549        {
3550
3551            // Debug
3552

3553            if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_FILEIO))
3554                logger.debug("File Write Error [" + netFile.getFileId() + "] : " + ex.toString());
3555
3556            // Failed to read the file
3557

3558            m_sess.sendErrorResponseSMB(SMBStatus.HRDWriteFault, SMBStatus.ErrHrd);
3559            return;
3560        }
3561
3562        // Return the count of bytes actually written
3563

3564        outPkt.setParameterCount(1);
3565        outPkt.setParameter(0, wrtlen);
3566        outPkt.setByteCount(0);
3567
3568        outPkt.setError(0, 0);
3569
3570        // Send the write response
3571

3572        m_sess.sendResponseSMB(outPkt);
3573    }
3574
3575    /**
3576     * Run the core SMB protocol handler.
3577     *
3578     * @return boolean true if the packet was processed, else false
3579     */

3580    public boolean runProtocol() throws java.io.IOException JavaDoc, SMBSrvException, TooManyConnectionsException
3581    {
3582
3583        // Check if the SMB packet is initialized
3584

3585        if (m_smbPkt == null)
3586            m_smbPkt = new SMBSrvPacket(m_sess.getBuffer());
3587
3588        // Determine the SMB command type
3589

3590        boolean handledOK = true;
3591        SMBSrvPacket outPkt = m_smbPkt;
3592
3593        switch (m_smbPkt.getCommand())
3594        {
3595
3596        // Session setup
3597

3598        case PacketType.SessionSetupAndX:
3599            procSessionSetup(outPkt);
3600            break;
3601
3602        // Tree connect
3603

3604        case PacketType.TreeConnect:
3605            procTreeConnect(outPkt);
3606            break;
3607
3608        // Tree disconnect
3609

3610        case PacketType.TreeDisconnect:
3611            procTreeDisconnect(outPkt);
3612            break;
3613
3614        // Search
3615

3616        case PacketType.Search:
3617            procSearch(outPkt);
3618            break;
3619
3620        // Get disk attributes
3621

3622        case PacketType.DiskInformation:
3623            procDiskAttributes(outPkt);
3624            break;
3625
3626        // Get file attributes
3627

3628        case PacketType.GetFileAttributes:
3629            procGetFileAttributes(outPkt);
3630            break;
3631
3632        // Set file attributes
3633

3634        case PacketType.SetFileAttributes:
3635            procSetFileAttributes(outPkt);
3636            break;
3637
3638        // Get file information
3639

3640        case PacketType.QueryInformation2:
3641            procGetFileInformation(outPkt);
3642            break;
3643
3644        // Set file information
3645

3646        case PacketType.SetInformation2:
3647            procSetFileInformation(outPkt);
3648            break;
3649
3650        // Open a file
3651

3652        case PacketType.OpenFile:
3653            procOpenFile(outPkt);
3654            break;
3655
3656        // Read from a file
3657

3658        case PacketType.ReadFile:
3659            procReadFile(outPkt);
3660            break;
3661
3662        // Seek file
3663

3664        case PacketType.SeekFile:
3665            procSeekFile(outPkt);
3666            break;
3667
3668        // Close a file
3669

3670        case PacketType.CloseFile:
3671            procCloseFile(outPkt);
3672            break;
3673
3674        // Create a new file
3675

3676        case PacketType.CreateFile:
3677        case PacketType.CreateNew:
3678            procCreateFile(outPkt);
3679            break;
3680
3681        // Write to a file
3682

3683        case PacketType.WriteFile:
3684            procWriteFile(outPkt);
3685            break;
3686
3687        // Write to a file, then close the file
3688

3689        case PacketType.WriteAndClose:
3690            procWriteAndCloseFile(outPkt);
3691            break;
3692
3693        // Flush file
3694

3695        case PacketType.FlushFile:
3696            procFlushFile(outPkt);
3697            break;
3698
3699        // Rename a file
3700

3701        case PacketType.RenameFile:
3702            procRenameFile(outPkt);
3703            break;
3704
3705        // Delete a file
3706

3707        case PacketType.DeleteFile:
3708            procDeleteFile(outPkt);
3709            break;
3710
3711        // Create a new directory
3712

3713        case PacketType.CreateDirectory:
3714            procCreateDirectory(outPkt);
3715            break;
3716
3717        // Delete a directory
3718

3719        case PacketType.DeleteDirectory:
3720            procDeleteDirectory(outPkt);
3721            break;
3722
3723        // Check if a directory exists
3724

3725        case PacketType.CheckDirectory:
3726            procCheckDirectory(outPkt);
3727            break;
3728
3729        // Unsupported requests
3730

3731        case PacketType.IOCtl:
3732            procUnsupported(outPkt);
3733            break;
3734
3735        // Echo request
3736

3737        case PacketType.Echo:
3738            procEcho(outPkt);
3739            break;
3740
3741        // Process exit request
3742

3743        case PacketType.ProcessExit:
3744            procProcessExit(outPkt);
3745            break;
3746
3747        // Create temoporary file request
3748

3749        case PacketType.CreateTemporary:
3750            procCreateTemporaryFile(outPkt);
3751            break;
3752
3753        // Lock file request
3754

3755        case PacketType.LockFile:
3756            procLockFile(outPkt);
3757            break;
3758
3759        // Unlock file request
3760

3761        case PacketType.UnLockFile:
3762            procUnLockFile(outPkt);
3763            break;
3764
3765        // Default
3766

3767        default:
3768
3769            // Indicate that the protocol handler did not process the SMB request
3770

3771            handledOK = false;
3772            break;
3773        }
3774
3775        // Return the handled status
3776

3777        return handledOK;
3778    }
3779}
Popular Tags