| /* 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 <limits.h> |
| #include <errno.h> |
| #include <pathname.h> |
| |
| #define UTF16_STRUCT_DUMP(D,S) \ |
| do { \ |
| (D).Length = (S).Length; \ |
| (D).MaximumLength = (S).MaximumLength; \ |
| (D).Buffer = (wchar_t *)malloc((D).MaximumLength); \ |
| if(!(D).Buffer) { \ |
| /* errno = ENOMEM; */ \ |
| return NULL; \ |
| } \ |
| memcpy((D).Buffer, (S).Buffer, (D).MaximumLength); \ |
| } while(0) |
| |
| char *getcwd(char *buf, unsigned int size) { |
| PROCESS_BASIC_INFORMATION pbi; |
| NtQueryInformationProcess((void *)-1, ProcessBasicInformation, &pbi, sizeof(pbi), NULL); |
| CURDIR *dir = &(pbi.PebBaseAddress->ProcessParameters->CurrentDirectory); |
| //printf("nativelibc debug: dir->Handle = %p\n", dir->Handle); |
| UNICODE_STRING path; |
| if(dir->DosPath.Buffer[0] == L'/') { |
| /* |
| path.Length = dir->DosPath.Length; |
| path.MaximumLength = dir->DosPath.MaximumLength; |
| path.Buffer = (wchar_t *)malloc(path.MaximumLength); |
| if(!path.Buffer) { |
| //errno = ENOMEM; |
| return NULL; |
| } |
| memcpy(path.Buffer, dir->DosPath.Buffer, path.MaximumLength); |
| */ |
| UTF16_STRUCT_DUMP(path, dir->DosPath); |
| } else { |
| size_t size = sizeof(OBJECT_NAME_INFORMATION) + 512; |
| OBJECT_NAME_INFORMATION *name_info = (OBJECT_NAME_INFORMATION *)malloc(size); |
| long int status = NtQueryObject(dir->Handle, ObjectNameInformation, name_info, size, NULL); |
| if(__set_errno_from_ntstatus(status)) return NULL; |
| //if(status < 0) return NULL; |
| /* |
| path.Length = name_info->Name.Length; |
| path.MaximumLength = name_info->Name.MaximumLength; |
| path.Buffer = (wchar_t *)malloc(path.MaximumLength); |
| if(!path.Buffer) { |
| return NULL; |
| } |
| memcpy(path.Buffer, name_info->Name.Buffer, path.MaximumLength); |
| */ |
| UTF16_STRUCT_DUMP(path, name_info->Name); |
| free(name_info); |
| } |
| size_t len = path.Length * 2; |
| PATHNAME_NT2UNIX_UTF16_STRUCT(path); |
| if(!size) { |
| if(buf) { |
| errno = EINVAL; |
| goto failed; |
| } |
| size = PATH_MAX * 2; |
| buf = (char *)malloc(size * sizeof(char)); |
| } else if(size < len) { |
| errno = ERANGE; |
| goto failed; |
| } |
| wcstombs(buf, path.Buffer, len); |
| RtlFreeUnicodeString(&path); |
| //if(len) while(--len) if(buf[len] == '\\') buf[len] = '/'; |
| return buf; |
| |
| failed: |
| RtlFreeUnicodeString(&path); |
| return NULL; |
| } |