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
00027
00028 #include "CSConfig.h"
00029
00030 #include <io.h>
00031
00032 #include "CSGlobal.h"
00033 #include "CSDefs.h"
00034 #include "CSStrUtil.h"
00035 #include "CSSys.h"
00036
00037 #define CS_MASK ((S_IRUSR | S_IWUSR) | (S_IRGRP | S_IWGRP) | (S_IROTH))
00038
00039
00040
00041 static int get_win_error()
00042 {
00043 return (int) GetLastError();
00044 }
00045
00046 bool CSSysFile::isDirNotFound(CSException *e) { return e->getErrorCode() == ERROR_PATH_NOT_FOUND; }
00047 bool CSSysFile::isFileNotFound(CSException *e) { return e->getErrorCode() == ERROR_FILE_NOT_FOUND; }
00048 bool CSSysFile::isDirExists(CSException *e) { return e->getErrorCode() == ERROR_ALREADY_EXISTS; }
00049
00050
00051
00052 void CSSysFile::sf_open(const char *path, bool readonly, bool create)
00053 {
00054 SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), 0, 0 };
00055 DWORD flags;
00056
00057 flags = (create)?OPEN_ALWAYS:OPEN_EXISTING;
00058
00059 if (sf_fh != INVALID_HANDLE_VALUE)
00060 sf_close();
00061
00062 sf_path = CSString::newString(path);
00063
00064 sf_fh = CreateFileA(
00065 path,
00066 readonly ? GENERIC_READ : (GENERIC_READ | GENERIC_WRITE),
00067 FILE_SHARE_READ | FILE_SHARE_WRITE,
00068 &sa,
00069 flags,
00070 FILE_FLAG_RANDOM_ACCESS,
00071 NULL);
00072
00073 if (sf_fh == INVALID_HANDLE_VALUE) {
00074 sf_path->release();
00075 sf_path = NULL;
00076 CSException::throwFileError(CS_CONTEXT, path, get_win_error());
00077 }
00078 }
00079
00080
00081 void CSSysFile::sf_close()
00082 {
00083 if (sf_fh != INVALID_HANDLE_VALUE) {
00084 CloseHandle(sf_fh);
00085 sf_fh = INVALID_HANDLE_VALUE;
00086 sf_path->release();
00087 sf_path = NULL;
00088 }
00089 }
00090
00091
00092 size_t CSSysFile::sf_pread(void *data, size_t size, off64_t offset)
00093 {
00094 LARGE_INTEGER liDistanceToMove;
00095 DWORD result;
00096
00097 liDistanceToMove.QuadPart = offset;
00098 if (!SetFilePointerEx(sf_fh, liDistanceToMove, NULL, FILE_BEGIN))
00099 CSException::throwFileError(CS_CONTEXT, sf_path->getCString(), get_win_error());
00100
00101 if (!ReadFile(sf_fh, data, size, &result, NULL))
00102 CSException::throwFileError(CS_CONTEXT, sf_path->getCString(), get_win_error());
00103
00104 return (size_t) result;
00105 }
00106
00107
00108 void CSSysFile::sf_pwrite(const void *data, size_t size, off64_t offset)
00109 {
00110 LARGE_INTEGER liDistanceToMove;
00111 DWORD result;
00112
00113 liDistanceToMove.QuadPart = offset;
00114 if (!SetFilePointerEx(sf_fh, liDistanceToMove, NULL, FILE_BEGIN))
00115 CSException::throwFileError(CS_CONTEXT, sf_path->getCString(), get_win_error());
00116
00117 if (!WriteFile(sf_fh, data, size, &result, NULL))
00118 CSException::throwFileError(CS_CONTEXT, sf_path->getCString(), get_win_error());
00119
00120 if (result != size)
00121 CSException::throwFileError(CS_CONTEXT, sf_path->getCString(), ERROR_HANDLE_EOF);
00122
00123 }
00124
00125
00126 void CSSysFile::sf_setEOF(off64_t offset)
00127 {
00128 LARGE_INTEGER liDistanceToMove;
00129
00130 liDistanceToMove.QuadPart = offset;
00131 if (!SetFilePointerEx(sf_fh, liDistanceToMove, NULL, FILE_BEGIN))
00132 CSException::throwFileError(CS_CONTEXT, sf_path->getCString(), get_win_error());
00133
00134 if (!SetEndOfFile(sf_fh))
00135 CSException::throwFileError(CS_CONTEXT, sf_path->getCString(), get_win_error());
00136 }
00137
00138
00139 off64_t CSSysFile::sf_getEOF()
00140 {
00141 DWORD result;
00142 LARGE_INTEGER lpFileSize;
00143
00144 result = SetFilePointer(sf_fh, 0, NULL, FILE_END);
00145 if (result == 0xFFFFFFFF)
00146 CSException::throwFileError(CS_CONTEXT, sf_path->getCString(), get_win_error());
00147
00148 if (!GetFileSizeEx(sf_fh, &lpFileSize))
00149 CSException::throwFileError(CS_CONTEXT, sf_path->getCString(), get_win_error());
00150
00151 return lpFileSize.QuadPart;
00152 }
00153
00154
00155 void CSSysFile::sf_sync()
00156 {
00157 if (!FlushFileBuffers(sf_fh))
00158 CSException::throwFileError(CS_CONTEXT, sf_path->getCString(), get_win_error());
00159 }
00160
00161
00162 void CSSysFile::sf_lock(bool shared)
00163 {
00164 OVERLAPPED overlap = {0};
00165
00166 if (!LockFileEx(sf_fh, (shared)? 0: LOCKFILE_EXCLUSIVE_LOCK, 0, 512, 0, &overlap))
00167 CSException::throwFileError(CS_CONTEXT, sf_path->getCString(), get_win_error());
00168 }
00169
00170
00171 void CSSysFile::sf_unlock()
00172 {
00173 OVERLAPPED overlap = {0};
00174
00175 if (!UnlockFileEx(sf_fh, 0, 512, 0, &overlap))
00176 CSException::throwFileError(CS_CONTEXT, sf_path->getCString(), get_win_error());
00177 }
00178
00179
00180
00181
00182
00183 bool CSSys::sys_exists(const char *path)
00184 {
00185 return (access(path, 0) != -1);
00186 }
00187
00188
00189 void CSSys::sys_getcwd(char *path, size_t size)
00190 {
00191 DWORD len;
00192
00193 len = GetCurrentDirectoryA(size, path);
00194 if (len == 0)
00195 CSException::throwFileError(CS_CONTEXT, "GetCurrentDirectory()" , get_win_error());
00196 else if (len > (size -1))
00197 CSException::throwFileError(CS_CONTEXT, "GetCurrentDirectory()overflow " , len);
00198
00199 }
00200
00201
00202 void CSSys::sys_setcwd(const char *path)
00203 {
00204 if (!SetCurrentDirectoryA(path))
00205 CSException::throwFileError(CS_CONTEXT, "SetCurrentDirectory()" , get_win_error());
00206 }
00207
00208
00209 void CSSys::sys_makeDir(const char *path)
00210 {
00211 SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), 0, 0 };
00212
00213 if (!CreateDirectoryA(path, &sa))
00214 CSException::throwFileError(CS_CONTEXT, path, get_win_error());
00215
00216 }
00217
00218 #define FILE_NOT_FOUND(x) ((x) == ERROR_FILE_NOT_FOUND || (x) == ERROR_PATH_NOT_FOUND)
00219
00220 void CSSys::sys_removeDir(const char *path)
00221 {
00222 if (!RemoveDirectoryA(path)) {
00223 int err = get_win_error();
00224
00225 if (!FILE_NOT_FOUND(err))
00226 CSException::throwFileError(CS_CONTEXT, path, err);
00227 }
00228 }
00229
00230
00231 void CSSys::sys_removeFile(const char *path)
00232 {
00233 if (!DeleteFileA(path)) {
00234 int err = get_win_error();
00235
00236 if (!FILE_NOT_FOUND(err))
00237 CSException::throwFileError(CS_CONTEXT, path, err);
00238 }
00239 }
00240
00241
00242
00243
00244 void CSSys::sys_stat(const char *path, bool *is_dir, off64_t *size, CSTime *mod_time)
00245 {
00246 HANDLE fh;
00247 BY_HANDLE_FILE_INFORMATION info;
00248 SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), 0, 0 };
00249
00250 fh = CreateFileA(
00251 path,
00252 0,
00253 FILE_SHARE_READ,
00254 &sa,
00255 OPEN_EXISTING,
00256 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS,
00257 NULL);
00258
00259 if (fh == INVALID_HANDLE_VALUE) {
00260 CSException::throwFileError(CS_CONTEXT, path, get_win_error());
00261 }
00262
00263 if (!GetFileInformationByHandle(fh, &info)) {
00264 CloseHandle(fh);
00265 CSException::throwFileError(CS_CONTEXT, path, get_win_error());
00266 }
00267
00268 CloseHandle(fh);
00269 if (is_dir)
00270 *is_dir = ((info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY);
00271
00272 if (size)
00273 *size = (off64_t) info.nFileSizeLow | (((off64_t) info.nFileSizeHigh) << 32);
00274
00275 if (mod_time) {
00276 SYSTEMTIME st;
00277 FileTimeToSystemTime(&info.ftLastWriteTime, &st);
00278 mod_time->setUTC(st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds * 1000000);
00279 }
00280
00281 }
00282
00283
00284 bool CSSys::sys_isLink(const char *path)
00285 {
00286 CSException::throwFileError(CS_CONTEXT, "CSSys::sys_isLink() not implimented on windows.", -1);
00287 return false;
00288 }
00289
00290
00291 void CSSys::sys_rename(const char *old_path, const char *new_path)
00292 {
00293 if (rename(old_path, new_path) == -1)
00294 CSException::throwFileError(CS_CONTEXT, old_path, errno);
00295 }
00296
00297
00298 uint32_t CSSys::sys_getpid()
00299 {
00300 return GetCurrentProcessId();
00301 }
00302
00303
00304 bool CSSys::sys_isAlive(uint32_t pid)
00305 {
00306 HANDLE h;
00307 bool isAlive = false;
00308 DWORD code;
00309
00310 h = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
00311 if (h) {
00312 if (GetExitCodeProcess(h, &code) && (code == STILL_ACTIVE))
00313 isAlive = true;
00314
00315 CloseHandle(h);
00316 } else {
00317 int err;
00318
00319 err = HRESULT_CODE(GetLastError());
00320 if (err != ERROR_INVALID_PARAMETER)
00321 isAlive = true;
00322 else
00323 fprintf(stderr, "ERROR CSSys::sys_isAlive(%d):OpenProcess %d\n", pid, err);
00324 }
00325
00326 return(isAlive);
00327 }
00328
00329
00330
00331
00332
00333
00334 CSSysDir::~CSSysDir()
00335 {
00336 close();
00337 if (sd_path)
00338 sd_path->release();
00339
00340 if (sd_filter)
00341 sd_filter->release();
00342 }
00343
00344
00345 void CSSysDir::open()
00346 {
00347 enter_();
00348
00349 if (! CSSys::sys_exists(sd_path->getCString()))
00350 CSException::throwFileError(CS_CONTEXT, sd_path->getCString(), ERROR_PATH_NOT_FOUND);
00351
00352 sd_filter = new CSStringBuffer();
00353 sd_filter->append(sd_path->getCString());
00354
00355 if (IS_DIR_CHAR(*(sd_filter->getBuffer(sd_filter->length()-1))))
00356 sd_filter->append("*");
00357 else
00358 sd_filter->append(CS_DIR_DELIM"*");
00359
00360 exit_();
00361 }
00362
00363
00364 void CSSysDir::close()
00365 {
00366 if (sd_dir != INVALID_HANDLE_VALUE) {
00367 FindClose(sd_dir);
00368 sd_dir = INVALID_HANDLE_VALUE;
00369 }
00370 }
00371
00372
00373 bool CSSysDir::next()
00374 {
00375 int err = 0;
00376
00377 while (true) {
00378 if (sd_dir == INVALID_HANDLE_VALUE) {
00379 sd_dir = FindFirstFileA(sd_filter->getCString(), &sd_entry);
00380 if (sd_dir == INVALID_HANDLE_VALUE)
00381 err = get_win_error();
00382 }
00383 else {
00384 if (!FindNextFileA(sd_dir, &sd_entry))
00385 err = get_win_error();
00386 }
00387
00388 if (err) {
00389 if ((err != ERROR_NO_MORE_FILES) && (err != ERROR_FILE_NOT_FOUND)){
00390 CSException::throwFileError(CS_CONTEXT, sd_path->getCString(), err);
00391 }
00392 return false;
00393 }
00394
00395
00396 if (sd_entry.cFileName[0] == '.') {
00397 if (sd_entry.cFileName[1] == '.') {
00398 if (sd_entry.cFileName[2] == '\0')
00399 continue;
00400 }
00401 else {
00402 if (sd_entry.cFileName[1] == '\0')
00403 continue;
00404 }
00405 }
00406 break;
00407 }
00408
00409 return true;
00410 }
00411
00412
00413
00414 void CSSysDir::getEntryPath(char *path, size_t size)
00415 {
00416 cs_strcpy(size, path, sd_path->getCString());
00417 cs_add_dir_char(size, path);
00418 cs_strcat(size, path, entryName());
00419 }
00420
00421
00422 const char *CSSysDir::entryName()
00423 {
00424 return (const char*) sd_entry.cFileName;
00425 }
00426
00427
00428 bool CSSysDir::entryIsFile()
00429 {
00430 if (sd_entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
00431 return false;
00432 return true;
00433 }
00434
00436
00437
00438
00439 #if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
00440 #define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
00441 #else
00442 #define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
00443 #endif
00444
00445 struct timezone
00446 {
00447 int tz_minuteswest;
00448 int tz_dsttime;
00449 };
00450
00451
00452
00453 int gettimeofday(struct timeval *tv, struct timezone *tz)
00454 {
00455
00456 FILETIME ft;
00457
00458
00459 unsigned __int64 tmpres = 0;
00460 static int tzflag = 0;
00461
00462 if (NULL != tv)
00463 {
00464 GetSystemTimeAsFileTime(&ft);
00465
00466
00467
00468
00469 tmpres |= ft.dwHighDateTime;
00470 tmpres <<= 32;
00471 tmpres |= ft.dwLowDateTime;
00472
00473
00474 tmpres /= 10;
00475
00476
00477
00478 tmpres -= DELTA_EPOCH_IN_MICROSECS;
00479
00480
00481
00482 tv->tv_sec = (long)(tmpres / 1000000UL);
00483 tv->tv_usec = (long)(tmpres % 1000000UL);
00484 }
00485
00486 if (NULL != tz)
00487 {
00488 if (!tzflag)
00489 {
00490 _tzset();
00491 tzflag++;
00492 }
00493
00494
00495 tz->tz_minuteswest = _timezone / 60;
00496 tz->tz_dsttime = _daylight;
00497 }
00498
00499 return 0;
00500 }
00501