mirror of
https://github.com/reactos/reactos.git
synced 2024-11-18 13:01:40 +00:00
c8719ee865
This fixes the following compiler errors: ../sdk/lib/crt/stdio/stat64.c:7:13: error: inline function 'release_ioinfo' declared but never defined [-Werror] inline void release_ioinfo(ioinfo *info); ^~~~~~~~~~~~~~ ../sdk/lib/crt/stdio/stat64.c:6:16: error: inline function 'get_ioinfo' declared but never defined [-Werror] inline ioinfo* get_ioinfo(int fd); ^~~~~~~~~~ ../sdk/lib/crt/stdio/file.c:186:5: error: 'init_ioinfo_cs' is static but used in inline function 'get_ioinfo' which is not static [-Werror] init_ioinfo_cs(ret); ^~~~~~~~~~~~~~ ../sdk/lib/crt/stdio/file.c:183:19: error: 'get_ioinfo_nolock' is static but used in inline function 'get_ioinfo' which is not static [-Werror] ioinfo *ret = get_ioinfo_nolock(fd);
164 lines
4.7 KiB
C
164 lines
4.7 KiB
C
#include <precomp.h>
|
|
#include <tchar.h>
|
|
#include <direct.h>
|
|
#include <internal/wine/msvcrt.h>
|
|
|
|
ioinfo* get_ioinfo(int fd);
|
|
void release_ioinfo(ioinfo *info);
|
|
|
|
#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))
|
|
|
|
#ifdef UNICODE
|
|
#define TCHAR4 ULONGLONG
|
|
#else
|
|
#define TCHAR4 ULONG
|
|
#endif
|
|
|
|
#define TCSIZE_BITS (sizeof(_TCHAR)*8)
|
|
|
|
#define EXE (((TCHAR4)('e')<<(2*TCSIZE_BITS)) | ((TCHAR4)('x')<<TCSIZE_BITS) | ((TCHAR4)('e')))
|
|
#define BAT (((TCHAR4)('b')<<(2*TCSIZE_BITS)) | ((TCHAR4)('a')<<TCSIZE_BITS) | ((TCHAR4)('t')))
|
|
#define CMD (((TCHAR4)('c')<<(2*TCSIZE_BITS)) | ((TCHAR4)('m')<<TCSIZE_BITS) | ((TCHAR4)('d')))
|
|
#define COM (((TCHAR4)('c')<<(2*TCSIZE_BITS)) | ((TCHAR4)('o')<<TCSIZE_BITS) | ((TCHAR4)('m')))
|
|
|
|
int CDECL _tstat64(const _TCHAR *path, struct __stat64 *buf)
|
|
{
|
|
DWORD dw;
|
|
WIN32_FILE_ATTRIBUTE_DATA hfi;
|
|
unsigned short mode = ALL_S_IREAD;
|
|
size_t plen;
|
|
|
|
TRACE(":file (%s) buf(%p)\n",path,buf);
|
|
|
|
plen = _tcslen(path);
|
|
while (plen && path[plen-1]==__T(' '))
|
|
plen--;
|
|
|
|
if (plen && (plen<2 || path[plen-2]!=__T(':')) &&
|
|
(path[plen-1]==__T(':') || path[plen-1]==__T('\\') || path[plen-1]==__T('/')))
|
|
{
|
|
*_errno() = ENOENT;
|
|
return -1;
|
|
}
|
|
|
|
if (!GetFileAttributesEx(path, GetFileExInfoStandard, &hfi))
|
|
{
|
|
TRACE("failed (%d)\n",GetLastError());
|
|
*_errno() = ENOENT;
|
|
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 (_istalpha(*path) && (*(path+1)==__T(':')))
|
|
buf->st_dev = buf->st_rdev = _totupper(*path) - __T('A'); /* drive num */
|
|
else
|
|
buf->st_dev = buf->st_rdev = _getdrive() - 1;
|
|
|
|
/* Dir, or regular file? */
|
|
if (hfi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
|
mode |= (_S_IFDIR | ALL_S_IEXEC);
|
|
else
|
|
{
|
|
mode |= _S_IFREG;
|
|
/* executable? */
|
|
if (plen > 6 && path[plen-4] == __T('.')) /* shortest exe: "\x.exe" */
|
|
{
|
|
|
|
TCHAR4 ext = (TCHAR4)_totlower(path[plen-1])
|
|
| ((TCHAR4)_totlower(path[plen-2]) << TCSIZE_BITS)
|
|
| ((TCHAR4)_totlower(path[plen-3]) << 2*TCSIZE_BITS);
|
|
|
|
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%08x%08x %d %d %d\n", buf->st_mode,buf->st_nlink,
|
|
(int)(buf->st_size >> 32),(int)buf->st_size,
|
|
(int)buf->st_atime,(int)buf->st_mtime,(int)buf->st_ctime);
|
|
return 0;
|
|
}
|
|
|
|
#ifndef _UNICODE
|
|
|
|
int CDECL _fstat64(int fd, struct __stat64* buf)
|
|
{
|
|
ioinfo *info = get_ioinfo(fd);
|
|
DWORD dw;
|
|
DWORD type;
|
|
BY_HANDLE_FILE_INFORMATION hfi;
|
|
|
|
TRACE(":fd (%d) stat (%p)\n", fd, buf);
|
|
if (info->handle == INVALID_HANDLE_VALUE)
|
|
{
|
|
release_ioinfo(info);
|
|
return -1;
|
|
}
|
|
|
|
if (!buf)
|
|
{
|
|
WARN(":failed-NULL buf\n");
|
|
_dosmaperr(ERROR_INVALID_PARAMETER);
|
|
release_ioinfo(info);
|
|
return -1;
|
|
}
|
|
|
|
memset(&hfi, 0, sizeof(hfi));
|
|
memset(buf, 0, sizeof(struct __stat64));
|
|
type = GetFileType(info->handle);
|
|
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(info->handle, &hfi))
|
|
{
|
|
WARN(":failed-last error (%d)\n",GetLastError());
|
|
_dosmaperr(ERROR_INVALID_PARAMETER);
|
|
release_ioinfo(info);
|
|
return -1;
|
|
}
|
|
buf->st_mode = _S_IFREG | ALL_S_IREAD;
|
|
if (!(hfi.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
|
|
buf->st_mode |= ALL_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 = (short)hfi.nNumberOfLinks;
|
|
}
|
|
TRACE(":dwFileAttributes = 0x%x, mode set to 0x%x\n",hfi.dwFileAttributes,
|
|
buf->st_mode);
|
|
release_ioinfo(info);
|
|
return 0;
|
|
}
|
|
|
|
#endif
|