DWORD bufLen = FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
error,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL );
if (bufLen)
LPCSTR lpMsgStr = (LPCSTR)lpMsgBuf;
std::string result(lpMsgStr, lpMsgStr+bufLen);
std::ostringstream ostr;
ostr << error << " "
<< result;
LocalFree(lpMsgBuf);
return ostr.str();
return std::string();
inline bool isMsysPty(int fd) noexcept
#if defined(UNICODE) || defined(_UNICODE)
LPCSTR functionName = "GetFinalPathNameByHandleW";
#else
LPCSTR functionName = "GetFinalPathNameByHandleA";
#endif
const auto ptrGetFinalPathNameByHandle
= reinterpret_cast
(
GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")),
functionName));
if (!ptrGetFinalPathNameByHandle) {
return false;
using STDTString = std::basic_string;
HANDLE h = reinterpret_cast(_get_osfhandle(fd));
if (h == INVALID_HANDLE_VALUE) {
return false;
if (GetFileType(h) != FILE_TYPE_PIPE) {
return false;
TCHAR Path[MAX_PATH] = { _T('\0') };
const DWORD retSize = ptrGetFinalPathNameByHandle(h, Path, MAX_PATH, VOLUME_NAME_NONE | FILE_NAME_OPENED);
if (!retSize || retSize >= MAX_PATH) {
// DEBUG OUTPUT:
std::cout << "ERROR GetFinalPathNameByHandle: " << GetLastErrorStdStr() << std::endl;
// Next try to use GetFinalPathNameByHandleEx:
const size_t sizeNameInfo = sizeof(FILE_NAME_INFO) + sizeof(WCHAR) * MAX_PATH;
auto pNameInfo = std::unique_ptr(
static_cast(std::malloc(sizeNameInfo)), &std::free);
// But GetFileInformationByHandleEx returns no error
if(GetFileInformationByHandleEx(h, FileNameInfo, pNameInfo.get(), sizeNameInfo)) {
std::wstring name(pNameInfo->FileName, pNameInfo->FileNameLength / sizeof(WCHAR));
std::wcout << "GetFileInformationByHandleEx No errors, and path is: " << name << std::endl;
return false;
STDTString name(Path,retSize);
if ((name.find(STDTString(TEXT("msys-"))) == STDTString::npos
&& name.find(STDTString(TEXT("cygwin-"))) == STDTString::npos)
|| name.find(STDTString(TEXT("-pty"))) == STDTString::npos) {
return false;
// DEBUG OUTPUT:
#if defined(UNICODE) || defined(_UNICODE)
std::wcout << name << std::endl;
#else
std::cout << name << std::endl;
#endif
return true;
int main()
isMsysPty(0);
isMsysPty(1);
isMsysPty(2);
std::wcout << L"Hello, world!\n";
ERROR GetFinalPathNameByHandle: 161 The specified path is invalid.
GetFileInformationByHandleEx No errors, and path is: \
ERROR GetFinalPathNameByHandle: 161 The specified path is invalid.
GetFileInformationByHandleEx No errors, and path is: \
ERROR GetFinalPathNameByHandle: 161 The specified path is invalid.
GetFileInformationByHandleEx No errors, and path is: \
Hello, world!