b6fd209d5d202adeb4426ef6d766cfdf1cb2e338
[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 /*
21  * @implemented
22  */
23 int _fstat(int fd, struct stat* statbuf)
24 {
25   BY_HANDLE_FILE_INFORMATION  FileInformation;
26   DWORD dwFileType;
27   void* handle;
28
29   if (!statbuf) {
30     __set_errno(EINVAL);
31     return -1;
32   }
33
34   if ((void*)-1 == (handle = _get_osfhandle(fd)))
35   {
36     __set_errno(EBADF);
37     return -1;
38   }
39
40   fflush(NULL);
41
42   memset (statbuf, 0, sizeof(struct stat));
43
44   dwFileType = GetFileType(handle);
45
46   if (dwFileType == FILE_TYPE_DISK)
47   {
48     if (!GetFileInformationByHandle(handle,&FileInformation))
49     {
50       __set_errno(EBADF);
51       return -1;
52     }
53     statbuf->st_ctime = FileTimeToUnixTime(&FileInformation.ftCreationTime,NULL);
54     statbuf->st_atime = FileTimeToUnixTime(&FileInformation.ftLastAccessTime,NULL);
55     statbuf->st_mtime = FileTimeToUnixTime(&FileInformation.ftLastWriteTime,NULL);
56
57     statbuf->st_dev = fd;
58     statbuf->st_size = FileInformation.nFileSizeLow;
59     statbuf->st_mode = S_IREAD;
60     if (FileInformation.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) 
61       statbuf->st_mode |= S_IFDIR;
62     else
63       statbuf->st_mode |= S_IFREG;
64     if (!(FileInformation.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
65       statbuf->st_mode |= S_IWRITE;
66   }
67   else if (dwFileType == FILE_TYPE_CHAR)
68   {
69     statbuf->st_dev = fd;
70     statbuf->st_mode = S_IFCHR;
71   }
72   else if (dwFileType == FILE_TYPE_PIPE)
73   {
74     statbuf->st_dev = fd;
75     statbuf->st_mode = S_IFIFO;
76   }
77   else
78   {
79     // dwFileType is FILE_TYPE_UNKNOWN or has a bad value
80     __set_errno(EBADF);
81     return -1;
82   }
83   return 0;
84 }