KickJava   Java API By Example, From Geeks To Geeks.

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


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 org.alfresco.filesys.server.filesys.FileInfo;
20 import org.alfresco.filesys.server.filesys.UnsupportedInfoLevelException;
21 import org.alfresco.filesys.smb.FileInfoLevel;
22 import org.alfresco.filesys.smb.NTTime;
23 import org.alfresco.filesys.smb.SMBDate;
24 import org.alfresco.filesys.smb.WinNT;
25 import org.alfresco.filesys.smb.server.ntfs.StreamInfo;
26 import org.alfresco.filesys.smb.server.ntfs.StreamInfoList;
27 import org.alfresco.filesys.util.DataBuffer;
28
29 /**
30  * Query File Information Packer Class
31  * <p>
32  * Packs file/directory information for the specified information level.
33  */

34 public class QueryInfoPacker
35 {
36
37     /**
38      * Pack a file information object into the specified buffer, using the specified information
39      * level.
40      *
41      * @param info File information to be packed.
42      * @param buf Buffer to pack the data into.
43      * @param infoLevel File information level.
44      * @param uni Pack Unicode strings if true, else pack ASCII strings
45      * @return int Length of data packed
46      */

47     public final static int packInfo(FileInfo info, DataBuffer buf, int infoLevel, boolean uni)
48             throws UnsupportedInfoLevelException
49     {
50
51         // Determine the information level
52

53         int curPos = buf.getPosition();
54
55         switch (infoLevel)
56         {
57
58         // Standard information
59

60         case FileInfoLevel.PathStandard:
61             packInfoStandard(info, buf, false, uni);
62             break;
63
64         // Standard information plus EA size
65

66         case FileInfoLevel.PathQueryEASize:
67             packInfoStandard(info, buf, true, uni);
68             break;
69
70         // Extended attributes list
71

72         case FileInfoLevel.PathQueryEAsFromList:
73             break;
74
75         // All extended attributes
76

77         case FileInfoLevel.PathAllEAs:
78             break;
79
80         // Validate a file name
81

82         case FileInfoLevel.PathIsNameValid:
83             break;
84
85         // Basic file information
86

87         case FileInfoLevel.PathFileBasicInfo:
88         case FileInfoLevel.NTFileBasicInfo:
89             packBasicFileInfo(info, buf);
90             break;
91
92         // Standard file information
93

94         case FileInfoLevel.PathFileStandardInfo:
95         case FileInfoLevel.NTFileStandardInfo:
96             packStandardFileInfo(info, buf);
97             break;
98
99         // Extended attribute information
100

101         case FileInfoLevel.PathFileEAInfo:
102         case FileInfoLevel.NTFileEAInfo:
103             packEAFileInfo(info, buf);
104             break;
105
106         // File name information
107

108         case FileInfoLevel.PathFileNameInfo:
109         case FileInfoLevel.NTFileNameInfo:
110             packNameFileInfo(info, buf, uni);
111             break;
112
113         // All information
114

115         case FileInfoLevel.PathFileAllInfo:
116         case FileInfoLevel.NTFileAllInfo:
117             packAllFileInfo(info, buf, uni);
118             break;
119
120         // Alternate name information
121

122         case FileInfoLevel.PathFileAltNameInfo:
123         case FileInfoLevel.NTFileAltNameInfo:
124             packAlternateNameFileInfo(info, buf);
125             break;
126
127         // Stream information
128

129         case FileInfoLevel.PathFileStreamInfo:
130         case FileInfoLevel.NTFileStreamInfo:
131             packStreamFileInfo(info, buf, uni);
132             break;
133
134         // Compression information
135

136         case FileInfoLevel.PathFileCompressionInfo:
137         case FileInfoLevel.NTFileCompressionInfo:
138             packCompressionFileInfo(info, buf);
139             break;
140
141         // File internal information
142

143         case FileInfoLevel.NTFileInternalInfo:
144             packFileInternalInfo(info, buf);
145             break;
146
147         // File position information
148

149         case FileInfoLevel.NTFilePositionInfo:
150             packFilePositionInfo(info, buf);
151             break;
152
153         // Attribute tag information
154

155         case FileInfoLevel.NTAttributeTagInfo:
156             packFileAttributeTagInfo(info, buf);
157             break;
158
159         // Network open information
160

161         case FileInfoLevel.NTNetworkOpenInfo:
162             packFileNetworkOpenInfo(info, buf);
163             break;
164         }
165
166         // Return the length of the data that was packed
167

168         return buf.getPosition() - curPos;
169     }
170
171     /**
172      * Pack the standard file information
173      *
174      * @param info File information
175      * @param buf Buffer to pack data into
176      * @param eaFlag Return EA size
177      * @param uni Pack unicode strings
178      */

179     private static void packInfoStandard(FileInfo info, DataBuffer buf, boolean eaFlag, boolean uni)
180     {
181
182         // Information format :-
183
// SMB_DATE CreationDate
184
// SMB_TIME CreationTime
185
// SMB_DATE LastAccessDate
186
// SMB_TIME LastAccessTime
187
// SMB_DATE LastWriteDate
188
// SMB_TIME LastWriteTime
189
// ULONG File size
190
// ULONG Allocation size
191
// USHORT File attributes
192
// [ ULONG EA size ]
193

194         // Pack the creation date/time
195

196         SMBDate dateTime = new SMBDate(0);
197
198         if (info.hasCreationDateTime())
199         {
200             dateTime.setTime(info.getCreationDateTime());
201             buf.putShort(dateTime.asSMBDate());
202             buf.putShort(dateTime.asSMBTime());
203         }
204         else
205             buf.putZeros(4);
206
207         // Pack the last access date/time
208

209         if (info.hasAccessDateTime())
210         {
211             dateTime.setTime(info.getAccessDateTime());
212             buf.putShort(dateTime.asSMBDate());
213             buf.putShort(dateTime.asSMBTime());
214         }
215         else
216             buf.putZeros(4);
217
218         // Pack the last write date/time
219

220         if (info.hasModifyDateTime())
221         {
222             dateTime.setTime(info.getModifyDateTime());
223             buf.putShort(dateTime.asSMBDate());
224             buf.putShort(dateTime.asSMBTime());
225         }
226         else
227             buf.putZeros(4);
228
229         // Pack the file size and allocation size
230

231         buf.putInt(info.getSizeInt());
232
233         if (info.getAllocationSize() < info.getSize())
234             buf.putInt(info.getSizeInt());
235         else
236             buf.putInt(info.getAllocationSizeInt());
237
238         // Pack the file attributes
239

240         buf.putShort(info.getFileAttributes());
241
242         // Pack the EA size, always zero
243

244         if (eaFlag == true)
245             buf.putZeros(4);
246     }
247
248     /**
249      * Pack the basic file information (level 0x101)
250      *
251      * @param info File information
252      * @param buf Buffer to pack data into
253      */

254     private static void packBasicFileInfo(FileInfo info, DataBuffer buf)
255     {
256
257         // Information format :-
258
// LARGE_INTEGER Creation date/time
259
// LARGE_INTEGER Access date/time
260
// LARGE_INTEGER Write date/time
261
// LARGE_INTEGER Change date/time
262
// UINT Attributes
263
// UINT Unknown
264

265         // Pack the creation date/time
266

267         if (info.hasCreationDateTime())
268         {
269             buf.putLong(NTTime.toNTTime(info.getCreationDateTime()));
270         }
271         else
272             buf.putZeros(8);
273
274         // Pack the last access date/time
275

276         if (info.hasAccessDateTime())
277         {
278             buf.putLong(NTTime.toNTTime(info.getAccessDateTime()));
279         }
280         else
281             buf.putZeros(8);
282
283         // Pack the last write and change date/time
284

285         if (info.hasModifyDateTime())
286         {
287             long ntTime = NTTime.toNTTime(info.getModifyDateTime());
288             buf.putLong(ntTime);
289             buf.putLong(ntTime);
290         }
291         else
292             buf.putZeros(16);
293
294         // Pack the file attributes
295

296         buf.putInt(info.getFileAttributes());
297
298         // Pack unknown value
299

300         buf.putZeros(4);
301     }
302
303     /**
304      * Pack the standard file information (level 0x102)
305      *
306      * @param info File information
307      * @param buf Buffer to pack data into
308      */

309     private static void packStandardFileInfo(FileInfo info, DataBuffer buf)
310     {
311
312         // Information format :-
313
// LARGE_INTEGER AllocationSize
314
// LARGE_INTEGER EndOfFile
315
// UINT NumberOfLinks
316
// BOOLEAN DeletePending
317
// BOOLEAN Directory
318
// SHORT Unknown
319

320         // Pack the allocation and file sizes
321

322         if (info.getAllocationSize() < info.getSize())
323             buf.putLong(info.getSize());
324         else
325             buf.putLong(info.getAllocationSize());
326
327         buf.putLong(info.getSize());
328
329         // Pack the number of links, always one for now
330

331         buf.putInt(1);
332
333         // Pack the delete pending and directory flags
334

335         buf.putByte(0);
336         buf.putByte(info.isDirectory() ? 1 : 0);
337
338         // buf.putZeros(2);
339
}
340
341     /**
342      * Pack the extended attribute information (level 0x103)
343      *
344      * @param info File information
345      * @param buf Buffer to pack data into
346      */

347     private static void packEAFileInfo(FileInfo info, DataBuffer buf)
348     {
349
350         // Information format :-
351
// ULONG EASize
352

353         // Pack the extended attribute size
354

355         buf.putInt(0);
356     }
357
358     /**
359      * Pack the file name information (level 0x104)
360      *
361      * @param info File information
362      * @param buf Buffer to pack data into
363      * @param uni Pack unicode strings
364      */

365     private static void packNameFileInfo(FileInfo info, DataBuffer buf, boolean uni)
366     {
367
368         // Information format :-
369
// UINT FileNameLength
370
// WCHAR FileName[]
371

372         // Pack the file name length and name string as Unicode
373

374         int nameLen = info.getFileName().length();
375         if (uni)
376             nameLen *= 2;
377
378         buf.putInt(nameLen);
379         buf.putString(info.getFileName(), uni, false);
380     }
381
382     /**
383      * Pack the all file information (level 0x107)
384      *
385      * @param info File information
386      * @param buf Buffer to pack data into
387      * @param uni Pack unicode strings
388      */

389     private static void packAllFileInfo(FileInfo info, DataBuffer buf, boolean uni)
390     {
391
392         // Information format :-
393
// LARGE_INTEGER Creation date/time
394
// LARGE_INTEGER Access date/time
395
// LARGE_INTEGER Write date/time
396
// LARGE_INTEGER Change date/time
397
// UINT Attributes
398
// UINT Number of links
399
// LARGE_INTEGER Allocation
400
// LARGE_INTEGER Size
401
// BYTE Delete pending
402
// BYTE Directory flag
403
// 2 byte longword alignment
404
// UINT EA Size
405
// UINT Access mask
406
// UINT File name length
407
// WCHAR FileName[]
408

409         // Pack the creation date/time
410

411         if (info.hasCreationDateTime())
412         {
413             buf.putLong(NTTime.toNTTime(info.getCreationDateTime()));
414         }
415         else
416             buf.putZeros(8);
417
418         // Pack the last access date/time
419

420         if (info.hasAccessDateTime())
421         {
422             buf.putLong(NTTime.toNTTime(info.getAccessDateTime()));
423         }
424         else
425             buf.putZeros(8);
426
427         // Pack the last write and change date/time
428

429         if (info.hasModifyDateTime())
430         {
431             long ntTime = NTTime.toNTTime(info.getModifyDateTime());
432             buf.putLong(ntTime);
433             buf.putLong(ntTime);
434         }
435         else
436             buf.putZeros(16);
437
438         // Pack the file attributes
439

440         buf.putInt(info.getFileAttributes());
441
442         // Number of links
443

444         buf.putInt(1);
445
446         // Pack the allocation and used file sizes
447

448         if (info.getAllocationSize() < info.getSize())
449             buf.putLong(info.getSize());
450         else
451             buf.putLong(info.getAllocationSize());
452
453         buf.putLong(info.getSize());
454
455         // Pack the delete pending and directory flags
456

457         buf.putByte(0);
458         buf.putByte(info.isDirectory() ? 1 : 0);
459         buf.putShort(0); // Alignment
460

461         // EA list size
462

463         buf.putInt(0);
464
465         // Access mask
466

467         buf.putInt(0x00000003);
468
469         // File name length in bytes and file name, Unicode
470

471         int nameLen = info.getFileName().length();
472         if (uni)
473             nameLen *= 2;
474
475         buf.putInt(nameLen);
476         buf.putString(info.getFileName(), uni, false);
477     }
478
479     /**
480      * Pack the alternate name information (level 0x108)
481      *
482      * @param info File information
483      * @param buf Buffer to pack data into
484      */

485     private static void packAlternateNameFileInfo(FileInfo info, DataBuffer buf)
486     {
487     }
488
489     /**
490      * Pack the stream information (level 0x109)
491      *
492      * @param info File information
493      * @param buf Buffer to pack data into
494      * @param uni Pack unicode strings
495      */

496     private static void packStreamFileInfo(FileInfo info, DataBuffer buf, boolean uni)
497     {
498
499         // Information format :-
500
// ULONG OffsetToNextStreamInfo
501
// ULONG NameLength (in bytes)
502
// LARGE_INTEGER StreamSize
503
// LARGE_INTEGER StreamAlloc
504
// WCHAR StreamName[]
505

506         // Pack a dummy data stream for now
507

508         String JavaDoc streamName = "::$DATA";
509
510         buf.putInt(0); // offset to next info (no more info)
511

512         int nameLen = streamName.length();
513         if (uni)
514             nameLen *= 2;
515         buf.putInt(nameLen);
516
517         // Stream size
518

519         buf.putLong(info.getSize());
520
521         // Allocation size
522

523         if (info.getAllocationSize() < info.getSize())
524             buf.putLong(info.getSize());
525         else
526             buf.putLong(info.getAllocationSize());
527
528         buf.putString(streamName, uni, false);
529     }
530
531     /**
532      * Pack the stream information (level 0x109)
533      *
534      * @param streams List of streams
535      * @param buf Buffer to pack data into
536      * @param uni Pack unicode strings
537      * @return int
538      */

539     public static int packStreamFileInfo(StreamInfoList streams, DataBuffer buf, boolean uni)
540     {
541
542         // Information format :-
543
// ULONG OffsetToNextStreamInfo
544
// ULONG NameLength (in bytes)
545
// LARGE_INTEGER StreamSize
546
// LARGE_INTEGER StreamAlloc
547
// WCHAR StreamName[]
548

549         // Loop through the available streams
550

551         int curPos = buf.getPosition();
552         int startPos = curPos;
553         int pos = 0;
554
555         for (int i = 0; i < streams.numberOfStreams(); i++)
556         {
557
558             // Get the current stream information
559

560             StreamInfo sinfo = streams.getStreamAt(i);
561
562             // Skip the offset to the next stream information structure
563

564             buf.putInt(0);
565
566             // Set the stream name length
567

568             int nameLen = sinfo.getName().length();
569             if (uni)
570                 nameLen *= 2;
571             buf.putInt(nameLen);
572
573             // Stream size
574

575             buf.putLong(sinfo.getSize());
576
577             // Allocation size
578

579             if (sinfo.getAllocationSize() < sinfo.getSize())
580                 buf.putLong(sinfo.getSize());
581             else
582                 buf.putLong(sinfo.getAllocationSize());
583
584             buf.putString(sinfo.getName(), uni, false);
585
586             // Word align the buffer
587

588             buf.wordAlign();
589
590             // Fill in the offset to the next stream information, if this is not the last stream
591

592             if (i < (streams.numberOfStreams() - 1))
593             {
594
595                 // Fill in the offset from the current stream information structure to the next
596

597                 pos = buf.getPosition();
598                 buf.setPosition(startPos);
599                 buf.putInt(pos - startPos);
600                 buf.setPosition(pos);
601                 startPos = pos;
602             }
603         }
604
605         // Return the data length
606

607         return buf.getPosition() - curPos;
608     }
609
610     /**
611      * Pack the compression information (level 0x10B)
612      *
613      * @param info File information
614      * @param buf Buffer to pack data into
615      */

616     private static void packCompressionFileInfo(FileInfo info, DataBuffer buf)
617     {
618
619         // Information format :-
620
// LARGE_INTEGER CompressedSize
621
// ULONG CompressionFormat (sess WinNT class)
622

623         buf.putLong(info.getSize());
624         buf.putInt(WinNT.CompressionFormatNone);
625     }
626
627     /**
628      * Pack the file internal information (level 1006)
629      *
630      * @param info File information
631      * @param buf Buffer to pack data into
632      */

633     private static void packFileInternalInfo(FileInfo info, DataBuffer buf)
634     {
635
636         // Information format :-
637
// ULONG Unknown1
638
// ULONG Unknown2
639

640         buf.putInt(1);
641         buf.putInt(0);
642     }
643
644     /**
645      * Pack the file position information (level 1014)
646      *
647      * @param info File information
648      * @param buf Buffer to pack data into
649      */

650     private static void packFilePositionInfo(FileInfo info, DataBuffer buf)
651     {
652
653         // Information format :-
654
// ULONG Unknown1
655
// ULONG Unknown2
656

657         buf.putInt(0);
658         buf.putInt(0);
659     }
660
661     /**
662      * Pack the network open information (level 1034)
663      *
664      * @param info File information
665      * @param buf Buffer to pack data into
666      */

667     private static void packFileNetworkOpenInfo(FileInfo info, DataBuffer buf)
668     {
669
670         // Information format :-
671
// LARGE_INTEGER Creation date/time
672
// LARGE_INTEGER Access date/time
673
// LARGE_INTEGER Write date/time
674
// LARGE_INTEGER Change date/time
675
// LARGE_INTEGER Allocation
676
// LARGE_INTEGER Size
677
// UINT Attributes
678
// UNIT Unknown
679

680         // Pack the creation date/time
681

682         if (info.hasCreationDateTime())
683         {
684             buf.putLong(NTTime.toNTTime(info.getCreationDateTime()));
685         }
686         else
687             buf.putZeros(8);
688
689         // Pack the last access date/time
690

691         if (info.hasAccessDateTime())
692         {
693             buf.putLong(NTTime.toNTTime(info.getAccessDateTime()));
694         }
695         else
696             buf.putZeros(8);
697
698         // Pack the last write and change date/time
699

700         if (info.hasModifyDateTime())
701         {
702             long ntTime = NTTime.toNTTime(info.getModifyDateTime());
703             buf.putLong(ntTime);
704             buf.putLong(ntTime);
705         }
706         else
707             buf.putZeros(16);
708
709         // Pack the allocation and used file sizes
710

711         if (info.getAllocationSize() < info.getSize())
712             buf.putLong(info.getSize());
713         else
714             buf.putLong(info.getAllocationSize());
715
716         buf.putLong(info.getSize());
717
718         // Pack the file attributes
719

720         buf.putInt(info.getFileAttributes());
721
722         // Pack the unknown value
723

724         buf.putInt(0);
725     }
726
727     /**
728      * Pack the attribute tag information (level 1035)
729      *
730      * @param info File information
731      * @param buf Buffer to pack data into
732      */

733     private static void packFileAttributeTagInfo(FileInfo info, DataBuffer buf)
734     {
735
736         // Information format :-
737
// ULONG Unknown1
738
// ULONG Unknown2
739

740         buf.putLong(0);
741         buf.putLong(0);
742     }
743 }
744
Popular Tags