update for HEAD-2003091401
[reactos.git] / lib / msvcrt / sys_stat / fstati64.c
1 /* $Id$
2  *
3  * COPYRIGHT:   See COPYING in the top level directory
4  * PROJECT:     ReactOS system libraries
5  * FILE:        lib/msvcrt/sys/fstat.c
6  * PURPOSE:     Gather file information
7  * PROGRAMER:   Boudewijn Dekker
8  * UPDATE HISTORY:
9  *              28/12/98: Created
10  */
11 #include <windows.h>
12 #include <msvcrt/sys/types.h>
13 #include <msvcrt/sys/stat.h>
14 #include <msvcrt/fcntl.h>
15 #include <msvcrt/string.h>
16 #include <msvcrt/errno.h>
17 #include <msvcrt/internal/file.h>
18
19
20 /*
21  * @implemented
22  */
23 __int64 _fstati64(int fd, struct _stati64* statbuf)
24 {
25   BY_HANDLE_FILE_INFORMATION FileInformation;
26   DWORD dwFileType;
27   void *handle;
28
29   if (!statbuf)
30   {
31     __set_errno(EINVAL);
32     return -1;
33   }
34
35   if ((void*)-1 == (handle = _get_osfhandle(fd)))
36   {
37     __set_errno(EBADF);
38     return -1;
39   }
40   
41   fflush(NULL);
42
43   memset(statbuf, 0, sizeof(struct _stati64));
44
45   dwFileType = GetFileType(handle);
46
47   if (dwFileType == FILE_TYPE_DISK)
48   {
49     if (!GetFileInformationByHandle(handle,&FileInformation))
50     {
51        __set_errno(EBADF);
52        return -1;
53     }
54     statbuf->st_ctime = FileTimeToUnixTime(&FileInformation.ftCreationTime,NULL);
55     statbuf->st_atime = FileTimeToUnixTime(&FileInformation.ftLastAccessTime,NULL);
56     statbuf->st_mtime = FileTimeToUnixTime(&FileInformation.ftLastWriteTime,NULL);
57
58     statbuf->st_dev = fd;
59     statbuf->st_size = (((__int64)FileInformation.nFileSizeHigh) << 32) +
60              FileInformation.nFileSizeLow;
61     statbuf->st_mode = S_IREAD;
62     if (FileInformation.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) 
63       statbuf->st_mode |= S_IFDIR;
64     else
65       statbuf->st_mode |= S_IFREG;
66     if (!(FileInformation.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) statbuf->st_mode |= S_IWRITE;
67   }
68   else if (dwFileType == FILE_TYPE_CHAR)
69   {
70     statbuf->st_dev = fd;
71     statbuf->st_mode = S_IFCHR;
72   }
73   else if (dwFileType == FILE_TYPE_PIPE)
74   {
75     statbuf->st_dev = fd;
76     statbuf->st_mode = S_IFIFO;
77   }
78   else
79   {
80     // dwFileType is FILE_TYPE_UNKNOWN or has a bad value
81     __set_errno(EBADF);
82     return -1;
83   }
84   return 0;
85 }