コード例 #1
0
ファイル: writelog.cpp プロジェクト: biglad/WinUAE
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);

			}
		}
	}
}
コード例 #2
0
ファイル: ConEmuCheck.cpp プロジェクト: alexlav/conemu
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;
}
コード例 #3
0
ファイル: writelog.cpp プロジェクト: biglad/WinUAE
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;
}
コード例 #4
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;
}
コード例 #5
0
ファイル: ConEmuCheck.cpp プロジェクト: alexlav/conemu
//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;
}
コード例 #6
0
ファイル: ConEmuCheck.cpp プロジェクト: alexlav/conemu
// 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;
}
コード例 #7
0
ファイル: ConEmuCheck.cpp プロジェクト: akrisiun/ConEmu
//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;
}