15
15
// You should have received a copy of the GNU Lesser General Public License
16
16
// along with BOINC. If not, see <http://www.gnu.org/licenses/>.
18
#if defined(_WIN32) && !defined(__STDWX_H__) && !defined(_BOINC_WIN_) && !defined(_AFX_STDAFX_H_)
18
#if defined(_WIN32) && !defined(__STDWX_H__)
19
19
#include "boinc_win.h"
20
#elif defined(_WIN32) && defined(__STDWX_H__)
24
#if defined(__MINGW32__)
29
#define getcwd _getcwd
22
32
#if !defined(_WIN32) || defined(__CYGWIN32__)
62
typedef BOOL (CALLBACK* FreeFn)(LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER);
72
typedef BOOL (CALLBACK* FreeFn)(LPCSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER);
66
76
#include "str_util.h"
77
#include "str_replace.h"
67
78
#include "error_numbers.h"
68
79
#include "filesys.h"
121
132
int dir_scan(char* p, DIRREF dirp, int p_len) {
123
WIN32_FIND_DATA data;
134
WIN32_FIND_DATAA data;
125
136
if (dirp->first) {
126
137
dirp->first = false;
127
dirp->handle = FindFirstFile(dirp->path, &data);
138
dirp->handle = FindFirstFileA(dirp->path, &data);
128
139
if (dirp->handle == INVALID_HANDLE_VALUE) {
129
140
return ERR_READDIR;
139
if (FindNextFile(dirp->handle, &data)) {
150
if (FindNextFileA(dirp->handle, &data)) {
140
151
if (!strcmp(data.cFileName, ".")) continue;
141
152
if (!strcmp(data.cFileName, "..")) continue;
142
153
if (p) strlcpy(p, data.cFileName, p_len);
193
bool is_dir_empty(const char *p) {
196
DIRREF dir = dir_open(p);
197
if (!dir) return true;
199
if (!dir_scan(file, dir, sizeof(file))) {
182
207
DirScanner::DirScanner(string const& path) {
197
222
bool DirScanner::scan(string& s) {
199
WIN32_FIND_DATA data;
224
WIN32_FIND_DATAA data;
203
handle = FindFirstFile(dir.c_str(), &data);
228
handle = FindFirstFileA(dir.c_str(), &data);
204
229
if (handle == INVALID_HANDLE_VALUE) {
350
375
char path2[_MAX_PATH];
351
376
sprintf(path2, "%s/*", dirpath);
353
WIN32_FIND_DATA findData;
354
HANDLE hFind = ::FindFirstFile(path2, &findData);
378
WIN32_FIND_DATAA findData;
379
HANDLE hFind = ::FindFirstFileA(path2, &findData);
355
380
if (INVALID_HANDLE_VALUE == hFind) return ERR_OPENDIR;
357
382
if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
368
393
size += findData.nFileSizeLow + ((__int64)(findData.nFileSizeHigh) << 32);
370
} while (FindNextFile(hFind, &findData));
395
} while (FindNextFileA(hFind, &findData));
371
396
::FindClose(hFind);
373
398
char filename[256], subdir[256];
496
521
int boinc_copy(const char* orig, const char* newf) {
498
if (!CopyFile(orig, newf, FALSE)) { // FALSE means overwrite OK
523
if (!CopyFileA(orig, newf, FALSE)) { // FALSE means overwrite OK
499
524
return GetLastError();
504
529
sprintf(cmd, "copy \"%s\" \"%s\"", orig, newf);
505
530
return system(cmd);
508
sprintf(cmd, "cp \"%s\" \"%s\"", orig, newf);
532
// POSIX requires that shells run from an application will use the
533
// real UID and GID if different from the effective UID and GID.
534
// Mac OS 10.4 did not enforce this, but OS 10.5 does. Since
535
// system() invokes a shell, it may not properly copy the file's
536
// ownership or permissions when called from the BOINC Client
537
// under sandbox security, so we copy the file directly.
542
unsigned char buf[65536];
543
src = boinc_fopen(orig, "r");
544
if (!src) return ERR_FOPEN;
545
dst = boinc_fopen(newf, "w");
551
n = fread(buf, 1, sizeof(buf), src);
553
m = fwrite(buf, 1, n, dst);
561
// Copy file's ownership, permissions to the extent we are allowed
562
lstat(orig, &sbuf); // Get source file's info
563
chown(newf, sbuf.st_uid, sbuf.st_gid);
564
chmod(newf, sbuf.st_mode);
513
569
static int boinc_rename_aux(const char* old, const char* newf) {
515
boinc_delete_file(newf);
516
if (MoveFile(old, newf)) return 0;
571
if (MoveFileExA(old, newf, MOVEFILE_REPLACE_EXISTING|MOVEFILE_WRITE_THROUGH)) return 0;
517
572
return GetLastError();
519
return rename(old, newf);
574
int retval = rename(old, newf);
575
if (retval) return ERR_RENAME;
540
597
int boinc_mkdir(const char* path) {
541
598
if (is_dir(path)) return 0;
543
if (!CreateDirectory(path, NULL)) {
600
if (!CreateDirectoryA(path, NULL)) {
544
601
return GetLastError();
548
604
mode_t old_mask = umask(0);
549
605
int retval = mkdir(path, 0771);
607
if (retval) return ERR_MKDIR;
555
612
int boinc_rmdir(const char* name) {
557
if (!RemoveDirectory(name)) {
614
if (!RemoveDirectoryA(name)) {
558
615
return ERR_RMDIR;
615
674
int FILE_LOCK::lock(const char* filename) {
616
675
#if defined(_WIN32) && !defined(__CYGWIN32__)
676
handle = CreateFileA(
618
677
filename, GENERIC_WRITE,
619
678
0, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0
621
680
if (handle == INVALID_HANDLE_VALUE) {
681
return GetLastError();
629
filename, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH
685
fd = open(filename, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH);
638
fl.l_whence=SEEK_SET;
641
if (-1 != fcntl(fd, F_SETLK, &fl)) return 0;
693
fl.l_whence = SEEK_SET;
696
if (fcntl(fd, F_SETLK, &fl) == -1) {
646
704
int FILE_LOCK::unlock(const char* filename) {
647
706
#if defined(_WIN32) && !defined(__CYGWIN32__)
648
707
if (!CloseHandle(handle)) {
649
perror("FILE_LOCK::unlock(): close failed.");
708
retval = GetLastError();
653
perror("FILE_LOCK::unlock(): close failed.");
656
716
boinc_delete_file(filename);
676
741
// get total and free space on current filesystem (in bytes)
678
int get_filesystem_info(double &total_space, double &free_space, char* path) {
744
int get_filesystem_info(double &total_space, double &free_space, char*) {
681
746
boinc_getcwd(buf);
682
747
FreeFn pGetDiskFreeSpaceEx;
683
748
pGetDiskFreeSpaceEx = (FreeFn)GetProcAddress(
684
GetModuleHandle("kernel32.dll"), "GetDiskFreeSpaceExA"
749
GetModuleHandleA("kernel32.dll"), "GetDiskFreeSpaceExA"
686
751
if (pGetDiskFreeSpaceEx) {
687
752
ULARGE_INTEGER TotalNumberOfFreeBytes;