|  | #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) { | 
|  | ntstatus_to_errno(status); | 
|  | return -1; | 
|  | } | 
|  | status = NtMakeTemporaryObject(handle); | 
|  | NtClose(handle); | 
|  | return ntstatus_to_errno(status) ? -1 : 0; | 
|  | } | 
|  | 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); | 
|  | ntstatus_to_errno(status); | 
|  | return -1; | 
|  | } | 
|  | NtClose(handle); | 
|  | status = NtDeleteFile(&o); | 
|  | RtlFreeUnicodeString(&name1); | 
|  | return ntstatus_to_errno(status) ? -1 : 0; | 
|  | //return status < 0 ? -1 : 0; | 
|  | } |