00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "file.h"
00027
00028 #include <windows.h>
00029
00030 #include <QtCore/QDir>
00031 #include <QtCore/QDirIterator>
00032 #include <QtCore/QFileInfo>
00033
00034 #include <config.h>
00035
00036 #include <kconfiggroup.h>
00037 #include <kdebug.h>
00038
00039 using namespace KIO;
00040
00041 static DWORD CALLBACK CopyProgressRoutine(
00042 LARGE_INTEGER TotalFileSize,
00043 LARGE_INTEGER TotalBytesTransferred,
00044 LARGE_INTEGER StreamSize,
00045 LARGE_INTEGER StreamBytesTransferred,
00046 DWORD dwStreamNumber,
00047 DWORD dwCallbackReason,
00048 HANDLE hSourceFile,
00049 HANDLE hDestinationFile,
00050 LPVOID lpData
00051 ) {
00052 FileProtocol *f = reinterpret_cast<FileProtocol*>(lpData);
00053 f->processedSize( TotalBytesTransferred.QuadPart );
00054 return PROGRESS_CONTINUE;
00055 }
00056
00057 static UDSEntry createUDSEntryWin( const QFileInfo &fileInfo )
00058 {
00059 UDSEntry entry;
00060
00061 entry.insert( KIO::UDSEntry::UDS_NAME, fileInfo.fileName() );
00062 if( fileInfo.isSymLink() ) {
00063 entry.insert( KIO::UDSEntry::UDS_TARGET_URL, fileInfo.symLinkTarget() );
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 }
00078 int type = S_IFREG;
00079 int access = 0;
00080 if( fileInfo.isDir() )
00081 type = S_IFDIR;
00082 else if( fileInfo.isSymLink() )
00083 type = S_IFLNK;
00084 if( fileInfo.isReadable() )
00085 access |= S_IRUSR;
00086 if( fileInfo.isWritable() )
00087 access |= S_IWUSR;
00088 if( fileInfo.isExecutable() )
00089 access |= S_IXUSR;
00090
00091 entry.insert( KIO::UDSEntry::UDS_FILE_TYPE, type );
00092 entry.insert( KIO::UDSEntry::UDS_ACCESS, access );
00093 entry.insert( KIO::UDSEntry::UDS_SIZE, fileInfo.size() );
00094 if( fileInfo.isHidden() )
00095 entry.insert( KIO::UDSEntry::UDS_HIDDEN, true );
00096
00097 entry.insert( KIO::UDSEntry::UDS_MODIFICATION_TIME, fileInfo.lastModified().toTime_t() );
00098 entry.insert( KIO::UDSEntry::UDS_USER, fileInfo.owner() );
00099 entry.insert( KIO::UDSEntry::UDS_GROUP, fileInfo.group() );
00100 entry.insert( KIO::UDSEntry::UDS_ACCESS_TIME, fileInfo.lastRead().toTime_t() );
00101
00102 return entry;
00103 }
00104
00105 void FileProtocol::copy( const KUrl &src, const KUrl &dest,
00106 int _mode, JobFlags _flags )
00107 {
00108 kDebug(7101) << "copy(): " << src << " -> " << dest << ", mode=" << _mode;
00109
00110 QFileInfo _src(src.toLocalFile());
00111 QFileInfo _dest(dest.toLocalFile());
00112 DWORD dwFlags = COPY_FILE_FAIL_IF_EXISTS;
00113
00114 if( _src == _dest ) {
00115 error( KIO::ERR_IDENTICAL_FILES, _dest.filePath() );
00116 return;
00117 }
00118
00119 if( !_src.exists() ) {
00120 error( KIO::ERR_DOES_NOT_EXIST, _src.filePath() );
00121 return;
00122 }
00123
00124 if ( _src.isDir() ) {
00125 error( KIO::ERR_IS_DIRECTORY, _src.filePath() );
00126 return;
00127 }
00128
00129 if( _dest.exists() ) {
00130 if( _dest.isDir() ) {
00131 error( KIO::ERR_DIR_ALREADY_EXIST, _dest.filePath() );
00132 return;
00133 }
00134
00135 if (!(_flags & KIO::Overwrite))
00136 {
00137 error( KIO::ERR_FILE_ALREADY_EXIST, _dest.filePath() );
00138 return;
00139 }
00140
00141 dwFlags = 0;
00142 }
00143
00144 if ( CopyFileExW( ( LPCWSTR ) _src.filePath().utf16(),
00145 ( LPCWSTR ) _dest.filePath().utf16(),
00146 CopyProgressRoutine,
00147 ( LPVOID ) this,
00148 FALSE,
00149 dwFlags) == 0 )
00150 {
00151 DWORD dwLastErr = GetLastError();
00152 if ( dwLastErr == ERROR_FILE_NOT_FOUND )
00153 error( KIO::ERR_DOES_NOT_EXIST, _src.filePath() );
00154 else if ( dwLastErr == ERROR_ACCESS_DENIED )
00155 error( KIO::ERR_ACCESS_DENIED, _dest.filePath() );
00156 else {
00157 error( KIO::ERR_CANNOT_RENAME, _src.filePath() );
00158 kDebug( 7101 ) << "Copying file "
00159 << _src.filePath()
00160 << " failed ("
00161 << dwLastErr << ")";
00162 }
00163 return;
00164 }
00165
00166 finished();
00167 }
00168
00169 void FileProtocol::listDir( const KUrl& url )
00170 {
00171 kDebug(7101) << "========= LIST " << url.url() << " =========";
00172
00173 if (!url.isLocalFile()) {
00174 KUrl redir(url);
00175 redir.setProtocol(config()->readEntry("DefaultRemoteProtocol", "smb"));
00176 redirection(redir);
00177 kDebug(7101) << "redirecting to " << redir.url();
00178 finished();
00179 return;
00180 }
00181
00182 QDir dir( url.toLocalFile() );
00183 dir.setFilter( QDir::AllEntries|QDir::Hidden );
00184
00185 if ( !dir.exists() ) {
00186 kDebug(7101) << "========= ERR_DOES_NOT_EXIST =========";
00187 error( KIO::ERR_DOES_NOT_EXIST, url.toLocalFile() );
00188 return;
00189 }
00190
00191 if ( !dir.isReadable() ) {
00192 kDebug(7101) << "========= ERR_CANNOT_ENTER_DIRECTORY =========";
00193 error( KIO::ERR_CANNOT_ENTER_DIRECTORY, url.toLocalFile() );
00194 return;
00195 }
00196 QDirIterator it( dir );
00197 UDSEntry entry;
00198 while( it.hasNext() ) {
00199 it.next();
00200 UDSEntry entry = createUDSEntryWin( it.fileInfo() );
00201
00202 listEntry( entry, false );
00203 entry.clear();
00204 }
00205
00206 listEntry( entry, true );
00207
00208 kDebug(7101) << "============= COMPLETED LIST ============";
00209
00210 finished();
00211 }
00212
00213 void FileProtocol::rename( const KUrl &src, const KUrl &dest,
00214 KIO::JobFlags _flags )
00215 {
00216 kDebug(7101) << "rename(): " << src << " -> " << dest;
00217
00218 QFileInfo _src(src.toLocalFile());
00219 QFileInfo _dest(dest.toLocalFile());
00220 DWORD dwFlags = 0;
00221
00222 if( _src == _dest ) {
00223 error( KIO::ERR_IDENTICAL_FILES, _dest.filePath() );
00224 return;
00225 }
00226
00227 if( !_src.exists() ) {
00228 error( KIO::ERR_DOES_NOT_EXIST, _src.filePath() );
00229 return;
00230 }
00231
00232 if( _dest.exists() ) {
00233 if( _dest.isDir() ) {
00234 error( KIO::ERR_DIR_ALREADY_EXIST, _dest.filePath() );
00235 return;
00236 }
00237
00238 if (!(_flags & KIO::Overwrite))
00239 {
00240 error( KIO::ERR_FILE_ALREADY_EXIST, _dest.filePath() );
00241 return;
00242 }
00243
00244 dwFlags = MOVEFILE_REPLACE_EXISTING;
00245 }
00246
00247 if ( MoveFileExW( ( LPCWSTR ) _src.filePath().utf16(),
00248 ( LPCWSTR ) _dest.filePath().utf16(), dwFlags) == 0 )
00249 {
00250 DWORD dwLastErr = GetLastError();
00251 if ( dwLastErr == ERROR_FILE_NOT_FOUND )
00252 error( KIO::ERR_DOES_NOT_EXIST, _src.filePath() );
00253 else if ( dwLastErr == ERROR_ACCESS_DENIED )
00254 error( KIO::ERR_ACCESS_DENIED, _dest.filePath() );
00255 else {
00256 error( KIO::ERR_CANNOT_RENAME, _src.filePath() );
00257 kDebug( 7101 ) << "Renaming file "
00258 << _src.filePath()
00259 << " failed ("
00260 << dwLastErr << ")";
00261 }
00262 return;
00263 }
00264
00265 finished();
00266 }
00267
00268 void FileProtocol::symlink( const QString &target, const KUrl &dest, KIO::JobFlags flags )
00269 {
00270
00271
00272 FileProtocol::copy( target, dest, 0, flags );
00273 }
00274
00275 void FileProtocol::del( const KUrl& url, bool isfile )
00276 {
00277 QString _path( url.toLocalFile() );
00278
00279
00280
00281
00282 if (isfile) {
00283 kDebug( 7101 ) << "Deleting file " << _path;
00284
00285 if( DeleteFileW( ( LPCWSTR ) _path.utf16() ) == 0 ) {
00286 DWORD dwLastErr = GetLastError();
00287 if ( dwLastErr == ERROR_PATH_NOT_FOUND )
00288 error( KIO::ERR_DOES_NOT_EXIST, _path );
00289 else if( dwLastErr == ERROR_ACCESS_DENIED )
00290 error( KIO::ERR_ACCESS_DENIED, _path );
00291 else {
00292 error( KIO::ERR_CANNOT_DELETE, _path );
00293 kDebug( 7101 ) << "Deleting file "
00294 << _path
00295 << " failed ("
00296 << dwLastErr << ")";
00297 }
00298 }
00299 } else {
00300 kDebug( 7101 ) << "Deleting directory " << _path;
00301 if (!deleteRecursive(_path))
00302 return;
00303 if( RemoveDirectoryW( ( LPCWSTR ) _path.utf16() ) == 0 ) {
00304 DWORD dwLastErr = GetLastError();
00305 if ( dwLastErr == ERROR_FILE_NOT_FOUND )
00306 error( KIO::ERR_DOES_NOT_EXIST, _path );
00307 else if( dwLastErr == ERROR_ACCESS_DENIED )
00308 error( KIO::ERR_ACCESS_DENIED, _path );
00309 else {
00310 error( KIO::ERR_CANNOT_DELETE, _path );
00311 kDebug( 7101 ) << "Deleting directory "
00312 << _path
00313 << " failed ("
00314 << dwLastErr << ")";
00315 }
00316 }
00317 }
00318 finished();
00319 }
00320
00321 void FileProtocol::chown( const KUrl& url, const QString&, const QString& )
00322 {
00323 error( KIO::ERR_CANNOT_CHOWN, url.toLocalFile() );
00324 }
00325
00326 void FileProtocol::stat( const KUrl & url )
00327 {
00328 if (!url.isLocalFile()) {
00329 KUrl redir(url);
00330 redir.setProtocol(config()->readEntry("DefaultRemoteProtocol", "smb"));
00331 redirection(redir);
00332 kDebug(7101) << "redirecting to " << redir.url();
00333 finished();
00334 return;
00335 }
00336
00337 const QString sDetails = metaData(QLatin1String("details"));
00338 int details = sDetails.isEmpty() ? 2 : sDetails.toInt();
00339 kDebug(7101) << "FileProtocol::stat details=" << details;
00340
00341 UDSEntry entry = createUDSEntryWin( QFileInfo(url.toLocalFile()) );
00342
00343 statEntry( entry );
00344
00345 finished();
00346 }