Example #1
0
    DWORD CALLBACK Thread()
    {
        IMDPROXY_CONNECT_REQ ConnectReq;

        KdPrint(("ImDskSvc: Thread created.%n"));

        if (Overlapped.BufRecv(hPipe, &ConnectReq.request_code,
            sizeof ConnectReq.request_code) !=
            sizeof ConnectReq.request_code)
        {
            KdPrintLastError(("Overlapped.BufRecv() failed"));

            delete this;
            return 0;
        }

        if (ConnectReq.request_code != IMDPROXY_REQ_CONNECT)
        {
            delete this;
            return 0;
        }

        if (Overlapped.BufRecv(hPipe,
            ((PUCHAR)&ConnectReq) +
            sizeof(ConnectReq.request_code),
            sizeof(ConnectReq) -
            sizeof(ConnectReq.request_code)) !=
            sizeof(ConnectReq) -
            sizeof(ConnectReq.request_code))
        {
            KdPrintLastError(("Overlapped.BufRecv() failed"));

            delete this;
            return 0;
        }

        if ((ConnectReq.length == 0) | (ConnectReq.length > 520))
        {
            KdPrint(("ImDskSvc: Bad connection string length received (%1!u!).%n",
                ConnectReq.length));

            delete this;
            return 0;
        }

        WCRTMem<WCHAR> ConnectionString((size_t)ConnectReq.length + 2);
        if (!ConnectionString)
        {
            KdPrintLastError(("malloc() failed"));

            delete this;
            return 0;
        }

        if (Overlapped.BufRecv(hPipe, ConnectionString,
            (DWORD)ConnectReq.length) !=
            ConnectReq.length)
        {
            KdPrintLastError(("Overlapped.BufRecv() failed"));

            
            delete this;
            return 0;
        }

        IMDPROXY_CONNECT_RESP connect_resp = { 0 };

        ConnectionString[ConnectReq.length / sizeof *ConnectionString] = 0;

        // Split server connection string and string that should be sent to server
        // for server side connection to specific image file.

        LPWSTR path_part = wcsstr(ConnectionString, L"://");

        if (path_part != NULL)
        {
            path_part[0] = 0;
            path_part++;
        }

        HANDLE hTarget;
        switch (IMDISK_PROXY_TYPE(ConnectReq.flags))
        {
        case IMDISK_PROXY_TYPE_COMM:
        {
            LPWSTR FileName = wcstok(ConnectionString, L": ");

            KdPrint(("ImDskSvc: Connecting to '%1!ws!'.%n", FileName));

            hTarget = CreateFile(FileName,
                GENERIC_READ | GENERIC_WRITE,
                0,
                NULL,
                OPEN_EXISTING,
                0,
                NULL);

            if (hTarget == INVALID_HANDLE_VALUE)
            {
                connect_resp.error_code = GetLastError();

                KdPrintLastError(("CreateFile() failed"));

                Overlapped.BufSend(hPipe, &connect_resp, sizeof connect_resp);

                delete this;
                return 0;
            }

            LPWSTR DCBAndTimeouts = wcstok(NULL, L"");
            if (DCBAndTimeouts != NULL)
            {
                DCB dcb = { 0 };
                COMMTIMEOUTS timeouts = { 0 };

                if (DCBAndTimeouts[0] == L' ')
                    ++DCBAndTimeouts;

                KdPrint(("ImDskSvc: Configuring '%1!ws!'.%n", DCBAndTimeouts));

                GetCommState(hTarget, &dcb);
                GetCommTimeouts(hTarget, &timeouts);
                BuildCommDCBAndTimeouts(DCBAndTimeouts, &dcb, &timeouts);
                SetCommState(hTarget, &dcb);
                SetCommTimeouts(hTarget, &timeouts);
            }

            KdPrint(("ImDskSvc: Connected to '%1!ws!' and configured.%n",
                FileName));

            break;
        }

        case IMDISK_PROXY_TYPE_TCP:
        {
            LPWSTR ServerName = wcstok(ConnectionString, L":");
            LPWSTR PortName = wcstok(NULL, L"");

            if (PortName == NULL)
                PortName = L"9000";

            KdPrint(("ImDskSvc: Connecting to '%1!ws!:%2!ws!'.%n",
                ServerName, PortName));

            hTarget = (HANDLE)ConnectTCP(ServerName, PortName);
            if (hTarget == INVALID_HANDLE_VALUE)
            {
                connect_resp.error_code = GetLastError();

                KdPrintLastError(("ConnectTCP() failed"));
                

                Overlapped.BufSend(hPipe, &connect_resp, sizeof connect_resp);

                delete this;
                return 0;
            }

            bool b = true;
            setsockopt((SOCKET)hTarget, IPPROTO_TCP, TCP_NODELAY, (LPCSTR)&b,
                sizeof b);

            KdPrint(("ImDskSvc: Connected to '%1!ws!:%2!ws!' and configured.%n",
                ServerName, PortName));

            break;
        }

        default:
            KdPrint(("ImDskSvc: Unsupported connection type (%1!#x!).%n",
                IMDISK_PROXY_TYPE(ConnectReq.flags)));

            connect_resp.error_code = (ULONGLONG)-1;
            Overlapped.BufSend(hPipe, &connect_resp, sizeof connect_resp);

            
            delete this;
            return 0;
        }

        // Connect to requested server side image path

        if (path_part != NULL)
        {
            size_t path_size = wcslen(path_part) << 1;

            size_t req_size = sizeof(IMDPROXY_CONNECT_REQ) +
                path_size;

            WCRTMem<IMDPROXY_CONNECT_REQ> open_request(req_size);

            if (!open_request)
            {
                KdPrintLastError(("malloc() failed"));

                connect_resp.error_code = (ULONGLONG)-1;
                Overlapped.BufSend(hPipe, &connect_resp, sizeof connect_resp);

                delete this;
                return 0;
            }

            ZeroMemory(open_request, req_size);

            open_request->request_code = IMDPROXY_REQ_CONNECT;
            open_request->length = path_size;

            memcpy(open_request + 1, path_part, path_size);

            if (!Overlapped.BufSend(hTarget, open_request, (DWORD)req_size))
            {
                KdPrintLastError(("Failed to send connect request to server"));

                connect_resp.error_code = (ULONGLONG)-1;
                Overlapped.BufSend(hPipe, &connect_resp, sizeof connect_resp);

                delete this;
                return 0;
            }

            open_request.Free();

            if (Overlapped.BufRecv(hTarget, &connect_resp, sizeof connect_resp) !=
                sizeof connect_resp)
            {
                connect_resp.object_ptr = NULL;
                if (connect_resp.error_code == 0)
                {
                    connect_resp.error_code = (ULONGLONG)-1;
                }

                Overlapped.BufSend(hPipe, &connect_resp, sizeof connect_resp);
                
                delete this;
                return 0;
            }
        }
        
        ConnectionString.Free();

        HANDLE hDriver = CreateFile(IMDISK_CTL_DOSDEV_NAME,
            GENERIC_READ | GENERIC_WRITE,
            FILE_SHARE_READ | FILE_SHARE_WRITE,
            NULL,
            OPEN_EXISTING,
            0,
            NULL);

        if (hDriver == INVALID_HANDLE_VALUE)
        {
            connect_resp.error_code = GetLastError();

            KdPrintLastError(("Opening ImDiskCtl device failed"));
            CloseHandle(hTarget);

            Overlapped.BufSend(hPipe, &connect_resp, sizeof connect_resp);

            delete this;
            return 0;
        }

        DWORD dw;
        if (!DeviceIoControl(hDriver,
            IOCTL_IMDISK_REFERENCE_HANDLE,
            &hTarget,
#pragma warning(suppress: 28132)
            sizeof hTarget,
            &connect_resp.object_ptr,
            sizeof connect_resp.object_ptr,
            &dw,
            NULL))
        {
            connect_resp.error_code = GetLastError();

            KdPrintLastError(("IOCTL_IMDISK_REFERENCE_HANDLE failed"));
            CloseHandle(hDriver);
            CloseHandle(hTarget);

            Overlapped.BufSend(hPipe, &connect_resp, sizeof connect_resp);

            delete this;
            return 0;
        }

        CloseHandle(hDriver);

        Overlapped.BufSend(hPipe, &connect_resp, sizeof connect_resp);

        // This will fail when driver closes the pipe, but that just indicates that
        // we should shut down this connection.
        Overlapped.BufRecv(hPipe, &dw, sizeof dw);

        KdPrint(("ImDskSvc: Cleaning up.%n"));

        CloseHandle(hTarget);

        delete this;
        return 1;
    }
