CIFSFile.java 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805
  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 java.io.*;
  21. import org.alfresco.jlan.client.info.FileInfo;
  22. import org.alfresco.jlan.netbios.RFCNetBIOSProtocol;
  23. import org.alfresco.jlan.server.filesys.FileAttribute;
  24. import org.alfresco.jlan.smb.Dialect;
  25. import org.alfresco.jlan.smb.LockingAndX;
  26. import org.alfresco.jlan.smb.OpLock;
  27. import org.alfresco.jlan.smb.PacketType;
  28. import org.alfresco.jlan.smb.SMBDate;
  29. import org.alfresco.jlan.smb.SMBException;
  30. import org.alfresco.jlan.smb.SMBStatus;
  31. import org.alfresco.jlan.smb.SeekType;
  32. /**
  33. * SMB CIFS file class
  34. *
  35. * <p>An SMB file provides read and/or write access to a remote file.
  36. *
  37. * <p>A CIFSFile is created via an DiskSession object, using the DiskSession.OpenFile()
  38. * method. A CIFSFile may also be created via the CIFSDiskSession.NTCreate() method if the
  39. * NT SMB dialect has been negotiated. The NTCreate() method provides access to more features
  40. * on an NTFS filesystem.
  41. *
  42. * <p>A remote file may also be opened as an InputStream or OutputStream using the
  43. * DiskSession.OpenInputStream () and DiskSession.OpenOutputStream () methods.
  44. *
  45. * @author gkspencer
  46. */
  47. public final class CIFSFile extends SMBFile {
  48. // Size of protocol packet to allocate
  49. private static final int DataSize = 4000;
  50. private static final int PacketSize = DataSize + 128;
  51. // Offset that the write data is placed within the write SMB packet, including protocol header of 4 bytes, and
  52. // padding byte count to word align the data
  53. private static final int WriteDataOffset = 64;
  54. private static final int WriteDataPadding = 1;
  55. // Maximum file offset for 32bit files
  56. private static final long Maximum32BitOffset = 0x0FFFFFFFFL;
  57. // Flag to indicate we are using NT dialect SMBs
  58. private boolean m_NTdialect;
  59. // Oplock type and callback
  60. private int m_oplockType = OpLock.TypeNone;
  61. private OplockInterface m_oplockIface;
  62. /**
  63. * Class constructor
  64. *
  65. * @param sess Session that this file is associated with
  66. * @param finfo File information for the new file
  67. * @param fid File identifier for this file
  68. */
  69. protected CIFSFile(Session sess, FileInfo finfo, int fid) {
  70. super(sess, finfo, fid);
  71. // Set the NT dialect flag
  72. if ( sess.getDialect() == Dialect.NT)
  73. m_NTdialect = true;
  74. else
  75. m_NTdialect = false;
  76. }
  77. /**
  78. * Class constructor
  79. *
  80. * @param sess Session that this file is associated with
  81. * @param finfo File information for the new file
  82. * @param fid File identifier for this file
  83. * @param oplockTyp Granted oplock type, if requested
  84. */
  85. protected CIFSFile(Session sess, FileInfo finfo, int fid, int oplockTyp) {
  86. super(sess, finfo, fid);
  87. // Set the NT dialect flag
  88. if ( sess.getDialect() == Dialect.NT)
  89. m_NTdialect = true;
  90. else
  91. m_NTdialect = false;
  92. // Set the granted oplock type
  93. m_oplockType = oplockTyp;
  94. }
  95. /**
  96. * Close the remote file.
  97. *
  98. * @param wrDateTime Set the last write date/time, or null to let the server set the date/time
  99. * @exception java.io.IOException If an I/O error occurs
  100. * @exception SMBException If an SMB level error occurs
  101. */
  102. public final void Close(SMBDate wrDateTime)
  103. throws java.io.IOException, SMBException {
  104. // Flush any buffered write data
  105. if ( m_txlen > 0)
  106. Flush();
  107. // Determine which packet to use to send the close file SMB
  108. SMBPacket pkt = new SMBPacket();
  109. pkt.setUserId(m_sess.getUserId());
  110. pkt.setTreeId(m_sess.getTreeId());
  111. // Close the remote file.
  112. pkt.setCommand(PacketType.CloseFile);
  113. pkt.setParameterCount(3);
  114. pkt.setParameter(0, m_FID);
  115. // Check if the last write date/time should be set
  116. if ( wrDateTime != null) {
  117. // Set the last write date/time for the file
  118. pkt.setParameter(1, wrDateTime.asSMBTime());
  119. pkt.setParameter(2, wrDateTime.asSMBDate());
  120. }
  121. else {
  122. // Let the server set the last write date/time
  123. pkt.setParameter(1, 0);
  124. pkt.setParameter(2, 0);
  125. }
  126. // Indicate that the file has been closed
  127. this.setStateFlag(SMBFile.Closed, true);
  128. // Exchange the close file SMB packet with the file server
  129. try {
  130. pkt.ExchangeSMB(m_sess, pkt);
  131. }
  132. catch (java.io.IOException ex) {
  133. return;
  134. }
  135. // Release the transmit/receive packets
  136. m_rxpkt = null;
  137. m_txpkt = null;
  138. // Inform the session that the file has been closed
  139. CIFSDiskSession diskSess = (CIFSDiskSession) m_sess;
  140. diskSess.fileClosed( this);
  141. }
  142. /**
  143. * Flush data to the remote file.
  144. *
  145. * @exception java.io.IOException If an I/O error occurs
  146. * @exception SMBException If an SMB level error occurs
  147. */
  148. public final void Flush()
  149. throws java.io.IOException, SMBException {
  150. // Check if there is any buffered write data
  151. if ( m_txlen > 0)
  152. WriteData();
  153. }
  154. /**
  155. * Read a block of data from the file.
  156. *
  157. * @param buf Byte buffer to receive the data.
  158. * @param siz Maximum length of data to receive.
  159. * @param offset Offset within buffer to place received data.
  160. * @return Actual length of data received.
  161. * @exception java.io.IOException If an I/O error occurs
  162. * @exception SMBException If an SMB level error occurs
  163. */
  164. public final int Read(byte[] buf, int siz, int offset)
  165. throws java.io.IOException, SMBException {
  166. // Check if the file has been closed
  167. if ( this.isClosed())
  168. return 0;
  169. // Copy data into the users receive buffer
  170. int retlen = 0;
  171. int bufidx = offset;
  172. while (retlen < siz && !this.atEndOfFile()) {
  173. // Check if there is any data buffered
  174. if ( m_rxlen == 0) {
  175. // Read a packet of data from the remote file
  176. if ( ReadData() == false)
  177. return -1;
  178. }
  179. // Check if enough data is buffered
  180. int rxlen = siz - retlen;
  181. if ( rxlen > m_rxlen)
  182. rxlen = m_rxlen;
  183. // Copy data to the users buffer
  184. byte[] pktbuf = m_rxpkt.getBuffer();
  185. System.arraycopy(pktbuf, m_rxoffset, buf, bufidx, rxlen);
  186. // Update the buffered data offset/length
  187. m_rxlen -= rxlen;
  188. m_rxoffset += rxlen;
  189. bufidx += rxlen;
  190. // Update the returned data length
  191. retlen += rxlen;
  192. } // end while
  193. // Return the actual data received
  194. return retlen;
  195. }
  196. /**
  197. * Read a packet of data from the remote file.
  198. *
  199. * @return true if a valid data packet has been received, else false
  200. * @exception SMBException If an SMB level error occurs
  201. * @exception IOException If an I/O error occurs
  202. */
  203. private final boolean ReadData()
  204. throws SMBException, IOException {
  205. // Check if the file offset requires large file support (64bit offsets)
  206. if ( isNTDialect() == false && m_rxpos > Maximum32BitOffset)
  207. throw new SMBException(SMBStatus.JLANErr, SMBStatus.JLANLargeFilesNotSupported);
  208. // Allocate and initialize a receive packet, if not already allocated
  209. if ( m_rxpkt == null) {
  210. // Allocate a receive packet
  211. m_rxpkt = m_sess.allocatePacket(PacketSize);
  212. // Initialize the packet
  213. m_rxpkt.setUserId(m_sess.getUserId());
  214. m_rxpkt.setTreeId(m_sess.getTreeId());
  215. }
  216. // Read a packet of data from the remote file
  217. m_rxpkt.setCommand(PacketType.ReadAndX);
  218. m_rxpkt.setParameterCount(isNTDialect() ? 12 : 10);
  219. m_rxpkt.setAndXCommand(PacketType.NoChainedCommand);
  220. m_rxpkt.setFlags(m_sess.getDefaultFlags());
  221. m_rxpkt.setFlags2(m_sess.getDefaultFlags2());
  222. m_rxpkt.setProcessId(m_sess.getProcessId());
  223. // Set the file id and read offset
  224. m_rxpkt.setParameter(2, getFileId());
  225. m_rxpkt.setParameterLong(3, (int) (m_rxpos & 0xFFFFFFFF));
  226. // Set the maximum/minimum read size
  227. int maxCount = m_rxpkt.getBuffer().length - 64;
  228. if ( (m_rxpos + maxCount) > getFileSize())
  229. maxCount = (int) (getFileSize() - m_rxpos);
  230. m_rxpkt.setParameter(5, maxCount);
  231. m_rxpkt.setParameter(6, 0);
  232. // Reserved value, must be zero
  233. m_rxpkt.setParameterLong(7, 0);
  234. // Bytes remaining to satisfy request
  235. m_rxpkt.setParameter(9, maxCount);
  236. // Set the top 32bits of the file offset for NT dialect
  237. if ( isNTDialect())
  238. m_rxpkt.setParameterLong(10, (int) ((m_rxpos >> 32) & 0x0FFFFFFFFL));
  239. // No byte data
  240. m_rxpkt.setByteCount(0);
  241. // Exchange the read data SMB packet with the file server
  242. m_rxpkt.ExchangeSMB(m_sess, m_rxpkt, true);
  243. // Check if a valid response was received
  244. if ( m_rxpkt.isValidResponse()) {
  245. // Set the received data length and offset within the received data
  246. m_rxlen = m_rxpkt.getParameter(5);
  247. m_rxoffset = m_rxpkt.getParameter(6) + RFCNetBIOSProtocol.HEADER_LEN;
  248. // Update the current receive file position
  249. m_rxpos += m_rxlen;
  250. // Check if we have reached the end of file, indicated by a zero length
  251. // read.
  252. if ( m_rxlen == 0)
  253. setStateFlag(SMBFile.EndOfFile, true);
  254. return true;
  255. }
  256. // Return a failure status
  257. return false;
  258. }
  259. /**
  260. * Write a block of data to the file.
  261. *
  262. * @param buf Byte buffer containing data to be written.
  263. * @param siz Length of data to be written.
  264. * @param offset Offset within buffer to start writing data from.
  265. * @return Actual length of data written.
  266. * @exception java.io.IOException If an I/O error occurs
  267. * @exception SMBException If an SMB level error occurs
  268. */
  269. public final int Write(byte[] buf, int siz, int offset)
  270. throws java.io.IOException, SMBException {
  271. // Check if the file has been closed
  272. if ( this.isClosed())
  273. return 0;
  274. // Allocate and initialize a transmit packet, if not already allocated
  275. if ( m_txpkt == null) {
  276. // Allocate a transmit packet
  277. m_txpkt = m_sess.allocatePacket(PacketSize);
  278. // Initialize the packet
  279. m_txpkt.setUserId(m_sess.getUserId());
  280. m_txpkt.setTreeId(m_sess.getTreeId());
  281. m_txpkt.setProcessId(m_sess.getProcessId());
  282. // Set the write SMB parameter count now, so that we can calculate the
  283. // offset of the byte buffer within the packet.
  284. m_txpkt.setParameterCount(isNTDialect() ? 14 : 12);
  285. // Clear the write packet length and initialize the write packet offset.
  286. m_txlen = 0;
  287. m_txoffset = WriteDataOffset;
  288. if ( isNTDialect())
  289. m_txoffset += 4;
  290. }
  291. // Move the data to the write packet and send write requests until the
  292. // user write has been done.
  293. int txlen = 0;
  294. while (txlen < siz) {
  295. // Determine if the current write request can be buffered in full
  296. byte[] pktbuf = m_txpkt.getBuffer();
  297. int len = pktbuf.length - m_txoffset;
  298. if ( len > (siz - txlen))
  299. len = siz - txlen;
  300. // Move the user data to the write packet
  301. System.arraycopy(buf, offset, pktbuf, m_txoffset, len);
  302. m_txoffset += len;
  303. offset += len;
  304. // Update the written data length
  305. txlen += len;
  306. m_txlen += len;
  307. // Check if the write packet is full, if so then send the write packet
  308. if ( m_txoffset >= pktbuf.length)
  309. WriteData();
  310. } // end while writing
  311. // Return the length of the data that was written
  312. return txlen;
  313. }
  314. /**
  315. * Write a packet of data to the remote file.
  316. *
  317. * @return true if the write was successful, else false
  318. * @exception SMBException If an SMB level error occurs
  319. * @exception IOException If an I/O error occurs
  320. */
  321. private final boolean WriteData()
  322. throws SMBException, IOException {
  323. // Check if the file offset requires large file support (64bit offsets)
  324. if ( isNTDialect() == false && m_txpos > Maximum32BitOffset)
  325. throw new SMBException(SMBStatus.JLANErr, SMBStatus.JLANLargeFilesNotSupported);
  326. // Write a packet of data to the remote file
  327. m_txpkt.setCommand(PacketType.WriteAndX);
  328. m_txpkt.setAndXCommand(PacketType.NoChainedCommand);
  329. m_txpkt.setFlags(m_sess.getDefaultFlags());
  330. m_txpkt.setFlags2(m_sess.getDefaultFlags2());
  331. m_txpkt.setParameterCount(isNTDialect() ? 14 : 12);
  332. // Set the file id and file offset
  333. m_txpkt.setParameter(2, getFileId());
  334. m_txpkt.setParameterLong(3, (int) (m_txpos & 0xFFFFFFFF));
  335. m_txpkt.setParameterLong(5, 0);
  336. // Set the write mode
  337. m_txpkt.setParameter(6, 0); // write-through mode
  338. // Set the bytes remaining for request and reserved area
  339. m_txpkt.setParameterLong(8, 0);
  340. // Set the data length and offset from start of packet
  341. m_txpkt.setParameter(10, m_txlen);
  342. int offset = WriteDataOffset - RFCNetBIOSProtocol.HEADER_LEN;
  343. if ( isNTDialect())
  344. offset += 4;
  345. m_txpkt.setParameter(11, offset);
  346. // Add the top 32bits of the file offset, for NT dialect. Set the byte count, includes any
  347. // padding bytes
  348. if ( isNTDialect()) {
  349. // Set the top 32bits of the file offset
  350. m_txpkt.setParameterLong(12, (int) ((m_txpos >> 32) & 0xFFFFFFFFL));
  351. }
  352. // Set the byte count, includes any padding bytes
  353. m_txpkt.setByteCount(m_txlen + WriteDataPadding);
  354. // Exchange the write data SMB packet with the file server
  355. m_txpkt.ExchangeSMB(m_sess, m_txpkt, false);
  356. // Check if a valid response was received
  357. if ( m_txpkt.isValidResponse()) {
  358. // Set the write data length
  359. int txlen = m_txpkt.getParameter(2);
  360. // Update the current write file position
  361. m_txpos += txlen;
  362. // Reset the write packet and write length
  363. m_txlen = 0;
  364. m_txoffset = WriteDataOffset;
  365. if ( isNTDialect())
  366. m_txoffset += 4;
  367. return true;
  368. }
  369. else {
  370. // Reset the write packet and write length
  371. m_txlen = 0;
  372. m_txoffset = WriteDataOffset;
  373. if ( isNTDialect())
  374. m_txoffset += 4;
  375. // Throw an exception
  376. m_txpkt.checkForError();
  377. }
  378. // Return a failure status
  379. return false;
  380. }
  381. /**
  382. * Seek to the specified point in the file. The seek may be relative to the start of file,
  383. * current file position or end of file.
  384. *
  385. * @param pos Relative offset
  386. * @param typ Seek type (@see org.alfresco.jlan.smb.SeekType)
  387. * @return New file offset from start of file
  388. * @exception IOException
  389. * @exception SMBException If an SMB level error occurs
  390. */
  391. public long Seek(long pos, int typ)
  392. throws IOException, SMBException {
  393. // Check if the file has been closed
  394. if ( this.isClosed())
  395. throw new IOException("Seek on closed file");
  396. // Flush any buffered data
  397. Flush();
  398. // Reset the read/write offsets to the new file position
  399. switch (typ) {
  400. // Seek relative to the start of file
  401. case SeekType.StartOfFile:
  402. m_txpos = m_rxpos = pos;
  403. break;
  404. // Seek realtive to the current file position
  405. case SeekType.CurrentPos:
  406. m_txpos = m_rxpos + pos;
  407. m_rxpos = m_txpos;
  408. break;
  409. // Seek relative to end of file
  410. case SeekType.EndOfFile:
  411. m_txpos = m_rxpos = getFileSize() + pos;
  412. break;
  413. }
  414. // Indicate that there is no buffered data
  415. m_txlen = 0;
  416. m_rxlen = 0;
  417. // Return the new file offset
  418. return m_rxpos;
  419. }
  420. /**
  421. * Lock a range of bytes within the file
  422. *
  423. * @param offset Offset within the file to start lock
  424. * @param len Number of bytes to lock
  425. * @exception IOException
  426. * @exception SMBException If an SMB level error occurs
  427. */
  428. public void Lock(long offset, long len)
  429. throws IOException, SMBException {
  430. // Check if the file offset requires large file support (64bit offsets)
  431. if ( isNTDialect() == false && offset > Maximum32BitOffset)
  432. throw new SMBException(SMBStatus.JLANErr, SMBStatus.JLANLargeFilesNotSupported);
  433. // Create the lock request packet
  434. SMBPacket pkt = new SMBPacket();
  435. pkt.setUserId(m_sess.getUserId());
  436. pkt.setTreeId(m_sess.getTreeId());
  437. pkt.setCommand(PacketType.LockingAndX);
  438. pkt.setProcessId(m_sess.getProcessId());
  439. // Set the parameters
  440. pkt.setParameterCount(8);
  441. pkt.setAndXCommand(PacketType.NoChainedCommand);
  442. pkt.setParameter(2, m_FID);
  443. pkt.setParameter(3, m_sess.supportsLargeFiles() ? LockingAndX.LargeFiles : 0);
  444. pkt.setParameterLong(4, 0); // timeout, for unlock
  445. pkt.setParameter(6, 0); // number of unlock structures
  446. pkt.setParameter(7, 1); // number of lock structures
  447. // Pack the lock structure
  448. pkt.resetBytePointer();
  449. if ( m_sess.supportsLargeFiles()) {
  450. // Pack a large file (64bit) format structure
  451. pkt.packWord(m_sess.getProcessId());
  452. pkt.packWord(0);
  453. pkt.packInt((int) ((offset >> 32) & 0xFFFFFFFFL));
  454. pkt.packInt((int) (offset & 0xFFFFFFFFL));
  455. pkt.packInt((int) ((len >> 32) & 0xFFFFFFFFL));
  456. pkt.packInt((int) (len & 0xFFFFFFFFL));
  457. }
  458. else {
  459. // Pack a normal (32bit) format structure
  460. pkt.packWord(m_sess.getProcessId());
  461. pkt.packInt((int) (offset & 0xFFFFFFFFL));
  462. pkt.packInt((int) (len & 0xFFFFFFFFL));
  463. }
  464. // Set the byte count
  465. pkt.setByteCount();
  466. // Send the lock request
  467. pkt.ExchangeSMB(m_sess, pkt, true);
  468. }
  469. /**
  470. * Unlock a range of bytes within the file
  471. *
  472. * @param offset Offset within the file to unlock
  473. * @param len Number of bytes to unlock
  474. * @exception IOException
  475. * @exception SMBException If an SMB level error occurs
  476. */
  477. public void Unlock(long offset, long len)
  478. throws IOException, SMBException {
  479. // Check if the file offset requires large file support (64bit offsets)
  480. if ( isNTDialect() == false && offset > Maximum32BitOffset)
  481. throw new SMBException(SMBStatus.JLANErr, SMBStatus.JLANLargeFilesNotSupported);
  482. // Create the unlock request packet
  483. SMBPacket pkt = new SMBPacket();
  484. pkt.setUserId(m_sess.getUserId());
  485. pkt.setTreeId(m_sess.getTreeId());
  486. pkt.setCommand(PacketType.LockingAndX);
  487. pkt.setProcessId(m_sess.getProcessId());
  488. // Set the parameters
  489. pkt.setParameterCount(8);
  490. pkt.setAndXCommand(PacketType.NoChainedCommand);
  491. pkt.setParameter(2, m_FID);
  492. pkt.setParameter(3, m_sess.supportsLargeFiles() ? LockingAndX.LargeFiles : 0);
  493. pkt.setParameterLong(4, 0); // timeout, for unlock
  494. pkt.setParameter(6, 1); // number of unlock structures
  495. pkt.setParameter(7, 0); // number of lock structures
  496. // Pack the unlock structure
  497. pkt.resetBytePointer();
  498. if ( m_sess.supportsLargeFiles()) {
  499. // Pack a large file (64bit) format structure
  500. pkt.packWord(m_sess.getProcessId());
  501. pkt.packWord(0);
  502. pkt.packInt((int) ((offset >> 32) & 0xFFFFFFFFL));
  503. pkt.packInt((int) (offset & 0xFFFFFFFFL));
  504. pkt.packInt((int) ((len >> 32) & 0xFFFFFFFFL));
  505. pkt.packInt((int) (len & 0xFFFFFFFFL));
  506. }
  507. else {
  508. // Pack a normal (32bit) format structure
  509. pkt.packWord(m_sess.getProcessId());
  510. pkt.packInt((int) (offset & 0xFFFFFFFFL));
  511. pkt.packInt((int) (len & 0xFFFFFFFFL));
  512. }
  513. // Set the byte count
  514. pkt.setByteCount();
  515. // Send the unlock request
  516. pkt.ExchangeSMB(m_sess, pkt, true);
  517. }
  518. /**
  519. * Check if NT dialect SMBs should be used
  520. *
  521. * @return boolean
  522. */
  523. protected final boolean isNTDialect() {
  524. return m_NTdialect;
  525. }
  526. /**
  527. * Check if the file is a repars point
  528. *
  529. * @return boolean
  530. */
  531. public final boolean isReparsePoint() {
  532. return (getAttributes() & FileAttribute.NTReparsePoint) != 0 ? true : false;
  533. }
  534. /**
  535. * Check if the file has an associated oplock
  536. *
  537. * @return int
  538. */
  539. public final int getOplockType() {
  540. return m_oplockType;
  541. }
  542. /**
  543. * Set the oplock type
  544. *
  545. * @param oplockTyp int
  546. */
  547. protected void setOplockType( int oplockTyp) {
  548. m_oplockType = oplockTyp;
  549. }
  550. /**
  551. * Set the oplock interface
  552. *
  553. * @param oplockIface OplockInterface
  554. */
  555. protected void setOplockInterface( OplockInterface oplockIface) {
  556. m_oplockIface = oplockIface;
  557. }
  558. /**
  559. * Return the oplock interface
  560. *
  561. * @return OplockInterface
  562. */
  563. protected OplockInterface getOplockInterface() {
  564. return m_oplockIface;
  565. }
  566. }