Esempio n. 1
0
int write(int fh, void const* buf, unsigned int count) {
  if (folly::portability::sockets::is_fh_socket(fh)) {
    SOCKET s = (SOCKET)_get_osfhandle(fh);
    if (s != INVALID_SOCKET) {
      auto r = folly::portability::sockets::send(fh, buf, (size_t)count, 0);
      if (r == -1 && WSAGetLastError() == WSAEWOULDBLOCK) {
        errno = EAGAIN;
      }
      return r;
    }
  }
  auto r = _write(fh, buf, count);
  if ((r > 0 && r != count) || (r == -1 && errno == ENOSPC)) {
    // Writing to a pipe with a full buffer doesn't generate
    // any error type, unless it caused us to write exactly 0
    // bytes, so we have to see if we have a pipe first. We
    // don't touch the errno for anything else.
    HANDLE h = (HANDLE)_get_osfhandle(fh);
    if (GetFileType(h) == FILE_TYPE_PIPE) {
      DWORD state = 0;
      if (GetNamedPipeHandleState(
              h, &state, nullptr, nullptr, nullptr, nullptr, 0)) {
        if ((state & PIPE_NOWAIT) == PIPE_NOWAIT) {
          errno = EAGAIN;
          return -1;
        }
      }
    }
  }
  return r;
}
Esempio n. 2
0
File: read.c Progetto: FaSan/Mingle
ssize_t
rpl_read (int fd, void *buf, size_t count)
{
  ssize_t ret = read_nothrow (fd, buf, count);

# if GNULIB_NONBLOCKING
  if (ret < 0
      && GetLastError () == ERROR_NO_DATA)
    {
      HANDLE h = (HANDLE) _get_osfhandle (fd);
      if (GetFileType (h) == FILE_TYPE_PIPE)
        {
          /* h is a pipe or socket.  */
          DWORD state;
          if (GetNamedPipeHandleState (h, &state, NULL, NULL, NULL, NULL, 0)
              && (state & PIPE_NOWAIT) != 0)
            /* h is a pipe in non-blocking mode.
               Change errno from EINVAL to EAGAIN.  */
            errno = EAGAIN;
        }
    }
# endif

  return ret;
}
int
get_nonblocking_flag (int desc)
{
  HANDLE h = (HANDLE) _get_osfhandle (desc);
  if (h == INVALID_HANDLE_VALUE)
    {
      errno = EBADF;
      return -1;
    }
  if (GetFileType (h) == FILE_TYPE_PIPE)
    {
      /* h is a pipe or socket.  */
      DWORD state;
      if (GetNamedPipeHandleState (h, &state, NULL, NULL, NULL, NULL, 0))
        /* h is a pipe.  */
        return (state & PIPE_NOWAIT) != 0;
      else
        /* h is a socket.  */
        errno = ENOSYS;
        return -1;
    }
  else
    /* The native Windows API does not support non-blocking on regular
       files.  */
    return 0;
}
Esempio n. 4
0
HRESULT PipeStream::GetState(DWORD* state, DWORD* instances,
                             DWORD* max_collections, DWORD* collect_timeout) {
  if (!IsValid())
    return E_HANDLE;

  if (!GetNamedPipeHandleState(handle_, state, instances, max_collections,
                               collect_timeout, nullptr, 0))
    return HRESULT_FROM_LAST_ERROR();

  return S_OK;
}
Esempio n. 5
0
HRESULT NamedPipeChannel::GetHandleState(DWORD* mode, DWORD* instances,
                                         wchar_t* user_name,
                                         DWORD user_name_size) const {
  if (!IsValid())
    return E_HANDLE;

  if (!GetNamedPipeHandleState(handle_, mode, instances, nullptr, nullptr,
                               user_name, user_name_size))
    return HRESULT_FROM_WIN32(GetLastError());

  return S_OK;
}
int
set_nonblocking_flag (int desc, bool value)
{
  HANDLE h = (HANDLE) _get_osfhandle (desc);
  if (h == INVALID_HANDLE_VALUE)
    {
      errno = EBADF;
      return -1;
    }
  if (GetFileType (h) == FILE_TYPE_PIPE)
    {
      /* h is a pipe or socket.  */
      DWORD state;
      if (GetNamedPipeHandleState (h, &state, NULL, NULL, NULL, NULL, 0))
        {
          /* h is a pipe.  */
          if ((state & PIPE_NOWAIT) != 0)
            {
              if (value)
                return 0;
              state &= ~PIPE_NOWAIT;
            }
          else
            {
              if (!value)
                return 0;
              state |= PIPE_NOWAIT;
            }
          if (SetNamedPipeHandleState (h, &state, NULL, NULL))
            return 0;
          errno = EINVAL;
          return -1;
        }
      else
        {
          /* h is a socket.  */
          int v = value;
          return ioctl (desc, FIONBIO, &v);
        }
    }
  else
    {
      /* The native Windows API does not support non-blocking on regular
         files.  */
      if (!value)
        return 0;
      errno = ENOTSUP;
      return -1;
    }
}
Esempio n. 7
0
String Pipe::UserName()
{
    Assert(_Handle != NULL, "Pipe invalid in Pipe::UserName");
    char Buffer[512];
    BOOL Success = GetNamedPipeHandleState(
        _Handle,
        NULL,
        NULL,
        NULL,
        NULL,
        Buffer,
        512);
    Assert(Success != FALSE, "GetNamedPipeHandleState failed in Pipe::UserName");
    return String(Buffer);
}
Esempio n. 8
0
UINT Pipe::ActiveInstances()
{
    Assert(_Handle != NULL, "Pipe invalid in Pipe::ActiveInstances");
    DWORD Instances;
    BOOL Success = GetNamedPipeHandleState(
        _Handle,
        NULL,
        &Instances,
        NULL,
        NULL,
        NULL,
        0);
    Assert(Success != FALSE, "GetNamedPipeHandleState failed in Pipe::ActiveInstances");
    return Instances;
}
Esempio n. 9
0
UINT Pipe::activeInstances()
{
    MLIB_ASSERT_STR(m_handle != nullptr, "Pipe invalid in Pipe::ActiveInstances");
    DWORD Instances;
    BOOL success = GetNamedPipeHandleState(
        m_handle,
        nullptr,
        &Instances,
        nullptr,
        nullptr,
        nullptr,
        0);
    MLIB_ASSERT_STR(success != FALSE, "GetNamedPipeHandleState failed in Pipe::ActiveInstances");
    return Instances;
}
Esempio n. 10
0
File: auth.c Progetto: Feechka/UOBP
static int
retrievePeerCredentials (PeerCredentials *credentials, FileDescriptor fd) {
  char buffer[0X100+1];

  if (GetNamedPipeHandleState(fd, NULL, NULL, NULL, NULL, buffer, sizeof(buffer))) {
    buffer[sizeof(buffer) - 1] = 0;

    if ((credentials->user = strdup(buffer))) {
      return 1;
    }
  } else {
    switch (GetLastError()) {
      default:
        logWindowsSystemError("GetNamedPipeHandleState");

      case ERROR_INSUFFICIENT_BUFFER: /* buffer too small */
      case ERROR_INVALID_HANDLE: /* not a named pipe */
      case ERROR_CANNOT_IMPERSONATE: /* no data transferred yet */
        break;
    }
  }

  return 0;
}
Esempio n. 11
0
static int uv__create_stdio_pipe_pair(uv_loop_t* loop, uv_pipe_t* server_pipe,
    HANDLE* child_pipe_ptr, unsigned int flags) {
  char pipe_name[64];
  SECURITY_ATTRIBUTES sa;
  DWORD server_access = 0;
  DWORD client_access = 0;
  HANDLE child_pipe = INVALID_HANDLE_VALUE;

  if (flags & UV_READABLE_PIPE) {
    server_access |= PIPE_ACCESS_OUTBOUND;
    client_access |= GENERIC_READ | FILE_WRITE_ATTRIBUTES;
  }
  if (flags & UV_WRITABLE_PIPE) {
    server_access |= PIPE_ACCESS_INBOUND;
    client_access |= GENERIC_WRITE;
  }

  /* Create server pipe handle. */
  if (uv_stdio_pipe_server(loop,
                           server_pipe,
                           server_access,
                           pipe_name,
                           sizeof(pipe_name)) < 0) {
    goto error;
  }

  /* Create child pipe handle. */
  sa.nLength = sizeof sa;
  sa.lpSecurityDescriptor = NULL;
  sa.bInheritHandle = TRUE;

  child_pipe = CreateFileA(pipe_name,
                           client_access,
                           0,
                           &sa,
                           OPEN_EXISTING,
                           server_pipe->ipc ? FILE_FLAG_OVERLAPPED : 0,
                           NULL);
  if (child_pipe == INVALID_HANDLE_VALUE) {
    uv__set_sys_error(loop, GetLastError());
    goto error;
  }

#ifndef NDEBUG
  /* Validate that the pipe was opened in the right mode. */
  {
    DWORD mode;
    BOOL r = GetNamedPipeHandleState(child_pipe,
                                     &mode,
                                     NULL,
                                     NULL,
                                     NULL,
                                     NULL,
                                     0);
    assert(r == TRUE);
    assert(mode == (PIPE_READMODE_BYTE | PIPE_WAIT));
  }
#endif

  /* Do a blocking ConnectNamedPipe.  This should not block because we have */
  /* both ends of the pipe created. */
  if (!ConnectNamedPipe(server_pipe->handle, NULL)) {
    if (GetLastError() != ERROR_PIPE_CONNECTED) {
      uv__set_sys_error(loop, GetLastError());
      goto error;
    }
  }

  *child_pipe_ptr = child_pipe;
  return 0;

 error:
  if (server_pipe->handle != INVALID_HANDLE_VALUE) {
    uv_pipe_cleanup(loop, server_pipe);
  }

  if (child_pipe != INVALID_HANDLE_VALUE) {
    CloseHandle(child_pipe);
  }

  return -1;
}
Esempio n. 12
0
// nTimeout - таймаут подключения
HANDLE ExecuteOpenPipe(const wchar_t* szPipeName, wchar_t (&szErr)[MAX_PATH*2], const wchar_t* szModule, DWORD nServerPID, DWORD nTimeout)
{
	HANDLE hPipe = NULL;
	DWORD dwErr = 0, dwMode = 0;
	BOOL fSuccess = FALSE;
	DWORD dwStartTick = GetTickCount();
	DWORD nSleepError = 10;
	int nTries = 10; // допустимое количество обломов, отличных от ERROR_PIPE_BUSY. после каждого - Sleep(nSleepError);
	DWORD nOpenPipeTimeout = nTimeout ? max(nTimeout,EXECUTE_CMD_OPENPIPE_TIMEOUT) : EXECUTE_CMD_OPENPIPE_TIMEOUT;
	BOOL bWaitPipeRc = FALSE, bWaitCalled = FALSE;
	DWORD nWaitPipeErr = 0;
	DWORD nDuration = 0;
#ifdef _DEBUG
	wchar_t szDbgMsg[512], szTitle[128];
#endif

	_ASSERTE(LocalSecurity()!=NULL);

#ifdef _DEBUG
	BOOL lbServerIsDebugged = FALSE;
	// WinXP SP1 и выше
	typedef BOOL (WINAPI* CheckRemoteDebuggerPresent_t)(HANDLE hProcess, PBOOL pbDebuggerPresent);
	static CheckRemoteDebuggerPresent_t _CheckRemoteDebuggerPresent = NULL;
	if (nServerPID)
	{
		if (!_CheckRemoteDebuggerPresent)
			_CheckRemoteDebuggerPresent = (CheckRemoteDebuggerPresent_t)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "CheckRemoteDebuggerPresent");
		
		if (_CheckRemoteDebuggerPresent)
		{
			HANDLE hProcess = OpenProcess(MY_PROCESS_ALL_ACCESS, FALSE, nServerPID);
			if (hProcess)
			{
				BOOL lb = FALSE;

				if (_CheckRemoteDebuggerPresent(hProcess, &lb) && lb)
					lbServerIsDebugged = TRUE;

				CloseHandle(hProcess);
			}
		}
	}
