示例#1
0
 /// <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);
     }
 }
示例#2
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();
         }
     }
 }