void reopen_console (void) { HWND hwnd; if (realconsole) return; if (consoleopen >= 0) return; hwnd = myGetConsoleWindow (); if (hwnd) { int newpos = 1; int x, y, w, h; if (!regqueryint (NULL, _T("LoggerPosX"), &x)) newpos = 0; if (!regqueryint (NULL, _T("LoggerPosY"), &y)) newpos = 0; if (!regqueryint (NULL, _T("LoggerPosW"), &w)) newpos = 0; if (!regqueryint (NULL, _T("LoggerPosH"), &h)) newpos = 0; if (newpos) { RECT rc; rc.left = x; rc.top = y; rc.right = x + w; rc.bottom = y + h; if (MonitorFromRect (&rc, MONITOR_DEFAULTTONULL) != NULL) { SetForegroundWindow (hwnd); SetWindowPos (hwnd, HWND_TOP, x, y, w, h, SWP_NOACTIVATE); } } } }
int GuiMessageBox(HWND hConEmuWndRoot, LPCWSTR asText, LPCWSTR asTitle, int anBtns) { int nResult = 0; if (hConEmuWndRoot) { HWND hConWnd = myGetConsoleWindow(); CESERVER_REQ *pIn = (CESERVER_REQ*)malloc(sizeof(*pIn)); ExecutePrepareCmd(pIn, CECMD_ASSERT, sizeof(CESERVER_REQ_HDR)+sizeof(MyAssertInfo)); pIn->AssertInfo.nBtns = anBtns; _wcscpyn_c(pIn->AssertInfo.szTitle, countof(pIn->AssertInfo.szTitle), asTitle, countof(pIn->AssertInfo.szTitle)); //-V501 _wcscpyn_c(pIn->AssertInfo.szDebugInfo, countof(pIn->AssertInfo.szDebugInfo), asText, countof(pIn->AssertInfo.szDebugInfo)); //-V501 wchar_t szGuiPipeName[128]; msprintf(szGuiPipeName, countof(szGuiPipeName), CEGUIPIPENAME, L".", (DWORD)hConEmuWndRoot); //-V205 CESERVER_REQ* pOut = ExecuteCmd(szGuiPipeName, pIn, 1000, hConWnd); free(pIn); if (pOut) { if (pOut->hdr.cbSize > sizeof(CESERVER_REQ_HDR)) { nResult = pOut->dwData[0]; } ExecuteFreeResult(pOut); } } else { //_ASSERTE(hConEmuWndRoot!=NULL); // Избежать статической линковки к user32 HMODULE hUser32 = GetModuleHandle(L"User32.dll"); if (hUser32 == NULL) hUser32 = LoadLibrary(L"User32.dll"); typedef int (WINAPI* MessageBoxW_T)(HWND, LPCWSTR, LPCWSTR, UINT); MessageBoxW_T _MessageBoxW = hUser32 ? (MessageBoxW_T)GetProcAddress(hUser32, "MessageBoxW") : NULL; if (_MessageBoxW) { nResult = _MessageBoxW(NULL, asText, asTitle, MB_SYSTEMMODAL|anBtns); } else { #ifdef _DEBUG _CrtDbgBreak(); #endif } } return nResult; }
void close_console (void) { if (realconsole) return; if (consoleopen > 0) { close_debug_window (); } else if (consoleopen < 0) { HWND hwnd = myGetConsoleWindow (); if (hwnd && !IsIconic (hwnd)) { RECT r; if (GetWindowRect (hwnd, &r)) { r.bottom -= r.top; r.right -= r.left; regsetint (NULL, _T("LoggerPosX"), r.left); regsetint (NULL, _T("LoggerPosY"), r.top); regsetint (NULL, _T("LoggerPosW"), r.right); regsetint (NULL, _T("LoggerPosH"), r.bottom); } } FreeConsole (); } consoleopen = 0; }
BOOL FindConEmuBaseDir(wchar_t (&rsConEmuBaseDir)[MAX_PATH+1], wchar_t (&rsConEmuExe)[MAX_PATH+1], HMODULE hPluginDll /*= NULL*/) { // Сначала пробуем Mapping консоли (вдруг есть?) { MFileMapping<CESERVER_CONSOLE_MAPPING_HDR> ConMap; ConMap.InitName(CECONMAPNAME, (DWORD)myGetConsoleWindow()); //-V205 CESERVER_CONSOLE_MAPPING_HDR* p = ConMap.Open(); if (p && p->ComSpec.ConEmuBaseDir[0]) { // Успешно wcscpy_c(rsConEmuBaseDir, p->ComSpec.ConEmuBaseDir); wcscpy_c(rsConEmuExe, p->sConEmuExe); return TRUE; } } // Теперь - пробуем найти существующее окно ConEmu HWND hConEmu = FindWindow(VirtualConsoleClassMain, NULL); DWORD dwGuiPID = 0; if (hConEmu) { if (GetWindowThreadProcessId(hConEmu, &dwGuiPID) && dwGuiPID) { MFileMapping<ConEmuGuiMapping> GuiMap; GuiMap.InitName(CEGUIINFOMAPNAME, dwGuiPID); ConEmuGuiMapping* p = GuiMap.Open(); if (p && p->ComSpec.ConEmuBaseDir[0]) { wcscpy_c(rsConEmuBaseDir, p->ComSpec.ConEmuBaseDir); wcscpy_c(rsConEmuExe, p->sConEmuExe); return TRUE; } } } wchar_t szExePath[MAX_PATH+1]; HKEY hkRoot[] = {NULL,HKEY_CURRENT_USER,HKEY_LOCAL_MACHINE,HKEY_LOCAL_MACHINE}; DWORD samDesired = KEY_QUERY_VALUE; BOOL isWin64 = WIN3264TEST(IsWindows64(),TRUE); DWORD RedirectionFlag = WIN3264TEST((isWin64 ? KEY_WOW64_64KEY : 0),KEY_WOW64_32KEY); //#ifdef _WIN64 // isWin64 = TRUE; // RedirectionFlag = KEY_WOW64_32KEY; //#else // isWin64 = IsWindows64(); // RedirectionFlag = isWin64 ? KEY_WOW64_64KEY : 0; //#endif for (size_t i = 0; i < countof(hkRoot); i++) { szExePath[0] = 0; if (i == 0) { // Запущенного ConEmu.exe нет, можно поискать в каталоге текущего приложения if (!GetModuleFileName(NULL, szExePath, countof(szExePath)-20)) continue; wchar_t* pszName = wcsrchr(szExePath, L'\\'); if (!pszName) continue; *(pszName+1) = 0; // Проверяем наличие файлов // LPCWSTR szGuiExe[2] = {L"ConEmu64.exe", L"ConEmu.exe"}; if (!IsConEmuExeExist(szExePath, rsConEmuExe) && hPluginDll) { // Попробовать найти наш exe-шник от пути плагина? if (!GetModuleFileName(hPluginDll, szExePath, countof(szExePath)-1)) continue; wchar_t* pszName = wcsrchr(szExePath, L'\\'); if (!pszName) continue; *(pszName+1) = 0; int nLen = lstrlen(szExePath); LPCWSTR pszCompare = L"\\Plugins\\ConEmu\\"; if (nLen <= lstrlen(pszCompare)) continue; nLen = lstrlen(pszCompare); int iCmp = lstrcmpi(pszName-nLen+1, pszCompare); if (iCmp != 0) continue; *(pszName-nLen+2) = 0; } } else { // Остался последний шанс - если ConEmu установлен через MSI, то путь указан в реестре // [HKEY_LOCAL_MACHINE\SOFTWARE\ConEmu] // "InstallDir"="C:\\Utils\\Far180\\" if (i == (countof(hkRoot)-1)) { if (RedirectionFlag) samDesired |= RedirectionFlag; else break; } HKEY hKey; if (RegOpenKeyEx(hkRoot[i], L"Software\\ConEmu", 0, samDesired, &hKey) != ERROR_SUCCESS) continue; memset(szExePath, 0, countof(szExePath)); DWORD nType = 0, nSize = sizeof(szExePath)-20*sizeof(wchar_t); int RegResult = RegQueryValueEx(hKey, L"", NULL, &nType, (LPBYTE)szExePath, &nSize); RegCloseKey(hKey); if (RegResult != ERROR_SUCCESS) continue; } if (szExePath[0]) { // Хоть и задано в реестре - файлов может не быть. Проверяем if (szExePath[lstrlen(szExePath)-1] != L'\\') wcscat_c(szExePath, L"\\"); // Проверяем наличие файлов // LPCWSTR szGuiExe[2] = {L"ConEmu64.exe", L"ConEmu.exe"}; BOOL lbExeFound = IsConEmuExeExist(szExePath, rsConEmuExe); // Если GUI-exe найден - ищем "base" if (lbExeFound) { wchar_t* pszName = szExePath+lstrlen(szExePath); LPCWSTR szSrvExe[4] = {L"ConEmuC64.exe", L"ConEmu\\ConEmuC64.exe", L"ConEmuC.exe", L"ConEmu\\ConEmuC.exe"}; for (size_t s = 0; s < countof(szSrvExe); s++) { if ((s <=1) && !isWin64) continue; wcscpy_add(pszName, szExePath, szSrvExe[s]); if (FileExists(szExePath)) { pszName = wcsrchr(szExePath, L'\\'); if (pszName) { *pszName = 0; // БЕЗ слеша на конце! wcscpy_c(rsConEmuBaseDir, szExePath); return TRUE; } } } } } } // Не удалось return FALSE; }
//Arguments: // hConWnd - Хэндл КОНСОЛЬНОГО окна (по нему формируется имя пайпа для GUI) // pIn - выполняемая команда // nTimeout- таймаут подключения //Returns: // CESERVER_REQ. Его необходимо освободить через free(...); //WARNING!!! // Эта процедура не может получить с сервера более 600 байт данных! // В заголовке hOwner в дебаге может быть отображена ошибка CESERVER_REQ* ExecuteCmd(const wchar_t* szPipeName, CESERVER_REQ* pIn, DWORD nWaitPipe, HWND hOwner, BOOL bAsyncNoResult, DWORD nServerPID) { CESERVER_REQ* pOut = NULL; HANDLE hPipe = NULL; BYTE cbReadBuf[600]; // чтобы CESERVER_REQ_OUTPUTFILE поместился wchar_t szErr[MAX_PATH*2]; szErr[0] = 0; BOOL fSuccess = FALSE; DWORD cbRead = 0, /*dwMode = 0,*/ dwErr = 0; if (!pIn || !szPipeName) { _ASSERTE(pIn && szPipeName); return NULL; } pIn->hdr.bAsync = bAsyncNoResult; _ASSERTE(pIn->hdr.nSrcPID && pIn->hdr.nSrcThreadId); _ASSERTE(pIn->hdr.cbSize >= sizeof(pIn->hdr)); hPipe = ExecuteOpenPipe(szPipeName, szErr, NULL/*Сюда хорошо бы имя модуля подкрутить*/, nServerPID, nWaitPipe); if (hPipe == NULL || hPipe == INVALID_HANDLE_VALUE) { #ifdef _DEBUG dwErr = GetLastError(); // в заголовке "чисто" запущенного фара появляются отладочные(?) сообщения // по идее - не должны, т.к. все должно быть через мэппинг _ASSERTEX(hPipe != NULL && hPipe != INVALID_HANDLE_VALUE); #ifdef CONEMU_MINIMAL SetConsoleTitle(szErr); #else if (hOwner) { if (hOwner == myGetConsoleWindow()) SetConsoleTitle(szErr); else SetWindowText(hOwner, szErr); } #endif #endif return NULL; } //// Try to open a named pipe; wait for it, if necessary. //while (1) //{ // hPipe = CreateFile( // szPipeName, // pipe name // GENERIC_READ | // read and write access // GENERIC_WRITE, // 0, // no sharing // NULL, // default security attributes // OPEN_EXISTING, // opens existing pipe // 0, // default attributes // NULL); // no template file // // // Break if the pipe handle is valid. // if (hPipe != INVALID_HANDLE_VALUE) // break; // // // Exit if an error other than ERROR_PIPE_BUSY occurs. // dwErr = GetLastError(); // if (dwErr != ERROR_PIPE_BUSY) // { // return NULL; // } // // // All pipe instances are busy, so wait for 1 second. // if (!WaitNamedPipe(szPipeName, nWaitPipe) ) // { // return NULL; // } //} // //// The pipe connected; change to message-read mode. //dwMode = PIPE_READMODE_MESSAGE; //fSuccess = SetNamedPipeHandleState( // hPipe, // pipe handle // &dwMode, // new pipe mode // NULL, // don't set maximum bytes // NULL); // don't set maximum time //if (!fSuccess) //{ // CloseHandle(hPipe); // return NULL; //} _ASSERTE(pIn->hdr.nSrcThreadId==GetCurrentThreadId()); if (bAsyncNoResult) { // Если нас не интересует возврат и нужно сразу вернуться fSuccess = WriteFile(hPipe, pIn, pIn->hdr.cbSize, &cbRead, NULL); #ifdef _DEBUG dwErr = GetLastError(); _ASSERTE(fSuccess && (cbRead == pIn->hdr.cbSize)); #endif return NULL; } else { WARNING("При Overlapped часто виснет в этом месте."); // Send a message to the pipe server and read the response. fSuccess = TransactNamedPipe( hPipe, // pipe handle (LPVOID)pIn, // message to server pIn->hdr.cbSize, // message length cbReadBuf, // buffer to receive reply sizeof(cbReadBuf), // size of read buffer &cbRead, // bytes read NULL); // not overlapped dwErr = GetLastError(); //CloseHandle(hPipe); if (!fSuccess && (dwErr != ERROR_MORE_DATA)) { //_ASSERTE(fSuccess || (dwErr == ERROR_MORE_DATA)); CloseHandle(hPipe); return NULL; } } if (cbRead < sizeof(CESERVER_REQ_HDR)) { CloseHandle(hPipe); return NULL; } pOut = (CESERVER_REQ*)cbReadBuf; // temporary if (pOut->hdr.cbSize < cbRead) { CloseHandle(hPipe); if (pOut->hdr.cbSize) { _ASSERTE(pOut->hdr.cbSize == 0 || pOut->hdr.cbSize >= cbRead); DEBUGSTR(L"!!! Wrong nSize received from GUI server !!!\n"); } return NULL; } if (pOut->hdr.nVersion != CESERVER_REQ_VER) { CloseHandle(hPipe); DEBUGSTR(L"!!! Wrong nVersion received from GUI server !!!\n"); return NULL; } int nAllSize = pOut->hdr.cbSize; pOut = (CESERVER_REQ*)malloc(nAllSize); _ASSERTE(pOut); if (!pOut) { CloseHandle(hPipe); return NULL; } memmove(pOut, cbReadBuf, cbRead); LPBYTE ptrData = ((LPBYTE)pOut)+cbRead; nAllSize -= cbRead; while (nAllSize>0) { // Break if TransactNamedPipe or ReadFile is successful if (fSuccess) break; // Read from the pipe if there is more data in the message. fSuccess = ReadFile( hPipe, // pipe handle ptrData, // buffer to receive reply nAllSize, // size of buffer &cbRead, // number of bytes read NULL); // not overlapped // Exit if an error other than ERROR_MORE_DATA occurs. if (!fSuccess && (GetLastError() != ERROR_MORE_DATA)) break; ptrData += cbRead; nAllSize -= cbRead; } CloseHandle(hPipe); if (pOut && (pOut->hdr.nCmd != pIn->hdr.nCmd)) { _ASSERTE(pOut->hdr.nCmd == pIn->hdr.nCmd); if (pOut->hdr.nCmd == 0) { ExecuteFreeResult(pOut); pOut = NULL; } } return pOut; }
// Returns HWND of ... // aiType==0: Gui console DC window // ==1: Gui Main window // ==2: Console window HWND GetConEmuHWND(int aiType) { //CESERVER_REQ *pIn = NULL; //CESERVER_REQ *pOut = NULL; DWORD nLastErr = GetLastError(); HWND FarHwnd = NULL, ConEmuHwnd = NULL, ConEmuRoot = NULL; size_t cchMax = 128; wchar_t *szGuiPipeName = NULL; FarHwnd = myGetConsoleWindow(); if (!FarHwnd || (aiType == 2)) { goto wrap; //SetLastError(nLastErr); //return NULL; } szGuiPipeName = (wchar_t*)malloc(cchMax*sizeof(*szGuiPipeName)); if (!szGuiPipeName) { _ASSERTE(szGuiPipeName!=NULL); return NULL; } // Сначала пробуем Mapping консоли (вдруг есть?) if (!ConEmuRoot) { // создание этого объекта не позволяет отказаться от CRT (создается __chkstk) //MFileMapping<CESERVER_CONSOLE_MAPPING_HDR> ConMap; //ConMap.InitName(CECONMAPNAME, (DWORD)FarHwnd); //CESERVER_CONSOLE_MAPPING_HDR* p = ConMap.Open(); CESERVER_CONSOLE_MAPPING_HDR* p = NULL; msprintf(szGuiPipeName, cchMax, CECONMAPNAME, (DWORD)FarHwnd); //-V205 #ifdef _DEBUG size_t nSize = sizeof(*p); #endif HANDLE hMapping = OpenFileMapping(FILE_MAP_READ, FALSE, szGuiPipeName); if (hMapping) { DWORD nFlags = FILE_MAP_READ; p = (CESERVER_CONSOLE_MAPPING_HDR*)MapViewOfFile(hMapping, nFlags,0,0,0); } if (p && p->hConEmuRoot && isWindow(p->hConEmuRoot)) { // Успешно ConEmuRoot = p->hConEmuRoot; ConEmuHwnd = p->hConEmuWnd; } if (p) UnmapViewOfFile(p); if (hMapping) CloseHandle(hMapping); } #if 0 // Сервер не мог подцепиться БЕЗ создания мэппинга, поэтому CECMD_GETGUIHWND можно не делать if (!ConEmuRoot) { //BOOL lbRc = FALSE; pIn = (CESERVER_REQ*)calloc(1,sizeof(CESERVER_REQ)); ExecutePrepareCmd(pIn, CECMD_GETGUIHWND, sizeof(CESERVER_REQ_HDR)); //_wsprintf(szGuiPipeName, SKIPLEN(countof(szGuiPipeName)) CEGUIPIPENAME, L".", (DWORD)FarHwnd); msprintf(szGuiPipeName, cchMax, CEGUIPIPENAME, L".", (DWORD)FarHwnd); // Таймаут уменьшим, т.к. на результат не надеемся pOut = ExecuteCmd(szGuiPipeName, pIn, 250, FarHwnd); if (!pOut) { goto wrap; } if (pOut->hdr.cbSize != (sizeof(CESERVER_REQ_HDR)+2*sizeof(DWORD)) || pOut->hdr.nCmd != pIn->hdr.nCmd) { ExecuteFreeResult(pOut); pOut = NULL; goto wrap; } ConEmuRoot = (HWND)pOut->dwData[0]; ConEmuHwnd = (HWND)pOut->dwData[1]; // Сервер не мог подцепиться БЕЗ создания мэппинга, поэтому CECMD_GETGUIHWND не должен был пройти успешно _ASSERTE(ConEmuRoot == NULL); ExecuteFreeResult(pOut); pOut = NULL; } #endif wrap: SetLastError(nLastErr); //if (pIn) // free(pIn); if (szGuiPipeName) free(szGuiPipeName); if (aiType == 2) return FarHwnd; else if (aiType == 0) return ConEmuHwnd; else // aiType == 1 return ConEmuRoot; }
//Arguments: // hConWnd - Хэндл КОНСОЛЬНОГО окна (по нему формируется имя пайпа для GUI) // pIn - выполняемая команда // nTimeout- таймаут подключения //Returns: // CESERVER_REQ. Его необходимо освободить через free(...); //WARNING!!! // Эта процедура не может получить с сервера более 600 байт данных! // В заголовке hOwner в дебаге может быть отображена ошибка CESERVER_REQ* ExecuteCmd(const wchar_t* szPipeName, CESERVER_REQ* pIn, DWORD nWaitPipe, HWND hOwner, BOOL bAsyncNoResult, DWORD nServerPID, BOOL bIgnoreAbsence /*= FALSE*/) { CESERVER_REQ* pOut = NULL; HANDLE hPipe = NULL; BYTE cbReadBuf[600]; // чтобы CESERVER_REQ_OUTPUTFILE поместился wchar_t szErr[MAX_PATH*2]; szErr[0] = 0; BOOL fSuccess = FALSE; DWORD cbRead = 0, /*dwMode = 0,*/ dwErr = 0; int nAllSize; LPBYTE ptrData; #ifdef _DEBUG bool bIsAltSrvCmd; wchar_t szDbgPrefix[64], szDbgResult[64], *pszDbgMsg = NULL; #endif if (!pIn || !szPipeName) { _ASSERTE(pIn && szPipeName); pOut = NULL; goto wrap; } #ifdef _DEBUG _wsprintf(szDbgPrefix, SKIPLEN(countof(szDbgPrefix)) L">> ExecCmd: PID=%5u TID=%5u Cmd=%3u ", GetCurrentProcessId(), GetCurrentThreadId(), pIn->hdr.nCmd); pszDbgMsg = lstrmerge(szDbgPrefix, szPipeName, L"\n"); if (pszDbgMsg) { DEBUGSTRCMD(pszDbgMsg); free(pszDbgMsg); } #endif pIn->hdr.bAsync = bAsyncNoResult; _ASSERTE(pIn->hdr.nSrcPID && pIn->hdr.nSrcThreadId); _ASSERTE(pIn->hdr.cbSize >= sizeof(pIn->hdr)); hPipe = ExecuteOpenPipe(szPipeName, szErr, NULL/*Сюда хорошо бы имя модуля подкрутить*/, nServerPID, nWaitPipe, FALSE, NULL, bIgnoreAbsence); if (hPipe == NULL || hPipe == INVALID_HANDLE_VALUE) { #ifdef _DEBUG dwErr = GetLastError(); // в заголовке "чисто" запущенного фара появляются отладочные(?) сообщения // по идее - не должны, т.к. все должно быть через мэппинг // *** _ASSERTEX(hPipe != NULL && hPipe != INVALID_HANDLE_VALUE); - no need in assert, it was already shown #ifdef CONEMU_MINIMAL SetConsoleTitle(szErr); #else if (hOwner) { if (hOwner == myGetConsoleWindow()) SetConsoleTitle(szErr); else SetWindowText(hOwner, szErr); } #endif #endif pOut = NULL; goto wrap; } #ifdef _DEBUG bIsAltSrvCmd = (pIn->hdr.nCmd==CECMD_ALTBUFFER || pIn->hdr.nCmd==CECMD_ALTBUFFERSTATE || pIn->hdr.nCmd==CECMD_SETCONSCRBUF || pIn->hdr.nCmd == CECMD_LOCKSTATION || pIn->hdr.nCmd == CECMD_UNLOCKSTATION); _ASSERTE(pIn->hdr.nSrcThreadId==GetCurrentThreadId() || (bIsAltSrvCmd && pIn->hdr.nSrcPID!=GetCurrentProcessId())); #endif if (bAsyncNoResult) { // Если нас не интересует возврат и нужно сразу вернуться fSuccess = WriteFile(hPipe, pIn, pIn->hdr.cbSize, &cbRead, NULL); #ifdef _DEBUG dwErr = GetLastError(); _ASSERTE(fSuccess && (cbRead == pIn->hdr.cbSize)); #endif // -- Do not close hPipe, otherwise the reader may fail with that packet // -- with error ‘pipe was closed before end’. // -- Handle leak, yeah, however this is rarely used op. // -- Must be refactored, but not so critical... // -- CloseHandle(hPipe); pOut = NULL; goto wrap; } else { WARNING("При Overlapped часто виснет в этом месте."); // Send a message to the pipe server and read the response. fSuccess = TransactNamedPipe( hPipe, // pipe handle (LPVOID)pIn, // message to server pIn->hdr.cbSize, // message length cbReadBuf, // buffer to receive reply sizeof(cbReadBuf), // size of read buffer &cbRead, // bytes read NULL); // not overlapped dwErr = GetLastError(); //CloseHandle(hPipe); if (!fSuccess && (dwErr != ERROR_MORE_DATA)) { //_ASSERTE(fSuccess || (dwErr == ERROR_MORE_DATA)); CloseHandle(hPipe); pOut = NULL; goto wrap; } } if (cbRead < sizeof(CESERVER_REQ_HDR)) { CloseHandle(hPipe); pOut = NULL; goto wrap; } pOut = (CESERVER_REQ*)cbReadBuf; // temporary if (pOut->hdr.cbSize < cbRead) { CloseHandle(hPipe); if (pOut->hdr.cbSize) { _ASSERTE(pOut->hdr.cbSize == 0 || pOut->hdr.cbSize >= cbRead); DEBUGSTR(L"!!! Wrong nSize received from GUI server !!!\n"); } pOut = NULL; goto wrap; } if (pOut->hdr.nVersion != CESERVER_REQ_VER) { CloseHandle(hPipe); DEBUGSTR(L"!!! Wrong nVersion received from GUI server !!!\n"); pOut = NULL; goto wrap; } nAllSize = pOut->hdr.cbSize; pOut = (CESERVER_REQ*)malloc(nAllSize); _ASSERTE(pOut); if (!pOut) { CloseHandle(hPipe); _ASSERTE(pOut == NULL); goto wrap; } memmove(pOut, cbReadBuf, cbRead); ptrData = ((LPBYTE)pOut)+cbRead; nAllSize -= cbRead; while (nAllSize>0) { // Break if TransactNamedPipe or ReadFile is successful if (fSuccess) break; // Read from the pipe if there is more data in the message. fSuccess = ReadFile( hPipe, // pipe handle ptrData, // buffer to receive reply nAllSize, // size of buffer &cbRead, // number of bytes read NULL); // not overlapped // Exit if an error other than ERROR_MORE_DATA occurs. if (!fSuccess && ((dwErr = GetLastError()) != ERROR_MORE_DATA)) break; ptrData += cbRead; nAllSize -= cbRead; } CloseHandle(hPipe); if (pOut && (pOut->hdr.nCmd != pIn->hdr.nCmd)) { _ASSERTE(pOut->hdr.nCmd == pIn->hdr.nCmd); if (pOut->hdr.nCmd == 0) { ExecuteFreeResult(pOut); pOut = NULL; } } wrap: #ifdef _DEBUG if (pOut) _wsprintf(szDbgResult, SKIPLEN(countof(szDbgResult)) L"- Data=%5u Err=%u\n", pOut->DataSize(), dwErr); else lstrcpyn(szDbgResult, L"[NULL]\n", countof(szDbgResult)); pszDbgMsg = lstrmerge(szDbgPrefix, szDbgResult); if (pszDbgMsg) { DEBUGSTRCMD(pszDbgMsg); free(pszDbgMsg); } #endif return pOut; }