FileInfoPacker.java 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539
  1. /*
  2. * Copyright (C) 2006-2010 Alfresco Software Limited.
  3. *
  4. * This file is part of Alfresco
  5. *
  6. * Alfresco is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU Lesser General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Alfresco is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. package org.alfresco.jlan.client;
  20. import org.alfresco.jlan.client.info.ExtendedFileInfo;
  21. import org.alfresco.jlan.client.info.FileInfo;
  22. import org.alfresco.jlan.client.info.StreamInfo;
  23. import org.alfresco.jlan.smb.NTTime;
  24. import org.alfresco.jlan.smb.SMBDate;
  25. import org.alfresco.jlan.smb.SMBException;
  26. import org.alfresco.jlan.smb.SMBStatus;
  27. import org.alfresco.jlan.util.DataBuffer;
  28. /**
  29. * File Information Packer/Unpacker Class
  30. *
  31. * @author gkspencer
  32. */
  33. class FileInfoPacker {
  34. /**
  35. * Unpack the standard file information levels 1 and 2
  36. *
  37. * @param fname String
  38. * @param buf DataBuffer
  39. * @param ea boolean
  40. * @return FileInfo
  41. */
  42. protected final static FileInfo unpackFileInfoStandard(String fname, DataBuffer buf, boolean ea) {
  43. // Unpack the various file date/times
  44. int cfdat = buf.getShort();
  45. int cftim = buf.getShort();
  46. int afdat = buf.getShort();
  47. int aftim = buf.getShort();
  48. int wfdat = buf.getShort();
  49. int wftim = buf.getShort();
  50. int fsiz = buf.getInt();
  51. int alloc = buf.getInt();
  52. int fattr = buf.getShort();
  53. int eaSize = 0;
  54. if ( ea == true)
  55. eaSize = buf.getInt();
  56. // Create a file information object
  57. FileInfo info = null;
  58. if ( ea == false) {
  59. // Create standard file information
  60. info = new FileInfo(fname, fsiz, fattr, wfdat, wftim);
  61. }
  62. else {
  63. // Create an extended file information to hold the extended attributes size
  64. ExtendedFileInfo extInfo = new ExtendedFileInfo(fname, fsiz, fattr, wfdat, wftim);
  65. extInfo.setExtendedAttributesSize(eaSize);
  66. info = extInfo;
  67. }
  68. // Set extra file information details
  69. if ( cfdat != 0)
  70. info.setCreationDateTime(cfdat, cftim);
  71. if ( afdat != 0)
  72. info.setAccessDateTime(afdat, aftim);
  73. info.setAllocationSize(alloc);
  74. // Return the file information
  75. return info;
  76. }
  77. /**
  78. * Pack the standard file information
  79. *
  80. * @param finfo FileInfo
  81. * @param buf DataBuffer
  82. * @param ea boolean
  83. * @exception SMBException If the file information does not match the required level
  84. */
  85. protected final static void packFileInfoStandard(FileInfo finfo, DataBuffer buf, boolean ea)
  86. throws SMBException {
  87. // If the extended attribute size is required the file information must contain extended
  88. // file information
  89. if ( ea == true && finfo instanceof ExtendedFileInfo == false)
  90. throw new SMBException(SMBStatus.JLANErr, SMBStatus.JLANInvalidFileInfo);
  91. // Pack the file creation date/time if available, or pack zero to indicate no change
  92. if ( finfo.hasCreationDateTime()) {
  93. SMBDate cDate = finfo.getCreationDateTime();
  94. buf.putShort(cDate.asSMBTime());
  95. buf.putShort(cDate.asSMBDate());
  96. }
  97. else
  98. buf.putZeros(4);
  99. // Pack the file access date/time if available
  100. if ( finfo.hasAccessDateTime()) {
  101. SMBDate aDate = finfo.getAccessDateTime();
  102. buf.putShort(aDate.asSMBTime());
  103. buf.putShort(aDate.asSMBDate());
  104. }
  105. else
  106. buf.putZeros(4);
  107. // Pack the file write date/time if available
  108. if ( finfo.hasModifyDateTime()) {
  109. SMBDate mDate = finfo.getModifyDateTime();
  110. buf.putShort(mDate.asSMBTime());
  111. buf.putShort(mDate.asSMBDate());
  112. }
  113. else
  114. buf.putZeros(4);
  115. // Pack the file size
  116. buf.putInt(finfo.getSizeInt());
  117. // Pack the file allocation size
  118. buf.putInt(finfo.getAllocationSizeInt());
  119. // Pack the file attributes
  120. buf.putShort(finfo.getFileAttributes());
  121. // Pack the EA size, if required
  122. if ( ea == true) {
  123. // Get the extended file information
  124. ExtendedFileInfo extInfo = (ExtendedFileInfo) finfo;
  125. // Pack the extended attribute size
  126. buf.putInt(extInfo.getExtendedAttributesSize());
  127. }
  128. }
  129. /**
  130. * Unpack the query standard information (FileInfoLevel.PathFileStandardInfo, 0x102)
  131. *
  132. * @param fname String
  133. * @param buf DataBuffer
  134. * @return FileInfo
  135. */
  136. protected final static FileInfo unpackQueryStandardInfo(String fname, DataBuffer buf) {
  137. // Get the file allocation size and end of file offset
  138. long fileSize = buf.getLong();
  139. long allocSize = buf.getLong();
  140. // Get the delete pending and directory flags
  141. boolean delPending = buf.getByte() != 0 ? true : false;
  142. boolean isDirectory = buf.getByte() != 0 ? true : false;
  143. // Create the extended file information
  144. ExtendedFileInfo extInfo = new ExtendedFileInfo(fname, fileSize, 0);
  145. extInfo.setAllocationSize(allocSize);
  146. extInfo.setDeletePending(delPending);
  147. // Return the extended file information
  148. return extInfo;
  149. }
  150. /**
  151. * Unpack the query extended attribute information (FileInfoLevel.PathFileEAInfo, 0x103)
  152. *
  153. * @param fname String
  154. * @param buf DataBuffer
  155. * @return FileInfo
  156. */
  157. protected final static FileInfo unpackQueryEAInfo(String fname, DataBuffer buf) {
  158. // Get the extended attribute size
  159. int eaSize = buf.getInt();
  160. // Create the extended file information
  161. ExtendedFileInfo extInfo = new ExtendedFileInfo(fname, 0, 0);
  162. extInfo.setExtendedAttributesSize(eaSize);
  163. // Return the extended file information
  164. return extInfo;
  165. }
  166. /**
  167. * Unpack the query name information and alternate name information
  168. * (FileInfoLevel.PathFileNameInfo and FileInfoLevel.PathFileAltNameInfo, 0x104 and 0x108)
  169. *
  170. * @param buf DataBuffer
  171. * @param uni boolean
  172. * @return FileInfo
  173. */
  174. protected final static FileInfo unpackQueryNameInfo(DataBuffer buf, boolean uni) {
  175. // Get the name size and string
  176. buf.getInt();
  177. String name = buf.getString(uni);
  178. // Create the file information
  179. FileInfo finfo = new ExtendedFileInfo(name, 0, 0);
  180. // Return the file information
  181. return finfo;
  182. }
  183. /**
  184. * Unpack the stream name information (FileInfoLevel.PathFileStreamInfo, 0x109)
  185. *
  186. * @param fname String
  187. * @param buf DataBuffer
  188. * @param uni boolean
  189. * @return FileInfo
  190. */
  191. protected final static FileInfo unpackQueryStreamInfo(String fname, DataBuffer buf, boolean uni) {
  192. // Get the offset to the next stream information structure
  193. int pos = buf.getPosition();
  194. int offset = buf.getInt();
  195. // Loop until the end of the stream list
  196. ExtendedFileInfo extInfo = new ExtendedFileInfo(fname, 0, 0);
  197. boolean endOfList = false;
  198. while (endOfList != true) {
  199. // Get the stream information
  200. int nameLen = buf.getInt();
  201. if ( uni == true)
  202. nameLen = nameLen / 2;
  203. long strmSize = buf.getLong();
  204. long strmAlloc = buf.getLong();
  205. String name = buf.getString(nameLen, uni);
  206. // Create the extended file information
  207. StreamInfo stream = new StreamInfo(name, 0, 0, strmSize, strmAlloc);
  208. extInfo.addNTFSStreamInfo(stream);
  209. // Position at the next stream information record
  210. if ( offset == 0)
  211. endOfList = true;
  212. else {
  213. pos += offset;
  214. buf.setPosition(pos);
  215. offset = buf.getInt();
  216. }
  217. }
  218. // Return the file information
  219. return extInfo;
  220. }
  221. /**
  222. * Unpack the compression information (FileInfoLevel.PathFileCompressionInfo, 0x10B)
  223. *
  224. * @param fname String
  225. * @param buf DataBuffer
  226. * @return FileInfo
  227. */
  228. protected final static FileInfo unpackQueryCompressionInfo(String fname, DataBuffer buf) {
  229. // Get the compressed file size and compression format
  230. long compSize = buf.getLong();
  231. int compFmt = buf.getShort();
  232. // Create the extended file information
  233. ExtendedFileInfo extInfo = new ExtendedFileInfo(fname, 0, 0);
  234. extInfo.setCompressedSizeFormat(compSize, compFmt);
  235. // Return the file information
  236. return extInfo;
  237. }
  238. /**
  239. * Unpack the full file information (FileInfoLevel.PathFileAllInfo, 0x107)
  240. *
  241. * @param buf DataBuffer
  242. * @param uni boolean
  243. * @return FileInfo
  244. */
  245. protected final static FileInfo unpackQueryAllInfo(DataBuffer buf, boolean uni) {
  246. // Get the file create/access/write/change times, in 64bit NT format
  247. long createTime = buf.getLong();
  248. long accessTime = buf.getLong();
  249. long writeTime = buf.getLong();
  250. long changeTime = buf.getLong();
  251. // Get the file attributes
  252. int attr = buf.getInt();
  253. buf.skipBytes(4); // unknown value
  254. // Get the file size and allocation size
  255. long allocSize = buf.getLong();
  256. long fileSize = buf.getLong();
  257. // Delete pending and directory flags
  258. boolean delPending = buf.getByte() != 0 ? true : false;
  259. boolean isDir = buf.getByte() != 0 ? true : false;
  260. buf.skipBytes(2);
  261. // Extended attributes size
  262. int eaSize = buf.getInt();
  263. // File name
  264. int nameLen = buf.getInt();
  265. if ( uni == true)
  266. nameLen = nameLen / 2;
  267. String name = buf.getString(nameLen, uni);
  268. // Create the extended file information
  269. ExtendedFileInfo extInfo = new ExtendedFileInfo(name, fileSize, attr);
  270. extInfo.setAllocationSize(allocSize);
  271. extInfo.setDeletePending(delPending);
  272. extInfo.setExtendedAttributesSize(eaSize);
  273. // Set the file times
  274. SMBDate smbDate = null;
  275. if ( createTime != 0) {
  276. smbDate = NTTime.toSMBDate(createTime);
  277. extInfo.setCreationDateTime(smbDate);
  278. }
  279. if ( accessTime != 0) {
  280. smbDate = NTTime.toSMBDate(accessTime);
  281. extInfo.setAccessDateTime(smbDate);
  282. }
  283. if ( writeTime != 0) {
  284. smbDate = NTTime.toSMBDate(writeTime);
  285. extInfo.setModifyDateTime(smbDate);
  286. }
  287. // Return the file information
  288. return extInfo;
  289. }
  290. /**
  291. * Unpack the basic file information (FileInfoLevel.PathFileBasicInfo, 0x101)
  292. *
  293. * @param fname String
  294. * @param buf DataBuffer
  295. * @return FileInfo
  296. */
  297. protected final static FileInfo unpackQueryBasicInfo(String fname, DataBuffer buf) {
  298. // Get the file create/access/write/change times, in 64bit NT format
  299. long createTime = buf.getLong();
  300. long accessTime = buf.getLong();
  301. long writeTime = buf.getLong();
  302. long changeTime = buf.getLong();
  303. // Get the file attributes
  304. int attr = buf.getInt();
  305. // Extended attributes size
  306. int eaSize = buf.getInt();
  307. // Create the extended file information
  308. ExtendedFileInfo extInfo = new ExtendedFileInfo(fname, 0, attr);
  309. extInfo.setExtendedAttributesSize(eaSize);
  310. // Set the file times
  311. SMBDate smbDate = null;
  312. if ( createTime != 0) {
  313. smbDate = NTTime.toSMBDate(createTime);
  314. extInfo.setCreationDateTime(smbDate);
  315. }
  316. if ( accessTime != 0) {
  317. smbDate = NTTime.toSMBDate(accessTime);
  318. extInfo.setAccessDateTime(smbDate);
  319. }
  320. if ( writeTime != 0) {
  321. smbDate = NTTime.toSMBDate(writeTime);
  322. extInfo.setModifyDateTime(smbDate);
  323. }
  324. // Return the file information
  325. return extInfo;
  326. }
  327. /**
  328. * Pack the file basic information
  329. *
  330. * @param finfo FileInfo
  331. * @param buf DataBuffer
  332. * @exception SMBException If the file information does not match the required level
  333. */
  334. protected final static void packFileBasicInfo(FileInfo finfo, DataBuffer buf)
  335. throws SMBException {
  336. // Extended file information is required by the file basic information
  337. if ( finfo instanceof ExtendedFileInfo == false)
  338. throw new SMBException(SMBStatus.JLANErr, SMBStatus.JLANInvalidFileInfo);
  339. ExtendedFileInfo extInfo = (ExtendedFileInfo) finfo;
  340. // Pack the file creation date/time in NT format, if available
  341. if ( extInfo.hasCreationDateTime())
  342. buf.putLong(NTTime.toNTTime(extInfo.getCreationDateTime()));
  343. else
  344. buf.putZeros(8);
  345. // Pack the file access date/time in NT format, if available
  346. if ( extInfo.hasAccessDateTime())
  347. buf.putLong(NTTime.toNTTime(extInfo.getAccessDateTime()));
  348. else
  349. buf.putZeros(8);
  350. // Pack the file write and change date/times in NT format, if available
  351. if ( extInfo.hasModifyDateTime()) {
  352. buf.putLong(NTTime.toNTTime(extInfo.getModifyDateTime()));
  353. buf.putLong(NTTime.toNTTime(extInfo.getModifyDateTime()));
  354. }
  355. else
  356. buf.putZeros(16);
  357. // Pack the NT file attributes
  358. buf.putInt(extInfo.getFileAttributes());
  359. // Pack the extended attributes size
  360. buf.putInt(extInfo.getExtendedAttributesSize());
  361. }
  362. /**
  363. * Unpack the quesy all EAs file information (FileInfoLevel.PathQueryAllEAs, 0x04)
  364. *
  365. * @param fname String
  366. * @param buf DataBuffer
  367. * @return FileInfo
  368. */
  369. protected final static FileInfo unpackQueryAllEAs(String fname, DataBuffer buf) {
  370. // Create the extended file information
  371. ExtendedFileInfo extInfo = new ExtendedFileInfo(fname, 0, 0);
  372. // Unpack the extended attribute raw data size
  373. int eaSize = buf.getInt() - 4;
  374. byte[] eaData = null;
  375. if ( eaSize > 0) {
  376. // Allocate the extended attribute data block and copy the data from the buffer
  377. eaData = new byte[eaSize];
  378. System.arraycopy(buf.getBuffer(), buf.getPosition(), eaData, 0, eaSize);
  379. }
  380. // Set the extended attribute details
  381. extInfo.setExtendedAttributesSize(eaSize);
  382. extInfo.setExtendedAttributeData(eaData);
  383. // Return the extended attribute file information
  384. return extInfo;
  385. }
  386. }