:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / lib / msvcrt / sys_stat / fstat.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 int _fstat(int fd, struct stat *statbuf)
20 {
21   BY_HANDLE_FILE_INFORMATION  FileInformation;
22   DWORD dwFileType;
23   void* handle;
24
25   if (!statbuf)
26   {
27     __set_errno(EINVAL);
28     return -1;
29   }
30
31   if ((void*)-1 == (handle = _get_osfhandle(fd)))
32   {
33     __set_errno(EBADF);
34     return -1;
35   }
36
37   fflush(NULL);
38
39   memset (statbuf, 0, sizeof(struct stat));
40
41   dwFileType = GetFileType(handle);
42
43   if (dwFileType == FILE_TYPE_DISK)
44   {
45     if (!GetFileInformationByHandle(handle,&FileInformation))
46     {
47       __set_errno(EBADF);
48       return -1;
49     }
50     statbuf->st_ctime = FileTimeToUnixTime(&FileInformation.ftCreationTime,NULL);
51     statbuf->st_atime = FileTimeToUnixTime(&FileInformation.ftLastAccessTime,NULL);
52     statbuf->st_mtime = FileTimeToUnixTime(&FileInformation.ftLastWriteTime,NULL);
53
54     statbuf->st_dev = fd;
55     statbuf->st_size = FileInformation.nFileSizeLow;
56     statbuf->st_mode = S_IREAD;
57     if (FileInformation.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) 
58       statbuf->st_mode |= S_IFDIR;
59     else
60       statbuf->st_mode |= S_IFREG;
61     if (!(FileInformation.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) statbuf->st_mode |= S_IWRITE;
62   }
63   else if (dwFileType == FILE_TYPE_CHAR)
64   {
65     statbuf->st_dev = fd;
66     statbuf->st_mode = S_IFCHR;
67   }
68   else if (dwFileType == FILE_TYPE_PIPE)
69   {
70     statbuf->st_dev = fd;
71     statbuf->st_mode = S_IFIFO;
72   }
73   else
74   {
75     // dwFileType is FILE_TYPE_UNKNOWN or has a bad value
76     __set_errno(EBADF);
77     return -1;
78   }
79   return 0;
80 }
81
82 __int64 _fstati64 (int fd, struct _stati64* statbuf)
83 {
84   BY_HANDLE_FILE_INFORMATION FileInformation;
85   DWORD dwFileType;
86   void *handle;
87
88   if (!statbuf)
89   {
90     __set_errno(EINVAL);
91     return -1;
92   }
93
94   if ((void*)-1 == (handle = _get_osfhandle(fd)))
95   {
96     __set_errno(EBADF);
97     return -1;
98   }
99   
100   fflush(NULL);
101
102   memset(statbuf, 0, sizeof(struct _stati64));
103
104   dwFileType = GetFileType(handle);
105
106   if (dwFileType == FILE_TYPE_DISK)
107   {
108     if (!GetFileInformationByHandle(handle,&FileInformation))
109     {
110        __set_errno(EBADF);
111        return -1;
112     }
113     statbuf->st_ctime = FileTimeToUnixTime(&FileInformation.ftCreationTime,NULL);
114     statbuf->st_atime = FileTimeToUnixTime(&FileInformation.ftLastAccessTime,NULL);
115     statbuf->st_mtime = FileTimeToUnixTime(&FileInformation.ftLastWriteTime,NULL);
116
117     statbuf->st_dev = fd;
118     statbuf->st_size = (((__int64)FileInformation.nFileSizeHigh) << 32) +
119                      FileInformation.nFileSizeLow;
120     statbuf->st_mode = S_IREAD;
121     if (FileInformation.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) 
122       statbuf->st_mode |= S_IFDIR;
123     else
124       statbuf->st_mode |= S_IFREG;
125     if (!(FileInformation.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) statbuf->st_mode |= S_IWRITE;
126   }
127   else if (dwFileType == FILE_TYPE_CHAR)
128   {
129     statbuf->st_dev = fd;
130     statbuf->st_mode = S_IFCHR;
131   }
132   else if (dwFileType == FILE_TYPE_PIPE)
133   {
134     statbuf->st_dev = fd;
135     statbuf->st_mode = S_IFIFO;
136   }
137   else
138   {
139     // dwFileType is FILE_TYPE_UNKNOWN or has a bad value
140     __set_errno(EBADF);
141     return -1;
142   }
143   return 0;
144 }
145
146