75
77
/** Default constructor */
76
Property() : mTimestamp(0), mFlags(NILFLAG) {}
78
Property() : mTimestamp(0), mFlags(NILFLAG)
77
82
/** Constructor with const char * */
78
83
Property(const char *pcszName, const char *pcszValue,
79
84
uint64_t u64Timestamp, uint32_t u32Flags)
80
85
: mName(pcszName), mValue(pcszValue), mTimestamp(u64Timestamp),
89
mStrCore.pszString = mName.c_str();
82
91
/** Constructor with std::string */
83
92
Property(std::string name, std::string value, uint64_t u64Timestamp,
287
312
* @copydoc VBOXHGCMSVCHELPERS::pfnCall
288
313
* Wraps to the call member function
290
static DECLCALLBACK(void) svcCall (void * pvService,
291
VBOXHGCMCALLHANDLE callHandle,
292
uint32_t u32ClientID,
294
uint32_t u32Function,
296
VBOXHGCMSVCPARM paParms[])
315
static DECLCALLBACK(void) svcCall(void * pvService,
316
VBOXHGCMCALLHANDLE callHandle,
317
uint32_t u32ClientID,
319
uint32_t u32Function,
321
VBOXHGCMSVCPARM paParms[])
298
323
AssertLogRelReturnVoid(VALID_PTR(pvService));
299
LogFlowFunc (("pvService=%p, callHandle=%p, u32ClientID=%u, pvClient=%p, u32Function=%u, cParms=%u, paParms=%p\n", pvService, callHandle, u32ClientID, pvClient, u32Function, cParms, paParms));
324
LogFlowFunc(("pvService=%p, callHandle=%p, u32ClientID=%u, pvClient=%p, u32Function=%u, cParms=%u, paParms=%p\n", pvService, callHandle, u32ClientID, pvClient, u32Function, cParms, paParms));
300
325
SELF *pSelf = reinterpret_cast<SELF *>(pvService);
301
326
pSelf->call(callHandle, u32ClientID, pvClient, u32Function, cParms, paParms);
302
LogFlowFunc (("returning\n"));
327
LogFlowFunc(("returning\n"));
306
331
* @copydoc VBOXHGCMSVCHELPERS::pfnHostCall
307
332
* Wraps to the hostCall member function
309
static DECLCALLBACK(int) svcHostCall (void *pvService,
310
uint32_t u32Function,
312
VBOXHGCMSVCPARM paParms[])
334
static DECLCALLBACK(int) svcHostCall(void *pvService,
335
uint32_t u32Function,
337
VBOXHGCMSVCPARM paParms[])
314
339
AssertLogRelReturn(VALID_PTR(pvService), VERR_INVALID_PARAMETER);
315
LogFlowFunc (("pvService=%p, u32Function=%u, cParms=%u, paParms=%p\n", pvService, u32Function, cParms, paParms));
340
LogFlowFunc(("pvService=%p, u32Function=%u, cParms=%u, paParms=%p\n", pvService, u32Function, cParms, paParms));
316
341
SELF *pSelf = reinterpret_cast<SELF *>(pvService);
317
342
int rc = pSelf->hostCall(u32Function, cParms, paParms);
318
LogFlowFunc (("rc=%Rrc\n", rc));
343
LogFlowFunc(("rc=%Rrc\n", rc));
352
377
int notifyHost(const char *pszName, const char *pszValue,
353
378
uint64_t u64Timestamp, const char *pszFlags);
355
void call (VBOXHGCMCALLHANDLE callHandle, uint32_t u32ClientID,
356
void *pvClient, uint32_t eFunction, uint32_t cParms,
357
VBOXHGCMSVCPARM paParms[]);
358
int hostCall (uint32_t eFunction, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
380
void call(VBOXHGCMCALLHANDLE callHandle, uint32_t u32ClientID,
381
void *pvClient, uint32_t eFunction, uint32_t cParms,
382
VBOXHGCMSVCPARM paParms[]);
383
int hostCall(uint32_t eFunction, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
442
467
int Service::setPropertyBlock(uint32_t cParms, VBOXHGCMSVCPARM paParms[])
444
char **ppNames, **ppValues, **ppFlags;
445
uint64_t *pTimestamps;
447
int rc = VINF_SUCCESS;
469
const char **papszNames;
470
const char **papszValues;
471
const char **papszFlags;
472
uint64_t *pau64Timestamps;
474
int rc = VINF_SUCCESS;
450
477
* Get and validate the parameters
453
|| RT_FAILURE(paParms[0].getPointer ((void **) &ppNames, &cbDummy))
454
|| RT_FAILURE(paParms[1].getPointer ((void **) &ppValues, &cbDummy))
455
|| RT_FAILURE(paParms[2].getPointer ((void **) &pTimestamps, &cbDummy))
456
|| RT_FAILURE(paParms[3].getPointer ((void **) &ppFlags, &cbDummy))
480
|| RT_FAILURE(paParms[0].getPointer((void **)&papszNames, &cbDummy))
481
|| RT_FAILURE(paParms[1].getPointer((void **)&papszValues, &cbDummy))
482
|| RT_FAILURE(paParms[2].getPointer((void **)&pau64Timestamps, &cbDummy))
483
|| RT_FAILURE(paParms[3].getPointer((void **)&papszFlags, &cbDummy))
458
485
rc = VERR_INVALID_PARAMETER;
461
* Add the properties to the end of the list. If we succeed then we
462
* will remove duplicates afterwards.
464
/* Remember the last property before we started adding, for rollback or
466
PropertyList::iterator itEnd = mProperties.end();
467
if (!mProperties.empty())
471
for (unsigned i = 0; RT_SUCCESS(rc) && ppNames[i] != NULL; ++i)
486
/** @todo validate the array sizes... */
488
for (unsigned i = 0; RT_SUCCESS(rc) && papszNames[i] != NULL; ++i)
490
if ( !RT_VALID_PTR(papszNames[i])
491
|| !RT_VALID_PTR(papszValues[i])
492
|| !RT_VALID_PTR(papszFlags[i])
494
rc = VERR_INVALID_POINTER;
498
rc = validateFlags(papszFlags[i], &fFlagsIgn);
505
* Add the properties. No way to roll back here.
507
for (unsigned i = 0; papszNames[i] != NULL; ++i)
474
if ( !VALID_PTR(ppNames[i])
475
|| !VALID_PTR(ppValues[i])
476
|| !VALID_PTR(ppFlags[i])
478
rc = VERR_INVALID_POINTER;
480
rc = validateFlags(ppFlags[i], &fFlags);
482
mProperties.push_back(Property(ppNames[i], ppValues[i],
483
pTimestamps[i], fFlags));
486
catch (std::bad_alloc)
510
rc = validateFlags(papszFlags[i], &fFlags);
492
* If all went well then remove the duplicate elements.
494
if (RT_SUCCESS(rc) && itEnd != mProperties.end())
497
for (unsigned i = 0; ppNames[i] != NULL; ++i)
498
for (PropertyList::iterator it = mProperties.begin(); it != itEnd; ++it)
499
if (it->mName.compare(ppNames[i]) == 0)
513
Property *pProp = getPropertyInternal(papszNames[i]);
516
/* Update existing property. */
517
pProp->mValue = papszValues[i];
518
pProp->mTimestamp = pau64Timestamps[i];
519
pProp->mFlags = fFlags;
523
/* Create a new property */
524
pProp = new Property(papszNames[i], papszValues[i], pau64Timestamps[i], fFlags);
501
mProperties.erase(it);
530
if (RTStrSpaceInsert(&mhProperties, &pProp->mStrCore))
535
rc = VERR_INTERNAL_ERROR_3;
507
* If something went wrong then rollback. This is possible because we
508
* haven't deleted anything yet.
512
if (itEnd != mProperties.end())
514
mProperties.erase(itEnd, mProperties.end());
531
557
int Service::getProperty(uint32_t cParms, VBOXHGCMSVCPARM paParms[])
533
int rc = VINF_SUCCESS;
534
560
const char *pcszName = NULL; /* shut up gcc */
536
uint32_t cchName, cchBuf;
537
char szFlags[MAX_FLAGS_LEN];
562
uint32_t cbName, cbBuf;
540
565
* Get and validate the parameters
542
567
LogFlowThisFunc(("\n"));
543
568
if ( cParms != 4 /* Hardcoded value as the next lines depend on it. */
544
|| RT_FAILURE (paParms[0].getString(&pcszName, &cchName)) /* name */
545
|| RT_FAILURE (paParms[1].getBuffer((void **) &pchBuf, &cchBuf)) /* buffer */
569
|| RT_FAILURE(paParms[0].getString(&pcszName, &cbName)) /* name */
570
|| RT_FAILURE(paParms[1].getBuffer((void **)&pchBuf, &cbBuf)) /* buffer */
547
572
rc = VERR_INVALID_PARAMETER;
549
rc = validateName(pcszName, cchName);
574
rc = validateName(pcszName, cbName);
577
LogFlowThisFunc(("rc = %Rrc\n", rc));
552
582
* Read and set the values we will return
555
/* Get the value size */
556
PropertyList::const_iterator it;
585
/* Get the property. */
586
Property *pProp = getPropertyInternal(pcszName);
589
char szFlags[MAX_FLAGS_LEN];
590
rc = writeFlags(pProp->mFlags, szFlags);
593
/* Check that the buffer is big enough */
594
size_t const cbFlags = strlen(szFlags) + 1;
595
size_t const cbValue = pProp->mValue.size() + 1;
596
size_t const cbNeeded = cbValue + cbFlags;
597
paParms[3].setUInt32((uint32_t)cbNeeded);
598
if (cbBuf >= cbNeeded)
600
/* Write the value, flags and timestamp */
601
memcpy(pchBuf, pProp->mValue.c_str(), cbValue);
602
memcpy(pchBuf + cbValue, szFlags, cbFlags);
604
paParms[2].setUInt64(pProp->mTimestamp);
607
* Done! Do exit logging and return.
609
Log2(("Queried string %s, value=%s, timestamp=%lld, flags=%s\n",
610
pcszName, pProp->mValue.c_str(), pProp->mTimestamp, szFlags));
613
rc = VERR_BUFFER_OVERFLOW;
559
617
rc = VERR_NOT_FOUND;
560
for (it = mProperties.begin(); it != mProperties.end(); ++it)
561
if (it->mName.compare(pcszName) == 0)
568
rc = writeFlags(it->mFlags, szFlags);
571
/* Check that the buffer is big enough */
572
size_t cchBufActual = it->mValue.size() + 1 + strlen(szFlags);
573
paParms[3].setUInt32 ((uint32_t)cchBufActual);
574
if (cchBufActual <= cchBuf)
576
/* Write the value, flags and timestamp */
577
it->mValue.copy(pchBuf, cchBuf, 0);
578
pchBuf[it->mValue.size()] = '\0'; /* Terminate the value */
579
strcpy(pchBuf + it->mValue.size() + 1, szFlags);
580
paParms[2].setUInt64 (it->mTimestamp);
583
* Done! Do exit logging and return.
585
Log2(("Queried string %s, value=%s, timestamp=%lld, flags=%s\n",
586
pcszName, it->mValue.c_str(), it->mTimestamp, szFlags));
589
rc = VERR_BUFFER_OVERFLOW;
592
LogFlowThisFunc(("rc = %Rrc\n", rc));
619
LogFlowThisFunc(("rc = %Rrc (%s)\n", rc, pcszName));
649
671
RTSTR_VALIDATE_ENCODING_ZERO_TERMINATED);
650
672
if ((3 == cParms) && RT_SUCCESS(rc))
651
673
rc = validateFlags(pcszFlags, &fFlags);
655
* If the property already exists, check its flags to see if we are allowed
658
PropertyList::iterator it;
660
for (it = mProperties.begin(); it != mProperties.end(); ++it)
661
if (it->mName.compare(pcszName) == 0)
667
rc = checkPermission(found ? (ePropFlags)it->mFlags : NILFLAG,
669
if (rc == VINF_SUCCESS)
672
* Set the actual value
676
it->mValue = pcszValue;
677
it->mTimestamp = u64TimeNano;
680
else /* This can throw. No problem as we have nothing to roll back. */
681
mProperties.push_back(Property(pcszName, pcszValue, u64TimeNano, fFlags));
684
* Send a notification to the host and return.
686
// if (isGuest) /* Notify the host even for properties that the host
687
// * changed. Less efficient, but ensures consistency. */
688
doNotifications(pcszName, u64TimeNano);
689
Log2(("Set string %s, rc=%Rrc, value=%s\n", pcszName, rc, pcszValue));
693
LogFlowThisFunc(("rc = %Rrc\n", rc));
676
LogFlowThisFunc(("rc = %Rrc\n", rc));
681
* If the property already exists, check its flags to see if we are allowed
684
Property *pProp = getPropertyInternal(pcszName);
685
rc = checkPermission(pProp ? (ePropFlags)pProp->mFlags : NILFLAG, isGuest);
686
if (rc == VINF_SUCCESS)
689
* Set the actual value
693
pProp->mValue = pcszValue;
694
pProp->mTimestamp = u64TimeNano;
695
pProp->mFlags = fFlags;
697
else if (mcProperties < MAX_PROPS)
699
/* Create a new string space record. */
700
pProp = new Property(pcszName, pcszValue, u64TimeNano, fFlags);
703
if (RTStrSpaceInsert(&mhProperties, &pProp->mStrCore))
709
rc = VERR_INTERNAL_ERROR_3;
716
rc = VERR_TOO_MUCH_DATA;
719
* Send a notification to the host and return.
721
// if (isGuest) /* Notify the host even for properties that the host
722
// * changed. Less efficient, but ensures consistency. */
723
doNotifications(pcszName, u64TimeNano);
724
Log2(("Set string %s, rc=%Rrc, value=%s\n", pcszName, rc, pcszValue));
727
LogFlowThisFunc(("rc = %Rrc (%s = %s)\n", rc, pcszName, pcszValue));
722
756
rc = validateName(pcszName, cbName);
724
758
rc = VERR_INVALID_PARAMETER;
728
* If the property exists, check its flags to see if we are allowed
731
PropertyList::iterator it;
733
for (it = mProperties.begin(); it != mProperties.end(); ++it)
734
if (it->mName.compare(pcszName) == 0)
737
rc = checkPermission((ePropFlags)it->mFlags, isGuest);
742
* And delete the property if all is well.
744
if (rc == VINF_SUCCESS && found)
746
uint64_t u64Timestamp = getCurrentTimestamp();
747
mProperties.erase(it);
748
// if (isGuest) /* Notify the host even for properties that the host
749
// * changed. Less efficient, but ensures consistency. */
750
doNotifications(pcszName, u64Timestamp);
754
LogFlowThisFunc(("rc = %Rrc\n", rc));
761
LogFlowThisFunc(("rc = %Rrc\n", rc));
766
* If the property exists, check its flags to see if we are allowed
769
Property *pProp = getPropertyInternal(pcszName);
771
rc = checkPermission((ePropFlags)pProp->mFlags, isGuest);
774
* And delete the property if all is well.
776
if (rc == VINF_SUCCESS && pProp)
778
uint64_t u64Timestamp = getCurrentTimestamp();
779
bool fRc = RTStrSpaceRemove(&mhProperties, pProp->mStrCore.pszString);
780
Assert(fRc); NOREF(fRc);
783
// if (isGuest) /* Notify the host even for properties that the host
784
// * changed. Less efficient, but ensures consistency. */
785
doNotifications(pcszName, u64Timestamp);
788
LogFlowThisFunc(("rc = %Rrc (%s)\n", rc, pcszName));
793
* Enumeration data shared between enumPropsCallback and Service::enumProps.
795
typedef struct EnumData
797
const char *pszPattern; /**< The pattern to match properties against. */
798
char *pchCur; /**< The current buffer postion. */
799
size_t cbLeft; /**< The amount of available buffer space. */
800
size_t cbNeeded; /**< The amount of needed buffer space. */
804
* @callback_method_impl{FNRTSTRSPACECALLBACK}
806
static DECLCALLBACK(int) enumPropsCallback(PRTSTRSPACECORE pStr, void *pvUser)
808
Property *pProp = (Property *)pStr;
809
EnumData *pEnum = (EnumData *)pvUser;
811
/* Included in the enumeration? */
812
if (!pProp->Matches(pEnum->pszPattern))
815
/* Convert the non-string members into strings. */
816
char szTimestamp[256];
817
size_t const cbTimestamp = RTStrFormatNumber(szTimestamp, pProp->mTimestamp, 10, 0, 0, 0) + 1;
819
char szFlags[MAX_FLAGS_LEN];
820
int rc = writeFlags(pProp->mFlags, szFlags);
823
size_t const cbFlags = strlen(szFlags) + 1;
825
/* Calculate the buffer space requirements. */
826
size_t const cbName = pProp->mName.length() + 1;
827
size_t const cbValue = pProp->mValue.length() + 1;
828
size_t const cbRequired = cbName + cbValue + cbTimestamp + cbFlags;
829
pEnum->cbNeeded += cbRequired;
831
/* Sufficient buffer space? */
832
if (cbRequired > pEnum->cbLeft)
835
return 0; /* don't quit */
837
pEnum->cbLeft -= cbRequired;
839
/* Append the property to the buffer. */
840
char *pchCur = pEnum->pchCur;
841
pEnum->pchCur += cbRequired;
843
memcpy(pchCur, pProp->mName.c_str(), cbName);
846
memcpy(pchCur, pProp->mValue.c_str(), cbValue);
849
memcpy(pchCur, szTimestamp, cbTimestamp);
850
pchCur += cbTimestamp;
852
memcpy(pchCur, szFlags, cbFlags);
855
Assert(pchCur == pEnum->pchCur);
759
860
* Enumerate guest properties by mask, checking the validity
760
861
* of the arguments passed.
772
873
* Get the HGCM function arguments.
774
char *pcchPatterns = NULL, *pchBuf = NULL;
775
uint32_t cchPatterns = 0, cchBuf = 0;
875
char const *pchPatterns = NULL;
877
uint32_t cbPatterns = 0;
776
879
LogFlowThisFunc(("\n"));
777
880
if ( (cParms != 3) /* Hardcoded value as the next lines depend on it. */
778
|| RT_FAILURE(paParms[0].getString(&pcchPatterns, &cchPatterns)) /* patterns */
779
|| RT_FAILURE(paParms[1].getBuffer((void **) &pchBuf, &cchBuf)) /* return buffer */
881
|| RT_FAILURE(paParms[0].getString(&pchPatterns, &cbPatterns)) /* patterns */
882
|| RT_FAILURE(paParms[1].getBuffer((void **)&pchBuf, &cbBuf)) /* return buffer */
781
884
rc = VERR_INVALID_PARAMETER;
782
if (RT_SUCCESS(rc) && cchPatterns > MAX_PATTERN_LEN)
885
if (RT_SUCCESS(rc) && cbPatterns > MAX_PATTERN_LEN)
783
886
rc = VERR_TOO_MUCH_DATA;
786
889
* First repack the patterns into the format expected by RTStrSimplePatternMatch()
788
char pszPatterns[MAX_PATTERN_LEN];
891
char szPatterns[MAX_PATTERN_LEN];
789
892
if (RT_SUCCESS(rc))
791
for (unsigned i = 0; i < cchPatterns - 1; ++i)
792
if (pcchPatterns[i] != '\0')
793
pszPatterns[i] = pcchPatterns[i];
894
for (unsigned i = 0; i < cbPatterns - 1; ++i)
895
if (pchPatterns[i] != '\0')
896
szPatterns[i] = pchPatterns[i];
795
pszPatterns[i] = '|';
796
pszPatterns[cchPatterns - 1] = '\0';
899
szPatterns[cbPatterns - 1] = '\0';
800
* Next enumerate into a temporary buffer. This can throw, but this is
801
* not a problem as we have nothing to roll back.
903
* Next enumerate into the buffer.
804
for (PropertyList::const_iterator it = mProperties.begin();
805
RT_SUCCESS(rc) && (it != mProperties.end()); ++it)
807
if (it->Matches(pszPatterns))
908
EnumData.pszPattern = szPatterns;
909
EnumData.pchCur = pchBuf;
910
EnumData.cbLeft = cbBuf;
911
EnumData.cbNeeded = 0;
912
rc = RTStrSpaceEnumerate(&mhProperties, enumPropsCallback, &EnumData);
809
char szFlags[MAX_FLAGS_LEN];
810
char szTimestamp[256];
811
uint32_t cchTimestamp;
814
buffer += it->mValue;
816
cchTimestamp = RTStrFormatNumber(szTimestamp, it->mTimestamp,
818
buffer.append(szTimestamp, cchTimestamp);
820
rc = writeFlags(it->mFlags, szFlags);
916
paParms[2].setUInt32((uint32_t)(EnumData.cbNeeded + 4));
917
if (EnumData.cbLeft >= 4)
919
/* The final terminators. */
920
EnumData.pchCur[0] = '\0';
921
EnumData.pchCur[1] = '\0';
922
EnumData.pchCur[2] = '\0';
923
EnumData.pchCur[3] = '\0';
926
rc = VERR_BUFFER_OVERFLOW;
827
buffer.append(4, '\0'); /* The final terminators */
830
* Finally write out the temporary buffer to the real one if it is not too
835
paParms[2].setUInt32 ((uint32_t)buffer.size());
836
/* Copy the memory if it fits into the guest buffer */
837
if (buffer.size() <= cchBuf)
838
buffer.copy(pchBuf, cchBuf);
840
rc = VERR_BUFFER_OVERFLOW;
998
1084
prop.mName = pszProperty;
999
1085
prop.mTimestamp = u64Timestamp;
1000
1086
/* prop is currently a delete event for pszProperty */
1003
for (PropertyList::const_iterator it = mProperties.begin();
1004
!found && it != mProperties.end(); ++it)
1005
if (it->mName.compare(pszProperty) == 0)
1008
/* Make prop into a change event. */
1009
prop.mValue = it->mValue;
1010
prop.mFlags = it->mFlags;
1087
Property const * const pProp = getPropertyInternal(pszProperty);
1090
/* Make prop into a change event. */
1091
prop.mValue = pProp->mValue;
1092
prop.mFlags = pProp->mFlags;
1014
1095
/* Release waiters if applicable and add the event to the queue for
1015
1096
* guest notifications */
1097
int rc = VINF_SUCCESS;
1100
CallList::iterator it = mGuestWaiters.begin();
1101
while (it != mGuestWaiters.end())
1020
CallList::iterator it = mGuestWaiters.begin();
1021
while (it != mGuestWaiters.end())
1103
const char *pszPatterns;
1104
uint32_t cchPatterns;
1105
it->mParms[0].getString(&pszPatterns, &cchPatterns);
1106
if (prop.Matches(pszPatterns))
1023
const char *pszPatterns;
1024
uint32_t cchPatterns;
1025
it->mParms[0].getString(&pszPatterns, &cchPatterns);
1026
if (prop.Matches(pszPatterns))
1028
GuestCall curCall = *it;
1029
int rc2 = getNotificationWriteOut(curCall.mParms, prop);
1030
if (RT_SUCCESS(rc2))
1032
mpHelpers->pfnCallComplete(curCall.mHandle, rc2);
1033
it = mGuestWaiters.erase(it);
1108
GuestCall curCall = *it;
1109
int rc2 = getNotificationWriteOut(curCall.mParms, prop);
1110
if (RT_SUCCESS(rc2))
1112
mpHelpers->pfnCallComplete(curCall.mHandle, rc2);
1113
it = mGuestWaiters.erase(it);
1038
mGuestNotifications.push_back(prop);
1040
catch (std::bad_alloc)
1042
rc = VERR_NO_MEMORY;
1118
mGuestNotifications.push_back(prop);
1120
catch (std::bad_alloc)
1122
rc = VERR_NO_MEMORY;
1045
1124
if (mGuestNotifications.size() > MAX_GUEST_NOTIFICATIONS)
1046
1125
mGuestNotifications.pop_front();
1084
1163
int Service::notifyHost(const char *pszName, const char *pszValue,
1085
1164
uint64_t u64Timestamp, const char *pszFlags)
1087
LogFlowFunc (("pszName=%s, pszValue=%s, u64Timestamp=%llu, pszFlags=%s\n",
1088
pszName, pszValue, u64Timestamp, pszFlags));
1166
LogFlowFunc(("pszName=%s, pszValue=%s, u64Timestamp=%llu, pszFlags=%s\n",
1167
pszName, pszValue, u64Timestamp, pszFlags));
1089
1168
HOSTCALLBACKDATA HostCallbackData;
1090
1169
HostCallbackData.u32Magic = HOSTCALLBACKMAGIC;
1091
1170
HostCallbackData.pcszName = pszName;
1268
1347
extern "C" DECLCALLBACK(DECLEXPORT(int)) VBoxHGCMSvcLoad (VBOXHGCMSVCFNTABLE *ptable)
1270
int rc = VINF_SUCCESS;
1349
int rc = VERR_IPE_UNINITIALIZED_STATUS;
1272
1351
LogFlowFunc(("ptable = %p\n", ptable));
1274
if (!VALID_PTR(ptable))
1353
if (!RT_VALID_PTR(ptable))
1276
1354
rc = VERR_INVALID_PARAMETER;
1280
1357
LogFlowFunc(("ptable->cbSize = %d, ptable->u32Version = 0x%08X\n", ptable->cbSize, ptable->u32Version));
1282
if ( ptable->cbSize != sizeof (VBOXHGCMSVCFNTABLE)
1359
if ( ptable->cbSize != sizeof(VBOXHGCMSVCFNTABLE)
1283
1360
|| ptable->u32Version != VBOX_HGCM_SVC_VERSION)
1285
1361
rc = VERR_VERSION_MISMATCH;
1289
std::auto_ptr<Service> apService;
1364
Service *pService = NULL;
1290
1365
/* No exceptions may propagate outside. */
1292
apService = std::auto_ptr<Service>(new Service(ptable->pHelpers));
1293
} catch (int rcThrown) {
1368
pService = new Service(ptable->pHelpers);
1371
catch (int rcThrown)
1296
rc = VERR_UNRESOLVED_ERROR;
1377
rc = VERR_UNEXPECTED_EXCEPTION;
1299
1380
if (RT_SUCCESS(rc))