Example #2
0
int
safe_read(SOCKET fd, void *pdata, safeio_size_t size)
{
  return Overlapped.BufRecv((HANDLE) fd, pdata, size) == (DWORD)size;
}
Example #3
0
int
safe_write(SOCKET fd, const void *pdata, safeio_size_t size)
{
  return Overlapped.BufSend((HANDLE) fd, pdata, size);
}
Example #4
0
  DWORD WINAPI WebEcho(HANDLE s, LPCSTR)
{
  WOverlapped ol;

  const char http_head[] = "HTTP/1.0 200 OK\r\n"
      "Server: Web Echo Server\r\n"
      "Connection: close\r\n"
      "Pragma: no-cache\r\n"
      "Content-Type: text/plain\r\n"
      "\r\n";
      "You are connecting from:\n";

  if (!ol.BufSend(s, http_head, sizeof(http_head)-1))
    {
      h_perror();
      return (DWORD)-1;
    }

  // Get peer IP and name
  sockaddr_in sin;
  int sin_length = sizeof sin;
  if (getpeername((SOCKET)s, (sockaddr*)&sin, &sin_length) == SOCKET_ERROR)
    {
      h_perror();
      return (DWORD)-1;
    }
  hostent *hent = gethostbyaddr((char*)&sin.sin_addr, 4, 2);
  if (!hent)
    {
      const char cNoNameMsg[] = "Host name lookup failed.\n";
      if (!ol.BufSend(s, cNoNameMsg, sizeof(cNoNameMsg)-1))
        {
          h_perror();
          return (DWORD)-1;
        }
    }
  else
    {
      const char cHostMsg[] = "Host:\t";
      if (!ol.BufSend(s, cHostMsg, sizeof(cHostMsg)-1))
        {
          h_perror();
          return (DWORD)-1;
        }
      if (!ol.BufSend(s, hent->h_name, (DWORD) strlen(hent->h_name)))
        {
          h_perror();
          return (DWORD)-1;
        }
      if (!ol.BufSend(s, "\n", 1))
        {
          h_perror();
          return (DWORD)-1;
        }

      const char cAliasMsg[] = "Alias:\t";
      int cou = -1;
      while (hent->h_aliases[++cou])
        {
          Sleep(0);
          if (!ol.BufSend(s, cAliasMsg, sizeof(cAliasMsg)-1))
            {
              h_perror();
              return (DWORD)-1;
            }
          if (!ol.BufSend(s, hent->h_aliases[cou],
			  (DWORD) strlen(hent->h_aliases[cou])))
            {
              h_perror();
              return (DWORD)-1;
            }
          if (!ol.BufSend(s, "\n", 1))
            {
              h_perror();
              return (DWORD)-1;
            }
        }

      const char cIPMsg[] = "IP:\t";
      cou = 0;
      while (hent->h_addr_list[cou])
        {
          Sleep(0);
          if (!ol.BufSend(s, cIPMsg, sizeof(cIPMsg)-1))
            {
              h_perror();
              return (DWORD)-1;
            }
          char *IPAlias = inet_ntoa(*(in_addr*)hent->h_addr_list[cou++]);
          if (!ol.BufSend(s, IPAlias, (DWORD) strlen(IPAlias)))
            {
              h_perror();
              return (DWORD)-1;
            }
          if (!ol.BufSend(s, "\n", 1))
            {
              h_perror();
              return (DWORD)-1;
            }
        }
    }

  const char cHeaderMsg[] = "\nClient headers:\n";
  if (!ol.BufSend(s, cHeaderMsg, sizeof(cHeaderMsg)-1))
    {
      h_perror();
      return (DWORD)-1;
    }

  for(;;)
    {
      Sleep(0);

      char recvbuf[MAX_LINE_LENGTH];
      int size_recv = recv((SOCKET)s, recvbuf, sizeof(recvbuf), 0);
      if (size_recv == SOCKET_ERROR)
        {
          h_perror();
          return (DWORD)-1;
        }

      if (size_recv < 1)
        break;

      if (!ol.BufSend(s, recvbuf, size_recv))
        {
          h_perror();
          return (DWORD)-1;
        }
    }

  shutdown((SOCKET)s, 0x01);
  return 0;
}