cb4035b810b9b111c5d1ef5ff1305d321f81610b
[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
20 int _fstat(int fd, struct stat* statbuf)
21 {
22   BY_HANDLE_FILE_INFORMATION  FileInformation;
23   DWORD dwFileType;
24   void* handle;
25
26   if (!statbuf) {
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))
62       statbuf->st_mode |= S_IWRITE;
63   }
64   else if (dwFileType == FILE_TYPE_CHAR)
65   {
66     statbuf->st_dev = fd;
67     statbuf->st_mode = S_IFCHR;
68   }
69   else if (dwFileType == FILE_TYPE_PIPE)
70   {
71     statbuf->st_dev = fd;
72     statbuf->st_mode = S_IFIFO;
73   }
74   else
75   {
76     // dwFileType is FILE_TYPE_UNKNOWN or has a bad value
77     __set_errno(EBADF);
78     return -1;
79   }
80   return 0;
81 }