Пример #1
0
Bool
RpcOut_send(RpcOut *out,         // IN
            char const *request, // IN
            size_t reqLen,       // IN
            char const **reply,  // OUT
            size_t *repLen)      // OUT
{
    unsigned char *myReply;
    size_t myRepLen;
    Bool success;

    ASSERT(out);

    ASSERT(out->channel);

    if (out->channel == NULL) {
        *reply = "RpcOut: Channel is not active";
        *repLen = strlen(*reply);

        return FALSE;
    }

    if (Message_Send(out->channel, (const unsigned char *)request, reqLen) == FALSE) {
        *reply = "RpcOut: Unable to send the RPCI command";
        *repLen = strlen(*reply);

        return FALSE;
    }

    if (Message_Receive(out->channel, &myReply, &myRepLen) == FALSE) {
        *reply = "RpcOut: Unable to receive the result of the RPCI command";
        *repLen = strlen(*reply);

        return FALSE;
    }

    if (myRepLen < 2
            || (   (success = strncmp((const char *)myReply, "1 ", 2) == 0) == FALSE
                   && strncmp((const char *)myReply, "0 ", 2))) {
        *reply = "RpcOut: Invalid format for the result of the RPCI command";
        *repLen = strlen(*reply);

        return FALSE;
    }

    *reply = ((const char *)myReply) + 2;
    *repLen = myRepLen - 2;

    return success;
}
Пример #2
0
static gboolean
#else
static Bool
#endif
RpcInLoop(void *clientData) // IN
{
   RpcIn *in;
   char const *errmsg = NULL;
   char const *reply;
   size_t repLen;
   Bool resched = FALSE;

#if defined(VMTOOLS_USE_GLIB)
   unsigned int current;
#endif

   in = (RpcIn *)clientData;
   ASSERT(in);
   ASSERT(in->nextEvent);
   ASSERT(in->channel);
   ASSERT(in->mustSend);

#if defined(VMTOOLS_USE_GLIB)
   current = in->delay;
#else
   /*
    * The event has fired: it is no longer valid. Note that this is
    * not true in the glib case!
    */
   in->nextEvent = NULL;
#endif

   in->inLoop = TRUE;

   /*
    * Workaround for bug 780404. Remove if we ever figure out the root cause.
    * Note that the ASSERT above catches this on non-release builds.
    */
   if (in->channel == NULL) {
      errmsg = "RpcIn: Channel is not active";
      goto error;
   }

   /*
    * This is very important: this is the only way to signal the existence of
    * this guest application to VMware.
    */
   if (RpcInSend(in, 0) == FALSE) {
      errmsg = "RpcIn: Unable to send";
      goto error;
   }

   if (Message_Receive(in->channel, (unsigned char **)&reply, &repLen) == FALSE) {
      errmsg = "RpcIn: Unable to receive";
      goto error;
   }

   if (repLen) {
      if (!RpcInExecRpc(in, reply, repLen, &errmsg)) {
         goto error;
      }
   } else {
      /*
       * Nothing to execute
       */

      /* No request -> No result */
      ASSERT(in->last_result == NULL);
      ASSERT(in->last_resultLen == 0);

      RpcInUpdateDelayTime(in);
   }

   ASSERT(in->mustSend == FALSE);
   in->mustSend = TRUE;

   if (!in->shouldStop) {
      Bool needResched = TRUE;
#if defined(VMTOOLS_USE_GLIB)
      resched = in->delay != current;
      needResched = resched;
#endif
      if (needResched && !RpcInScheduleRecvEvent(in)) {
         errmsg = "RpcIn: Unable to run the loop";
         goto error;
      }
   }

exit:
   if (in->shouldStop) {
      RpcInStop(in);
      in->shouldStop = FALSE;
#if defined(VMTOOLS_USE_GLIB)
      /* Force the GMainContext to unref the GSource that runs the RpcIn loop. */
      resched = TRUE;
#endif
   }

   in->inLoop = FALSE;

   return !resched;

error:
   /* Call the error routine */
   (*in->errorFunc)(in->errorData, errmsg);
   in->shouldStop = TRUE;
   goto exit;
}