KDECore
kde_file_win.cpp
Go to the documentation of this file.
00001 /* 00002 This file is part of the KDE libraries 00003 Copyright (C) 2004 Jarosław Staniek <staniek@kde.org> 00004 Copyright (C) 2009 Christian Ehrlicher <ch.ehrlicher@gmx.de> 00005 00006 This library is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU Library General Public 00008 License version 2 as published by the Free Software Foundation. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Library General Public License for more details. 00014 00015 You should have received a copy of the GNU Library General Public License 00016 along with this library; see the file COPYING.LIB. If not, write to 00017 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00018 Boston, MA 02110-1301, USA. 00019 */ 00020 00021 // needed for _wstat64 00022 #define __MSVCRT_VERSION__ 0x601 00023 00024 #include "kde_file.h" 00025 00026 #include <QtCore/QFile> 00027 #include <errno.h> 00028 00029 #include <sys/utime.h> 00030 #include <sys/stat.h> 00031 #include <wchar.h> 00032 #define CONV(x) ((wchar_t*)x.utf16()) 00033 00035 static int kdewin_fix_mode_string(char *fixed_mode, const char *mode) 00036 { 00037 if (strlen(mode)<1 || strlen(mode)>3) { 00038 errno = EINVAL; 00039 return 1; 00040 } 00041 00042 strncpy(fixed_mode, mode, 3); 00043 if (fixed_mode[0]=='b' || fixed_mode[1]=='b' || fixed_mode[0]=='t' || fixed_mode[1]=='t') 00044 return 0; 00045 /* no 't' or 'b': append 'b' */ 00046 if (fixed_mode[1]=='+') { 00047 fixed_mode[1]='b'; 00048 fixed_mode[2]='+'; 00049 fixed_mode[3]=0; 00050 } 00051 else { 00052 fixed_mode[1]='b'; 00053 fixed_mode[2]=0; 00054 } 00055 return 0; 00056 } 00057 00059 static int kdewin_fix_flags(int flags) 00060 { 00061 if ((flags & O_TEXT) == 0 && (flags & O_BINARY) == 0) 00062 return flags | O_BINARY; 00063 return flags; 00064 } 00065 00066 /* from kdefakes library 00067 Generate a unique temporary directory name from TEMPLATE. 00068 00069 TEMPLATE has the form: 00070 00071 <path>/ccXXXXXX 00072 00073 00074 The last six characters of TEMPLATE must be "XXXXXX"; 00075 they are replaced with a string that makes the filename unique. 00076 00077 Returns a file descriptor open on the file for reading and writing. */ 00078 00079 QString mkdtemp_QString (const QString &_template) 00080 { 00081 static const char letters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; 00082 char XXXXXX[7]; 00083 int value; 00084 00085 if ( !_template.endsWith(QLatin1String("XXXXXX")) ) 00086 return QString(); 00087 00088 strcpy(XXXXXX, "XXXXXX"); 00089 const QString tmpl = _template.left(_template.length() - 6); 00090 00091 value = rand(); 00092 for (int count = 0; count < 256; ++count) 00093 { 00094 int v = value; 00095 00096 /* Fill in the random bits. */ 00097 XXXXXX[0] = letters[v % 62]; 00098 v /= 62; 00099 XXXXXX[1] = letters[v % 62]; 00100 v /= 62; 00101 XXXXXX[2] = letters[v % 62]; 00102 v /= 62; 00103 XXXXXX[3] = letters[v % 62]; 00104 v /= 62; 00105 XXXXXX[4] = letters[v % 62]; 00106 v /= 62; 00107 XXXXXX[5] = letters[v % 62]; 00108 00109 /* This is a random value. It is only necessary that the next 00110 TMP_MAX values generated by adding 7777 to VALUE are different 00111 with (module 2^32). */ 00112 value += 7777; 00113 00114 const QString tmp = tmpl + QString::fromAscii( XXXXXX ); 00115 if (!KDE::mkdir(tmp,0700)) 00116 return tmp; 00117 } 00118 return QString(); 00119 } 00120 00121 namespace KDE 00122 { 00123 int access(const QString &path, int mode) 00124 { 00125 int x_mode = 0; 00126 // X_OK gives an assert on msvc2005 and up - use stat() instead 00127 if( ( mode & X_OK ) == X_OK ) { 00128 KDE_struct_stat st; 00129 if( KDE::stat( path, &st ) != 0 ) 00130 return 1; 00131 if( ( st.st_mode & S_IXUSR ) != S_IXUSR ) 00132 return 1; 00133 } 00134 mode &= ~X_OK; 00135 return _waccess( CONV(path), mode ); 00136 } 00137 00138 int chmod(const QString &path, mode_t mode) 00139 { 00140 return _wchmod( CONV(path), mode ); 00141 } 00142 00143 FILE *fopen(const QString &pathname, const char *mode) 00144 { 00145 return _wfopen( CONV(pathname), CONV(QString::fromAscii( mode )) ); 00146 } 00147 00148 int lstat(const QString &path, KDE_struct_stat *buf) 00149 { 00150 return KDE::stat( path, buf ); 00151 } 00152 00153 int mkdir(const QString &pathname, mode_t) 00154 { 00155 return _wmkdir( CONV(pathname) ); 00156 } 00157 00158 int open(const QString &pathname, int flags, mode_t mode) 00159 { 00160 return _wopen( CONV(pathname), kdewin_fix_flags(flags), mode ); 00161 } 00162 00163 int rename(const QString &in, const QString &out) 00164 { 00165 // better than :waccess/_wunlink/_wrename 00166 #ifndef _WIN32_WCE 00167 bool ok = ( MoveFileExW( CONV(in), CONV(out), 00168 MOVEFILE_REPLACE_EXISTING|MOVEFILE_COPY_ALLOWED ) != 0 ); 00169 #else 00170 bool ok = ( MoveFileW( CONV(in), CONV(out)) != 0 ); 00171 #endif 00172 return ok ? 0 : -1; 00173 } 00174 00175 int stat(const QString &path, KDE_struct_stat *buf) 00176 { 00177 int result; 00178 #ifdef Q_CC_MSVC 00179 #ifndef _WIN32_WCE 00180 struct _stat64 s64; 00181 #else 00182 struct stat st; 00183 #endif 00184 #else 00185 struct __stat64 s64; 00186 #endif 00187 const int len = path.length(); 00188 if ( (len==2 || len==3) && path[1]==QLatin1Char(':') && path[0].isLetter() ) { 00189 /* 1) */ 00190 QString newPath(path); 00191 if (len==2) 00192 newPath += QLatin1Char('\\'); 00193 #ifndef _WIN32_WCE 00194 result = _wstat64( CONV(newPath), &s64 ); 00195 #else 00196 result = wstat( CONV(newPath), &st ); 00197 #endif 00198 } else 00199 if ( len > 1 && (path.endsWith(QLatin1Char('\\')) || path.endsWith(QLatin1Char('/'))) ) { 00200 /* 2) */ 00201 const QString newPath = path.left( len - 1 ); 00202 #ifndef _WIN32_WCE 00203 result = _wstat64( CONV(newPath), &s64 ); 00204 #else 00205 result = wstat( CONV(newPath), &st ); 00206 #endif 00207 } else { 00208 //TODO: is stat("/") ok? 00209 #ifndef _WIN32_WCE 00210 result = _wstat64( CONV(path), &s64 ); 00211 #else 00212 result = wstat( CONV(path), &st ); 00213 #endif 00214 } 00215 if( result != 0 ) 00216 return result; 00217 // KDE5: fixme! 00218 #ifndef _WIN32_WCE 00219 buf->st_dev = s64.st_dev; 00220 buf->st_ino = s64.st_ino; 00221 buf->st_mode = s64.st_mode; 00222 buf->st_nlink = s64.st_nlink; 00223 #else 00224 buf->st_dev = st.st_dev; 00225 buf->st_ino = st.st_ino; 00226 buf->st_mode = st.st_mode; 00227 buf->st_nlink = st.st_nlink; 00228 #endif 00229 buf->st_uid = -2; // be in sync with Qt4 00230 buf->st_gid = -2; // be in sync with Qt4 00231 #ifndef _WIN32_WCE 00232 buf->st_rdev = s64.st_rdev; 00233 buf->st_size = s64.st_size; 00234 buf->st_atime = s64.st_atime; 00235 buf->st_mtime = s64.st_mtime; 00236 buf->st_ctime = s64.st_ctime; 00237 #else 00238 buf->st_rdev = st.st_rdev; 00239 buf->st_size = st.st_size; 00240 buf->st_atime = st.st_atime; 00241 buf->st_mtime = st.st_mtime; 00242 buf->st_ctime = st.st_ctime; 00243 #endif 00244 return result; 00245 } 00246 int utime(const QString &filename, struct utimbuf *buf) 00247 { 00248 #ifndef _WIN32_WCE 00249 return _wutime( CONV(filename), (struct _utimbuf*)buf ); 00250 #else 00251 return _wutime( CONV(filename), (struct utimbuf*)buf ); 00252 #endif 00253 } 00254 };
KDE 4.6 API Reference