#endif


	// Try to open a named pipe; wait for it, if necessary.
	while (1)
	{
		hPipe = CreateFile(
		            szPipeName,     // pipe name
		            GENERIC_READ|GENERIC_WRITE,
		            0,              // no sharing
		            LocalSecurity(), // default security attributes
		            OPEN_EXISTING,  // opens existing pipe
		            0,              // default attributes
		            NULL);          // no template file
		dwErr = GetLastError();

		// Break if the pipe handle is valid.
		if (hPipe != INVALID_HANDLE_VALUE)
			break; // OK, открыли

#ifdef _DEBUG
		if (gbPipeDebugBoxes)
		{
			szDbgMsg[0] = 0;
			GetModuleFileName(NULL, szDbgMsg, countof(szDbgMsg));
			msprintf(szTitle, countof(szTitle), L"%s: PID=%u", PointToName(szDbgMsg), GetCurrentProcessId());
			msprintf(szDbgMsg, countof(szDbgMsg), L"Can't open pipe, ErrCode=%u\n%s\nWait: %u,%u,%u", dwErr, szPipeName, bWaitCalled, bWaitPipeRc, nWaitPipeErr);
			int nBtn = ::MessageBox(NULL, szDbgMsg, szTitle, MB_SYSTEMMODAL|MB_RETRYCANCEL);
			if (nBtn == IDCANCEL)
				return NULL;
		}
#endif

		nDuration = GetTickCount() - dwStartTick;

		if (dwErr == ERROR_PIPE_BUSY)
		{
			if ((nTries > 0) && (nDuration < nOpenPipeTimeout))
			{
				bWaitCalled = TRUE;
				// All pipe instances are busy, so wait for 500 ms.
				bWaitPipeRc = WaitNamedPipe(szPipeName, 500);
				nWaitPipeErr = GetLastError();
				UNREFERENCED_PARAMETER(bWaitPipeRc); UNREFERENCED_PARAMETER(nWaitPipeErr);
				// -- 120602 раз они заняты (но живы), то будем ждать, пока не освободятся
				//nTries--;
				continue;
			}
			else
			{
				_ASSERTEX(dwErr != ERROR_PIPE_BUSY);
			}
		}

		// Сделаем так, чтобы хотя бы пару раз он попробовал повторить
		if ((nTries <= 0) || (nDuration > nOpenPipeTimeout))
		{
			//if (pszErr)
			{
				msprintf(szErr, countof(szErr), L"%s.%u: CreateFile(%s) failed, code=0x%08X, Timeout",
				          ModuleName(szModule), GetCurrentProcessId(), szPipeName, dwErr);
			}
			return NULL;
		}
		else
		{
			nTries--;
		}

		// Может быть пайп еще не создан (в процессе срабатывания семафора)
		if (dwErr == ERROR_FILE_NOT_FOUND)
		{
			Sleep(nSleepError);
			continue;
		}

		// Exit if an error other than ERROR_PIPE_BUSY occurs.
		// -- if (dwErr != ERROR_PIPE_BUSY) // уже проверено выше
		{
			//if (pszErr)
			{
				msprintf(szErr, countof(szErr), L"%s.%u: CreateFile(%s) failed, code=0x%08X",
				          ModuleName(szModule), GetCurrentProcessId(), szPipeName, dwErr);
			}
			return NULL;
		}

		// Уже сделано выше
		//// All pipe instances are busy, so wait for 500 ms.
		//WaitNamedPipe(szPipeName, 500);
		//if (!WaitNamedPipe(szPipeName, 1000) )
		//{
		//	dwErr = GetLastError();
		//	if (pszErr)
		//	{
		//		StringCchPrintf(pszErr, countof(pszErr), L"%s: WaitNamedPipe(%s) failed, code=0x%08X, WaitNamedPipe",
		//			szModule ? szModule : L"Unknown", szPipeName, dwErr);
		//		// Видимо это возникает в момент запуска (обычно для ShiftEnter - новая консоль)
		//		// не сразу срабатывает GUI и RCon еще не создал Pipe для HWND консоли
		//		_ASSERTE(dwErr == 0);
		//	}
		//    return NULL;
		//}
	}

