blob: ccd4ff26ee620c1999fdf722b6584db157da55ee [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 <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;
}