blob: cd94cbb5907c097ed5d9fb061b982fe599d3769f [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 <windows.h>
#include <nt.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <pathname.h>
#include <ntstatus.h>
int unlink(const char *name) {
if(!name) {
errno = EFAULT;
return -1;
}
//int fd = open(name, O_RDONLY);
//if(fd == -1 || close(fd) == -1) return -1;
/*
int fd = open(name, O_DIRECTORY);
if(fd != -1 && close(fd) != -1) {
errno = EISDIR;
return -1;
}
*/
UNICODE_STRING name1;
RtlCreateUnicodeStringFromAsciiz(&name1, name);
PATHNAME_UNIX2NT_UTF16_STRUCT(name1);
OBJECT_ATTRIBUTES o = { sizeof(OBJECT_ATTRIBUTES), NULL, &name1, 0, NULL, NULL };
void *handle;
long int status = NtOpenSymbolicLinkObject(&handle, DELETE, &o);
//printf("nativelibc debug: unlink: status = 0x%lx\n", status);
if(status != STATUS_OBJECT_TYPE_MISMATCH) {
RtlFreeUnicodeString(&name1);
if(status < 0) {
__set_errno_from_ntstatus(status);
return -1;
}
status = NtMakeTemporaryObject(handle);
NtClose(handle);
return __set_errno_from_ntstatus(status) ? -1 : 0;
}
status = NtOpenDirectoryObject(&handle, 0, &o);
if(status != STATUS_OBJECT_TYPE_MISMATCH) {
RtlFreeUnicodeString(&name1);
if(status >= 0) NtClose(handle);
errno = EISDIR;
return -1;
}
IO_STATUS_BLOCK io_status;
unsigned long int file_share = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
unsigned long int options = FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT;
status = NtOpenFile(&handle, DELETE | SYNCHRONIZE, &o, &io_status, file_share, options);
if(status < 0/* && status != STATUS_INVALID_PARAMETER*/) {
RtlFreeUnicodeString(&name1);
__set_errno_from_ntstatus(status);
return -1;
}
NtClose(handle);
status = NtDeleteFile(&o);
RtlFreeUnicodeString(&name1);
return __set_errno_from_ntstatus(status) ? -1 : 0;
//return status < 0 ? -1 : 0;
}