#ifdef _DEBUG
	DWORD nCurState = 0, nCurInstances = 0;
	BOOL bCurState = GetNamedPipeHandleState(hPipe, &nCurState, &nCurInstances, NULL, NULL, NULL, 0);
#endif

	// 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 0
	if (!fSuccess)
	{
		dwErr = GetLastError();
		_ASSERTE(fSuccess);
		//if (pszErr)
		{
			msprintf(szErr, countof(szErr), L"%s.%u: SetNamedPipeHandleState(%s) failed, code=0x%08X",
			          ModuleName(szModule), GetCurrentProcessId(), szPipeName, dwErr);
			#ifdef _DEBUG
			int nCurLen = lstrlen(szErr);
			msprintf(szErr+nCurLen, countof(szErr)-nCurLen, L"\nCurState: %u,x%08X,%u", bCurState, nCurState, nCurInstances);
			#endif
		}
		CloseHandle(hPipe);

#ifdef _DEBUG
		if (gbPipeDebugBoxes)
		{
			szDbgMsg[0] = 0;
			GetModuleFileName(NULL, szDbgMsg, countof(szDbgMsg));
			msprintf(szTitle, countof(szTitle), L"%s: PID=%u", PointToName(szDbgMsg), GetCurrentProcessId());
			::MessageBox(NULL, szErr, szTitle, MB_SYSTEMMODAL);
		}
#endif

		return NULL;
	}
