blob: 4acadab487c67459eab3611f2d0a17b4fdb145d9 [file] [log] [blame] [raw]
/* A part of the Native C Library for Windows NT
Copyright 2007-2015 PC GO Ld.
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*/
#include <sys/stat.h>
#include <windows.h>
#include <nt.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
int fstat(int fd, struct stat *st) {
//printf("function: fstat(%d, %p)\n", fd, st);
if(!st) {
errno = EFAULT;
return -1;
}
{
//OBJECT_TYPE_INFORMATION oti;
size_t oti_len = sizeof(OBJECT_TYPE_INFORMATION) + 256;
OBJECT_TYPE_INFORMATION *oti = malloc(oti_len);
long int status = NtQueryObject((void *)fd, ObjectTypeInformation, oti, oti_len, NULL);
printf("nativelibc debug: fstat: status = 0x%lx\n", status);
if(status >= 0) {
printf("TypeName: ");
NtDisplayString(&oti->TypeName);
putchar('\n');
printf("PoolType: %lu\n", oti->PoolType);
}
free(oti);
size_t oni_len = sizeof(OBJECT_NAME_INFORMATION) + 256;
OBJECT_NAME_INFORMATION *oni = malloc(oni_len);
status = NtQueryObject((void *)fd, ObjectNameInformation, oni, oni_len, NULL);
printf("nativelibc debug: fstat: status = 0x%lx\n", status);
if(status >= 0) {
printf("Name: ");
NtDisplayString(&oni->Name);
putchar('\n');
}
free(oni);
OBJECT_BASIC_INFORMATION obi;
status = NtQueryObject((void *)fd, ObjectBasicInformation, &obi, sizeof obi, NULL);
printf("nativelibc debug: fstat: status = 0x%lx\n", status);
if(status >= 0) {
unsigned long int t;
printf("Attributes = 0x%lx\n"
"GrantedAccess = 0x%lx\n"
"NameInformationLength = %lu\n"
"TypeInformationLength = %lu\n",
obi.Attributes,
obi.GrantedAccess,
obi.NameInformationLength,
obi.TypeInformationLength);
if(RtlTimeToSecondsSince1970(&obi.CreateTime, &t)) printf("\nctime = %lu\n", t);
}
putchar('\n');
}
FILE_BASIC_INFORMATION fbi;
FILE_STANDARD_INFORMATION fsi;
FILE_INTERNAL_INFORMATION fii;
IO_STATUS_BLOCK io_status;
long int status1 = NtQueryInformationFile((void *)fd, &io_status, &fbi, sizeof fbi, FileBasicInformation);
printf("nativelibc debug: fstat: status1 = 0x%lx\n", status1);
//if(ntstatus_to_errno(status)) return -1;
st->st_mode = S_IREAD | S_IEXEC;
if(status1 >= 0) {
unsigned long int t;
st->st_ctime = RtlTimeToSecondsSince1970(&fbi.ChangeTime, &t) ? t : 0;
st->st_mtime = RtlTimeToSecondsSince1970(&fbi.LastWriteTime, &t) ? t : 0;
st->st_atime = RtlTimeToSecondsSince1970(&fbi.LastAccessTime, &t) ? t : 0;
//st->st_mode = 0777;
//if(fbi.FileAttributes & FILE_ATTRIBUTE_READONLY) st->st_mode &= ~0222;
if(!(fbi.FileAttributes & FILE_ATTRIBUTE_READONLY)) st->st_mode |= S_IWRITE;
printf("nativelibc debug: fstat: fbi.FileAttributes = 0x%lx\n", fbi.FileAttributes);
if(st->st_ctime) printf("ctime = %lu\n", (unsigned long int)st->st_ctime);
}
long int status2 = NtQueryInformationFile((void *)fd, &io_status, &fsi, sizeof fsi, FileStandardInformation);
if(ntstatus_to_errno(status2)) {
if(status1 < 0) return -1;
st->st_blocks = 0;
st->st_size = 0;
st->st_rdev = 0;
st->st_gid = 0;
st->st_uid = 0;
st->st_nlink = 1;
} else {
if(status1 < 0) {
st->st_ctime = 0;
st->st_mtime = 0;
st->st_atime = 0;
}
st->st_blocks = fsi.AllocationSize.QuadPart / 512;
st->st_size = fsi.EndOfFile.QuadPart;
st->st_rdev = 0;
st->st_gid = 0;
st->st_uid = 0;
st->st_nlink = fsi.NumberOfLinks;
//printf("nativelibc debug: fsi.Directory = %hhu\n", fsi.Directory);
//if(fsi.Directory) st->st_mode |= S_IFDIR;
st->st_mode |= fsi.Directory ? S_IFDIR : S_IFREG;
}
//if(!(fbi.FileAttributes & FILE_ATTRIBUTE_READONLY)) st->st_mode |= S_IWRITE;
st->st_dev = 0;
long int status3 = NtQueryInformationFile((void *)fd, &io_status, &fii, sizeof fii, FileInternalInformation);
if(ntstatus_to_errno(status3)) st->st_ino = 0;
else st->st_ino = fii.IndexNumber.QuadPart;
return 0;
}
int stat(const char *path, struct stat *st) {
if(!path || !st) {
errno = EFAULT;
return -1;
}
if(!*path) {
errno = ENOENT;
return -1;
}
int fd = open(path, O_RDONLY);
if(fd == -1) {
if(errno != EISDIR) return -1;
fd = open(path, O_DIRECTORY);
//printf("nativelibc debug: stat: fd = %d\n", fd);
if(fd == -1) return -1;
}
int r = fstat(fd, st);
int e = errno;
close(fd);
errno = e;
return r;
}
int lstat(const char *path, struct stat *st) {
if(!path || !st) {
errno = EFAULT;
return -1;
}
if(!*path) {
errno = ENOENT;
return -1;
}
int fd = open(path, O_RDONLY | O_NOFOLLOW);
if(fd == -1) {
perror("nativelibc debug");
if(errno != EISDIR) return -1;
fd = open(path, O_DIRECTORY | O_NOFOLLOW);
//printf("nativelibc debug: stat: fd = %d\n", fd);
if(fd == -1) return -1;
}
int r = fstat(fd, st);
int e = errno;
close(fd);
errno = e;
return r;
}