BOOL WINAPI OnReadConsoleA(HANDLE hConsoleInput, LPVOID lpBuffer, DWORD nNumberOfCharsToRead, LPDWORD lpNumberOfCharsRead, LPVOID pInputControl) { // typedef BOOL (WINAPI* OnReadConsoleA_t)(HANDLE hConsoleInput, LPVOID lpBuffer, DWORD nNumberOfCharsToRead, LPDWORD lpNumberOfCharsRead, LPVOID pInputControl); SUPPRESSORIGINALSHOWCALL; ORIGINAL_KRNL(ReadConsoleA); BOOL lbRc = FALSE; OnReadConsoleStart(false, hConsoleInput, lpBuffer, nNumberOfCharsToRead, lpNumberOfCharsRead, pInputControl); lbRc = F(ReadConsoleA)(hConsoleInput, lpBuffer, nNumberOfCharsToRead, lpNumberOfCharsRead, pInputControl); DWORD nErr = GetLastError(); // gh#465: For consistence with OnReadConsoleW if (lbRc && lpBuffer && lpNumberOfCharsRead && *lpNumberOfCharsRead // pInputControl has no evvect on ANSI version && (*lpNumberOfCharsRead <= 3)) { // To avoid checking of the mapping, we check result first const char* pchTest = (const char*)lpBuffer; if ((pchTest[0] == 26 /* Ctrl-Z / ^Z / (char)('Z' - '@') */) && (((*lpNumberOfCharsRead == 3) && (pchTest[1] == '\r') && (pchTest[2] == '\n')) // Expected variant || ((*lpNumberOfCharsRead == 2) && (pchTest[1] == '\n')) // Possible variant? )) { if (isProcessCtrlZ()) *lpNumberOfCharsRead = 0; } } OnReadConsoleEnd(lbRc, false, hConsoleInput, lpBuffer, nNumberOfCharsToRead, lpNumberOfCharsRead, pInputControl); SetLastError(nErr); return lbRc; }
BOOL WINAPI OnReadConsoleA(HANDLE hConsoleInput, LPVOID lpBuffer, DWORD nNumberOfCharsToRead, LPDWORD lpNumberOfCharsRead, LPVOID pInputControl) { // typedef BOOL (WINAPI* OnReadConsoleA_t)(HANDLE hConsoleInput, LPVOID lpBuffer, DWORD nNumberOfCharsToRead, LPDWORD lpNumberOfCharsRead, LPVOID pInputControl); SUPPRESSORIGINALSHOWCALL; ORIGINAL_KRNL(ReadConsoleA); BOOL lbRc = FALSE; OnReadConsoleStart(false, hConsoleInput, lpBuffer, nNumberOfCharsToRead, lpNumberOfCharsRead, pInputControl); lbRc = F(ReadConsoleA)(hConsoleInput, lpBuffer, nNumberOfCharsToRead, lpNumberOfCharsRead, pInputControl); DWORD nErr = GetLastError(); OnReadConsoleEnd(lbRc, false, hConsoleInput, lpBuffer, nNumberOfCharsToRead, lpNumberOfCharsRead, pInputControl); SetLastError(nErr); return lbRc; }
BOOL WINAPI OnReadConsoleW(HANDLE hConsoleInput, LPVOID lpBuffer, DWORD nNumberOfCharsToRead, LPDWORD lpNumberOfCharsRead, MY_CONSOLE_READCONSOLE_CONTROL* pInputControl) { //typedef BOOL (WINAPI* OnReadConsoleW_t)(HANDLE hConsoleInput, LPVOID lpBuffer, DWORD nNumberOfCharsToRead, LPDWORD lpNumberOfCharsRead, MY_CONSOLE_READCONSOLE_CONTROL* pInputControl); SUPPRESSORIGINALSHOWCALL; ORIGINAL_KRNL(ReadConsoleW); BOOL lbRc = FALSE; DWORD nErr = GetLastError(); DWORD nStartTick = GetTickCount(), nEndTick = 0; OnReadConsoleStart(true, hConsoleInput, lpBuffer, nNumberOfCharsToRead, lpNumberOfCharsRead, pInputControl); lbRc = F(ReadConsoleW)(hConsoleInput, lpBuffer, nNumberOfCharsToRead, lpNumberOfCharsRead, pInputControl); nErr = GetLastError(); // Debug purposes nEndTick = GetTickCount(); // gh#465: Terminate Go input with Ctrl-Z if (lbRc && lpBuffer && lpNumberOfCharsRead && *lpNumberOfCharsRead && (!pInputControl) // Probably, if application pass this structure it really knows what it's doing && (*lpNumberOfCharsRead <= 3)) { // To avoid checking of the mapping, we check result first const wchar_t* pchTest = (const wchar_t*)lpBuffer; if ((pchTest[0] == 26 /* Ctrl-Z / ^Z / (char)('Z' - '@') */) && (((*lpNumberOfCharsRead == 3) && (pchTest[1] == '\r') && (pchTest[2] == '\n')) // Expected variant || ((*lpNumberOfCharsRead == 2) && (pchTest[1] == '\n')) // Possible variant? )) { if (isProcessCtrlZ()) *lpNumberOfCharsRead = 0; } } OnReadConsoleEnd(lbRc, true, hConsoleInput, lpBuffer, nNumberOfCharsToRead, lpNumberOfCharsRead, pInputControl); // cd \\server\share\dir\... if (gbAllowUncPaths && lpBuffer && lpNumberOfCharsRead && *lpNumberOfCharsRead && (nNumberOfCharsToRead >= *lpNumberOfCharsRead) && (nNumberOfCharsToRead > 6)) { wchar_t* pszCmd = (wchar_t*)lpBuffer; // "cd " ? if ((pszCmd[0]==L'c' || pszCmd[0]==L'C') && (pszCmd[1]==L'd' || pszCmd[1]==L'D') && pszCmd[2] == L' ') { pszCmd[*lpNumberOfCharsRead] = 0; wchar_t* pszPath = (wchar_t*)SkipNonPrintable(pszCmd+3); // Don't worry about local paths, check only network if (pszPath[0] == L'\\' && pszPath[1] == L'\\') { wchar_t* pszEnd; if (*pszPath == L'"') pszEnd = wcschr(++pszPath, L'"'); else pszEnd = wcspbrk(pszPath, L"\r\n\t&| "); if (!pszEnd) pszEnd = pszPath + lstrlen(pszPath); if ((pszEnd - pszPath) < MAX_PATH) { wchar_t ch = *pszEnd; *pszEnd = 0; BOOL bSet = SetCurrentDirectory(pszPath); if (ch) *pszEnd = ch; if (bSet) { if (*pszEnd == L'"') pszEnd++; pszEnd = (wchar_t*)SkipNonPrintable(pszEnd); if (*pszEnd && wcschr(L"&|", *pszEnd)) { while (*pszEnd && wcschr(L"&|", *pszEnd)) pszEnd++; pszEnd = (wchar_t*)SkipNonPrintable(pszEnd); } // Return anything... if (*pszEnd) { int nLeft = lstrlen(pszEnd); memmove(lpBuffer, pszEnd, (nLeft+1)*sizeof(*pszEnd)); } else { lstrcpyn((wchar_t*)lpBuffer, L"cd\r\n", nNumberOfCharsToRead); } *lpNumberOfCharsRead = lstrlen((wchar_t*)lpBuffer); } } } } } SetLastError(nErr); UNREFERENCED_PARAMETER(nStartTick); UNREFERENCED_PARAMETER(nEndTick); return lbRc; }
BOOL WINAPI OnReadConsoleW(HANDLE hConsoleInput, LPVOID lpBuffer, DWORD nNumberOfCharsToRead, LPDWORD lpNumberOfCharsRead, MY_CONSOLE_READCONSOLE_CONTROL* pInputControl) { //typedef BOOL (WINAPI* OnReadConsoleW_t)(HANDLE hConsoleInput, LPVOID lpBuffer, DWORD nNumberOfCharsToRead, LPDWORD lpNumberOfCharsRead, MY_CONSOLE_READCONSOLE_CONTROL* pInputControl); SUPPRESSORIGINALSHOWCALL; ORIGINAL_KRNL(ReadConsoleW); BOOL lbRc = FALSE; DWORD nErr = GetLastError(); DWORD nStartTick = GetTickCount(), nEndTick = 0; OnReadConsoleStart(true, hConsoleInput, lpBuffer, nNumberOfCharsToRead, lpNumberOfCharsRead, pInputControl); lbRc = F(ReadConsoleW)(hConsoleInput, lpBuffer, nNumberOfCharsToRead, lpNumberOfCharsRead, pInputControl); nErr = GetLastError(); // Debug purposes nEndTick = GetTickCount(); OnReadConsoleEnd(lbRc, true, hConsoleInput, lpBuffer, nNumberOfCharsToRead, lpNumberOfCharsRead, pInputControl); // cd \\server\share\dir\... if (gbAllowUncPaths && lpBuffer && lpNumberOfCharsRead && *lpNumberOfCharsRead && (nNumberOfCharsToRead >= *lpNumberOfCharsRead) && (nNumberOfCharsToRead > 6)) { wchar_t* pszCmd = (wchar_t*)lpBuffer; // "cd " ? if ((pszCmd[0]==L'c' || pszCmd[0]==L'C') && (pszCmd[1]==L'd' || pszCmd[1]==L'D') && pszCmd[2] == L' ') { pszCmd[*lpNumberOfCharsRead] = 0; wchar_t* pszPath = (wchar_t*)SkipNonPrintable(pszCmd+3); // Don't worry about local paths, check only network if (pszPath[0] == L'\\' && pszPath[1] == L'\\') { wchar_t* pszEnd; if (*pszPath == L'"') pszEnd = wcschr(++pszPath, L'"'); else pszEnd = wcspbrk(pszPath, L"\r\n\t&| "); if (!pszEnd) pszEnd = pszPath + lstrlen(pszPath); if ((pszEnd - pszPath) < MAX_PATH) { wchar_t ch = *pszEnd; *pszEnd = 0; BOOL bSet = SetCurrentDirectory(pszPath); if (ch) *pszEnd = ch; if (bSet) { if (*pszEnd == L'"') pszEnd++; pszEnd = (wchar_t*)SkipNonPrintable(pszEnd); if (*pszEnd && wcschr(L"&|", *pszEnd)) { while (*pszEnd && wcschr(L"&|", *pszEnd)) pszEnd++; pszEnd = (wchar_t*)SkipNonPrintable(pszEnd); } // Return anything... if (*pszEnd) { int nLeft = lstrlen(pszEnd); memmove(lpBuffer, pszEnd, (nLeft+1)*sizeof(*pszEnd)); } else { lstrcpyn((wchar_t*)lpBuffer, L"cd\r\n", nNumberOfCharsToRead); } *lpNumberOfCharsRead = lstrlen((wchar_t*)lpBuffer); } } } } } SetLastError(nErr); UNREFERENCED_PARAMETER(nStartTick); UNREFERENCED_PARAMETER(nEndTick); return lbRc; }
BOOL WINAPI OnReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped) { //typedef BOOL (WINAPI* OnReadFile_t)(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped); SUPPRESSORIGINALSHOWCALL; ORIGINAL_KRNL(ReadFile); BOOL lbRc = FALSE; bool bConIn = false; DWORD nPrevErr = GetLastError(); if (hFile == ghLastConInHandle) { bConIn = true; } else if (hFile != ghLastNotConInHandle) { DWORD nMode = 0; BOOL lbConRc = GetConsoleMode(hFile, &nMode); if (lbConRc && ((nMode & (ENABLE_LINE_INPUT & ENABLE_ECHO_INPUT)) == (ENABLE_LINE_INPUT & ENABLE_ECHO_INPUT))) { bConIn = true; ghLastConInHandle = hFile; } else { ghLastNotConInHandle = hFile; } } if (bConIn) OnReadConsoleStart(false, hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, NULL); SetLastError(nPrevErr); lbRc = F(ReadFile)(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped); DWORD nErr = GetLastError(); if (bConIn) { OnReadConsoleEnd(lbRc, false, hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, NULL); #ifdef _DEBUG // Only for input_bug search purposes in Debug builds const char* pszChr = (const char*)lpBuffer; int cchRead = *lpNumberOfBytesRead; wchar_t* pszDbgCurChars = NULL; while ((cchRead--) > 0) { LONG idx = (InterlockedIncrement(&gn_LogReadChars) & (gn_LogReadCharsMax-1))*2; if (!pszDbgCurChars) pszDbgCurChars = gs_LogReadChars+idx; gs_LogReadChars[idx++] = L'|'; gs_LogReadChars[idx++] = *pszChr ? *pszChr : L'.'; gs_LogReadChars[idx] = 0; pszChr++; } #endif SetLastError(nErr); } return lbRc; }