#endif

	return hPipe;
}
Esempio n. 13
0
ssize_t
rpl_write (int fd, const void *buf, size_t count)
{
  for (;;)
    {
      ssize_t ret = write_nothrow (fd, buf, count);

      if (ret < 0)
        {
# if GNULIB_NONBLOCKING
          if (errno == ENOSPC)
            {
              HANDLE h = (HANDLE) _get_osfhandle (fd);
              if (GetFileType (h) == FILE_TYPE_PIPE)
                {
                  /* h is a pipe or socket.  */
                  DWORD state;
                  if (GetNamedPipeHandleState (h, &state, NULL, NULL, NULL,
                                               NULL, 0)
                      && (state & PIPE_NOWAIT) != 0)
                    {
                      /* h is a pipe in non-blocking mode.
                         We can get here in four situations:
                           1. When the pipe buffer is full.
                           2. When count <= pipe_buf_size and the number of
                              free bytes in the pipe buffer is < count.
                           3. When count > pipe_buf_size and the number of free
                              bytes in the pipe buffer is > 0, < pipe_buf_size.
                           4. When count > pipe_buf_size and the pipe buffer is
                              entirely empty.
                         The cases 1 and 2 are POSIX compliant.  In cases 3 and
                         4 POSIX specifies that write() must split the request
                         and succeed with a partial write.  We fix case 4.
                         We don't fix case 3 because it is not essential for
                         programs.  */
                      DWORD out_size; /* size of the buffer for outgoing data */
                      DWORD in_size;  /* size of the buffer for incoming data */
                      if (GetNamedPipeInfo (h, NULL, &out_size, &in_size, NULL))
                        {
                          size_t reduced_count = count;
                          /* In theory we need only one of out_size, in_size.
                             But I don't know which of the two.  The description
                             is ambiguous.  */
                          if (out_size != 0 && out_size < reduced_count)
                            reduced_count = out_size;
                          if (in_size != 0 && in_size < reduced_count)
                            reduced_count = in_size;
                          if (reduced_count < count)
                            {
                              /* Attempt to write only the first part.  */
                              count = reduced_count;
                              continue;
                            }
                        }
                      /* Change errno from ENOSPC to EAGAIN.  */
                      errno = EAGAIN;
                    }
                }
            }
          else
# endif
            {
# if GNULIB_SIGPIPE
              if (GetLastError () == ERROR_NO_DATA
                  && GetFileType ((HANDLE) _get_osfhandle (fd))
                     == FILE_TYPE_PIPE)
                {
                  /* Try to raise signal SIGPIPE.  */
                  raise (SIGPIPE);
                  /* If it is currently blocked or ignored, change errno from
                     EINVAL to EPIPE.  */
                  errno = EPIPE;
                }
# endif
            }
        }
      return ret;
    }
}
Esempio n. 14
0
// nTimeout - таймаут подключения
HANDLE ExecuteOpenPipe(const wchar_t* szPipeName, wchar_t (&szErr)[MAX_PATH*2], const wchar_t* szModule, DWORD nServerPID, DWORD nTimeout, BOOL Overlapped /*= FALSE*/, HANDLE hStop /*= NULL*/)
{
	HANDLE hPipe = NULL;
	DWORD dwErr = 0, dwMode = 0;
	BOOL fSuccess = FALSE;
	DWORD dwStartTick = GetTickCount();
	DWORD nSleepError = 10;
	// допустимое количество обломов, отличных от ERROR_PIPE_BUSY. после каждого - Sleep(nSleepError);
	int nTries = 10;
	// nTimeout должен ограничивать ВЕРХНЮЮ границу времени ожидания
	_ASSERTE(EXECUTE_CMD_OPENPIPE_TIMEOUT >= nTimeout);
	DWORD nOpenPipeTimeout = nTimeout ? min(nTimeout,EXECUTE_CMD_OPENPIPE_TIMEOUT) : EXECUTE_CMD_OPENPIPE_TIMEOUT;
	_ASSERTE(nOpenPipeTimeout > 0);
	DWORD nWaitPipeTimeout = min(250,nOpenPipeTimeout);

	BOOL bWaitPipeRc = FALSE, bWaitCalled = FALSE;
	DWORD nWaitPipeErr = 0;
	DWORD nDuration = 0;
	DWORD nStopWaitRc = (DWORD)-1;

	#ifdef _DEBUG
	wchar_t szDbgMsg[512], szTitle[128];
	#endif

	// WinXP SP1 и выше
	DEBUGTEST(BOOL lbServerIsDebugged = nServerPID ? IsProcessDebugged(nServerPID) : FALSE);

	
	_ASSERTE(LocalSecurity()!=NULL);


	// Try to open a named pipe; wait for it, if necessary.
	while (1)
	{
		hPipe = CreateFile(
		            szPipeName,     // pipe name
		            GENERIC_READ|GENERIC_WRITE,
		            0,              // no sharing
		            LocalSecurity(), // default security attributes
		            OPEN_EXISTING,  // opens existing pipe
		            (Overlapped ? FILE_FLAG_OVERLAPPED : 0), // default attributes
		            NULL);          // no template file
		dwErr = GetLastError();

		// Break if the pipe handle is valid.
		if (hPipe != INVALID_HANDLE_VALUE)
		{
			_ASSERTE(hPipe);
			break; // OK, открыли
		}

		#ifdef _DEBUG
		if (gbPipeDebugBoxes)
		{
			szDbgMsg[0] = 0;
			GetModuleFileName(NULL, szDbgMsg, countof(szDbgMsg));
			msprintf(szTitle, countof(szTitle), L"%s: PID=%u", PointToName(szDbgMsg), GetCurrentProcessId());
			msprintf(szDbgMsg, countof(szDbgMsg), L"Can't open pipe, ErrCode=%u\n%s\nWait: %u,%u,%u", dwErr, szPipeName, bWaitCalled, bWaitPipeRc, nWaitPipeErr);
			int nBtn = ::MessageBox(NULL, szDbgMsg, szTitle, MB_SYSTEMMODAL|MB_RETRYCANCEL);
			if (nBtn == IDCANCEL)
				return NULL;
		}
		#endif

		nDuration = GetTickCount() - dwStartTick;

		if (hStop)
		{
			// Затребовано завершение приложения или еще что-то
			nStopWaitRc = WaitForSingleObject(hStop, 0);
			if (nStopWaitRc == WAIT_OBJECT_0)
			{
				return NULL;
			}
		}

		if (dwErr == ERROR_PIPE_BUSY)
		{
			if ((nTries > 0) && (nDuration < nOpenPipeTimeout))
			{
				bWaitCalled = TRUE;

				// All pipe instances are busy, so wait for a while (not more 500 ms).
				bWaitPipeRc = WaitNamedPipe(szPipeName, nWaitPipeTimeout);
				nWaitPipeErr = GetLastError();
				UNREFERENCED_PARAMETER(bWaitPipeRc); UNREFERENCED_PARAMETER(nWaitPipeErr);
				// -- 120602 раз они заняты (но живы), то будем ждать, пока не освободятся
				//nTries--;
				continue;
			}
			else
			{
				_ASSERTEX(dwErr != ERROR_PIPE_BUSY);
			}
		}

		// Сделаем так, чтобы хотя бы пару раз он попробовал повторить
		if ((nTries <= 0) || (nDuration > nOpenPipeTimeout))
		{
			//if (pszErr)
			{
				msprintf(szErr, countof(szErr), L"%s.%u: CreateFile(%s) failed, code=0x%08X, Timeout",
				          ModuleName(szModule), GetCurrentProcessId(), szPipeName, dwErr);
				_ASSERTEX(FALSE && "Pipe open failed with timeout!");
			}
			return NULL;
		}
		else
		{
			nTries--;
		}

		// Может быть пайп еще не создан (в процессе срабатывания семафора)
		if (dwErr == ERROR_FILE_NOT_FOUND)
		{
			// Wait for a while (10 ms)
			Sleep(nSleepError);
			continue;
		}

		// Exit if an error other than ERROR_PIPE_BUSY occurs.
		// -- if (dwErr != ERROR_PIPE_BUSY) // уже проверено выше
		{
			//if (pszErr)
			{
				msprintf(szErr, countof(szErr), L"%s.%u: CreateFile(%s) failed, code=0x%08X",
				          ModuleName(szModule), GetCurrentProcessId(), szPipeName, dwErr);
			}
			return NULL;
		}

		// Уже сделано выше
		//// All pipe instances are busy, so wait for 500 ms.
		//WaitNamedPipe(szPipeName, 500);
		//if (!WaitNamedPipe(szPipeName, 1000) )
		//{
		//	dwErr = GetLastError();
		//	if (pszErr)
		//	{
		//		StringCchPrintf(pszErr, countof(pszErr), L"%s: WaitNamedPipe(%s) failed, code=0x%08X, WaitNamedPipe",
		//			szModule ? szModule : L"Unknown", szPipeName, dwErr);
		//		// Видимо это возникает в момент запуска (обычно для ShiftEnter - новая консоль)
		//		// не сразу срабатывает GUI и RCon еще не создал Pipe для HWND консоли
		//		_ASSERTE(dwErr == 0);
		//	}
		//    return NULL;
		//}
	}

#ifdef _DEBUG
	DWORD nCurState = 0, nCurInstances = 0;
	BOOL bCurState = GetNamedPipeHandleState(hPipe, &nCurState, &nCurInstances, NULL, NULL, NULL, 0);
#endif

	// The pipe connected; change to message-read mode.
	dwMode = CE_PIPE_READMODE;
	fSuccess = SetNamedPipeHandleState(
	               hPipe,    // pipe handle
	               &dwMode,  // new pipe mode
	               NULL,     // don't set maximum bytes
	               NULL);    // don't set maximum time

#if 0
	if (!fSuccess)
	{
		dwErr = GetLastError();
		_ASSERTE(fSuccess);
		//if (pszErr)
		{
			msprintf(szErr, countof(szErr), L"%s.%u: SetNamedPipeHandleState(%s) failed, code=0x%08X",
			          ModuleName(szModule), GetCurrentProcessId(), szPipeName, dwErr);
			#ifdef _DEBUG
			int nCurLen = lstrlen(szErr);
			msprintf(szErr+nCurLen, countof(szErr)-nCurLen, L"\nCurState: %u,x%08X,%u", bCurState, nCurState, nCurInstances);
			#endif
		}
		CloseHandle(hPipe);

#ifdef _DEBUG
		if (gbPipeDebugBoxes)
		{
			szDbgMsg[0] = 0;
			GetModuleFileName(NULL, szDbgMsg, countof(szDbgMsg));
			msprintf(szTitle, countof(szTitle), L"%s: PID=%u", PointToName(szDbgMsg), GetCurrentProcessId());
			::MessageBox(NULL, szErr, szTitle, MB_SYSTEMMODAL);
		}
#endif

		return NULL;
	}
#endif

	UNREFERENCED_PARAMETER(bWaitCalled);
	UNREFERENCED_PARAMETER(fSuccess);

	return hPipe;
}
Esempio n. 15
0
static int uv__create_stdio_pipe_pair(uv_loop_t* loop,
    uv_pipe_t* server_pipe, HANDLE* child_pipe_ptr, unsigned int flags) {
  char pipe_name[64];
  SECURITY_ATTRIBUTES sa;
  DWORD server_access = 0;
  DWORD client_access = 0;
  HANDLE child_pipe = INVALID_HANDLE_VALUE;
  int err;

  if (flags & UV_READABLE_PIPE) {
    /* The server needs inbound access too, otherwise CreateNamedPipe() */
    /* won't give us the FILE_READ_ATTRIBUTES permission. We need that to */
    /* probe the state of the write buffer when we're trying to shutdown */
    /* the pipe. */
    server_access |= PIPE_ACCESS_OUTBOUND | PIPE_ACCESS_INBOUND;
    client_access |= GENERIC_READ | FILE_WRITE_ATTRIBUTES;
  }
  if (flags & UV_WRITABLE_PIPE) {
    server_access |= PIPE_ACCESS_INBOUND;
    client_access |= GENERIC_WRITE | FILE_READ_ATTRIBUTES;
  }

  /* Create server pipe handle. */
  err = uv_stdio_pipe_server(loop,
                             server_pipe,
                             server_access,
                             pipe_name,
                             sizeof(pipe_name));
  if (err)
    goto error;

  /* Create child pipe handle. */
  sa.nLength = sizeof sa;
  sa.lpSecurityDescriptor = NULL;
  sa.bInheritHandle = TRUE;

  child_pipe = CreateFileA(pipe_name,
                           client_access,
                           0,
                           &sa,
                           OPEN_EXISTING,
                           server_pipe->ipc ? FILE_FLAG_OVERLAPPED : 0,
                           NULL);
  if (child_pipe == INVALID_HANDLE_VALUE) {
    err = GetLastError();
    goto error;
  }

#ifndef NDEBUG
  /* Validate that the pipe was opened in the right mode. */
  {
    DWORD mode;
    BOOL r = GetNamedPipeHandleState(child_pipe,
                                     &mode,
                                     NULL,
                                     NULL,
                                     NULL,
                                     NULL,
                                     0);
    assert(r == TRUE);
    assert(mode == (PIPE_READMODE_BYTE | PIPE_WAIT));
  }
#endif

  /* Do a blocking ConnectNamedPipe.  This should not block because we have */
  /* both ends of the pipe created. */
  if (!ConnectNamedPipe(server_pipe->handle, NULL)) {
    if (GetLastError() != ERROR_PIPE_CONNECTED) {
      err = GetLastError();
      goto error;
    }
  }

  /* The server end is now readable and/or writable. */
  if (flags & UV_READABLE_PIPE)
    server_pipe->flags |= UV_HANDLE_WRITABLE;
  if (flags & UV_WRITABLE_PIPE)
    server_pipe->flags |= UV_HANDLE_READABLE;

  *child_pipe_ptr = child_pipe;
  return 0;

 error:
  if (server_pipe->handle != INVALID_HANDLE_VALUE) {
    uv_pipe_cleanup(loop, server_pipe);
  }

  if (child_pipe != INVALID_HANDLE_VALUE) {
    CloseHandle(child_pipe);
  }

  return err;
}
Esempio n. 16
0
RTDECL(int)  RTPipeFromNative(PRTPIPE phPipe, RTHCINTPTR hNativePipe, uint32_t fFlags)
{
    AssertPtrReturn(phPipe, VERR_INVALID_POINTER);
    AssertReturn(!(fFlags & ~RTPIPE_N_VALID_MASK), VERR_INVALID_PARAMETER);
    AssertReturn(!!(fFlags & RTPIPE_N_READ) != !!(fFlags & RTPIPE_N_WRITE), VERR_INVALID_PARAMETER);

    /*
     * Get and validate the pipe handle info.
     */
    HANDLE hNative = (HANDLE)hNativePipe;
    AssertReturn(GetFileType(hNative) == FILE_TYPE_PIPE, VERR_INVALID_HANDLE);

    DWORD cMaxInstances;
    DWORD fInfo;
    if (!GetNamedPipeInfo(hNative, &fInfo, NULL, NULL, &cMaxInstances))
        return RTErrConvertFromWin32(GetLastError());
    AssertReturn(!(fInfo & PIPE_TYPE_MESSAGE), VERR_INVALID_HANDLE);
    AssertReturn(cMaxInstances == 1, VERR_INVALID_HANDLE);

    DWORD cInstances;
    DWORD fState;
    if (!GetNamedPipeHandleState(hNative, &fState, &cInstances, NULL, NULL, NULL, 0))
        return RTErrConvertFromWin32(GetLastError());
    AssertReturn(!(fState & PIPE_NOWAIT), VERR_INVALID_HANDLE);
    AssertReturn(!(fState & PIPE_READMODE_MESSAGE), VERR_INVALID_HANDLE);
    AssertReturn(cInstances <= 1, VERR_INVALID_HANDLE);

    /*
     * Looks kind of OK, create a handle so we can try rtPipeQueryInfo on it
     * and see if we need to duplicate it to make that call work.
     */
    RTPIPEINTERNAL *pThis = (RTPIPEINTERNAL *)RTMemAllocZ(sizeof(RTPIPEINTERNAL));
    if (!pThis)
        return VERR_NO_MEMORY;
    int rc = RTCritSectInit(&pThis->CritSect);
    if (RT_SUCCESS(rc))
    {
        pThis->Overlapped.hEvent = CreateEvent(NULL, TRUE /*fManualReset*/,
                                               TRUE /*fInitialState*/, NULL /*pName*/);
        if (pThis->Overlapped.hEvent != NULL)
        {
            pThis->u32Magic        = RTPIPE_MAGIC;
            pThis->hPipe           = hNative;
            pThis->fRead           = !!(fFlags & RTPIPE_N_READ);
            //pThis->fIOPending      = false;
            //pThis->fZeroByteRead   = false;
            //pThis->fBrokenPipe     = false;
            //pThisR->fPromisedWritable= false;
            //pThis->cUsers          = 0;
            //pThis->pbBounceBuf     = NULL;
            //pThis->cbBounceBufUsed = 0;
            //pThis->cbBounceBufAlloc= 0;
            pThis->hPollSet        = NIL_RTPOLLSET;

            HANDLE  hNative2 = INVALID_HANDLE_VALUE;
            FILE_PIPE_LOCAL_INFORMATION Info;
            if (rtPipeQueryInfo(pThis, &Info))
                rc = VINF_SUCCESS;
            else
            {
                if (DuplicateHandle(GetCurrentProcess() /*hSrcProcess*/, hNative /*hSrcHandle*/,
                                    GetCurrentProcess() /*hDstProcess*/, &hNative2 /*phDstHandle*/,
                                    pThis->fRead ? GENERIC_READ : GENERIC_WRITE | FILE_READ_ATTRIBUTES /*dwDesiredAccess*/,
                                    !!(fFlags & RTPIPE_N_INHERIT) /*fInheritHandle*/,
                                    0 /*dwOptions*/))
                {
                    pThis->hPipe = hNative2;
                    if (rtPipeQueryInfo(pThis, &Info))
                        rc = VINF_SUCCESS;
                    else
                    {
                        rc = VERR_ACCESS_DENIED;
                        CloseHandle(hNative2);
                    }
                }
                else
                    hNative2 = INVALID_HANDLE_VALUE;
            }
            if (RT_SUCCESS(rc))
            {
                /*
                 * Verify the pipe state and correct the inheritability.
                 */
                AssertStmt(   Info.NamedPipeState == FILE_PIPE_CONNECTED_STATE
                           || Info.NamedPipeState == FILE_PIPE_CLOSING_STATE
                           || Info.NamedPipeState == FILE_PIPE_DISCONNECTED_STATE,
                           VERR_INVALID_HANDLE);
                AssertStmt(   Info.NamedPipeConfiguration
                           == (   Info.NamedPipeEnd == FILE_PIPE_SERVER_END
                               ? (pThis->fRead ? FILE_PIPE_INBOUND  : FILE_PIPE_OUTBOUND)
                               : (pThis->fRead ? FILE_PIPE_OUTBOUND : FILE_PIPE_INBOUND) ),
                           VERR_INVALID_HANDLE);
                if (   RT_SUCCESS(rc)
                    && hNative2 == INVALID_HANDLE_VALUE
                    && !SetHandleInformation(hNative,
                                             HANDLE_FLAG_INHERIT /*dwMask*/,
                                             fFlags & RTPIPE_N_INHERIT ? HANDLE_FLAG_INHERIT : 0))
                {
                    rc = RTErrConvertFromWin32(GetLastError());
                    AssertMsgFailed(("%Rrc\n", rc));
                }
                if (RT_SUCCESS(rc))
                {
                    /*
                     * Ok, we're good!
                     */
                    if (hNative2 != INVALID_HANDLE_VALUE)
                        CloseHandle(hNative);
                    *phPipe = pThis;
                    return VINF_SUCCESS;
                }
            }

            /* Bail out. */
            if (hNative2 != INVALID_HANDLE_VALUE)
                CloseHandle(hNative2);
            CloseHandle(pThis->Overlapped.hEvent);
        }
        RTCritSectDelete(&pThis->CritSect);
    }
    RTMemFree(pThis);
    return rc;
}