/// <exception cref="SharpCifs.Smb.SmbException"></exception> /// <exception cref="System.UriFormatException"></exception> /// <exception cref="UnknownHostException"></exception> public SmbRandomAccessFile(SmbFile file, string mode) { this._file = file; if (mode.Equals("r")) { _openFlags = SmbFile.OCreat | SmbFile.ORdonly; } else { if (mode.Equals("rw")) { _openFlags = SmbFile.OCreat | SmbFile.ORdwr | SmbFile.OAppend; _writeAndxResp = new SmbComWriteAndXResponse(); _options = WriteOptions; _access = SmbConstants.FileReadData | SmbConstants.FileWriteData; } else { throw new ArgumentException("Invalid mode"); } } file.Open(_openFlags, _access, SmbFile.AttrNormal, _options); _readSize = file.Tree.Session.transport.RcvBufSize - 70; _writeSize = file.Tree.Session.transport.SndBufSize - 70; _fp = 0L; }
/// <exception cref="SharpCifs.Smb.SmbException"></exception> /// <exception cref="System.UriFormatException"></exception> /// <exception cref="UnknownHostException"></exception> internal SmbFileInputStream(SmbFile file, int openFlags) { this.File = file; this._openFlags = openFlags & 0xFFFF; _access = ((int)(((uint)openFlags) >> 16)) & 0xFFFF; if (file.Type != SmbFile.TypeNamedPipe) { file.Open(openFlags, _access, SmbFile.AttrNormal, 0); this._openFlags &= ~(SmbFile.OCreat | SmbFile.OTrunc); } else { file.Connect0(); } _readSize = Math.Min(file.Tree.Session.transport.RcvBufSize - 70, file.Tree.Session .transport.Server.MaxBufferSize - 70); }
/// <summary> /// Constructs an SmbFile representing a resource on an SMB network such /// as a file or directory. /// </summary> /// <remarks> /// Constructs an SmbFile representing a resource on an SMB network such /// as a file or directory. The second parameter is a relative path from /// the <code>context</code>. See the description above for examples of /// using the second <code>name</code> parameter. The <tt>shareAccess</tt> /// parameter controls what permissions other clients have when trying /// to access the same file while this instance is still open. This /// value is either <tt>FILE_NO_SHARE</tt> or any combination /// of <tt>FILE_SHARE_READ</tt>, <tt>FILE_SHARE_WRITE</tt>, and /// <tt>FILE_SHARE_DELETE</tt> logically OR'd together. /// </remarks> /// <param name="context">A base <code>SmbFile</code></param> /// <param name="name">A path string relative to the <code>context</code> file path</param> /// <param name="shareAccess">Specifies what access other clients have while this file is open. /// </param> /// <exception cref="System.UriFormatException"> /// If the <code>context</code> and <code>name</code> parameters /// do not follow the prescribed syntax /// </exception> /// <exception cref="UnknownHostException"></exception> public SmbFile(SmbFile context, string name, int shareAccess) : this(context.IsWorkgroup0() ? new Uri("smb://" + name) : new Uri( context.Url.AbsoluteUri + name), context.Auth) { if ((shareAccess & ~(FileShareRead | FileShareWrite | FileShareDelete)) != 0) { throw new RuntimeException("Illegal shareAccess parameter"); } if (!context.IsWorkgroup0()) { this.Addresses = context.Addresses; if (context._share != null || context.Tree != null) { Tree = context.Tree; _dfsReferral = context._dfsReferral; } } this._shareAccess = shareAccess; this._enableDfs = context.EnableDfs; }
/// <summary> /// Constructs an SmbFile representing a resource on an SMB network such /// as a file or directory. /// </summary> /// <remarks> /// Constructs an SmbFile representing a resource on an SMB network such /// as a file or directory. The second parameter is a relative path from /// the <code>parent SmbFile</code>. See the description above for examples /// of using the second <code>name</code> parameter. /// </remarks> /// <param name="context">A base <code>SmbFile</code></param> /// <param name="name">A path string relative to the <code>parent</code> paremeter</param> /// <exception cref="System.UriFormatException"> /// If the <code>parent</code> and <code>child</code> parameters /// do not follow the prescribed syntax /// </exception> /// <exception cref="UnknownHostException">If the server or workgroup of the <tt>context</tt> file cannot be determined /// </exception> public SmbFile(SmbFile context, string name) : this(context.IsWorkgroup0 () ? new Uri("smb://" + name) : new Uri(context.Url.AbsoluteUri + name), context.Auth) { this._enableDfs = context.EnableDfs; if (!context.IsWorkgroup0()) { Addresses = context.Addresses; if (context._share != null) { Tree = context.Tree; _dfsReferral = context._dfsReferral; } } }
/// <summary> /// Creates a directory with the path specified by this <tt>SmbFile</tt> /// and any parent directories that do not exist. /// </summary> /// <remarks> /// Creates a directory with the path specified by this <tt>SmbFile</tt> /// and any parent directories that do not exist. This method will fail /// when used with <code>smb://</code>, <code>smb://workgroup/</code>, /// <code>smb://server/</code>, or <code>smb://server/share/</code> URLs /// because workgroups, servers, and shares cannot be dynamically created /// (although in the future it may be possible to create shares). /// </remarks> /// <exception cref="SmbException">SmbException</exception> /// <exception cref="SharpCifs.Smb.SmbException"></exception> public virtual void Mkdirs() { SmbFile parent; try { parent = new SmbFile(GetParent(), Auth); } catch (IOException) { return; } if (parent.Exists() == false) { parent.Mkdirs(); } Mkdir(); }
/// <summary> /// This method will copy the file or directory represented by this /// <tt>SmbFile</tt> and it's sub-contents to the location specified by the /// <tt>dest</tt> parameter. /// </summary> /// <remarks> /// This method will copy the file or directory represented by this /// <tt>SmbFile</tt> and it's sub-contents to the location specified by the /// <tt>dest</tt> parameter. This file and the destination file do not /// need to be on the same host. This operation does not copy extended /// file attibutes such as ACLs but it does copy regular attributes as /// well as create and last write times. This method is almost twice as /// efficient as manually copying as it employs an additional write /// thread to read and write data concurrently. /// <p/> /// It is not possible (nor meaningful) to copy entire workgroups or /// servers. /// </remarks> /// <param name="dest">the destination file or directory</param> /// <exception cref="SmbException">SmbException</exception> /// <exception cref="SharpCifs.Smb.SmbException"></exception> public virtual void CopyTo(SmbFile dest) { SmbComReadAndX req; SmbComReadAndXResponse resp; WriterThread w; int bsize; byte[][] b; if (_share == null || dest._share == null) { throw new SmbException("Invalid operation for workgroups or servers"); } req = new SmbComReadAndX(); resp = new SmbComReadAndXResponse(); Connect0(); dest.Connect0(); ResolveDfs(null); try { if (GetAddress().Equals(dest.GetAddress()) && _canon.RegionMatches(true, 0, dest._canon , 0, Math.Min(_canon.Length, dest._canon.Length))) { throw new SmbException("Source and destination paths overlap."); } } catch (UnknownHostException) { } w = new WriterThread(this); w.SetDaemon(true); w.Start(); SmbTransport t1 = Tree.Session.transport; SmbTransport t2 = dest.Tree.Session.transport; if (t1.SndBufSize < t2.SndBufSize) { t2.SndBufSize = t1.SndBufSize; } else { t1.SndBufSize = t2.SndBufSize; } bsize = Math.Min(t1.RcvBufSize - 70, t1.SndBufSize - 70); b = new[] { new byte[bsize], new byte[bsize] }; try { CopyTo0(dest, b, bsize, w, req, resp); } finally { w.Write(null, -1, null, 0); } }
/// <exception cref="SharpCifs.Smb.SmbException"></exception> internal virtual void CopyTo0(SmbFile dest, byte[][] b, int bsize, WriterThread w, SmbComReadAndX req, SmbComReadAndXResponse resp) { int i; if (_attrExpiration < Runtime.CurrentTimeMillis()) { _attributes = AttrReadonly | AttrDirectory; _createTime = 0L; _lastModified = 0L; _isExists = false; IInfo info = QueryPath(GetUncPath0(), Trans2QueryPathInformationResponse.SMB_QUERY_FILE_BASIC_INFO ); _attributes = info.GetAttributes(); _createTime = info.GetCreateTime(); _lastModified = info.GetLastWriteTime(); _isExists = true; _attrExpiration = Runtime.CurrentTimeMillis() + AttrExpirationPeriod; } if (IsDirectory()) { SmbFile[] files; SmbFile ndest; string path = dest.GetUncPath0(); if (path.Length > 1) { try { dest.Mkdir(); dest.SetPathInformation(_attributes, _createTime, _lastModified); } catch (SmbException se) { if (se.GetNtStatus() != NtStatus.NtStatusAccessDenied && se.GetNtStatus() != NtStatus .NtStatusObjectNameCollision) { throw; } } } files = ListFiles("*", AttrDirectory | AttrHidden | AttrSystem, null, null); try { for (i = 0; i < files.Length; i++) { ndest = new SmbFile(dest, files[i].GetName(), files[i].Type, files[i]._attributes, files[i]._createTime, files[i]._lastModified, files[i]._size); files[i].CopyTo0(ndest, b, bsize, w, req, resp); } } catch (UnknownHostException uhe) { throw new SmbException(Url.ToString(), uhe); } catch (UriFormatException mue) { throw new SmbException(Url.ToString(), mue); } } else { long off; try { Open(ORdonly, 0, AttrNormal, 0); try { dest.Open(OCreat | OWronly | OTrunc, SmbConstants.FileWriteData | SmbConstants.FileWriteAttributes, _attributes, 0); } catch (SmbAuthException sae) { if ((dest._attributes & AttrReadonly) != 0) { dest.SetPathInformation(dest._attributes & ~AttrReadonly, 0L, 0L); dest.Open(OCreat | OWronly | OTrunc, SmbConstants.FileWriteData | SmbConstants.FileWriteAttributes, _attributes, 0); } else { throw; } } i = 0; off = 0L; for (; ; ) { req.SetParam(Fid, off, bsize); resp.SetParam(b[i], 0); Send(req, resp); lock (w) { if (w.E != null) { throw w.E; } while (!w.Ready) { try { Runtime.Wait(w); } catch (Exception ie) { throw new SmbException(dest.Url.ToString(), ie); } } if (w.E != null) { throw w.E; } if (resp.DataLength <= 0) { break; } w.Write(b[i], resp.DataLength, dest, off); } i = i == 1 ? 0 : 1; off += resp.DataLength; } dest.Send(new Trans2SetFileInformation(dest.Fid, _attributes, _createTime, _lastModified ), new Trans2SetFileInformationResponse()); dest.Close(0L); } catch (SmbException se) { if (IgnoreCopyToException == false) { throw new SmbException("Failed to copy file from [" + ToString() + "] to [" + dest + "]", se); } if (Log.Level > 1) { Runtime.PrintStackTrace(se, Log); } } finally { Close(); } } }
/// <summary> /// Rename file async /// </summary> /// <param name="smbFile"></param> /// <param name="destination"></param> /// <returns></returns> public static Task RenameToAsync(this SmbFile smbFile, SmbFile destination) { return Task.Run(() => smbFile.RenameTo(destination)); }
/// <exception cref="SharpCifs.Smb.SmbException"></exception> /// <exception cref="System.UriFormatException"></exception> /// <exception cref="UnknownHostException"></exception> internal SmbFileOutputStream(SmbFile file, bool append, int openFlags) { this._file = file; this._append = append; this._openFlags = openFlags; _access = ((int)(((uint)openFlags) >> 16)) & 0xFFFF; if (append) { try { _fp = file.Length(); } catch (SmbAuthException sae) { throw; } catch (SmbException) { _fp = 0L; } } if (file is SmbNamedPipe && file.Unc.StartsWith("\\pipe\\")) { file.Unc = Runtime.Substring(file.Unc, 5); file.Send(new TransWaitNamedPipe("\\pipe" + file.Unc), new TransWaitNamedPipeResponse ()); } file.Open(openFlags, _access | SmbConstants.FileWriteData, SmbFile.AttrNormal, 0); this._openFlags &= ~(SmbFile.OCreat | SmbFile.OTrunc); _writeSize = file.Tree.Session.transport.SndBufSize - 70; _useNtSmbs = file.Tree.Session.transport.HasCapability(SmbConstants.CapNtSmbs ); if (_useNtSmbs) { _reqx = new SmbComWriteAndX(); _rspx = new SmbComWriteAndXResponse(); } else { _req = new SmbComWrite(); _rsp = new SmbComWriteResponse(); } }
/// <summary> /// Changes the name of the file this <code>SmbFile</code> represents to the name /// designated by the <code>SmbFile</code> argument. /// </summary> /// <remarks> /// Changes the name of the file this <code>SmbFile</code> represents to the name /// designated by the <code>SmbFile</code> argument. /// <p/> /// <i>Remember: <code>SmbFile</code>s are immutible and therefore /// the path associated with this <code>SmbFile</code> object will not /// change). To access the renamed file it is necessary to construct a /// new <tt>SmbFile</tt></i>. /// </remarks> /// <param name="dest">An <code>SmbFile</code> that represents the new pathname</param> /// <exception cref="System.ArgumentNullException">If the <code>dest</code> argument is <code>null</code> /// </exception> /// <exception cref="SharpCifs.Smb.SmbException"></exception> public virtual void RenameTo(SmbFile dest) { if (GetUncPath0().Length == 1 || dest.GetUncPath0().Length == 1) { throw new SmbException("Invalid operation for workgroups, servers, or shares"); } ResolveDfs(null); dest.ResolveDfs(null); if (!Tree.Equals(dest.Tree)) { throw new SmbException("Invalid operation for workgroups, servers, or shares"); } if (Log.Level >= 3) { Log.WriteLine("renameTo: " + Unc + " -> " + dest.Unc); } _attrExpiration = _sizeExpiration = 0; dest._attrExpiration = 0; Send(new SmbComRename(Unc, dest.Unc), Blank_resp()); }
/// <exception cref="SharpCifs.Smb.SmbException"></exception> /// <exception cref="UnknownHostException"></exception> /// <exception cref="System.UriFormatException"></exception> internal virtual void DoFindFirstNext(List<object> list, bool files, string wildcard , int searchAttributes, ISmbFilenameFilter fnf, ISmbFileFilter ff) { SmbComTransaction req; Trans2FindFirst2Response resp; int sid; string path = GetUncPath0(); string p = Url.AbsolutePath; if (p.LastIndexOf('/') != (p.Length - 1)) { throw new SmbException(Url + " directory must end with '/'"); } req = new Trans2FindFirst2(path, wildcard, searchAttributes); resp = new Trans2FindFirst2Response(); if (Log.Level >= 3) { Log.WriteLine("doFindFirstNext: " + req.Path); } Send(req, resp); sid = resp.Sid; req = new Trans2FindNext2(sid, resp.ResumeKey, resp.LastName); resp.SubCommand = SmbComTransaction.Trans2FindNext2; for (; ; ) { for (int i = 0; i < resp.NumEntries; i++) { IFileEntry e = resp.Results[i]; string name = e.GetName(); if (name.Length < 3) { int h = name.GetHashCode(); if (h == HashDot || h == HashDotDot) { if (name.Equals(".") || name.Equals("..")) { continue; } } } if (fnf != null && fnf.Accept(this, name) == false) { continue; } if (name.Length > 0) { SmbFile f = new SmbFile(this, name, TypeFilesystem, e.GetAttributes (), e.CreateTime(), e.LastModified(), e.Length()); if (ff != null && ff.Accept(f) == false) { continue; } if (files) { list.Add(f); } else { list.Add(name); } } } if (resp.IsEndOfSearch || resp.NumEntries == 0) { break; } req.Reset(resp.ResumeKey, resp.LastName); resp.Reset(); Send(req, resp); } try { Send(new SmbComFindClose2(sid), Blank_resp()); } catch (SmbException se) { if (Log.Level >= 4) { Runtime.PrintStackTrace(se, Log); } } }
/// <exception cref="SharpCifs.Smb.SmbException"></exception> /// <exception cref="UnknownHostException"></exception> /// <exception cref="System.UriFormatException"></exception> internal virtual void DoNetServerEnum(List<object> list, bool files, string wildcard , int searchAttributes, ISmbFilenameFilter fnf, ISmbFileFilter ff) { int listType = Url.GetHost().Length == 0 ? 0 : GetType(); SmbComTransaction req; SmbComTransactionResponse resp; if (listType == 0) { Connect0(); req = new NetServerEnum2(Tree.Session.transport.Server.OemDomainName, NetServerEnum2 .SvTypeDomainEnum); resp = new NetServerEnum2Response(); } else { if (listType == TypeWorkgroup) { req = new NetServerEnum2(Url.GetHost(), NetServerEnum2.SvTypeAll); resp = new NetServerEnum2Response(); } else { throw new SmbException("The requested list operations is invalid: " + Url); } } bool more; do { int n; Send(req, resp); if (resp.Status != WinError.ErrorSuccess && resp.Status != WinError.ErrorMoreData) { throw new SmbException(resp.Status, true); } more = resp.Status == WinError.ErrorMoreData; n = more ? resp.NumEntries - 1 : resp.NumEntries; for (int i = 0; i < n; i++) { IFileEntry e = resp.Results[i]; string name = e.GetName(); if (fnf != null && fnf.Accept(this, name) == false) { continue; } if (name.Length > 0) { // if !files we don't need to create SmbFiles here SmbFile f = new SmbFile(this, name, e.GetType(), AttrReadonly | AttrDirectory, 0L, 0L, 0L); if (ff != null && ff.Accept(f) == false) { continue; } if (files) { list.Add(f); } else { list.Add(name); } } } if (GetType() != TypeWorkgroup) { break; } req.SubCommand = unchecked(SmbComTransaction.NetServerEnum3); req.Reset(0, ((NetServerEnum2Response)resp).LastName); resp.Reset(); } while (more); }
/// <exception cref="SharpCifs.Smb.SmbException"></exception> /// <exception cref="UnknownHostException"></exception> /// <exception cref="System.UriFormatException"></exception> internal virtual void DoShareEnum(List<object> list, bool files, string wildcard, int searchAttributes, ISmbFilenameFilter fnf, ISmbFileFilter ff) { string p = Url.AbsolutePath; IOException last = null; IFileEntry[] entries; UniAddress addr; IFileEntry e; Hashtable map; if (p.LastIndexOf('/') != (p.Length - 1)) { throw new SmbException(Url + " directory must end with '/'"); } if (GetType() != TypeServer) { throw new SmbException("The requested list operations is invalid: " + Url); } map = new Hashtable(); if (_enableDfs && Dfs.IsTrustedDomain(GetServer(), Auth)) { try { entries = DoDfsRootEnum(); for (int ei = 0; ei < entries.Length; ei++) { e = entries[ei]; if (map.ContainsKey(e) == false) { map.Put(e, e); } } } catch (IOException ioe) { if (Log.Level >= 4) { Runtime.PrintStackTrace(ioe, Log); } } } addr = GetFirstAddress(); while (addr != null) { try { last = null; DoConnect(); try { entries = DoMsrpcShareEnum(); } catch (IOException ioe) { if (Log.Level >= 3) { Runtime.PrintStackTrace(ioe, Log); } entries = DoNetShareEnum(); } for (int ei = 0; ei < entries.Length; ei++) { e = entries[ei]; if (map.ContainsKey(e) == false) { map.Put(e, e); } } break; } catch (IOException ioe) { if (Log.Level >= 3) { Runtime.PrintStackTrace(ioe, Log); } last = ioe; if (!(ioe is SmbAuthException)) { RemoveCurrentAddress(); addr = GetNextAddress(); } else { break; } } } if (last != null && map.Count == 0) { if (last is SmbException == false) { throw new SmbException(Url.ToString(), last); } throw (SmbException)last; } //Iterator iter = map.Keys.Iterator(); //while (iter.HasNext()) foreach (var item in map.Keys) { e = (IFileEntry)item; string name = e.GetName(); if (fnf != null && fnf.Accept(this, name) == false) { continue; } if (name.Length > 0) { // if !files we don't need to create SmbFiles here SmbFile f = new SmbFile(this, name, e.GetType(), AttrReadonly | AttrDirectory, 0L, 0L, 0L); if (ff != null && ff.Accept(f) == false) { continue; } if (files) { list.Add(f); } else { list.Add(name); } } } }
/// <summary> /// Creates an /// <see cref="System.IO.InputStream">System.IO.InputStream</see> /// for reading bytes from a file on /// an SMB server represented by the /// <see cref="SmbFile">SmbFile</see> /// parameter. See /// <see cref="SmbFile">SmbFile</see> /// for a detailed description and examples of /// the smb URL syntax. /// </summary> /// <param name="file">An <code>SmbFile</code> specifying the file to read from</param> /// <exception cref="SharpCifs.Smb.SmbException"></exception> /// <exception cref="System.UriFormatException"></exception> /// <exception cref="UnknownHostException"></exception> public SmbFileInputStream(SmbFile file) : this(file, SmbFile.ORdonly) { }
/// <exception cref="System.UriFormatException"></exception> /// <exception cref="UnknownHostException"></exception> /*internal SmbFile(Jcifs.Smb.SmbFile context, string name, int type, int attributes , long createTime, long lastModified, long size) : this(context.IsWorkgroup0() ? new Uri(null, "smb://" + name + "/") : new Uri(context.url, name + ((attributes & ATTR_DIRECTORY) > 0 ? "/" : string.Empty)))*/ internal SmbFile(SmbFile context, string name, int type, int attributes , long createTime, long lastModified, long size) : this(context.IsWorkgroup0() ? new Uri("smb://" + name + "/") : new Uri(context.Url.AbsoluteUri + name + ((attributes & AttrDirectory) > 0 ? "/" : string.Empty))) { Auth = context.Auth; if (context._share != null) { Tree = context.Tree; _dfsReferral = context._dfsReferral; } int last = name.Length - 1; if (name[last] == '/') { name = Runtime.Substring(name, 0, last); } if (context._share == null) { Unc = "\\"; } else { if (context.Unc.Equals("\\")) { Unc = '\\' + name; } else { Unc = context.Unc + '\\' + name; } } if (!context.IsWorkgroup0()) { Addresses = context.Addresses; } this._enableDfs = context.EnableDfs; this.Type = type; this._attributes = attributes; this._createTime = createTime; this._lastModified = lastModified; this._size = size; _isExists = true; _attrExpiration = _sizeExpiration = Runtime.CurrentTimeMillis() + AttrExpirationPeriod; }
/// <summary> /// Creates an /// <see cref="System.IO.OutputStream">System.IO.OutputStream</see> /// for writing bytes to a file /// on an SMB server addressed by the <code>SmbFile</code> parameter. See /// <see cref="SmbFile">SmbFile</see> /// for a detailed description and examples of /// the smb URL syntax. If the second argument is <code>true</code>, then /// bytes will be written to the end of the file rather than the beginning. /// </summary> /// <param name="file">An <code>SmbFile</code> representing the file to write to</param> /// <param name="append">Append to the end of file</param> /// <exception cref="SharpCifs.Smb.SmbException"></exception> /// <exception cref="System.UriFormatException"></exception> /// <exception cref="UnknownHostException"></exception> public SmbFileOutputStream(SmbFile file, bool append) : this(file, append, append ? SmbFile.OCreat | SmbFile.OWronly | SmbFile.OAppend : SmbFile.OCreat | SmbFile .OWronly | SmbFile.OTrunc) { }
/// <exception cref="SharpCifs.Smb.SmbException"></exception> public WriterThread(SmbFile enclosing) : base("JCIFS-WriterThread") { this._enclosing = enclosing; UseNtSmbs = this._enclosing.Tree.Session.transport.HasCapability(SmbConstants.CapNtSmbs); if (UseNtSmbs) { Reqx = new SmbComWriteAndX(); Resp = new SmbComWriteAndXResponse(); } else { Req = new SmbComWrite(); Resp = new SmbComWriteResponse(); } Ready = false; }
/// <summary> /// Creates an /// <see cref="System.IO.OutputStream">System.IO.OutputStream</see> /// for writing bytes to a file on /// an SMB server represented by the /// <see cref="SmbFile">SmbFile</see> /// parameter. See /// <see cref="SmbFile">SmbFile</see> /// for a detailed description and examples of /// the smb URL syntax. /// </summary> /// <param name="file">An <code>SmbFile</code> specifying the file to write to</param> /// <exception cref="SharpCifs.Smb.SmbException"></exception> /// <exception cref="System.UriFormatException"></exception> /// <exception cref="UnknownHostException"></exception> public SmbFileOutputStream(SmbFile file) : this(file, false) { }
internal virtual void Write(byte[] b, int n, SmbFile dest, long off) { lock (this) { this.B = b; this.N = n; this.Dest = dest; this.Off = off; Ready = false; Runtime.Notify(this); } }