blob: 5c215851fa98baff081cf3a5a7cd652f97a076b5 [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/time.h>
#include <windows.h>
#include <nt.h>
#include <errno.h>
#include <pathname.h>
int utimes(const char *filename, const struct timeval *times) {
if(!filename) {
errno = EFAULT;
return -1;
}
if(!*filename) {
errno = ENOENT;
return -1;
}
if(*filename != '/') {
errno = ENOSYS;
return -1;
}
FILE_BASIC_INFORMATION fbi;
memset(&fbi, 0, sizeof fbi);
if(times) {
__timeval_to_hurdred_nanoseconds_since_1601(times, &fbi.LastAccessTime);
__timeval_to_hurdred_nanoseconds_since_1601(times + 1, &fbi.LastWriteTime);
} else {
long int status = NtQuerySystemTime(&fbi.LastAccessTime);
if(status < 0) {
__set_errno_from_ntstatus(status);
return -1;
}
fbi.LastWriteTime = fbi.LastAccessTime;
}
void *handle;
IO_STATUS_BLOCK io_status;
unsigned long int file_access = GENERIC_WRITE | SYNCHRONIZE;
unsigned long int file_share = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
unsigned long int options = FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT;
UNICODE_STRING name1;
if(!RtlCreateUnicodeStringFromAsciiz(&name1, filename)) {
errno = ENOMEM;
return -1;
}
PATHNAME_UNIX2NT_UTF16_STRUCT(name1);
OBJECT_ATTRIBUTES object_attrib = { sizeof(OBJECT_ATTRIBUTES), NULL, &name1, 0, NULL, NULL };
long int status = NtOpenFile(&handle, file_access, &object_attrib, &io_status, file_share, options);
RtlFreeUnicodeString(&name1);
if(status < 0) {
__set_errno_from_ntstatus(status);
return -1;
}
status = NtSetInformationFile(handle, &io_status, &fbi, sizeof fbi, FileBasicInformation);
if(status < 0) {
__set_errno_from_ntstatus(status);
return -1;
}
return __set_errno_from_ntstatus(NtClose(handle)) ? -1 : 0;
}