/*****************************************************************************\ * * * Filename getcwd.c * * * * Description: WIN32 port of standard C library's getcwd() * * * * Notes: * * * * History: * * 2014-02-28 JFL Created this module. * * 2014-07-02 JFL Added support for pathnames >= 260 characters. * * * * Copyright 2016 Hewlett Packard Enterprise Development LP * * Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * \*****************************************************************************/ #define _UTF8_SOURCE /* Generate the UTF-8 version of routines */ /* Microsoft C libraries include files */ #include #include /* MsvcLibX library extensions */ #include "msvcUnistd.h" #include "msvcDebugm.h" #include "msvcLimits.h" #if defined(_MSDOS) /* DOS own getcwd() is OK. */ #endif /* defined(_MSDOS) */ #ifdef _WIN32 #include /*---------------------------------------------------------------------------*\ * * | Function: getcwd | | | | Description: Get the current directory, encoded in UTF-8 | | | | Parameters: char *buf Buffer for the output | | size_t bufSize Buffer size | | | | Returns: The converted string size. -1=error, and errno set. | | | | Notes: We can't use the getcwd name, as MSVC has an incompatible | | prototype for it. So a getcwd macro calls this routine. | | | | History: | | 2014-02-28 JFL Created this routine | | 2014-07-02 JFL Added support for pathnames >= 260 characters. | * * \*---------------------------------------------------------------------------*/ char *getcwdA(char *buf, size_t bufSize) { int n; WCHAR wbuf[PATH_MAX]; DWORD dwSize; dwSize = GetCurrentDirectoryW(COUNTOF(wbuf), wbuf); if (!dwSize) { errno = Win32ErrorToErrno(); DEBUG_PRINTF(("getcwd(0x%p, %d); // Error: GetCurrentDirectoryW() Failed\n", buf, bufSize)); return NULL; } n = WideCharToMultiByte(CP_ACP, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */ 0, /* dwFlags, */ wbuf, /* lpWideCharStr, */ dwSize+1, /* cchWideChar, */ buf, /* lpMultiByteStr, */ (int)bufSize, /* cbMultiByte, */ NULL, /* lpDefaultChar, */ NULL /* lpUsedDefaultChar */ ); if (!n) { errno = Win32ErrorToErrno(); DEBUG_PRINTF(("getcwd(0x%p, %d); // Error: WideCharToMultiByte() Failed\n", buf, bufSize)); return NULL; } DEBUG_PRINTF(("getcwd(0x%p, %d); // \"%s\"\n", buf, bufSize, buf)); return buf; } char *getcwdU(char *buf, size_t bufSize) { int n; WCHAR wbuf[PATH_MAX]; DWORD dwSize; dwSize = GetCurrentDirectoryW(COUNTOF(wbuf), wbuf); if (!dwSize) { errno = Win32ErrorToErrno(); DEBUG_PRINTF(("getcwd(0x%p, %d); // Error: GetCurrentDirectoryW() Failed\n", buf, bufSize)); return NULL; } n = WideCharToMultiByte(CP_UTF8, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */ 0, /* dwFlags, */ wbuf, /* lpWideCharStr, */ dwSize+1, /* cchWideChar, */ buf, /* lpMultiByteStr, */ (int)bufSize, /* cbMultiByte, */ NULL, /* lpDefaultChar, */ NULL /* lpUsedDefaultChar */ ); if (!n) { errno = Win32ErrorToErrno(); DEBUG_PRINTF(("getcwd(0x%p, %d); // Error: WideCharToMultiByte() Failed\n", buf, bufSize)); return NULL; } DEBUG_PRINTF(("getcwd(0x%p, %d); // \"%s\"\n", buf, bufSize, buf)); return buf; } char *_getdcwdA(int iDrive, char *buf, int iBuflen) { char *pBuf; int iDrive0 = _getdrive(); if (iDrive && (iDrive != iDrive0)) _chdrive(iDrive); pBuf = getcwdA(buf, iBuflen); if (iDrive && (iDrive != iDrive0)) _chdrive(iDrive0); DEBUG_CODE( if (pBuf) { DEBUG_PRINTF(("_getdcwd(%d, 0x%p, %d); // \"%s\"\n", iDrive, buf, iBuflen, pBuf)); } else { DEBUG_PRINTF(("_getdcwd(%d, 0x%p, %d); // Failed\n", iDrive, buf, iBuflen, pBuf)); } ) return pBuf; } char *_getdcwdU(int iDrive, char *buf, int iBuflen) { char *pBuf; int iDrive0 = _getdrive(); if (iDrive && (iDrive != iDrive0)) _chdrive(iDrive); pBuf = getcwdU(buf, iBuflen); if (iDrive && (iDrive != iDrive0)) _chdrive(iDrive0); DEBUG_CODE( if (pBuf) { DEBUG_PRINTF(("_getdcwd(%d, 0x%p, %d); // \"%s\"\n", iDrive, buf, iBuflen, pBuf)); } else { DEBUG_PRINTF(("_getdcwd(%d, 0x%p, %d); // Failed\n", iDrive, buf, iBuflen, pBuf)); } ) return pBuf; } #endif /* _WIN32 */