VirtualBox

Changeset 6999 in vbox for trunk/src/libs/xpcom18a4/ipc/ipcd


Ignore:
Timestamp:
Feb 18, 2008 4:46:28 PM (17 years ago)
Author:
vboxsync
Message:

XPCOM/IPC/DConnect: Serialize/deserialize out/retval method params in case of warning result codes too (regression of r28156). Don't replace warning error codes with NS_OK on the caller's side by deserialization of out/retval params.

Location:
trunk/src/libs/xpcom18a4/ipc/ipcd/extensions/dconnect/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/libs/xpcom18a4/ipc/ipcd/extensions/dconnect/src/ipcDConnectService.cpp

    r6974 r6999  
    8888
    8989//
    90 // +--------------------------------+
    91 // | opcode : 1 byte                |
    92 // +--------------------------------+
    93 // | flags  : 1 byte                |
    94 // +--------------------------------+
    95 // .                                .
    96 // . variable payload               .
    97 // .                                .
    98 // +--------------------------------+
     90// +--------------------------------------+
     91// | major opcode : 1 byte                |
     92// +--------------------------------------+
     93// | minor opcode : 1 byte                |
     94// +--------------------------------------+
     95// | flags        : 2 bytes               |
     96// +--------------------------------------+
     97// .                                      .
     98// . variable payload                     .
     99// .                                      .
     100// +--------------------------------------+
    99101//
    100102
     
    117119// dconnect minor opcodes for INVOKE
    118120
     121// DCON_OP_SETUP_REPLY and DCON_OP_INVOKE_REPLY flags
     122#define DCON_OP_FLAGS_REPLY_EXCEPTION   0x0001
     123
    119124#pragma pack(1)
    120125
     
    123128  PRUint8  opcode_major;
    124129  PRUint8  opcode_minor;
     130  PRUint16 flags;
    125131  PRUint32 request_index; // initialized with NewRequestIndex
    126132};
     
    154160  DConAddr instance;
    155161  nsresult status;
    156   // followed by a specially serialized nsIException instance if
    157   // NS_FAILED(status) (see ipcDConnectService::SerializeException)
     162  // optionally followed by a specially serialized nsIException instance (see
     163  // ipcDConnectService::SerializeException) if DCON_OP_FLAGS_REPLY_EXCEPTION is
     164  // present in flags
    158165};
    159166
     
    179186{
    180187  nsresult result;
    181   // followed by an array of out-param blobs if NS_SUCCEEDED(result), or by a
    182   // specially serialized nsIException instance if NS_FAILED(result)
    183   // (see ipcDConnectService::SerializeException)
     188  // followed by an array of out-param blobs if NS_SUCCEEDED(result), and
     189  // optionally by a specially serialized nsIException instance (see
     190  // ipcDConnectService::SerializeException) if DCON_OP_FLAGS_REPLY_EXCEPTION is
     191  // present in flags
    184192};
    185193
     
    19631971
    19641972nsresult
    1965 ipcDConnectService::DeserializeException(const PRUint8 *data,
    1966                                          PRUint32 dataLen,
     1973ipcDConnectService::DeserializeException(ipcMessageReader &reader,
    19671974                                         PRUint32 peer,
    19681975                                         nsIException **xcpt)
     
    19711978  if (!xcpt)
    19721979    return NS_ERROR_INVALID_POINTER;
    1973 
    1974   ipcMessageReader reader(data, dataLen);
    19751980
    19761981  nsresult rv;
     
    21542159        msg.opcode_major = DCON_OP_RELEASE;
    21552160        msg.opcode_minor = 0;
     2161        msg.flags = 0;
    21562162        msg.request_index = 0; // not used, set to some unused value
    21572163        msg.instance = mInstance;
     
    23672373  invoke.opcode_major = DCON_OP_INVOKE;
    23682374  invoke.opcode_minor = 0;
     2375  invoke.flags = 0;
    23692376  invoke.request_index = NewRequestIndex();
    23702377  invoke.instance = mInstance;
     
    24662473  while (completion.IsPending());
    24672474
     2475  ipcMessageReader reader(completion.Params(), completion.ParamsLen());
     2476
    24682477  rv = completion.GetResult();
    2469   if (rv != NS_OK)
    2470   {
    2471     NS_ASSERTION(completion.ParamsLen() == 0 ||
    2472                  completion.ParamsLen() >= sizeof(void*),
    2473                  "invalid nsIException serialization length");
    2474     if (completion.ParamsLen() >= sizeof(void*))
    2475     {
    2476       LOG(("got nsIException instance (%p), will create a stub\n",
    2477            *((void **) completion.Params())));
    2478 
    2479       nsIException *xcpt = nsnull;
    2480       nsresult rv2; // preserve rv for returning to the caller
    2481       rv2 = dConnect->DeserializeException (completion.Params(),
    2482                                             completion.ParamsLen(),
    2483                                             mPeerID, &xcpt);
    2484       if (NS_SUCCEEDED(rv2))
    2485       {
    2486         rv2 = em->SetCurrentException(xcpt);
    2487         NS_IF_RELEASE(xcpt);
    2488       }
    2489       NS_ASSERTION(NS_SUCCEEDED(rv2), "failed to deserialize/set exception");
    2490     }
    2491   }
    2492   else if (completion.ParamsLen() > 0)
    2493   {
    2494     ipcMessageReader reader(completion.Params(), completion.ParamsLen());
    2495 
     2478  if (NS_SUCCEEDED(rv))
     2479  {
    24962480    PRUint8 i;
    24972481
     
    25292513          if (NS_SUCCEEDED(rv))
    25302514          {
    2531               nsISupports *obj = nsnull;
    2532               rv = dConnect->DeserializeInterfaceParamBits(bits, mPeerID, iid, obj);
    2533               if (NS_SUCCEEDED(rv))
    2534                 *pptr = obj;
     2515            nsISupports *obj = nsnull;
     2516            rv = dConnect->DeserializeInterfaceParamBits(bits, mPeerID, iid, obj);
     2517            if (NS_SUCCEEDED(rv))
     2518              *pptr = obj;
    25352519          }
    25362520        }
     
    25482532  }
    25492533
    2550   return rv;
     2534  if (completion.Reply()->flags & DCON_OP_FLAGS_REPLY_EXCEPTION)
     2535  {
     2536    LOG(("got nsIException instance, will create a stub\n"));
     2537
     2538    nsIException *xcpt = nsnull;
     2539    rv = dConnect->DeserializeException (reader, mPeerID, &xcpt);
     2540    if (NS_SUCCEEDED(rv))
     2541    {
     2542      rv = em->SetCurrentException(xcpt);
     2543      NS_IF_RELEASE(xcpt);
     2544    }
     2545    NS_ASSERTION(NS_SUCCEEDED(rv), "failed to deserialize/set exception");
     2546  }
     2547
     2548  return NS_SUCCEEDED(rv) ? completion.GetResult() : rv;
    25512549}
    25522550
     
    25822580    LOG(("got SETUP_REPLY: status=%x instance=%p\n", reply->status, reply->instance));
    25832581
    2584     if (reply->status != NS_OK)
    2585     {
    2586       mStatus = reply->status;
    2587 
    2588       const PRUint8 *params = ((const PRUint8 *) op) + sizeof (DConnectSetupReply);
    2589       const PRUint32 paramsLen = opLen - sizeof (DConnectSetupReply);
    2590 
    2591       NS_ASSERTION(paramsLen == 0 || paramsLen >= sizeof(void*),
    2592                    "invalid nsIException serialization length");
    2593       if (paramsLen >= sizeof(void*))
    2594       {
    2595         LOG(("got nsIException instance (%p), will create a stub\n",
    2596              *((void **) params)));
    2597 
    2598         nsresult rv;
    2599         nsCOMPtr <nsIExceptionService> es;
    2600         es = do_GetService (NS_EXCEPTIONSERVICE_CONTRACTID, &rv);
    2601         if (NS_SUCCEEDED(rv))
    2602         {
    2603           nsCOMPtr <nsIExceptionManager> em;
    2604           rv = es->GetCurrentExceptionManager (getter_AddRefs(em));
    2605           if (NS_SUCCEEDED(rv))
    2606           {
    2607             // ensure ipcDConnectService is not deleted before we finish
    2608             nsRefPtr <ipcDConnectService> dConnect (ipcDConnectService::GetInstance());
    2609             if (dConnect)
    2610             {
    2611               nsIException *xcpt = nsnull;
    2612               rv = dConnect->DeserializeException (params, paramsLen,
    2613                                                    sender, &xcpt);
    2614               if (NS_SUCCEEDED(rv))
    2615               {
    2616                 rv = em->SetCurrentException(xcpt);
    2617                 NS_IF_RELEASE(xcpt);
    2618               }
    2619             }
    2620             else
    2621               rv = NS_ERROR_UNEXPECTED;
    2622           }
    2623         }
    2624         NS_ASSERTION(NS_SUCCEEDED(rv), "failed to deserialize/set exception");
    2625       }
    2626     }
    2627     else
     2582    mStatus = reply->status;
     2583
     2584    if (NS_SUCCEEDED(reply->status))
    26282585    {
    26292586      // ensure ipcDConnectService is not deleted before we finish
     
    26382595        mStatus = rv;
    26392596    }
     2597
     2598    if (reply->flags & DCON_OP_FLAGS_REPLY_EXCEPTION)
     2599    {
     2600      const PRUint8 *params = ((const PRUint8 *) op) + sizeof (DConnectSetupReply);
     2601      const PRUint32 paramsLen = opLen - sizeof (DConnectSetupReply);
     2602
     2603      ipcMessageReader reader(params, paramsLen);
     2604
     2605      LOG(("got nsIException instance, will create a stub\n"));
     2606
     2607      nsresult rv;
     2608      nsCOMPtr <nsIExceptionService> es;
     2609      es = do_GetService (NS_EXCEPTIONSERVICE_CONTRACTID, &rv);
     2610      if (NS_SUCCEEDED(rv))
     2611      {
     2612        nsCOMPtr <nsIExceptionManager> em;
     2613        rv = es->GetCurrentExceptionManager (getter_AddRefs(em));
     2614        if (NS_SUCCEEDED(rv))
     2615        {
     2616          // ensure ipcDConnectService is not deleted before we finish
     2617          nsRefPtr <ipcDConnectService> dConnect (ipcDConnectService::GetInstance());
     2618          if (dConnect)
     2619          {
     2620            nsIException *xcpt = nsnull;
     2621            rv = dConnect->DeserializeException (reader, sender, &xcpt);
     2622            if (NS_SUCCEEDED(rv))
     2623            {
     2624              rv = em->SetCurrentException(xcpt);
     2625              NS_IF_RELEASE(xcpt);
     2626            }
     2627          }
     2628          else
     2629            rv = NS_ERROR_UNEXPECTED;
     2630        }
     2631      }
     2632      NS_ASSERTION(NS_SUCCEEDED(rv), "failed to deserialize/set exception");
     2633      if (NS_FAILED(rv))
     2634        mStatus = rv;
     2635    }
    26402636  }
    26412637
     
    26652661
    26662662  aMsg->opcode_major = DCON_OP_SETUP;
     2663  aMsg->flags = 0;
    26672664  aMsg->request_index = NewRequestIndex();
    26682665
     
    26882685  {
    26892686    rv = IPC_WaitMessage(IPC_SENDER_ANY, kDConnectTargetID,
    2690                         &completion.GetSelector(), &completion,
     2687                        &completion.GetSelector(), &completion,
    26912688                         DCON_WAIT_TIMEOUT);
    26922689    if (NS_FAILED(rv))
     
    35213518  NS_IF_RELEASE(instance);
    35223519
     3520  nsCOMPtr <nsIException> exception;
     3521  PRBool got_exception = PR_FALSE;
     3522
     3523  if (rv != NS_OK)
     3524  {
     3525    // try to fetch an nsIException possibly set by one of the setup methods
     3526    nsresult rv2;
     3527    nsCOMPtr <nsIExceptionService> es;
     3528    es = do_GetService(NS_EXCEPTIONSERVICE_CONTRACTID, &rv2);
     3529    if (NS_SUCCEEDED(rv2))
     3530    {
     3531      nsCOMPtr <nsIExceptionManager> em;
     3532      rv2 = es->GetCurrentExceptionManager (getter_AddRefs (em));
     3533      if (NS_SUCCEEDED(rv2))
     3534      {
     3535        nsCOMPtr <nsIException> exception;
     3536        rv2 = em->GetCurrentException (getter_AddRefs (exception));
     3537        if (NS_SUCCEEDED(rv2))
     3538        {
     3539          LOG(("got nsIException instance, will serialize\n"));
     3540          got_exception = PR_TRUE;
     3541        }
     3542      }
     3543    }
     3544    NS_ASSERTION(NS_SUCCEEDED(rv2), "failed to get/serialize exception");
     3545    if (NS_FAILED(rv2))
     3546      rv = rv2;
     3547  }
     3548
    35233549  ipcMessageWriter writer(64);
    35243550
     
    35263552  msg.opcode_major = DCON_OP_SETUP_REPLY;
    35273553  msg.opcode_minor = 0;
     3554  msg.flags = 0;
    35283555  msg.request_index = setup->request_index;
    35293556  msg.instance = wrapper;
    35303557  msg.status = rv;
    35313558
     3559  if (got_exception)
     3560    msg.flags |= DCON_OP_FLAGS_REPLY_EXCEPTION;
     3561
    35323562  writer.PutBytes(&msg, sizeof(msg));
    35333563
    3534   if (rv != NS_OK)
    3535   {
    3536     // try to fetch an nsIException possibly set by one of the setup methods
    3537     // and send it instead of the failed instance (even if it is null)
    3538     nsCOMPtr <nsIExceptionService> es;
    3539     es = do_GetService(NS_EXCEPTIONSERVICE_CONTRACTID, &rv);
    3540     if (NS_SUCCEEDED(rv))
    3541     {
    3542       nsCOMPtr <nsIExceptionManager> em;
    3543       rv = es->GetCurrentExceptionManager (getter_AddRefs (em));
    3544       if (NS_SUCCEEDED(rv))
    3545       {
    3546         nsCOMPtr <nsIException> exception;
    3547         rv = em->GetCurrentException (getter_AddRefs (exception));
    3548         if (NS_SUCCEEDED(rv))
    3549         {
    3550           LOG(("got nsIException instance (%p), will serialize\n",
    3551                (nsIException *)exception));
    3552 
    3553           rv = SerializeException(writer, peer, exception, wrappers);
    3554         }
    3555       }
    3556     }
    3557     NS_ASSERTION(NS_SUCCEEDED(rv), "failed to get/serialze exception");
     3564  if (got_exception)
     3565  {
     3566    rv = SerializeException(writer, peer, exception, wrappers);
     3567    NS_ASSERTION(NS_SUCCEEDED(rv), "failed to get/serialize exception");
    35583568  }
    35593569
     
    37313741  {
    37323742    // try to fetch an nsIException possibly set by the method
    3733     nsresult invoke_rv = rv;
     3743    nsresult rv2;
    37343744    nsCOMPtr <nsIExceptionService> es;
    3735     es = do_GetService(NS_EXCEPTIONSERVICE_CONTRACTID, &rv);
    3736     if (NS_SUCCEEDED(rv))
     3745    es = do_GetService(NS_EXCEPTIONSERVICE_CONTRACTID, &rv2);
     3746    if (NS_SUCCEEDED(rv2))
    37373747    {
    37383748      nsCOMPtr <nsIExceptionManager> em;
    3739       rv = es->GetCurrentExceptionManager (getter_AddRefs (em));
    3740       if (NS_SUCCEEDED(rv))
    3741       {
    3742         rv = em->GetCurrentException (getter_AddRefs (exception));
    3743         if (NS_SUCCEEDED(rv))
     3749      rv2 = es->GetCurrentExceptionManager (getter_AddRefs (em));
     3750      if (NS_SUCCEEDED(rv2))
     3751      {
     3752        rv2 = em->GetCurrentException (getter_AddRefs (exception));
     3753        if (NS_SUCCEEDED(rv2))
    37443754        {
    3745           LOG(("got nsIException instance (%p), will serialize\n",
    3746                (nsIException *)exception));
     3755          LOG(("got nsIException instance, will serialize\n"));
    37473756          got_exception = PR_TRUE;
    3748           // restore the method's result
    3749           rv = invoke_rv;
    37503757        }
    37513758      }
    37523759    }
     3760    NS_ASSERTION(NS_SUCCEEDED(rv2), "failed to get/serialize exception");
     3761    if (NS_FAILED(rv2))
     3762      rv = rv2;
    37533763  }
    37543764
     
    37653775  reply.opcode_major = DCON_OP_INVOKE_REPLY;
    37663776  reply.opcode_minor = 0;
     3777  reply.flags = 0;
    37673778  reply.request_index = invoke->request_index;
    37683779  reply.result = rv;
    37693780
     3781  if (got_exception)
     3782    reply.flags |= DCON_OP_FLAGS_REPLY_EXCEPTION;
     3783
    37703784  writer.PutBytes(&reply, sizeof(reply));
    37713785
    37723786  nsVoidArray wrappers;
    37733787
    3774   if (got_exception)
    3775   {
    3776     rv = SerializeException(writer, peer, exception, wrappers);
    3777     NS_ASSERTION(NS_SUCCEEDED(rv), "failed to get/serialze exception");
    3778   }
    3779   else if (NS_SUCCEEDED(rv) && params)
     3788  if (NS_SUCCEEDED(rv) && params)
    37803789  {
    37813790    // serialize out-params and retvals
     
    38333842  }
    38343843
     3844  if (got_exception)
     3845  {
     3846    rv = SerializeException(writer, peer, exception, wrappers);
     3847    NS_ASSERTION(NS_SUCCEEDED(rv), "failed to get/serialize exception");
     3848  }
     3849
    38353850  if (NS_FAILED(rv))
    38363851    rv = IPC_SendMessage(peer, kDConnectTargetID, (const PRUint8 *) &reply, sizeof(reply));
  • trunk/src/libs/xpcom18a4/ipc/ipcd/extensions/dconnect/src/ipcDConnectService.h

    r6850 r6999  
    8383
    8484class nsIException;
     85class ipcMessageReader;
    8586class ipcMessageWriter;
    8687
     
    231232                                          PRUint32 peer, nsIException *xcpt,
    232233                                          nsVoidArray &wrappers);
    233   NS_HIDDEN_(nsresult) DeserializeException(const PRUint8 *data, PRUint32 dataLen,
     234  NS_HIDDEN_(nsresult) DeserializeException(ipcMessageReader &reader,
    234235                                            PRUint32 peer, nsIException **xcpt);
    235236
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette