/** * Implements the SUPDRV component factor interface query method. * * @returns Pointer to an interface. NULL if not supported. * * @param pSupDrvFactory Pointer to the component factory registration structure. * @param pSession The session - unused. * @param pszInterfaceUuid The factory interface id. */ static DECLCALLBACK(void *) vboxNetAdpQueryFactoryInterface(PCSUPDRVFACTORY pSupDrvFactory, PSUPDRVSESSION pSession, const char *pszInterfaceUuid) { PVBOXNETADPGLOBALS pGlobals = (PVBOXNETADPGLOBALS)((uint8_t *)pSupDrvFactory - RT_OFFSETOF(VBOXNETADPGLOBALS, SupDrvFactory)); /* * Convert the UUID strings and compare them. */ RTUUID UuidReq; int rc = RTUuidFromStr(&UuidReq, pszInterfaceUuid); if (RT_SUCCESS(rc)) { if (!RTUuidCompareStr(&UuidReq, INTNETTRUNKFACTORY_UUID_STR)) { ASMAtomicIncS32(&pGlobals->cFactoryRefs); return &pGlobals->TrunkFactory; } #ifdef LOG_ENABLED else Log(("VBoxNetAdp: unknown factory interface query (%s)\n", pszInterfaceUuid)); #endif } else Log(("VBoxNetAdp: rc=%Rrc, uuid=%s\n", rc, pszInterfaceUuid)); return NULL; }
/** Decode the content of the octet string value if known. */ static int rtCrSpcSerializedObject_DecodeMore(PRTASN1CURSOR pCursor, uint32_t fFlags, PRTCRSPCSERIALIZEDOBJECT pThis, const char *pszErrorTag) { RT_NOREF_PV(fFlags); RT_NOREF_PV(pszErrorTag); int rc; RTASN1CURSOR SubCursor; if (RTUuidCompareStr(pThis->Uuid.Asn1Core.uData.pUuid, RTCRSPCSERIALIZEDOBJECT_UUID_STR) == 0) { rc = RTAsn1MemAllocZ(&pThis->SerializedData.EncapsulatedAllocation, (void **)&pThis->u.pData, sizeof(*pThis->u.pData)); if (RT_SUCCESS(rc)) { pThis->SerializedData.pEncapsulated = (PRTASN1CORE)pThis->u.pData; pThis->enmType = RTCRSPCSERIALIZEDOBJECTTYPE_ATTRIBUTES; rc = RTAsn1CursorInitSubFromCore(pCursor, &pThis->SerializedData.Asn1Core, &SubCursor, "SerializedData"); if (RT_SUCCESS(rc)) rc = RTCrSpcSerializedObjectAttributes_DecodeAsn1(&SubCursor, 0, pThis->u.pData, "SD"); } } else return VINF_SUCCESS; if (RT_SUCCESS(rc)) rc = RTAsn1CursorCheckEnd(&SubCursor); return rc; }
RTCrSpcIndirectDataContent_GetPeImageObjAttrib(PCRTCRSPCINDIRECTDATACONTENT pThis, RTCRSPCSERIALIZEDOBJECTATTRIBUTETYPE enmType) { if (pThis->Data.enmType == RTCRSPCAAOVTYPE_PE_IMAGE_DATA) { Assert(RTAsn1ObjId_CompareWithString(&pThis->Data.Type, RTCRSPCPEIMAGEDATA_OID) == 0); if ( pThis->Data.uValue.pPeImage && pThis->Data.uValue.pPeImage->T0.File.enmChoice == RTCRSPCLINKCHOICE_MONIKER && RTCrSpcSerializedObject_IsPresent(pThis->Data.uValue.pPeImage->T0.File.u.pMoniker) ) { if (pThis->Data.uValue.pPeImage->T0.File.u.pMoniker->enmType == RTCRSPCSERIALIZEDOBJECTTYPE_ATTRIBUTES) { Assert(RTUuidCompareStr(pThis->Data.uValue.pPeImage->T0.File.u.pMoniker->Uuid.Asn1Core.uData.pUuid, RTCRSPCSERIALIZEDOBJECT_UUID_STR) == 0); PCRTCRSPCSERIALIZEDOBJECTATTRIBUTES pData = pThis->Data.uValue.pPeImage->T0.File.u.pMoniker->u.pData; if (pData) for (uint32_t i = 0; i < pData->cItems; i++) if (pData->paItems[i].enmType == enmType) return &pData->paItems[i]; } } } return NULL; }
/** * Implements the SUPDRV component factor interface query method. * * @returns Pointer to an interface. NULL if not supported. * * @param pSupDrvFactory Pointer to the component factory registration structure. * @param pSession The session - unused. * @param pszInterfaceUuid The factory interface id. */ static DECLCALLBACK(void *) vboxPciQueryFactoryInterface(PCSUPDRVFACTORY pSupDrvFactory, PSUPDRVSESSION pSession, const char *pszInterfaceUuid) { PVBOXRAWPCIGLOBALS pGlobals = (PVBOXRAWPCIGLOBALS)((uint8_t *)pSupDrvFactory - RT_OFFSETOF(VBOXRAWPCIGLOBALS, SupDrvFactory)); /* * Convert the UUID strings and compare them. */ RTUUID UuidReq; int rc = RTUuidFromStr(&UuidReq, pszInterfaceUuid); if (RT_SUCCESS(rc)) { if (!RTUuidCompareStr(&UuidReq, RAWPCIFACTORY_UUID_STR)) { ASMAtomicIncS32(&pGlobals->cFactoryRefs); return &pGlobals->RawPciFactory; } } else Log(("VBoxRawPci: rc=%Rrc, uuid=%s\n", rc, pszInterfaceUuid)); return NULL; }
int main(int argc, char **argv) { RTTEST hTest; int rc = RTTestInitAndCreate("tstRTUuid", &hTest); if (rc) return rc; RTTestBanner(hTest); #define CHECK_RC() \ do { if (RT_FAILURE(rc)) { RTTestFailed(hTest, "line %d: rc=%Rrc", __LINE__, rc); } } while (0) RTTestSub(hTest, "RTUuidClear & RTUuisIsNull"); RTUUID UuidNull; rc = RTUuidClear(&UuidNull); CHECK_RC(); RTTEST_CHECK(hTest, RTUuidIsNull(&UuidNull)); RTTEST_CHECK(hTest, RTUuidCompare(&UuidNull, &UuidNull) == 0); RTTestSub(hTest, "RTUuidCreate"); RTUUID Uuid; rc = RTUuidCreate(&Uuid); CHECK_RC(); RTTEST_CHECK(hTest, !RTUuidIsNull(&Uuid)); RTTEST_CHECK(hTest, RTUuidCompare(&Uuid, &Uuid) == 0); RTTEST_CHECK(hTest, RTUuidCompare(&Uuid, &UuidNull) > 0); RTTEST_CHECK(hTest, RTUuidCompare(&UuidNull, &Uuid) < 0); RTTestSub(hTest, "RTUuidToStr"); char sz[RTUUID_STR_LENGTH]; rc = RTUuidToStr(&Uuid, sz, sizeof(sz)); CHECK_RC(); RTTEST_CHECK(hTest, strlen(sz) == RTUUID_STR_LENGTH - 1); RTTestPrintf(hTest, RTTESTLVL_INFO, "UUID=%s\n", sz); RTTestSub(hTest, "RTUuidFromStr"); RTUUID Uuid2; rc = RTUuidFromStr(&Uuid2, sz); CHECK_RC(); RTTEST_CHECK(hTest, RTUuidCompare(&Uuid, &Uuid2) == 0); char *psz = (char *)RTTestGuardedAllocTail(hTest, RTUUID_STR_LENGTH); if (psz) { RTStrPrintf(psz, RTUUID_STR_LENGTH, "%s", sz); RTTESTI_CHECK_RC(RTUuidFromStr(&Uuid2, psz), VINF_SUCCESS); RTTEST_CHECK(hTest, RTUuidCompare(&Uuid, &Uuid2) == 0); for (unsigned off = 1; off < RTUUID_STR_LENGTH; off++) { char *psz2 = psz + off; RTStrPrintf(psz2, RTUUID_STR_LENGTH - off, "%s", sz); RTTESTI_CHECK_RC(RTUuidFromStr(&Uuid2, psz2), VERR_INVALID_UUID_FORMAT); } RTTestGuardedFree(hTest, psz); } RTUuidClear(&Uuid2); char sz2[RTUUID_STR_LENGTH + 2]; RTStrPrintf(sz2, sizeof(sz2), "{%s}", sz); rc = RTUuidFromStr(&Uuid2, sz2); CHECK_RC(); RTTEST_CHECK(hTest, RTUuidCompare(&Uuid, &Uuid2) == 0); psz = (char *)RTTestGuardedAllocTail(hTest, RTUUID_STR_LENGTH + 2); if (psz) { RTStrPrintf(psz, RTUUID_STR_LENGTH + 2, "{%s}", sz); RTTESTI_CHECK_RC(RTUuidFromStr(&Uuid2, psz), VINF_SUCCESS); RTTEST_CHECK(hTest, RTUuidCompare(&Uuid, &Uuid2) == 0); for (unsigned off = 1; off < RTUUID_STR_LENGTH + 2; off++) { char *psz2 = psz + off; RTStrPrintf(psz2, RTUUID_STR_LENGTH + 2 - off, "{%s}", sz); RTTESTI_CHECK_RC(RTUuidFromStr(&Uuid2, psz2), VERR_INVALID_UUID_FORMAT); } RTTestGuardedFree(hTest, psz); } RTTestSub(hTest, "RTUuidToUtf16"); RTUTF16 wsz[RTUUID_STR_LENGTH]; rc = RTUuidToUtf16(&Uuid, wsz, sizeof(wsz)); CHECK_RC(); RTTEST_CHECK(hTest, RTUtf16Len(wsz) == RTUUID_STR_LENGTH - 1); RTTestSub(hTest, "RTUuidFromUtf16"); rc = RTUuidFromUtf16(&Uuid2, wsz); CHECK_RC(); RTTEST_CHECK(hTest, RTUuidCompare(&Uuid, &Uuid2) == 0); RTUTF16 *pwsz; rc = RTStrToUtf16(sz2, &pwsz); RTTEST_CHECK(hTest, rc == VINF_SUCCESS); if (RT_SUCCESS(rc)) { RTTESTI_CHECK_RC(RTUuidFromUtf16(&Uuid2, pwsz), VINF_SUCCESS); RTTEST_CHECK(hTest, RTUuidCompare(&Uuid, &Uuid2) == 0); RTUTF16 *pwsz2 = (RTUTF16*)RTTestGuardedAllocTail(hTest, 2 * (RTUUID_STR_LENGTH + 2)); if (pwsz2) { memcpy(pwsz2, pwsz, 2 * (RTUUID_STR_LENGTH + 2)); RTTESTI_CHECK_RC(RTUuidFromUtf16(&Uuid2, pwsz2), VINF_SUCCESS); RTTEST_CHECK(hTest, RTUuidCompare(&Uuid, &Uuid2) == 0); for (unsigned off = 1; off < RTUUID_STR_LENGTH + 2; off++) { RTUTF16 *pwsz3 = pwsz2 + off; memcpy(pwsz3, pwsz, 2 * (RTUUID_STR_LENGTH + 1 - off)); pwsz3[RTUUID_STR_LENGTH + 1 - off] = 0; RTTESTI_CHECK_RC(RTUuidFromUtf16(&Uuid2, pwsz3), VERR_INVALID_UUID_FORMAT); } RTTestGuardedFree(hTest, pwsz2); } RTUtf16Free(pwsz); } RTTestSub(hTest, "RTUuidCompareStr"); RTTEST_CHECK(hTest, RTUuidCompareStr(&Uuid, sz) == 0); RTTEST_CHECK(hTest, RTUuidCompareStr(&Uuid, "00000000-0000-0000-0000-000000000000") > 0); RTTEST_CHECK(hTest, RTUuidCompareStr(&UuidNull, "00000000-0000-0000-0000-000000000000") == 0); RTTestSub(hTest, "RTUuidCompare2Strs"); RTTEST_CHECK(hTest, RTUuidCompare2Strs(sz, sz) == 0); RTTEST_CHECK(hTest, RTUuidCompare2Strs(sz, "00000000-0000-0000-0000-000000000000") > 0); RTTEST_CHECK(hTest, RTUuidCompare2Strs("00000000-0000-0000-0000-000000000000", sz) < 0); RTTEST_CHECK(hTest, RTUuidCompare2Strs("00000000-0000-0000-0000-000000000000", "00000000-0000-0000-0000-000000000000") == 0); RTTEST_CHECK(hTest, RTUuidCompare2Strs("d95d883b-f91d-4ce5-a5c5-d08bb6a85dec", "a56193c7-3e0b-4c03-9d66-56efb45082f7") > 0); RTTEST_CHECK(hTest, RTUuidCompare2Strs("a56193c7-3e0b-4c03-9d66-56efb45082f7", "d95d883b-f91d-4ce5-a5c5-d08bb6a85dec") < 0); /* * Check the binary representation. */ RTTestSub(hTest, "Binary representation"); RTUUID Uuid3; Uuid3.au8[0] = 0x01; Uuid3.au8[1] = 0x23; Uuid3.au8[2] = 0x45; Uuid3.au8[3] = 0x67; Uuid3.au8[4] = 0x89; Uuid3.au8[5] = 0xab; Uuid3.au8[6] = 0xcd; Uuid3.au8[7] = 0x4f; Uuid3.au8[8] = 0x10; Uuid3.au8[9] = 0xb2; Uuid3.au8[10] = 0x54; Uuid3.au8[11] = 0x76; Uuid3.au8[12] = 0x98; Uuid3.au8[13] = 0xba; Uuid3.au8[14] = 0xdc; Uuid3.au8[15] = 0xfe; Uuid3.Gen.u8ClockSeqHiAndReserved = (Uuid3.Gen.u8ClockSeqHiAndReserved & 0x3f) | 0x80; Uuid3.Gen.u16TimeHiAndVersion = (Uuid3.Gen.u16TimeHiAndVersion & 0x0fff) | 0x4000; const char *pszUuid3 = "67452301-ab89-4fcd-90b2-547698badcfe"; rc = RTUuidToStr(&Uuid3, sz, sizeof(sz)); CHECK_RC(); RTTEST_CHECK(hTest, strcmp(sz, pszUuid3) == 0); rc = RTUuidFromStr(&Uuid, pszUuid3); CHECK_RC(); RTTEST_CHECK(hTest, RTUuidCompare(&Uuid, &Uuid3) == 0); RTTEST_CHECK(hTest, memcmp(&Uuid3, &Uuid, sizeof(Uuid)) == 0); /* * checking the clock seq and time hi and version bits... */ RTTestSub(hTest, "Clock seq, time hi, version bits"); RTUUID Uuid4Changes; Uuid4Changes.au64[0] = 0; Uuid4Changes.au64[1] = 0; RTUUID Uuid4Prev; RTUuidCreate(&Uuid4Prev); for (unsigned i = 0; i < 1024; i++) { RTUUID Uuid4; RTUuidCreate(&Uuid4); Uuid4Changes.au64[0] |= Uuid4.au64[0] ^ Uuid4Prev.au64[0]; Uuid4Changes.au64[1] |= Uuid4.au64[1] ^ Uuid4Prev.au64[1]; #if 0 /** @todo make a bit string/dumper similar to %Rhxs/d. */ RTPrintf("tstUuid: %d %d %d %d-%d %d %d %d %d %d %d %d-%d %d %d %d ; %d %d %d %d-%d %d %d %d %d %d %d %d-%d %d %d %d\n", !!(Uuid4.Gen.u16ClockSeq & RT_BIT(0)), !!(Uuid4.Gen.u16ClockSeq & RT_BIT(1)), !!(Uuid4.Gen.u16ClockSeq & RT_BIT(2)), !!(Uuid4.Gen.u16ClockSeq & RT_BIT(3)), !!(Uuid4.Gen.u16ClockSeq & RT_BIT(4)), !!(Uuid4.Gen.u16ClockSeq & RT_BIT(5)), !!(Uuid4.Gen.u16ClockSeq & RT_BIT(6)), !!(Uuid4.Gen.u16ClockSeq & RT_BIT(7)), !!(Uuid4.Gen.u16ClockSeq & RT_BIT(8)), !!(Uuid4.Gen.u16ClockSeq & RT_BIT(9)), !!(Uuid4.Gen.u16ClockSeq & RT_BIT(10)), !!(Uuid4.Gen.u16ClockSeq & RT_BIT(11)), !!(Uuid4.Gen.u16ClockSeq & RT_BIT(12)), !!(Uuid4.Gen.u16ClockSeq & RT_BIT(13)), !!(Uuid4.Gen.u16ClockSeq & RT_BIT(14)), !!(Uuid4.Gen.u16ClockSeq & RT_BIT(15)), !!(Uuid4.Gen.u16TimeHiAndVersion & RT_BIT(0)), !!(Uuid4.Gen.u16TimeHiAndVersion & RT_BIT(1)), !!(Uuid4.Gen.u16TimeHiAndVersion & RT_BIT(2)), !!(Uuid4.Gen.u16TimeHiAndVersion & RT_BIT(3)), !!(Uuid4.Gen.u16TimeHiAndVersion & RT_BIT(4)), !!(Uuid4.Gen.u16TimeHiAndVersion & RT_BIT(5)), !!(Uuid4.Gen.u16TimeHiAndVersion & RT_BIT(6)), !!(Uuid4.Gen.u16TimeHiAndVersion & RT_BIT(7)), !!(Uuid4.Gen.u16TimeHiAndVersion & RT_BIT(8)), !!(Uuid4.Gen.u16TimeHiAndVersion & RT_BIT(9)), !!(Uuid4.Gen.u16TimeHiAndVersion & RT_BIT(10)), !!(Uuid4.Gen.u16TimeHiAndVersion & RT_BIT(11)), !!(Uuid4.Gen.u16TimeHiAndVersion & RT_BIT(12)), !!(Uuid4.Gen.u16TimeHiAndVersion & RT_BIT(13)), !!(Uuid4.Gen.u16TimeHiAndVersion & RT_BIT(14)), !!(Uuid4.Gen.u16TimeHiAndVersion & RT_BIT(15)) ); #endif Uuid4Prev = Uuid4; } RTUUID Uuid4Fixed; Uuid4Fixed.au64[0] = ~Uuid4Changes.au64[0]; Uuid4Fixed.au64[1] = ~Uuid4Changes.au64[1]; RTTestPrintf(hTest, RTTESTLVL_INFO, "fixed bits: %RTuuid (mask)\n", &Uuid4Fixed); RTTestPrintf(hTest, RTTESTLVL_INFO, "tstUuid: raw: %.*Rhxs\n", sizeof(Uuid4Fixed), &Uuid4Fixed); Uuid4Prev.au64[0] &= Uuid4Fixed.au64[0]; Uuid4Prev.au64[1] &= Uuid4Fixed.au64[1]; RTTestPrintf(hTest, RTTESTLVL_INFO, "tstUuid: fixed bits: %RTuuid (value)\n", &Uuid4Prev); RTTestPrintf(hTest, RTTESTLVL_INFO, "tstUuid: raw: %.*Rhxs\n", sizeof(Uuid4Prev), &Uuid4Prev); /* * Summary. */ return RTTestSummaryAndDestroy(hTest); }
RTDECL(int) RTCrSpcIndirectDataContent_CheckSanityEx(PCRTCRSPCINDIRECTDATACONTENT pIndData, PCRTCRPKCS7SIGNEDDATA pSignedData, uint32_t fFlags, PRTERRINFO pErrInfo) { /* * Match up the digest algorithms (page 8, v1.0). */ if (pSignedData->SignerInfos.cItems != 1) return RTErrInfoSetF(pErrInfo, VERR_CR_SPC_NOT_EXACTLY_ONE_SIGNER_INFOS, "SpcIndirectDataContent expects SignedData to have exactly one SignerInfos entries, found: %u", pSignedData->SignerInfos.cItems); if (pSignedData->DigestAlgorithms.cItems != 1) return RTErrInfoSetF(pErrInfo, VERR_CR_SPC_NOT_EXACTLY_ONE_DIGEST_ALGO, "SpcIndirectDataContent expects SignedData to have exactly one DigestAlgorithms entries, found: %u", pSignedData->DigestAlgorithms.cItems); if (RTCrX509AlgorithmIdentifier_Compare(&pIndData->DigestInfo.DigestAlgorithm, /** @todo not entirely sure about this check... */ &pSignedData->SignerInfos.paItems[0].DigestAlgorithm) != 0) return RTErrInfoSetF(pErrInfo, VERR_CR_SPC_SIGNED_IND_DATA_DIGEST_ALGO_MISMATCH, "SpcIndirectDataContent DigestInfo and SignerInfos algorithms mismatch: %s vs %s", pIndData->DigestInfo.DigestAlgorithm.Algorithm.szObjId, pSignedData->SignerInfos.paItems[0].DigestAlgorithm.Algorithm.szObjId); if (RTCrX509AlgorithmIdentifier_Compare(&pIndData->DigestInfo.DigestAlgorithm, &pSignedData->DigestAlgorithms.paItems[0]) != 0) return RTErrInfoSetF(pErrInfo, VERR_CR_SPC_IND_DATA_DIGEST_ALGO_NOT_IN_DIGEST_ALGOS, "SpcIndirectDataContent DigestInfo and SignedData.DigestAlgorithms[0] mismatch: %s vs %s", pIndData->DigestInfo.DigestAlgorithm.Algorithm.szObjId, pSignedData->DigestAlgorithms.paItems[0].Algorithm.szObjId); if (fFlags & RTCRSPCINDIRECTDATACONTENT_SANITY_F_ONLY_KNOWN_HASH) { if (RTCrX509AlgorithmIdentifier_QueryDigestType(&pIndData->DigestInfo.DigestAlgorithm) == RTDIGESTTYPE_INVALID) return RTErrInfoSetF(pErrInfo, VERR_CR_SPC_UNKNOWN_DIGEST_ALGO, "SpcIndirectDataContent DigestAlgortihm is not known: %s", pIndData->DigestInfo.DigestAlgorithm.Algorithm.szObjId); } uint32_t cbDigest = RTCrX509AlgorithmIdentifier_QueryDigestSize(&pIndData->DigestInfo.DigestAlgorithm); if ( pIndData->DigestInfo.Digest.Asn1Core.cb != cbDigest && (cbDigest != UINT32_MAX || (fFlags & RTCRSPCINDIRECTDATACONTENT_SANITY_F_ONLY_KNOWN_HASH))) return RTErrInfoSetF(pErrInfo, VERR_CR_SPC_IND_DATA_DIGEST_SIZE_MISMATCH, "SpcIndirectDataContent Digest size mismatch with algorithm: %u, expected %u (%s)", pIndData->DigestInfo.Digest.Asn1Core.cb, cbDigest, pIndData->DigestInfo.DigestAlgorithm.Algorithm.szObjId); /* * Data. */ if (fFlags & RTCRSPCINDIRECTDATACONTENT_SANITY_F_PE_IMAGE) { if ( pIndData->Data.enmType != RTCRSPCAAOVTYPE_PE_IMAGE_DATA || RTAsn1ObjId_CompareWithString(&pIndData->Data.Type, RTCRSPCPEIMAGEDATA_OID) != 0) return RTErrInfoSetF(pErrInfo, VERR_CR_SPC_EXPECTED_PE_IMAGE_DATA, "SpcIndirectDataContent.Data.Type is %s, expected %s (SpcPeImageData) [enmType=%d]", pIndData->Data.Type.szObjId, RTCRSPCPEIMAGEDATA_OID, pIndData->Data.enmType); if ( pIndData->Data.uValue.pPeImage || !RTCrSpcPeImageData_IsPresent(pIndData->Data.uValue.pPeImage) ) return RTErrInfoSet(pErrInfo, VERR_CR_SPC_PEIMAGE_DATA_NOT_PRESENT, "SpcIndirectDataContent.Data.uValue/PEImage is missing"); if ( pIndData->Data.uValue.pPeImage->T0.File.enmChoice == RTCRSPCLINKCHOICE_MONIKER && RTCrSpcSerializedObject_IsPresent(pIndData->Data.uValue.pPeImage->T0.File.u.pMoniker) ) { PCRTCRSPCSERIALIZEDOBJECT pObj = pIndData->Data.uValue.pPeImage->T0.File.u.pMoniker; if (pObj->Uuid.Asn1Core.cb != sizeof(RTUUID)) return RTErrInfoSetF(pErrInfo, VERR_CR_SPC_BAD_MONIKER_UUID, "SpcIndirectDataContent...MonikerT1.Uuid incorrect size: %u, expected %u.", pObj->Uuid.Asn1Core.cb, sizeof(RTUUID)); if (RTUuidCompareStr(pObj->Uuid.Asn1Core.uData.pUuid, RTCRSPCSERIALIZEDOBJECT_UUID_STR) != 0) return RTErrInfoSetF(pErrInfo, VERR_CR_SPC_UNKNOWN_MONIKER_UUID, "SpcIndirectDataContent...MonikerT1.Uuid mismatch: %RTuuid, expected %s.", pObj->Uuid.Asn1Core.uData.pUuid, RTCRSPCSERIALIZEDOBJECT_UUID_STR); if (pObj->enmType != RTCRSPCSERIALIZEDOBJECTTYPE_ATTRIBUTES) return RTErrInfoSetF(pErrInfo, VERR_CR_SPC_BAD_MONIKER_CHOICE, "SpcIndirectDataContent...pMoniker->enmType=%d, expected %d.", pObj->enmType, RTCRSPCSERIALIZEDOBJECTTYPE_ATTRIBUTES); if (!pObj->u.pData) return RTErrInfoSet(pErrInfo, VERR_CR_SPC_MONIKER_BAD_DATA, "SpcIndirectDataContent...pMoniker->pData is NULL."); uint32_t cPageHashTabs = 0; for (uint32_t i = 0; i < pObj->u.pData->cItems; i++) { PCRTCRSPCSERIALIZEDOBJECTATTRIBUTE pAttr = &pObj->u.pData->paItems[i]; if ( RTAsn1ObjId_CompareWithString(&pAttr->Type, RTCRSPC_PE_IMAGE_HASHES_V1_OID) == 0 || RTAsn1ObjId_CompareWithString(&pAttr->Type, RTCRSPC_PE_IMAGE_HASHES_V2_OID) == 0 ) { cPageHashTabs++; AssertPtr(pAttr->u.pPageHashes->pData); } else return RTErrInfoSetF(pErrInfo, VERR_CR_SPC_PEIMAGE_UNKNOWN_ATTRIBUTE, "SpcIndirectDataContent...MonikerT1 unknown attribute %u: %s.", i, pAttr->Type.szObjId); } if (cPageHashTabs > 0) return RTErrInfoSetF(pErrInfo, VERR_CR_SPC_PEIMAGE_MULTIPLE_HASH_TABS, "SpcIndirectDataContent...MonikerT1 multiple page hash attributes (%u).", cPageHashTabs); } else if ( pIndData->Data.uValue.pPeImage->T0.File.enmChoice == RTCRSPCLINKCHOICE_FILE && RTCrSpcString_IsPresent(&pIndData->Data.uValue.pPeImage->T0.File.u.pT2->File) ) { /* Could check for "<<<Obsolete>>>" here, but it's really irrelevant. */ } else if ( pIndData->Data.uValue.pPeImage->T0.File.enmChoice == RTCRSPCLINKCHOICE_URL && RTAsn1String_IsPresent(pIndData->Data.uValue.pPeImage->T0.File.u.pUrl) ) return RTErrInfoSet(pErrInfo, VERR_CR_SPC_PEIMAGE_URL_UNEXPECTED, "SpcIndirectDataContent.Data.uValue.pPeImage->File is an URL, expected object Moniker or File."); else return RTErrInfoSet(pErrInfo, VERR_CR_SPC_PEIMAGE_NO_CONTENT, "SpcIndirectDataContent.Data.uValue.pPeImage->File has no content"); } return VINF_SUCCESS; }