mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-02 19:26:32 +00:00
Move several functions out of file.c, use common code for 64bit, 32bit, unicode and non-unicode versions and provide proper definition. Fixes amd64 build of crt lib. (nothing tested)
svn path=/branches/ros-amd64-bringup/; revision=36176
This commit is contained in:
@@ -259,15 +259,19 @@
|
||||
</directory>
|
||||
<directory name="stdio">
|
||||
<file>access.c</file>
|
||||
<!-- file>file.c</file -->
|
||||
<!-- file>find.c</file -->
|
||||
<file>file.c</file>
|
||||
<file>find.c</file>
|
||||
<file>find64.c</file>
|
||||
<file>fmode.c</file>
|
||||
<file>lnx_sprintf.c</file>
|
||||
<file>perror.c</file>
|
||||
<file>popen.c</file>
|
||||
<file>stat.c</file>
|
||||
<file>stat64.c</file>
|
||||
<file>waccess.c</file>
|
||||
<!-- file>wfind.c</file -->
|
||||
<file>wfind.c</file>
|
||||
<file>wpopen.c</file>
|
||||
<file>wstat.c</file>
|
||||
</directory>
|
||||
<directory name="stdlib">
|
||||
<file>_exit.c</file>
|
||||
|
||||
@@ -68,11 +68,6 @@ int *__p___mb_cur_max(void);
|
||||
#undef vprintf
|
||||
#undef vwprintf
|
||||
|
||||
/* for stat mode, permissions apply to all,owner and group */
|
||||
#define ALL_S_IREAD (_S_IREAD | (_S_IREAD >> 3) | (_S_IREAD >> 6))
|
||||
#define ALL_S_IWRITE (_S_IWRITE | (_S_IWRITE >> 3) | (_S_IWRITE >> 6))
|
||||
#define ALL_S_IEXEC (_S_IEXEC | (_S_IEXEC >> 3) | (_S_IEXEC >> 6))
|
||||
|
||||
/* _access() bit flags FIXME: incomplete */
|
||||
/* defined in crt/io.h */
|
||||
|
||||
@@ -94,7 +89,7 @@ typedef struct {
|
||||
DWORD unkn[7]; /* critical section and init flag */
|
||||
} ioinfo;
|
||||
|
||||
/*static */ioinfo fdesc[MAX_FILES];
|
||||
ioinfo fdesc[MAX_FILES];
|
||||
|
||||
FILE _iob[3] = { { 0 } };
|
||||
|
||||
@@ -110,17 +105,6 @@ static int MSVCRT_umask = 0;
|
||||
/* INTERNAL: Static buffer for temp file name */
|
||||
static char tmpname[MAX_PATH];
|
||||
|
||||
static const unsigned int EXE = 'e' << 16 | 'x' << 8 | 'e';
|
||||
static const unsigned int BAT = 'b' << 16 | 'a' << 8 | 't';
|
||||
static const unsigned int CMD = 'c' << 16 | 'm' << 8 | 'd';
|
||||
static const unsigned int COM = 'c' << 16 | 'o' << 8 | 'm';
|
||||
|
||||
#define TOUL(x) (ULONGLONG)(x)
|
||||
static const ULONGLONG WCEXE = TOUL('e') << 32 | TOUL('x') << 16 | TOUL('e');
|
||||
static const ULONGLONG WCBAT = TOUL('b') << 32 | TOUL('a') << 16 | TOUL('t');
|
||||
static const ULONGLONG WCCMD = TOUL('c') << 32 | TOUL('m') << 16 | TOUL('d');
|
||||
static const ULONGLONG WCCOM = TOUL('c') << 32 | TOUL('o') << 16 | TOUL('m');
|
||||
|
||||
/* This critical section protects the tables fdesc and fstreams,
|
||||
* and their related indexes, fdstart, fdend,
|
||||
* and stream_idx, from race conditions.
|
||||
@@ -132,23 +116,6 @@ static CRITICAL_SECTION FILE_cs;
|
||||
#define LOCK_FILES() do { EnterCriticalSection(&FILE_cs); } while (0)
|
||||
#define UNLOCK_FILES() do { LeaveCriticalSection(&FILE_cs); } while (0)
|
||||
|
||||
#ifndef _WIN64
|
||||
static void stat64_to_stati64(const struct __stat64 *buf64, struct _stati64 *buf)
|
||||
{
|
||||
buf->st_dev = buf64->st_dev;
|
||||
buf->st_ino = buf64->st_ino;
|
||||
buf->st_mode = buf64->st_mode;
|
||||
buf->st_nlink = buf64->st_nlink;
|
||||
buf->st_uid = buf64->st_uid;
|
||||
buf->st_gid = buf64->st_gid;
|
||||
buf->st_rdev = buf64->st_rdev;
|
||||
buf->st_size = buf64->st_size;
|
||||
buf->st_atime = buf64->st_atime;
|
||||
buf->st_mtime = buf64->st_mtime;
|
||||
buf->st_ctime = buf64->st_ctime;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline BOOL is_valid_fd(int fd)
|
||||
{
|
||||
return fd >= 0 && fd < fdend && (fdesc[fd].wxflag & WX_OPEN);
|
||||
@@ -160,7 +127,7 @@ static inline BOOL is_valid_fd(int fd)
|
||||
* it returns a valid handle which is about to be closed, a subsequent call
|
||||
* will fail, most likely in a sane way.
|
||||
*/
|
||||
static HANDLE fdtoh(int fd)
|
||||
HANDLE fdtoh(int fd)
|
||||
{
|
||||
if (!is_valid_fd(fd))
|
||||
{
|
||||
@@ -1149,138 +1116,6 @@ int CDECL _fileno(FILE* file)
|
||||
return file->_file;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* _fstat64 (MSVCRT.@)
|
||||
*/
|
||||
int CDECL _fstat64(int fd, struct _stat64* buf)
|
||||
{
|
||||
DWORD dw;
|
||||
DWORD type;
|
||||
BY_HANDLE_FILE_INFORMATION hfi;
|
||||
HANDLE hand = fdtoh(fd);
|
||||
|
||||
TRACE(":fd (%d) stat (%p)\n",fd,buf);
|
||||
if (hand == INVALID_HANDLE_VALUE)
|
||||
return -1;
|
||||
|
||||
if (!buf)
|
||||
{
|
||||
WARN(":failed-NULL buf\n");
|
||||
__set_errno(ERROR_INVALID_PARAMETER);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&hfi, 0, sizeof(hfi));
|
||||
memset(buf, 0, sizeof(struct __stat64));
|
||||
type = GetFileType(hand);
|
||||
if (type == FILE_TYPE_PIPE)
|
||||
{
|
||||
buf->st_dev = buf->st_rdev = fd;
|
||||
buf->st_mode = S_IFIFO;
|
||||
buf->st_nlink = 1;
|
||||
}
|
||||
else if (type == FILE_TYPE_CHAR)
|
||||
{
|
||||
buf->st_dev = buf->st_rdev = fd;
|
||||
buf->st_mode = S_IFCHR;
|
||||
buf->st_nlink = 1;
|
||||
}
|
||||
else /* FILE_TYPE_DISK etc. */
|
||||
{
|
||||
if (!GetFileInformationByHandle(hand, &hfi))
|
||||
{
|
||||
WARN(":failed-last error (%d)\n",GetLastError());
|
||||
__set_errno(ERROR_INVALID_PARAMETER);
|
||||
return -1;
|
||||
}
|
||||
buf->st_mode = S_IFREG | S_IREAD;
|
||||
if (!(hfi.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
|
||||
buf->st_mode |= S_IWRITE;
|
||||
buf->st_size = ((__int64)hfi.nFileSizeHigh << 32) + hfi.nFileSizeLow;
|
||||
RtlTimeToSecondsSince1970((LARGE_INTEGER *)&hfi.ftLastAccessTime, &dw);
|
||||
buf->st_atime = dw;
|
||||
RtlTimeToSecondsSince1970((LARGE_INTEGER *)&hfi.ftLastWriteTime, &dw);
|
||||
buf->st_mtime = buf->st_ctime = dw;
|
||||
buf->st_nlink = hfi.nNumberOfLinks;
|
||||
}
|
||||
TRACE(":dwFileAttributes = 0x%x, mode set to 0x%x\n",hfi.dwFileAttributes,
|
||||
buf->st_mode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* _fstati64 (MSVCRT.@)
|
||||
*/
|
||||
int CDECL _fstati64(int fd, struct _stati64* buf)
|
||||
{
|
||||
int ret;
|
||||
struct __stat64 buf64;
|
||||
|
||||
ret = _fstat64(fd, &buf64);
|
||||
if (!ret)
|
||||
stat64_to_stati64(&buf64, buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* _fstat (MSVCRT.@)
|
||||
*/
|
||||
int CDECL _fstat(int fd, struct _stat32* buf)
|
||||
{
|
||||
DWORD dw;
|
||||
DWORD type;
|
||||
BY_HANDLE_FILE_INFORMATION hfi;
|
||||
HANDLE hand = fdtoh(fd);
|
||||
|
||||
TRACE(":fd (%d) stat (%p)\n",fd,buf);
|
||||
if (hand == INVALID_HANDLE_VALUE)
|
||||
return -1;
|
||||
|
||||
if (!buf)
|
||||
{
|
||||
WARN(":failed-NULL buf\n");
|
||||
__set_errno(ERROR_INVALID_PARAMETER);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&hfi, 0, sizeof(hfi));
|
||||
memset(buf, 0, sizeof(struct _stat32));
|
||||
type = GetFileType(hand);
|
||||
if (type == FILE_TYPE_PIPE)
|
||||
{
|
||||
buf->st_dev = buf->st_rdev = fd;
|
||||
buf->st_mode = S_IFIFO;
|
||||
buf->st_nlink = 1;
|
||||
}
|
||||
else if (type == FILE_TYPE_CHAR)
|
||||
{
|
||||
buf->st_dev = buf->st_rdev = fd;
|
||||
buf->st_mode = S_IFCHR;
|
||||
buf->st_nlink = 1;
|
||||
}
|
||||
else /* FILE_TYPE_DISK etc. */
|
||||
{
|
||||
if (!GetFileInformationByHandle(hand, &hfi))
|
||||
{
|
||||
WARN(":failed-last error (%d)\n",GetLastError());
|
||||
__set_errno(ERROR_INVALID_PARAMETER);
|
||||
return -1;
|
||||
}
|
||||
buf->st_mode = S_IFREG | S_IREAD;
|
||||
if (!(hfi.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
|
||||
buf->st_mode |= S_IWRITE;
|
||||
buf->st_size = ((__int32)hfi.nFileSizeHigh << 16) + hfi.nFileSizeLow;
|
||||
RtlTimeToSecondsSince1970((LARGE_INTEGER *)&hfi.ftLastAccessTime, &dw);
|
||||
buf->st_atime = dw;
|
||||
RtlTimeToSecondsSince1970((LARGE_INTEGER *)&hfi.ftLastWriteTime, &dw);
|
||||
buf->st_mtime = buf->st_ctime = dw;
|
||||
buf->st_nlink = hfi.nNumberOfLinks;
|
||||
}
|
||||
TRACE(":dwFileAttributes = 0x%x, mode set to 0x%x\n",hfi.dwFileAttributes,
|
||||
buf->st_mode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* _futime (MSVCRT.@)
|
||||
*/
|
||||
@@ -1829,290 +1664,6 @@ int CDECL _setmode(int fd,int mode)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* _stat64 (MSVCRT.@)
|
||||
*/
|
||||
int CDECL _stat64(const char* path, struct __stat64 * buf)
|
||||
{
|
||||
DWORD dw;
|
||||
WIN32_FILE_ATTRIBUTE_DATA hfi;
|
||||
unsigned short mode = ALL_S_IREAD;
|
||||
int plen;
|
||||
|
||||
TRACE(":file (%s) buf(%p)\n",path,buf);
|
||||
|
||||
if (!GetFileAttributesExA(path, GetFileExInfoStandard, &hfi))
|
||||
{
|
||||
TRACE("failed (%d)\n",GetLastError());
|
||||
__set_errno(ERROR_FILE_NOT_FOUND);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(buf,0,sizeof(struct __stat64));
|
||||
|
||||
/* FIXME: rdev isn't drive num, despite what the docs say-what is it?
|
||||
Bon 011120: This FIXME seems incorrect
|
||||
Also a letter as first char isn't enough to be classified
|
||||
as a drive letter
|
||||
*/
|
||||
if (isalpha(*path)&& (*(path+1)==':'))
|
||||
buf->st_dev = buf->st_rdev = toupper(*path) - 'A'; /* drive num */
|
||||
else
|
||||
buf->st_dev = buf->st_rdev = _getdrive() - 1;
|
||||
|
||||
plen = strlen(path);
|
||||
|
||||
/* Dir, or regular file? */
|
||||
if ((hfi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ||
|
||||
(path[plen-1] == '\\'))
|
||||
mode |= (_S_IFDIR | ALL_S_IEXEC);
|
||||
else
|
||||
{
|
||||
mode |= _S_IFREG;
|
||||
/* executable? */
|
||||
if (plen > 6 && path[plen-4] == '.') /* shortest exe: "\x.exe" */
|
||||
{
|
||||
unsigned int ext = tolower(path[plen-1]) | (tolower(path[plen-2]) << 8) |
|
||||
(tolower(path[plen-3]) << 16);
|
||||
if (ext == EXE || ext == BAT || ext == CMD || ext == COM)
|
||||
mode |= ALL_S_IEXEC;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(hfi.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
|
||||
mode |= ALL_S_IWRITE;
|
||||
|
||||
buf->st_mode = mode;
|
||||
buf->st_nlink = 1;
|
||||
buf->st_size = ((__int64)hfi.nFileSizeHigh << 32) + hfi.nFileSizeLow;
|
||||
RtlTimeToSecondsSince1970((LARGE_INTEGER *)&hfi.ftLastAccessTime, &dw);
|
||||
buf->st_atime = dw;
|
||||
RtlTimeToSecondsSince1970((LARGE_INTEGER *)&hfi.ftLastWriteTime, &dw);
|
||||
buf->st_mtime = buf->st_ctime = dw;
|
||||
TRACE("%d %d 0x%08lx%08lx %ld %ld %ld\n", buf->st_mode,buf->st_nlink,
|
||||
(long)(buf->st_size >> 32),(long)buf->st_size,
|
||||
(long)buf->st_atime,(long)buf->st_mtime,(long)buf->st_ctime);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* _stati64 (MSVCRT.@)
|
||||
*/
|
||||
int CDECL _stati64(const char* path, struct _stati64 * buf)
|
||||
{
|
||||
int ret;
|
||||
struct __stat64 buf64;
|
||||
|
||||
ret = _stat64(path, &buf64);
|
||||
if (!ret)
|
||||
stat64_to_stati64(&buf64, buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* _stat (MSVCRT.@)
|
||||
*/
|
||||
int CDECL _stat32(const char* path, struct _stat32 * buf)
|
||||
{
|
||||
DWORD dw;
|
||||
WIN32_FILE_ATTRIBUTE_DATA hfi;
|
||||
unsigned short mode = ALL_S_IREAD;
|
||||
int plen;
|
||||
|
||||
TRACE(":file (%s) buf(%p)\n",path,buf);
|
||||
|
||||
if (!GetFileAttributesExA(path, GetFileExInfoStandard, &hfi))
|
||||
{
|
||||
TRACE("failed (%d)\n",GetLastError());
|
||||
__set_errno(ERROR_FILE_NOT_FOUND);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(buf,0,sizeof(struct _stat32));
|
||||
|
||||
/* FIXME: rdev isn't drive num, despite what the docs say-what is it?
|
||||
Bon 011120: This FIXME seems incorrect
|
||||
Also a letter as first char isn't enough to be classified
|
||||
as a drive letter
|
||||
*/
|
||||
if (isalpha(*path)&& (*(path+1)==':'))
|
||||
buf->st_dev = buf->st_rdev = toupper(*path) - 'A'; /* drive num */
|
||||
else
|
||||
buf->st_dev = buf->st_rdev = _getdrive() - 1;
|
||||
|
||||
plen = strlen(path);
|
||||
|
||||
/* Dir, or regular file? */
|
||||
if ((hfi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ||
|
||||
(path[plen-1] == '\\'))
|
||||
mode |= (_S_IFDIR | ALL_S_IEXEC);
|
||||
else
|
||||
{
|
||||
mode |= _S_IFREG;
|
||||
/* executable? */
|
||||
if (plen > 6 && path[plen-4] == '.') /* shortest exe: "\x.exe" */
|
||||
{
|
||||
unsigned int ext = tolower(path[plen-1]) | (tolower(path[plen-2]) << 8) |
|
||||
(tolower(path[plen-3]) << 16);
|
||||
if (ext == EXE || ext == BAT || ext == CMD || ext == COM)
|
||||
mode |= ALL_S_IEXEC;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(hfi.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
|
||||
mode |= ALL_S_IWRITE;
|
||||
|
||||
buf->st_mode = mode;
|
||||
buf->st_nlink = 1;
|
||||
buf->st_size = ((__int32)hfi.nFileSizeHigh << 16) + hfi.nFileSizeLow;
|
||||
RtlTimeToSecondsSince1970((LARGE_INTEGER *)&hfi.ftLastAccessTime, &dw);
|
||||
buf->st_atime = dw;
|
||||
RtlTimeToSecondsSince1970((LARGE_INTEGER *)&hfi.ftLastWriteTime, &dw);
|
||||
buf->st_mtime = buf->st_ctime = dw;
|
||||
TRACE("%d %d 0x%08lx%08lx %ld %ld %ld\n", buf->st_mode,buf->st_nlink,
|
||||
(long)(buf->st_size >> 16),(long)buf->st_size,
|
||||
(long)buf->st_atime,(long)buf->st_mtime,(long)buf->st_ctime);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* _wstat64 (MSVCRT.@)
|
||||
*/
|
||||
int CDECL _wstat64(const wchar_t* path, struct __stat64 * buf)
|
||||
{
|
||||
DWORD dw;
|
||||
WIN32_FILE_ATTRIBUTE_DATA hfi;
|
||||
unsigned short mode = ALL_S_IREAD;
|
||||
int plen;
|
||||
|
||||
TRACE(":file (%s) buf(%p)\n",debugstr_w(path),buf);
|
||||
|
||||
if (!GetFileAttributesExW(path, GetFileExInfoStandard, &hfi))
|
||||
{
|
||||
TRACE("failed (%d)\n",GetLastError());
|
||||
__set_errno(ERROR_FILE_NOT_FOUND);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(buf,0,sizeof(struct __stat64));
|
||||
|
||||
/* FIXME: rdev isn't drive num, despite what the docs says-what is it? */
|
||||
if (iswalpha(*path))
|
||||
buf->st_dev = buf->st_rdev = toupperW(*path - 'A'); /* drive num */
|
||||
else
|
||||
buf->st_dev = buf->st_rdev = _getdrive() - 1;
|
||||
|
||||
plen = strlenW(path);
|
||||
|
||||
/* Dir, or regular file? */
|
||||
if ((hfi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ||
|
||||
(path[plen-1] == '\\'))
|
||||
mode |= (_S_IFDIR | ALL_S_IEXEC);
|
||||
else
|
||||
{
|
||||
mode |= _S_IFREG;
|
||||
/* executable? */
|
||||
if (plen > 6 && path[plen-4] == '.') /* shortest exe: "\x.exe" */
|
||||
{
|
||||
ULONGLONG ext = tolowerW(path[plen-1]) | (tolowerW(path[plen-2]) << 16) |
|
||||
((ULONGLONG)tolowerW(path[plen-3]) << 32);
|
||||
if (ext == WCEXE || ext == WCBAT || ext == WCCMD || ext == WCCOM)
|
||||
mode |= ALL_S_IEXEC;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(hfi.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
|
||||
mode |= ALL_S_IWRITE;
|
||||
|
||||
buf->st_mode = mode;
|
||||
buf->st_nlink = 1;
|
||||
buf->st_size = ((__int64)hfi.nFileSizeHigh << 32) + hfi.nFileSizeLow;
|
||||
RtlTimeToSecondsSince1970((LARGE_INTEGER *)&hfi.ftLastAccessTime, &dw);
|
||||
buf->st_atime = dw;
|
||||
RtlTimeToSecondsSince1970((LARGE_INTEGER *)&hfi.ftLastWriteTime, &dw);
|
||||
buf->st_mtime = buf->st_ctime = dw;
|
||||
TRACE("%d %d 0x%08lx%08lx %ld %ld %ld\n", buf->st_mode,buf->st_nlink,
|
||||
(long)(buf->st_size >> 32),(long)buf->st_size,
|
||||
(long)buf->st_atime,(long)buf->st_mtime,(long)buf->st_ctime);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* _wstati64 (MSVCRT.@)
|
||||
*/
|
||||
int CDECL _wstati64(const wchar_t* path, struct _stati64 * buf)
|
||||
{
|
||||
int ret;
|
||||
struct __stat64 buf64;
|
||||
|
||||
ret = _wstat64(path, &buf64);
|
||||
if (!ret)
|
||||
stat64_to_stati64(&buf64, buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* _wstat (MSVCRT.@)
|
||||
*/
|
||||
int CDECL _wstat32(const wchar_t* path, struct _stat32 * buf)
|
||||
{
|
||||
DWORD dw;
|
||||
WIN32_FILE_ATTRIBUTE_DATA hfi;
|
||||
unsigned short mode = ALL_S_IREAD;
|
||||
int plen;
|
||||
|
||||
TRACE(":file (%s) buf(%p)\n",debugstr_w(path),buf);
|
||||
|
||||
if (!GetFileAttributesExW(path, GetFileExInfoStandard, &hfi))
|
||||
{
|
||||
TRACE("failed (%d)\n",GetLastError());
|
||||
__set_errno(ERROR_FILE_NOT_FOUND);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(buf,0,sizeof(struct _stat32));
|
||||
|
||||
/* FIXME: rdev isn't drive num, despite what the docs says-what is it? */
|
||||
if (iswalpha(*path))
|
||||
buf->st_dev = buf->st_rdev = toupperW(*path - 'A'); /* drive num */
|
||||
else
|
||||
buf->st_dev = buf->st_rdev = _getdrive() - 1;
|
||||
|
||||
plen = strlenW(path);
|
||||
|
||||
/* Dir, or regular file? */
|
||||
if ((hfi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ||
|
||||
(path[plen-1] == '\\'))
|
||||
mode |= (_S_IFDIR | ALL_S_IEXEC);
|
||||
else
|
||||
{
|
||||
mode |= _S_IFREG;
|
||||
/* executable? */
|
||||
if (plen > 6 && path[plen-4] == '.') /* shortest exe: "\x.exe" */
|
||||
{
|
||||
ULONGLONG ext = tolowerW(path[plen-1]) | (tolowerW(path[plen-2]) << 16) |
|
||||
((ULONGLONG)tolowerW(path[plen-3]) << 32);
|
||||
if (ext == WCEXE || ext == WCBAT || ext == WCCMD || ext == WCCOM)
|
||||
mode |= ALL_S_IEXEC;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(hfi.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
|
||||
mode |= ALL_S_IWRITE;
|
||||
|
||||
buf->st_mode = mode;
|
||||
buf->st_nlink = 1;
|
||||
buf->st_size = ((__int32)hfi.nFileSizeHigh << 16) + hfi.nFileSizeLow;
|
||||
RtlTimeToSecondsSince1970((LARGE_INTEGER *)&hfi.ftLastAccessTime, &dw);
|
||||
buf->st_atime = dw;
|
||||
RtlTimeToSecondsSince1970((LARGE_INTEGER *)&hfi.ftLastWriteTime, &dw);
|
||||
buf->st_mtime = buf->st_ctime = dw;
|
||||
TRACE("%d %d 0x%08lx%08lx %ld %ld %ld\n", buf->st_mode,buf->st_nlink,
|
||||
(long)(buf->st_size >> 16),(long)buf->st_size,
|
||||
(long)buf->st_atime,(long)buf->st_mtime,(long)buf->st_ctime);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* _tell (MSVCRT.@)
|
||||
*/
|
||||
|
||||
@@ -1,106 +1,5 @@
|
||||
#include <precomp.h>
|
||||
#include <tchar.h>
|
||||
#include <io.h>
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
intptr_t
|
||||
_tfindfirst(const _TCHAR* _name, struct _tfinddata_t* result)
|
||||
{
|
||||
WIN32_FIND_DATA FindFileData;
|
||||
long hFindFile;
|
||||
|
||||
hFindFile = (intptr_t)FindFirstFile(_name, &FindFileData);
|
||||
if (hFindFile == -1) {
|
||||
_dosmaperr(GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
result->attrib = FindFileData.dwFileAttributes;
|
||||
result->time_create = FileTimeToUnixTime(&FindFileData.ftCreationTime,NULL);
|
||||
result->time_access = FileTimeToUnixTime(&FindFileData.ftLastAccessTime,NULL);
|
||||
result->time_write = FileTimeToUnixTime(&FindFileData.ftLastWriteTime,NULL);
|
||||
result->size = FindFileData.nFileSizeLow;
|
||||
_tcsncpy(result->name,FindFileData.cFileName,MAX_PATH);
|
||||
|
||||
return hFindFile;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
intptr_t _tfindnext(intptr_t handle, struct _tfinddata_t* result)
|
||||
{
|
||||
WIN32_FIND_DATA FindFileData;
|
||||
|
||||
if (!FindNextFile((void*)handle, &FindFileData)) {
|
||||
_dosmaperr(GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
result->attrib = FindFileData.dwFileAttributes;
|
||||
result->time_create = FileTimeToUnixTime(&FindFileData.ftCreationTime,NULL);
|
||||
result->time_access = FileTimeToUnixTime(&FindFileData.ftLastAccessTime,NULL);
|
||||
result->time_write = FileTimeToUnixTime(&FindFileData.ftLastWriteTime,NULL);
|
||||
result->size = FindFileData.nFileSizeLow;
|
||||
_tcsncpy(result->name,FindFileData.cFileName, MAX_PATH);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
intptr_t _tfindfirsti64(const _TCHAR *_name, struct _tfinddatai64_t *result)
|
||||
{
|
||||
WIN32_FIND_DATA FindFileData;
|
||||
long hFindFile;
|
||||
|
||||
hFindFile = (intptr_t)FindFirstFile(_name, &FindFileData);
|
||||
if (hFindFile == -1)
|
||||
{
|
||||
_dosmaperr(GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
result->attrib = FindFileData.dwFileAttributes;
|
||||
result->time_create = FileTimeToUnixTime(&FindFileData.ftCreationTime,NULL);
|
||||
result->time_access = FileTimeToUnixTime(&FindFileData.ftLastAccessTime,NULL);
|
||||
result->time_write = FileTimeToUnixTime(&FindFileData.ftLastWriteTime,NULL);
|
||||
result->size =
|
||||
(((__int64)FindFileData.nFileSizeLow)<<32) + FindFileData.nFileSizeLow;
|
||||
_tcsncpy(result->name,FindFileData.cFileName,MAX_PATH);
|
||||
|
||||
return hFindFile;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
int _tfindnexti64(intptr_t handle, struct _tfinddatai64_t *result)
|
||||
{
|
||||
WIN32_FIND_DATA FindFileData;
|
||||
|
||||
if (!FindNextFile((HANDLE)handle, &FindFileData)) {
|
||||
_dosmaperr(GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
result->attrib = FindFileData.dwFileAttributes;
|
||||
result->time_create = FileTimeToUnixTime(&FindFileData.ftCreationTime,NULL);
|
||||
result->time_access = FileTimeToUnixTime(&FindFileData.ftLastAccessTime,NULL);
|
||||
result->time_write = FileTimeToUnixTime(&FindFileData.ftLastWriteTime,NULL);
|
||||
result->size =
|
||||
(((__int64)FindFileData.nFileSizeLow)<<32) + FindFileData.nFileSizeLow;
|
||||
_tcsncpy(result->name,FindFileData.cFileName,MAX_PATH);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifndef _UNICODE
|
||||
#define _USE_FIND64 0
|
||||
#include "find64.c"
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
@@ -114,5 +13,3 @@ int _findclose(intptr_t handle)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
#include <precomp.h>
|
||||
#include <tchar.h>
|
||||
#include <io.h>
|
||||
|
||||
#ifndef _USE_FIND64
|
||||
#define _USE_FIND64 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
#if _USE_FIND64
|
||||
intptr_t _tfindfirst32i64(const _TCHAR* _name, struct _tfinddata32i64_t* result)
|
||||
#else
|
||||
intptr_t _tfindfirst32(const _TCHAR* _name, struct _tfinddata32_t* result)
|
||||
#endif
|
||||
{
|
||||
WIN32_FIND_DATA FindFileData;
|
||||
HANDLE hFindFile;
|
||||
|
||||
hFindFile = FindFirstFile(_name, &FindFileData);
|
||||
if (hFindFile == INVALID_HANDLE_VALUE) {
|
||||
_dosmaperr(GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
result->attrib = FindFileData.dwFileAttributes;
|
||||
result->time_create = FileTimeToUnixTime(&FindFileData.ftCreationTime,NULL);
|
||||
result->time_access = FileTimeToUnixTime(&FindFileData.ftLastAccessTime,NULL);
|
||||
result->time_write = FileTimeToUnixTime(&FindFileData.ftLastWriteTime,NULL);
|
||||
result->size = FindFileData.nFileSizeLow;
|
||||
_tcsncpy(result->name,FindFileData.cFileName,MAX_PATH);
|
||||
|
||||
return (intptr_t)hFindFile;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
#if _USE_FIND64
|
||||
int _tfindnext32i64(intptr_t handle, struct _tfinddata32i64_t* result)
|
||||
#else
|
||||
int _tfindnext32(intptr_t handle, struct _tfinddata32_t* result)
|
||||
#endif
|
||||
{
|
||||
WIN32_FIND_DATA FindFileData;
|
||||
|
||||
if (!FindNextFile((HANDLE)handle, &FindFileData)) {
|
||||
_dosmaperr(GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
result->attrib = FindFileData.dwFileAttributes;
|
||||
result->time_create = FileTimeToUnixTime(&FindFileData.ftCreationTime,NULL);
|
||||
result->time_access = FileTimeToUnixTime(&FindFileData.ftLastAccessTime,NULL);
|
||||
result->time_write = FileTimeToUnixTime(&FindFileData.ftLastWriteTime,NULL);
|
||||
result->size = FindFileData.nFileSizeLow;
|
||||
_tcsncpy(result->name,FindFileData.cFileName, MAX_PATH);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
#if _USE_FIND64
|
||||
intptr_t _tfindfirst64(const _TCHAR *_name, struct _tfinddata64_t *result)
|
||||
#else
|
||||
intptr_t _tfindfirst64i32(const _TCHAR *_name, struct _tfinddata64i32_t *result)
|
||||
#endif
|
||||
{
|
||||
WIN32_FIND_DATA FindFileData;
|
||||
HANDLE hFindFile;
|
||||
|
||||
hFindFile = FindFirstFile(_name, &FindFileData);
|
||||
if (hFindFile == INVALID_HANDLE_VALUE) {
|
||||
_dosmaperr(GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
result->attrib = FindFileData.dwFileAttributes;
|
||||
result->time_create = FileTimeToUnixTime(&FindFileData.ftCreationTime,NULL);
|
||||
result->time_access = FileTimeToUnixTime(&FindFileData.ftLastAccessTime,NULL);
|
||||
result->time_write = FileTimeToUnixTime(&FindFileData.ftLastWriteTime,NULL);
|
||||
result->size =
|
||||
(((__int64)FindFileData.nFileSizeLow)<<32) + FindFileData.nFileSizeLow;
|
||||
_tcsncpy(result->name,FindFileData.cFileName,MAX_PATH);
|
||||
|
||||
return (intptr_t)hFindFile;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
#if _USE_FIND64
|
||||
int _tfindnext64(intptr_t handle, struct _tfinddata64_t *result)
|
||||
#else
|
||||
int _tfindnext64i32(intptr_t handle, struct _tfinddata64i32_t *result)
|
||||
#endif
|
||||
{
|
||||
WIN32_FIND_DATA FindFileData;
|
||||
|
||||
if (!FindNextFile((HANDLE)handle, &FindFileData)) {
|
||||
_dosmaperr(GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
result->attrib = FindFileData.dwFileAttributes;
|
||||
result->time_create = FileTimeToUnixTime(&FindFileData.ftCreationTime,NULL);
|
||||
result->time_access = FileTimeToUnixTime(&FindFileData.ftLastAccessTime,NULL);
|
||||
result->time_write = FileTimeToUnixTime(&FindFileData.ftLastWriteTime,NULL);
|
||||
result->size =
|
||||
(((__int64)FindFileData.nFileSizeLow)<<32) + FindFileData.nFileSizeLow;
|
||||
_tcsncpy(result->name,FindFileData.cFileName,MAX_PATH);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
#define _USE_STAT64 0
|
||||
#include "stat64.c"
|
||||
|
||||
|
||||
//only version needed
|
||||
//int CDECL _fstati64(int fd, struct _stati64* buf)
|
||||
//{
|
||||
// int ret;
|
||||
// struct __stat64 buf64;
|
||||
//
|
||||
// ret = _fstat64(fd, &buf64);
|
||||
// if (!ret)
|
||||
// stat64_to_stati64(&buf64, buf);
|
||||
// return ret;
|
||||
//}
|
||||
@@ -0,0 +1,365 @@
|
||||
#include <precomp.h>
|
||||
#include "wine/unicode.h"
|
||||
|
||||
#include <direct.h>
|
||||
#include <tchar.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifndef _UNICODE
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#ifndef _USE_STAT64
|
||||
#define _USE_STAT64 1
|
||||
#endif
|
||||
|
||||
/* for stat mode, permissions apply to all,owner and group */
|
||||
#define ALL_S_IREAD (_S_IREAD | (_S_IREAD >> 3) | (_S_IREAD >> 6))
|
||||
#define ALL_S_IWRITE (_S_IWRITE | (_S_IWRITE >> 3) | (_S_IWRITE >> 6))
|
||||
#define ALL_S_IEXEC (_S_IEXEC | (_S_IEXEC >> 3) | (_S_IEXEC >> 6))
|
||||
|
||||
#define EXE ('e' << 16 | 'x' << 8 | 'e')
|
||||
#define BAT ('b' << 16 | 'a' << 8 | 't')
|
||||
#define CMD ('c' << 16 | 'm' << 8 | 'd')
|
||||
#define COM ('c' << 16 | 'o' << 8 | 'm')
|
||||
|
||||
#define TOUL(x) (ULONGLONG)(x)
|
||||
#define WCEXE (TOUL('e') << 32 | TOUL('x') << 16 | TOUL('e'))
|
||||
#define WCBAT (TOUL('b') << 32 | TOUL('a') << 16 | TOUL('t'))
|
||||
#define WCCMD (TOUL('c') << 32 | TOUL('m') << 16 | TOUL('d'))
|
||||
#define WCCOM (TOUL('c') << 32 | TOUL('o') << 16 | TOUL('m'))
|
||||
|
||||
#if _USE_STAT64
|
||||
void stat64_to_stati64(const struct __stat64 *buf64, struct _stati64 *buf)
|
||||
{
|
||||
buf->st_dev = buf64->st_dev;
|
||||
buf->st_ino = buf64->st_ino;
|
||||
buf->st_mode = buf64->st_mode;
|
||||
buf->st_nlink = buf64->st_nlink;
|
||||
buf->st_uid = buf64->st_uid;
|
||||
buf->st_gid = buf64->st_gid;
|
||||
buf->st_rdev = buf64->st_rdev;
|
||||
buf->st_size = buf64->st_size;
|
||||
buf->st_atime = buf64->st_atime;
|
||||
buf->st_mtime = buf64->st_mtime;
|
||||
buf->st_ctime = buf64->st_ctime;
|
||||
}
|
||||
|
||||
//int _tstati64(const TCHAR* path, struct _stati64 * buf)
|
||||
//{
|
||||
// int ret;
|
||||
// struct __stat64 buf64;
|
||||
//
|
||||
// ret = _tstat64(path, &buf64);
|
||||
// if (!ret)
|
||||
// stat64_to_stati64(&buf64, buf);
|
||||
// return ret;
|
||||
//}
|
||||
|
||||
#endif
|
||||
|
||||
HANDLE fdtoh(int fd); //file.c
|
||||
|
||||
#if _USE_STAT64
|
||||
int CDECL _tstat64(const _TCHAR *path, struct _stat64 *buf)
|
||||
#else
|
||||
int CDECL _tstat64i32(const _TCHAR *path, struct _stat64i32 *buf)
|
||||
#endif
|
||||
{
|
||||
DWORD dw;
|
||||
WIN32_FILE_ATTRIBUTE_DATA hfi;
|
||||
unsigned short mode = ALL_S_IREAD;
|
||||
int plen;
|
||||
|
||||
TRACE(":file (%s) buf(%p)\n",path,buf);
|
||||
|
||||
if (!GetFileAttributesEx(path, GetFileExInfoStandard, &hfi))
|
||||
{
|
||||
TRACE("failed (%d)\n",GetLastError());
|
||||
__set_errno(ERROR_FILE_NOT_FOUND);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(buf,0,sizeof(struct __stat64));
|
||||
|
||||
/* FIXME: rdev isn't drive num, despite what the docs say-what is it?
|
||||
Bon 011120: This FIXME seems incorrect
|
||||
Also a letter as first char isn't enough to be classified
|
||||
as a drive letter
|
||||
*/
|
||||
#ifndef _UNICODE
|
||||
if (isalpha(*path)&& (*(path+1)==':'))
|
||||
buf->st_dev = buf->st_rdev = toupper(*path) - 'A'; /* drive num */
|
||||
#else
|
||||
if (iswalpha(*path))
|
||||
buf->st_dev = buf->st_rdev = toupperW(*path - 'A'); /* drive num */
|
||||
#endif
|
||||
else
|
||||
buf->st_dev = buf->st_rdev = _getdrive() - 1;
|
||||
|
||||
#ifndef _UNICODE
|
||||
plen = strlen(path);
|
||||
#else
|
||||
plen = strlenW(path);
|
||||
#endif
|
||||
|
||||
/* Dir, or regular file? */
|
||||
if ((hfi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ||
|
||||
(path[plen-1] == '\\'))
|
||||
mode |= (_S_IFDIR | ALL_S_IEXEC);
|
||||
else
|
||||
{
|
||||
mode |= _S_IFREG;
|
||||
/* executable? */
|
||||
if (plen > 6 && path[plen-4] == '.') /* shortest exe: "\x.exe" */
|
||||
{
|
||||
#ifndef _UNICODE
|
||||
unsigned int ext = tolower(path[plen-1]) | (tolower(path[plen-2]) << 8) |
|
||||
(tolower(path[plen-3]) << 16);
|
||||
if (ext == EXE || ext == BAT || ext == CMD || ext == COM)
|
||||
mode |= ALL_S_IEXEC;
|
||||
#else
|
||||
ULONGLONG ext = tolowerW(path[plen-1]) | (tolowerW(path[plen-2]) << 16) |
|
||||
((ULONGLONG)tolowerW(path[plen-3]) << 32);
|
||||
if (ext == WCEXE || ext == WCBAT || ext == WCCMD || ext == WCCOM)
|
||||
mode |= ALL_S_IEXEC;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (!(hfi.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
|
||||
mode |= ALL_S_IWRITE;
|
||||
|
||||
buf->st_mode = mode;
|
||||
buf->st_nlink = 1;
|
||||
#if _USE_STAT64
|
||||
buf->st_size = buf->st_size = ((__int64)hfi.nFileSizeHigh << 32) + hfi.nFileSizeLow;
|
||||
#else
|
||||
buf->st_size = hfi.nFileSizeLow;
|
||||
#endif
|
||||
RtlTimeToSecondsSince1970((LARGE_INTEGER *)&hfi.ftLastAccessTime, &dw);
|
||||
buf->st_atime = dw;
|
||||
RtlTimeToSecondsSince1970((LARGE_INTEGER *)&hfi.ftLastWriteTime, &dw);
|
||||
buf->st_mtime = buf->st_ctime = dw;
|
||||
TRACE("%d %d 0x%08lx%08lx %ld %ld %ld\n", buf->st_mode,buf->st_nlink,
|
||||
(long)(buf->st_size >> 16),(long)buf->st_size,
|
||||
(long)buf->st_atime,(long)buf->st_mtime,(long)buf->st_ctime);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* _stat (MSVCRT.@)
|
||||
*/
|
||||
#if _USE_STAT64
|
||||
int CDECL _tstat32i64(const _TCHAR *path,struct _stat32i64 *buf)
|
||||
#else
|
||||
int CDECL _tstat32(const _TCHAR *path,struct _stat32 *buf)
|
||||
#endif
|
||||
{
|
||||
DWORD dw;
|
||||
WIN32_FILE_ATTRIBUTE_DATA hfi;
|
||||
unsigned short mode = ALL_S_IREAD;
|
||||
int plen;
|
||||
|
||||
TRACE(":file (%s) buf(%p)\n",path,buf);
|
||||
|
||||
if (!GetFileAttributesEx(path, GetFileExInfoStandard, &hfi))
|
||||
{
|
||||
TRACE("failed (%d)\n",GetLastError());
|
||||
__set_errno(ERROR_FILE_NOT_FOUND);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(buf,0,sizeof(*buf));
|
||||
|
||||
/* FIXME: rdev isn't drive num, despite what the docs say-what is it?
|
||||
Bon 011120: This FIXME seems incorrect
|
||||
Also a letter as first char isn't enough to be classified
|
||||
as a drive letter
|
||||
*/
|
||||
#ifndef _UNICODE
|
||||
if (isalpha(*path)&& (*(path+1)==':'))
|
||||
buf->st_dev = buf->st_rdev = toupper(*path) - 'A'; /* drive num */
|
||||
#else
|
||||
if (iswalpha(*path))
|
||||
buf->st_dev = buf->st_rdev = toupperW(*path - 'A'); /* drive num */
|
||||
#endif
|
||||
else
|
||||
buf->st_dev = buf->st_rdev = _getdrive() - 1;
|
||||
|
||||
#ifndef _UNICODE
|
||||
plen = strlen(path);
|
||||
#else
|
||||
plen = strlenW(path);
|
||||
#endif
|
||||
|
||||
/* Dir, or regular file? */
|
||||
if ((hfi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ||
|
||||
(path[plen-1] == '\\'))
|
||||
mode |= (_S_IFDIR | ALL_S_IEXEC);
|
||||
else
|
||||
{
|
||||
mode |= _S_IFREG;
|
||||
/* executable? */
|
||||
if (plen > 6 && path[plen-4] == '.') /* shortest exe: "\x.exe" */
|
||||
{
|
||||
#ifndef _UNICODE
|
||||
unsigned int ext = tolower(path[plen-1]) | (tolower(path[plen-2]) << 8) |
|
||||
(tolower(path[plen-3]) << 16);
|
||||
if (ext == EXE || ext == BAT || ext == CMD || ext == COM)
|
||||
mode |= ALL_S_IEXEC;
|
||||
#else
|
||||
ULONGLONG ext = tolowerW(path[plen-1]) | (tolowerW(path[plen-2]) << 16) |
|
||||
((ULONGLONG)tolowerW(path[plen-3]) << 32);
|
||||
if (ext == WCEXE || ext == WCBAT || ext == WCCMD || ext == WCCOM)
|
||||
mode |= ALL_S_IEXEC;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (!(hfi.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
|
||||
mode |= ALL_S_IWRITE;
|
||||
|
||||
buf->st_mode = mode;
|
||||
buf->st_nlink = 1;
|
||||
#if _USE_STAT64
|
||||
buf->st_size = ((__int32)hfi.nFileSizeHigh << 16) + hfi.nFileSizeLow;
|
||||
#else
|
||||
buf->st_size = hfi.nFileSizeLow;
|
||||
#endif
|
||||
RtlTimeToSecondsSince1970((LARGE_INTEGER *)&hfi.ftLastAccessTime, &dw);
|
||||
buf->st_atime = dw;
|
||||
RtlTimeToSecondsSince1970((LARGE_INTEGER *)&hfi.ftLastWriteTime, &dw);
|
||||
buf->st_mtime = buf->st_ctime = dw;
|
||||
TRACE("%d %d 0x%08lx%08lx %ld %ld %ld\n", buf->st_mode,buf->st_nlink,
|
||||
(long)(buf->st_size >> 16),(long)buf->st_size,
|
||||
(long)buf->st_atime,(long)buf->st_mtime,(long)buf->st_ctime);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef _UNICODE //No wide versions needed
|
||||
|
||||
#if _USE_STAT64
|
||||
int CDECL _fstat64(int fd, struct _stat64* buf)
|
||||
#else
|
||||
int CDECL _fstat64i32(int fd, struct _stat64i32* buf)
|
||||
#endif
|
||||
{
|
||||
DWORD dw;
|
||||
DWORD type;
|
||||
BY_HANDLE_FILE_INFORMATION hfi;
|
||||
HANDLE hand = fdtoh(fd);
|
||||
|
||||
TRACE(":fd (%d) stat (%p)\n",fd,buf);
|
||||
if (hand == INVALID_HANDLE_VALUE)
|
||||
return -1;
|
||||
|
||||
if (!buf)
|
||||
{
|
||||
WARN(":failed-NULL buf\n");
|
||||
__set_errno(ERROR_INVALID_PARAMETER);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&hfi, 0, sizeof(hfi));
|
||||
memset(buf, 0, sizeof(struct __stat64));
|
||||
type = GetFileType(hand);
|
||||
if (type == FILE_TYPE_PIPE)
|
||||
{
|
||||
buf->st_dev = buf->st_rdev = fd;
|
||||
buf->st_mode = S_IFIFO;
|
||||
buf->st_nlink = 1;
|
||||
}
|
||||
else if (type == FILE_TYPE_CHAR)
|
||||
{
|
||||
buf->st_dev = buf->st_rdev = fd;
|
||||
buf->st_mode = S_IFCHR;
|
||||
buf->st_nlink = 1;
|
||||
}
|
||||
else /* FILE_TYPE_DISK etc. */
|
||||
{
|
||||
if (!GetFileInformationByHandle(hand, &hfi))
|
||||
{
|
||||
WARN(":failed-last error (%d)\n",GetLastError());
|
||||
__set_errno(ERROR_INVALID_PARAMETER);
|
||||
return -1;
|
||||
}
|
||||
buf->st_mode = S_IFREG | S_IREAD;
|
||||
if (!(hfi.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
|
||||
buf->st_mode |= S_IWRITE;
|
||||
buf->st_size = ((__int64)hfi.nFileSizeHigh << 32) + hfi.nFileSizeLow;
|
||||
RtlTimeToSecondsSince1970((LARGE_INTEGER *)&hfi.ftLastAccessTime, &dw);
|
||||
buf->st_atime = dw;
|
||||
RtlTimeToSecondsSince1970((LARGE_INTEGER *)&hfi.ftLastWriteTime, &dw);
|
||||
buf->st_mtime = buf->st_ctime = dw;
|
||||
buf->st_nlink = hfi.nNumberOfLinks;
|
||||
}
|
||||
TRACE(":dwFileAttributes = 0x%x, mode set to 0x%x\n",hfi.dwFileAttributes,
|
||||
buf->st_mode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* _fstat (MSVCRT.@)
|
||||
*/
|
||||
#if _USE_STAT64
|
||||
int CDECL _fstat32(int fd, struct _stat32* buf)
|
||||
#else
|
||||
int CDECL _fstat32i64(int fd, struct _stat32i64* buf)
|
||||
#endif
|
||||
{
|
||||
DWORD dw;
|
||||
DWORD type;
|
||||
BY_HANDLE_FILE_INFORMATION hfi;
|
||||
HANDLE hand = fdtoh(fd);
|
||||
|
||||
TRACE(":fd (%d) stat (%p)\n",fd,buf);
|
||||
if (hand == INVALID_HANDLE_VALUE)
|
||||
return -1;
|
||||
|
||||
if (!buf)
|
||||
{
|
||||
WARN(":failed-NULL buf\n");
|
||||
__set_errno(ERROR_INVALID_PARAMETER);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&hfi, 0, sizeof(hfi));
|
||||
memset(buf, 0, sizeof(struct _stat32));
|
||||
type = GetFileType(hand);
|
||||
if (type == FILE_TYPE_PIPE)
|
||||
{
|
||||
buf->st_dev = buf->st_rdev = fd;
|
||||
buf->st_mode = S_IFIFO;
|
||||
buf->st_nlink = 1;
|
||||
}
|
||||
else if (type == FILE_TYPE_CHAR)
|
||||
{
|
||||
buf->st_dev = buf->st_rdev = fd;
|
||||
buf->st_mode = S_IFCHR;
|
||||
buf->st_nlink = 1;
|
||||
}
|
||||
else /* FILE_TYPE_DISK etc. */
|
||||
{
|
||||
if (!GetFileInformationByHandle(hand, &hfi))
|
||||
{
|
||||
WARN(":failed-last error (%d)\n",GetLastError());
|
||||
__set_errno(ERROR_INVALID_PARAMETER);
|
||||
return -1;
|
||||
}
|
||||
buf->st_mode = S_IFREG | S_IREAD;
|
||||
if (!(hfi.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
|
||||
buf->st_mode |= S_IWRITE;
|
||||
buf->st_size = ((__int32)hfi.nFileSizeHigh << 16) + hfi.nFileSizeLow;
|
||||
RtlTimeToSecondsSince1970((LARGE_INTEGER *)&hfi.ftLastAccessTime, &dw);
|
||||
buf->st_atime = dw;
|
||||
RtlTimeToSecondsSince1970((LARGE_INTEGER *)&hfi.ftLastWriteTime, &dw);
|
||||
buf->st_mtime = buf->st_ctime = dw;
|
||||
buf->st_nlink = hfi.nNumberOfLinks;
|
||||
}
|
||||
TRACE(":dwFileAttributes = 0x%x, mode set to 0x%x\n",hfi.dwFileAttributes,
|
||||
buf->st_mode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,5 +1,8 @@
|
||||
|
||||
#define UNICODE
|
||||
#define _UNICODE
|
||||
|
||||
#include "find.c"
|
||||
#define _USE_FIND64 0
|
||||
#include <wchar.h>
|
||||
#include "find64.c"
|
||||
#undef _USE_FIND64
|
||||
#include "find64.c"
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
#define _UNICODE
|
||||
#define UNICODE
|
||||
#define _USE_STAT64 0
|
||||
#include <wchar.h>
|
||||
#include "stat64.c"
|
||||
#undef _USE_STAT64
|
||||
#include "stat64.c"
|
||||
Reference in New Issue
Block a user