[CRYPT32_WINETEST]
authorAmine Khaldi <amine.khaldi@reactos.org>
Tue, 22 Apr 2014 15:11:03 +0000 (15:11 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Tue, 22 Apr 2014 15:11:03 +0000 (15:11 +0000)
* Sync with Wine 1.7.17.
CORE-8080

svn path=/trunk/; revision=62884

rostests/winetests/crypt32/cert.c
rostests/winetests/crypt32/chain.c
rostests/winetests/crypt32/crl.c
rostests/winetests/crypt32/ctl.c
rostests/winetests/crypt32/encode.c
rostests/winetests/crypt32/sip.c
rostests/winetests/crypt32/store.c
rostests/winetests/crypt32/testlist.c

index ca40914..b5486f2 100644 (file)
@@ -351,7 +351,7 @@ static void checkHash(const BYTE *data, DWORD dataLen, ALG_ID algID,
      dwSizeWithNull,size);
 }
 
-static CHAR cspNameA[] = "WineCryptTemp";
+static const CHAR cspNameA[] = "WineCryptTemp";
 static WCHAR cspNameW[] = { 'W','i','n','e','C','r','y','p','t','T','e','m','p',0 };
 static const BYTE v1CertWithPubKey[] = {
 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
@@ -660,7 +660,6 @@ static void testCreateCert(void)
      selfSignedCert, sizeof(selfSignedCert));
     ok(cert != NULL, "creating cert failed: %08x\n", GetLastError());
     /* Even in-memory certs are expected to have a store associated with them */
-    todo_wine
     ok(cert->hCertStore != NULL, "expected created cert to have a store\n");
     /* The cert doesn't have the archived property set (which would imply it
      * doesn't show up in enumerations.)
@@ -681,8 +680,8 @@ static void testCreateCert(void)
 
 static void testDupCert(void)
 {
-    HCERTSTORE store;
-    PCCERT_CONTEXT context, dupContext;
+    PCCERT_CONTEXT context, dupContext, storeContext, storeContext2, context2;
+    HCERTSTORE store, store2;
     BOOL ret;
 
     store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
@@ -720,9 +719,86 @@ static void testDupCert(void)
     }
     CertCloseStore(store, 0);
 
+    context = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, sizeof(bigCert));
+    ok(context != NULL, "CertCreateCertificateContext failed\n");
+
+    dupContext = CertDuplicateCertificateContext(context);
+    ok(dupContext == context, "context != dupContext\n");
+
+    ret = CertFreeCertificateContext(dupContext);
+    ok(ret, "CertFreeCertificateContext failed\n");
+
+    store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
+    ok(store != NULL, "CertOpenStore failed: %d\n", GetLastError());
+
+    ret = CertAddCertificateContextToStore(store, context, CERT_STORE_ADD_NEW, &storeContext);
+    ok(ret, "CertAddCertificateContextToStore failed\n");
+    ok(storeContext != NULL && storeContext != context, "unexpected storeContext\n");
+    ok(storeContext->hCertStore == store, "unexpected hCertStore\n");
+
+    ok(storeContext->pbCertEncoded != context->pbCertEncoded, "unexpected pbCertEncoded\n");
+    ok(storeContext->cbCertEncoded == context->cbCertEncoded, "unexpected cbCertEncoded\n");
+    ok(storeContext->pCertInfo != context->pCertInfo, "unexpected pCertInfo\n");
+
+    store2 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
+    ok(store2 != NULL, "CertOpenStore failed: %d\n", GetLastError());
+
+    ret = CertAddCertificateContextToStore(store2, storeContext, CERT_STORE_ADD_NEW, &storeContext2);
+    ok(ret, "CertAddCertificateContextToStore failed\n");
+    ok(storeContext2 != NULL && storeContext2 != storeContext, "unexpected storeContext\n");
+    ok(storeContext2->hCertStore == store2, "unexpected hCertStore\n");
+
+    ok(storeContext2->pbCertEncoded != storeContext->pbCertEncoded, "unexpected pbCertEncoded\n");
+    ok(storeContext2->cbCertEncoded == storeContext->cbCertEncoded, "unexpected cbCertEncoded\n");
+    ok(storeContext2->pCertInfo != storeContext->pCertInfo, "unexpected pCertInfo\n");
+
+    CertFreeCertificateContext(storeContext2);
+    CertFreeCertificateContext(storeContext);
+
+    context2 = CertCreateCertificateContext(X509_ASN_ENCODING, certWithUsage, sizeof(certWithUsage));
+    ok(context2 != NULL, "CertCreateCertificateContext failed\n");
+
+    ok(context2->hCertStore == context->hCertStore, "Unexpected hCertStore\n");
+
+    CertFreeCertificateContext(context2);
+    ret = CertFreeCertificateContext(context);
+    ok(ret, "CertFreeCertificateContext failed\n");
+
+    CertCloseStore(store, 0);
+    CertCloseStore(store2, 0);
+
     SetLastError(0xdeadbeef);
     context = CertDuplicateCertificateContext(NULL);
     ok(context == NULL, "Expected context to be NULL\n");
+
+    ret = CertFreeCertificateContext(NULL);
+    ok(ret, "CertFreeCertificateContext failed\n");
+}
+
+static void testLinkCert(void)
+{
+    const CERT_CONTEXT *context, *link;
+    HCERTSTORE store;
+    BOOL ret;
+
+    context = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, sizeof(bigCert));
+    ok(context != NULL, "CertCreateCertificateContext failed\n");
+
+    store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
+    ok(store != NULL, "CertOpenStore failed: %d\n", GetLastError());
+
+    ret = CertAddCertificateLinkToStore(store, context, CERT_STORE_ADD_NEW, &link);
+    ok(ret, "CertAddCertificateContextToStore failed\n");
+    ok(link != NULL && link != context, "unexpected storeContext\n");
+    ok(link->hCertStore == store, "unexpected hCertStore\n");
+
+    ok(link->pbCertEncoded == context->pbCertEncoded, "unexpected pbCertEncoded\n");
+    ok(link->cbCertEncoded == context->cbCertEncoded, "unexpected cbCertEncoded\n");
+    ok(link->pCertInfo == context->pCertInfo, "unexpected pCertInfo\n");
+
+    CertFreeCertificateContext(link);
+
+    CertCloseStore(store, 0);
 }
 
 static BYTE subjectName3[] = { 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
@@ -3648,7 +3724,7 @@ static void testAcquireCertPrivateKey(void)
      &keyProvInfo);
     ret = pCryptAcquireCertificatePrivateKey(cert, 0, NULL, &csp, &keySpec,
      &callerFree);
-    ok(!ret && GetLastError() == CRYPT_E_NO_KEY_PROPERTY,
+    ok(!ret && (GetLastError() == CRYPT_E_NO_KEY_PROPERTY || GetLastError() == NTE_BAD_KEYSET /* win8 */),
      "Expected CRYPT_E_NO_KEY_PROPERTY, got %08x\n", GetLastError());
 
     pCryptAcquireContextA(&csp, cspNameA, MS_DEF_PROV_A, PROV_RSA_FULL,
@@ -3903,6 +3979,7 @@ START_TEST(cert)
     testFindCert();
     testGetSubjectCert();
     testGetIssuerCert();
+    testLinkCert();
 
     testCryptHashCert();
     testCertSigs();
index 412e4cd..2d8667a 100644 (file)
@@ -3880,9 +3880,8 @@ static void testGetCertChain(void)
     ok(ret, "CertGetCertificateChain failed: %08x\n", GetLastError());
     if (ret)
     {
-        ok(!(chain->TrustStatus.dwErrorStatus &
-         CERT_TRUST_IS_NOT_VALID_FOR_USAGE),
-         "didn't expect CERT_TRUST_IS_NOT_VALID_FOR_USAGE\n");
+        ok(!(chain->TrustStatus.dwErrorStatus & CERT_TRUST_IS_NOT_VALID_FOR_USAGE),
+           "didn't expect CERT_TRUST_IS_NOT_VALID_FOR_USAGE, got %x\n", chain->TrustStatus.dwErrorStatus);
         pCertFreeCertificateChain(chain);
     }
     oids[1] = one_two_three;
@@ -3998,13 +3997,14 @@ static void testGetCertChain(void)
     ok(ret, "CertGetCertificateChain failed: %u\n", GetLastError());
 
     if(chain->TrustStatus.dwErrorStatus == CERT_TRUST_IS_PARTIAL_CHAIN) { /* win2k */
-        todo_wine win_skip("winehq cert reported as partial chain, skipping its tests\n");
+        win_skip("winehq cert reported as partial chain, skipping its tests\n");
         pCertFreeCertificateChain(chain);
         CertCloseStore(store, 0);
         return;
     }
 
     ok(!chain->TrustStatus.dwErrorStatus, "chain->TrustStatus.dwErrorStatus = %x\n", chain->TrustStatus.dwErrorStatus);
+    todo_wine
     ok(chain->TrustStatus.dwInfoStatus == CERT_TRUST_HAS_PREFERRED_ISSUER, "chain->TrustStatus.dwInfoStatus = %x\n",
        chain->TrustStatus.dwInfoStatus);
 
@@ -4016,6 +4016,7 @@ static void testGetCertChain(void)
     ok(simple_chain->cbSize == sizeof(*simple_chain), "simple_chain->cbSize = %u\n", simple_chain->cbSize);
     ok(!simple_chain->TrustStatus.dwErrorStatus, "simple_chain->TrustStatus.dwErrorStatus = %x\n",
        simple_chain->TrustStatus.dwErrorStatus);
+    todo_wine
     ok(simple_chain->TrustStatus.dwInfoStatus == CERT_TRUST_HAS_PREFERRED_ISSUER,
        "simple_chain->TrustStatus.dwInfoStatus = %x\n", simple_chain->TrustStatus.dwInfoStatus);
     ok(simple_chain->cElement == 3, "simple_chain->cElement = %u\n", simple_chain->cElement);
@@ -4039,6 +4040,13 @@ static void testGetCertChain(void)
     test_name_blob(&simple_chain->rgpElement[2]->pCertContext->pCertInfo->Subject, "US, GeoTrust Inc., GeoTrust Global CA");
 
     pCertFreeCertificateChain(chain);
+
+    /* Test HCCE_LOCAL_MACHINE */
+    ret = CertGetCertificateChain(HCCE_LOCAL_MACHINE, cert, &fileTime, store, &para, 0, NULL, &chain);
+    ok(ret, "CertGetCertificateChain failed: %u\n", GetLastError());
+    pCertFreeCertificateChain(chain);
+
+    CertFreeCertificateContext(cert);
     CertCloseStore(store, 0);
 }
 
index b2831a3..f0a784e 100644 (file)
@@ -120,6 +120,7 @@ static void testCreateCRL(void)
 static void testDupCRL(void)
 {
     PCCRL_CONTEXT context, dupContext;
+    BOOL res;
 
     context = CertDuplicateCRLContext(NULL);
     ok(context == NULL, "expected NULL\n");
@@ -128,15 +129,22 @@ static void testDupCRL(void)
     dupContext = CertDuplicateCRLContext(context);
     ok(dupContext != NULL, "expected a context\n");
     ok(dupContext == context, "expected identical context addresses\n");
-    CertFreeCRLContext(dupContext);
-    CertFreeCRLContext(context);
+
+    res = CertFreeCRLContext(dupContext);
+    ok(res, "CertFreeCRLContext failed\n");
+
+    res = CertFreeCRLContext(context);
+    ok(res, "CertFreeCRLContext failed\n");
+
+    res = CertFreeCRLContext(NULL);
+    ok(res, "CertFreeCRLContext failed\n");
 }
 
 static void testAddCRL(void)
 {
     HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
      CERT_STORE_CREATE_NEW_FLAG, NULL);
-    PCCRL_CONTEXT context;
+    PCCRL_CONTEXT context, context2;
     BOOL ret;
     DWORD GLE;
 
@@ -221,6 +229,24 @@ static void testAddCRL(void)
     ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError());
 
     CertCloseStore(store, 0);
+
+    store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
+    ok(store != NULL, "CertOpenStore failed\n");
+
+    context = CertCreateCRLContext(X509_ASN_ENCODING, CRL, sizeof(CRL));
+    ok(context != NULL, "CertCreateCRLContext failed\n");
+
+    ret = CertAddCRLContextToStore(store, context, CERT_STORE_ADD_NEW, &context2);
+    ok(ret, "CertAddCRLContextToStore failed\n");
+    ok(context2 != NULL && context2 != context, "unexpected context2\n");
+
+    ok(context->pbCrlEncoded != context2->pbCrlEncoded, "Unexpected pbCrlEncoded\n");
+    ok(context->cbCrlEncoded == context2->cbCrlEncoded, "Unexpected cbCrlEncoded\n");
+    ok(context->pCrlInfo != context2->pCrlInfo, "Unexpected pCrlInfo\n");
+
+    CertFreeCRLContext(context2);
+    CertFreeCRLContext(context);
+    CertCloseStore(store, 0);
 }
 
 static const BYTE v1CRLWithIssuerAndEntry[] = { 0x30, 0x44, 0x30, 0x02, 0x06,
index 015b07e..e3b773c 100644 (file)
@@ -190,6 +190,7 @@ static void testCreateCTL(void)
 static void testDupCTL(void)
 {
     PCCTL_CONTEXT context, dupContext;
+    BOOL res;
 
     context = CertDuplicateCTLContext(NULL);
     ok(context == NULL, "expected NULL\n");
@@ -198,8 +199,15 @@ static void testDupCTL(void)
     dupContext = CertDuplicateCTLContext(context);
     ok(dupContext != NULL, "expected a context\n");
     ok(dupContext == context, "expected identical context addresses\n");
-    CertFreeCTLContext(dupContext);
-    CertFreeCTLContext(context);
+
+    res = CertFreeCTLContext(dupContext);
+    ok(res, "CertFreeCTLContext failed\n");
+
+    res = CertFreeCTLContext(context);
+    ok(res, "CertFreeCTLContext failed\n");
+
+    res = CertFreeCTLContext(NULL);
+    ok(res, "CertFreeCTLContext failed\n");
 }
 
 static void checkHash(const BYTE *data, DWORD dataLen, ALG_ID algID,
index b221e5f..d1cb42f 100644 (file)
@@ -849,7 +849,7 @@ static void test_encodeName(DWORD dwEncoding)
     {
         ok(size == sizeof(encodedTwoRDNs), "Unexpected size %d\n", size);
         ok(!memcmp(buf, encodedTwoRDNs, size),
-         "Unexpected value for re-endoded two RDN array\n");
+         "Unexpected value for re-encoded two RDN array\n");
         LocalFree(buf);
     }
     /* CERT_RDN_ANY_TYPE is too vague for X509_NAMEs, check the return */
@@ -973,7 +973,7 @@ static void test_encodeUnicodeName(DWORD dwEncoding)
     {
         ok(size == sizeof(encodedTwoRDNs), "Unexpected size %d\n", size);
         ok(!memcmp(buf, encodedTwoRDNs, size),
-         "Unexpected value for re-endoded two RDN array\n");
+         "Unexpected value for re-encoded two RDN array\n");
         LocalFree(buf);
     }
     /* Unicode names infer the type for CERT_RDN_ANY_TYPE */
@@ -1003,7 +1003,8 @@ static void compareNameValues(const CERT_NAME_VALUE *expected,
     ok(got->dwValueType == expected->dwValueType,
      "Expected string type %d, got %d\n", expected->dwValueType,
      got->dwValueType);
-    ok(got->Value.cbData == expected->Value.cbData,
+    ok(got->Value.cbData == expected->Value.cbData ||
+     got->Value.cbData == expected->Value.cbData - sizeof(WCHAR) /* Win8 */,
      "String type %d: unexpected data size, got %d, expected %d\n",
      expected->dwValueType, got->Value.cbData, expected->Value.cbData);
     if (got->Value.cbData && got->Value.pbData)
@@ -4581,7 +4582,8 @@ static void test_decodeCRLToBeSigned(DWORD dwEncoding)
      v1CRLWithIssuerAndEmptyEntry, v1CRLWithIssuerAndEmptyEntry[1] + 2,
      CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
     ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
-     GetLastError() == OSS_DATA_ERROR /* Win9x */),
+     GetLastError() == OSS_DATA_ERROR /* Win9x */ ||
+     GetLastError() == CRYPT_E_BAD_ENCODE /* Win8 */),
      "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
      GetLastError());
     /* with a real CRL entry */
@@ -6765,7 +6767,7 @@ static void test_encodeCMSSignerInfo(DWORD dwEncoding)
     ok(GetLastError() == E_INVALIDARG,
        "Expected E_INVALIDARG, got %08x\n", GetLastError());
     /* To be encoded, a signer must have a valid cert ID, where a valid ID may
-     * be a key id or a issuer serial number with at least the issuer set, and
+     * be a key id or an issuer serial number with at least the issuer set, and
      * the encoding must include PKCS_7_ASN_ENCODING.
      * (That isn't enough to be decoded, see decoding tests.)
      */
@@ -6909,7 +6911,7 @@ static void test_decodeCMSSignerInfo(DWORD dwEncoding)
     LPBYTE buf = NULL;
     DWORD size = 0;
     CMSG_CMS_SIGNER_INFO *info;
-    static char oid1[] = "1.2.3", oid2[] = "1.5.6";
+    static const char oid1[] = "1.2.3", oid2[] = "1.5.6";
 
     /* A CMS signer can't be decoded without a serial number. */
     SetLastError(0xdeadbeef);
@@ -8054,9 +8056,9 @@ static void testPortPublicKeyInfo(void)
     PCERT_PUBLIC_KEY_INFO info = NULL;
 
     /* Just in case a previous run failed, delete this thing */
-    CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
+    CryptAcquireContextA(&csp, cspName, MS_DEF_PROV_A, PROV_RSA_FULL,
      CRYPT_DELETEKEYSET);
-    ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
+    ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV_A, PROV_RSA_FULL,
      CRYPT_NEWKEYSET);
     ok(ret,"CryptAcquireContextA failed\n");
 
@@ -8065,7 +8067,7 @@ static void testPortPublicKeyInfo(void)
 
     HeapFree(GetProcessHeap(), 0, info);
     CryptReleaseContext(csp, 0);
-    ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
+    ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV_A, PROV_RSA_FULL,
      CRYPT_DELETEKEYSET);
     ok(ret,"CryptAcquireContextA failed\n");
 }
index 2034e41..753e4e7 100644 (file)
@@ -36,17 +36,6 @@ static BOOL (WINAPI * funcCryptSIPCreateIndirectData)(SIP_SUBJECTINFO *,DWORD *,
 static BOOL (WINAPI * funcCryptSIPVerifyIndirectData)(SIP_SUBJECTINFO *,SIP_INDIRECT_DATA *);
 static BOOL (WINAPI * funcCryptSIPRemoveSignedDataMsg)(SIP_SUBJECTINFO *,DWORD);
 
-static char *show_guid(const GUID *guid, char *buf)
-{
-    sprintf(buf,
-        "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
-        guid->Data1, guid->Data2, guid->Data3,
-        guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
-        guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] );
-
-    return buf;
-}
-
 static void test_AddRemoveProvider(void)
 {
     BOOL ret;
@@ -165,7 +154,6 @@ static void test_SIPRetrieveSubjectGUID(void)
     static CHAR path[MAX_PATH];
     static CHAR tempfile[MAX_PATH];
     static WCHAR tempfileW[MAX_PATH];
-    static char guid1[39], guid2[39];
     DWORD written;
 
     /* NULL check */
@@ -186,7 +174,7 @@ static void test_SIPRetrieveSubjectGUID(void)
         "Expected ERROR_FILE_NOT_FOUND or ERROR_PATH_NOT_FOUND, got %d.\n",
         GetLastError());
     ok ( !memcmp(&subject, &nullSubject, sizeof(GUID)),
-        "Expected a NULL GUID for c:\\deadbeef.dbf, not %s\n", show_guid(&subject, guid1));
+        "Expected a NULL GUID for c:\\deadbeef.dbf, not %s\n", wine_dbgstr_guid(&subject));
 
     /* Now with an executable that should exist
      *
@@ -205,7 +193,7 @@ static void test_SIPRetrieveSubjectGUID(void)
     ret = CryptSIPRetrieveSubjectGuid(regeditPathW, NULL, &subject);
     ok ( ret, "Expected CryptSIPRetrieveSubjectGuid to succeed\n");
     ok ( !memcmp(&subject, &unknownGUID, sizeof(GUID)),
-        "Expected (%s), got (%s).\n", show_guid(&unknownGUID, guid1), show_guid(&subject, guid2));
+        "Expected (%s), got (%s).\n", wine_dbgstr_guid(&unknownGUID), wine_dbgstr_guid(&subject));
 
     /* The same thing but now with a handle instead of a filename */
     file = CreateFileA(regeditPath, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
@@ -214,7 +202,7 @@ static void test_SIPRetrieveSubjectGUID(void)
     ret = CryptSIPRetrieveSubjectGuid(NULL, file, &subject);
     ok ( ret, "Expected CryptSIPRetrieveSubjectGuid to succeed\n");
     ok ( !memcmp(&subject, &unknownGUID, sizeof(GUID)),
-        "Expected (%s), got (%s).\n", show_guid(&unknownGUID, guid1), show_guid(&subject, guid2));
+        "Expected (%s), got (%s).\n", wine_dbgstr_guid(&unknownGUID), wine_dbgstr_guid(&subject));
     CloseHandle(file);
 
     /* And both */
@@ -224,7 +212,7 @@ static void test_SIPRetrieveSubjectGUID(void)
     ret = CryptSIPRetrieveSubjectGuid(regeditPathW, file, &subject);
     ok ( ret, "Expected CryptSIPRetrieveSubjectGuid to succeed\n");
     ok ( !memcmp(&subject, &unknownGUID, sizeof(GUID)),
-        "Expected (%s), got (%s).\n", show_guid(&unknownGUID, guid1), show_guid(&subject, guid2));
+        "Expected (%s), got (%s).\n", wine_dbgstr_guid(&unknownGUID), wine_dbgstr_guid(&subject));
     CloseHandle(file);
 
     /* Now with an empty file */
@@ -244,7 +232,7 @@ static void test_SIPRetrieveSubjectGUID(void)
          GetLastError() == TRUST_E_SUBJECT_FORM_UNKNOWN /* some Win98 */,
         "Expected ERROR_FILE_INVALID, ERROR_INVALID_PARAMETER, ERROR_SUCCESS or TRUST_E_SUBJECT_FORM_UNKNOWN, got 0x%08x\n", GetLastError());
     ok ( !memcmp(&subject, &nullSubject, sizeof(GUID)),
-        "Expected a NULL GUID for empty file %s, not %s\n", tempfile, show_guid(&subject, guid1));
+        "Expected a NULL GUID for empty file %s, not %s\n", tempfile, wine_dbgstr_guid(&subject));
 
     /* Use a file with a size of 3 (at least < 4) */
     file = CreateFileA(tempfile, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
@@ -260,7 +248,7 @@ static void test_SIPRetrieveSubjectGUID(void)
          GetLastError() == TRUST_E_SUBJECT_FORM_UNKNOWN /* some Win98 */,
         "Expected ERROR_INVALID_PARAMETER, ERROR_SUCCESS or TRUST_E_SUBJECT_FORM_UNKNOWN, got 0x%08x\n", GetLastError());
     ok ( !memcmp(&subject, &nullSubject, sizeof(GUID)),
-        "Expected a NULL GUID for empty file %s, not %s\n", tempfile, show_guid(&subject, guid1));
+        "Expected a NULL GUID for empty file %s, not %s\n", tempfile, wine_dbgstr_guid(&subject));
 
     /* And now >= 4 */
     file = CreateFileA(tempfile, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
@@ -275,7 +263,7 @@ static void test_SIPRetrieveSubjectGUID(void)
          GetLastError() == ERROR_SUCCESS /* Win98 */,
         "Expected TRUST_E_SUBJECT_FORM_UNKNOWN or ERROR_SUCCESS, got 0x%08x\n", GetLastError());
     ok ( !memcmp(&subject, &nullSubject, sizeof(GUID)),
-        "Expected a NULL GUID for empty file %s, not %s\n", tempfile, show_guid(&subject, guid1));
+        "Expected a NULL GUID for empty file %s, not %s\n", tempfile, wine_dbgstr_guid(&subject));
 
     /* Clean up */
     DeleteFileA(tempfile);
@@ -293,7 +281,7 @@ static void test_SIPRetrieveSubjectGUID(void)
     ok( ret, "CryptSIPRetrieveSubjectGuid failed: %d (0x%08x)\n",
             GetLastError(), GetLastError() );
     ok ( !memcmp(&subject, &cabGUID, sizeof(GUID)),
-        "Expected GUID %s for cabinet file, not %s\n", show_guid(&cabGUID, guid1), show_guid(&subject, guid2));
+        "Expected GUID %s for cabinet file, not %s\n", wine_dbgstr_guid(&cabGUID), wine_dbgstr_guid(&subject));
 
     /* Clean up */
     DeleteFileA(tempfile);
@@ -311,7 +299,7 @@ static void test_SIPRetrieveSubjectGUID(void)
     ok( ret, "CryptSIPRetrieveSubjectGuid failed: %d (0x%08x)\n",
             GetLastError(), GetLastError() );
     ok ( !memcmp(&subject, &cabGUID, sizeof(GUID)),
-        "Expected GUID %s for cabinet file, not %s\n", show_guid(&cabGUID, guid1), show_guid(&subject, guid2));
+        "Expected GUID %s for cabinet file, not %s\n", wine_dbgstr_guid(&cabGUID), wine_dbgstr_guid(&subject));
 
     /* Clean up */
     DeleteFileA(tempfile);
index c9c04c7..d0c51df 100644 (file)
@@ -93,6 +93,26 @@ static const BYTE bigCert2[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
  0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
  0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
  0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
+static const BYTE signedCTLWithCTLInnerContent[] = {
+0x30,0x82,0x01,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
+0xa0,0x82,0x01,0x00,0x30,0x81,0xfd,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,
+0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x30,0x06,0x09,
+0x2b,0x06,0x01,0x04,0x01,0x82,0x37,0x0a,0x01,0xa0,0x23,0x30,0x21,0x30,0x00,
+0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
+0x30,0x5a,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,
+0x00,0x31,0x81,0xb5,0x30,0x81,0xb2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,
+0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
+0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
+0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0xa0,0x3b,0x30,0x18,0x06,0x09,0x2a,0x86,
+0x48,0x86,0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2b,0x06,0x01,0x04,
+0x01,0x82,0x37,0x0a,0x01,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
+0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x54,0x71,0xbc,0xe1,0x56,0x31,0xa2,0xf9,
+0x65,0x70,0x34,0xf8,0xe2,0xe9,0xb4,0xf4,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
+0x40,0x2f,0x1b,0x9f,0x5a,0x4a,0x15,0x73,0xfa,0xb1,0x93,0x3d,0x09,0x52,0xdf,
+0x6b,0x98,0x4b,0x13,0x5e,0xe7,0xbf,0x65,0xf4,0x9c,0xc2,0xb1,0x77,0x09,0xb1,
+0x66,0x4d,0x72,0x0d,0xb1,0x1a,0x50,0x20,0xe0,0x57,0xa2,0x39,0xc7,0xcd,0x7f,
+0x8e,0xe7,0x5f,0x76,0x2b,0xd1,0x6a,0x82,0xb3,0x30,0x25,0x61,0xf6,0x25,0x23,
+0x57,0x6c,0x0b,0x47,0xb8 };
 
 
 static BOOL (WINAPI *pCertAddStoreToCollection)(HCERTSTORE,HCERTSTORE,DWORD,DWORD);
@@ -104,6 +124,15 @@ static void (WINAPI *pCertRemoveStoreFromCollection)(HCERTSTORE,HCERTSTORE);
 static BOOL (WINAPI *pCertSetStoreProperty)(HCERTSTORE,DWORD,DWORD,const void*);
 static BOOL (WINAPI *pCertAddCertificateLinkToStore)(HCERTSTORE,PCCERT_CONTEXT,DWORD,PCCERT_CONTEXT*);
 
+#define test_store_is_empty(store) _test_store_is_empty(__LINE__,store)
+static void _test_store_is_empty(unsigned line, HCERTSTORE store)
+{
+    const CERT_CONTEXT *cert;
+
+    cert = CertEnumCertificatesInStore(store, NULL);
+    ok_(__FILE__,line)(!cert && GetLastError() == CRYPT_E_NOT_FOUND, "store is not empty\n");
+}
+
 static void testMemStore(void)
 {
     HCERTSTORE store1, store2;
@@ -2498,6 +2527,176 @@ static DWORD countCRLsInStore(HCERTSTORE store)
     return crls;
 }
 
+static void testEmptyStore(void)
+{
+    const CERT_CONTEXT *cert, *cert2, *cert3;
+    const CRL_CONTEXT *crl;
+    const CTL_CONTEXT *ctl;
+    HCERTSTORE store;
+    BOOL res;
+
+    cert = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, sizeof(bigCert));
+    ok(cert != NULL, "CertCreateCertificateContext failed\n");
+    ok(cert->hCertStore != NULL, "cert->hCertStore == NULL\n");
+    if(!cert->hCertStore) {
+        CertFreeCertificateContext(cert);
+        return;
+    }
+
+    test_store_is_empty(cert->hCertStore);
+
+    cert2 = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert2, sizeof(bigCert2));
+    ok(cert2 != NULL, "CertCreateCertificateContext failed\n");
+    ok(cert2->hCertStore == cert->hCertStore, "Unexpected hCertStore\n");
+
+    test_store_is_empty(cert2->hCertStore);
+
+    res = CertAddCertificateContextToStore(cert->hCertStore, cert2, CERT_STORE_ADD_NEW, &cert3);
+    ok(res, "CertAddCertificateContextToStore failed\n");
+    todo_wine
+    ok(cert3 && cert3 != cert2, "Unexpected cert3\n");
+    ok(cert3->hCertStore == cert->hCertStore, "Unexpected hCertStore\n");
+
+    test_store_is_empty(cert->hCertStore);
+
+    res = CertDeleteCertificateFromStore(cert3);
+    ok(res, "CertDeleteCertificateContextFromStore failed\n");
+    ok(cert3->hCertStore == cert->hCertStore, "Unexpected hCertStore\n");
+
+    CertFreeCertificateContext(cert3);
+
+    store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
+    ok(store != NULL, "CertOpenStore failed\n");
+
+    res = CertAddCertificateContextToStore(store, cert2, CERT_STORE_ADD_NEW, &cert3);
+    ok(res, "CertAddCertificateContextToStore failed\n");
+    ok(cert3 && cert3 != cert2, "Unexpected cert3\n");
+    ok(cert3->hCertStore == store, "Unexpected hCertStore\n");
+
+    res = CertDeleteCertificateFromStore(cert3);
+    ok(res, "CertDeleteCertificateContextFromStore failed\n");
+    ok(cert3->hCertStore == store, "Unexpected hCertStore\n");
+
+    CertFreeCertificateContext(cert3);
+
+    CertCloseStore(store, 0);
+
+    res = CertCloseStore(cert->hCertStore, CERT_CLOSE_STORE_CHECK_FLAG);
+    ok(!res && GetLastError() == E_UNEXPECTED, "CertCloseStore returned: %x(%x)\n", res, GetLastError());
+
+    res = CertCloseStore(cert->hCertStore, 0);
+    ok(!res && GetLastError() == E_UNEXPECTED, "CertCloseStore returned: %x(%x)\n", res, GetLastError());
+
+    CertFreeCertificateContext(cert2);
+
+    crl = CertCreateCRLContext(X509_ASN_ENCODING, signedCRL, sizeof(signedCRL));
+    ok(crl != NULL, "CertCreateCRLContext failed\n");
+    ok(crl->hCertStore == cert->hCertStore, "unexpected hCertStore\n");
+
+    CertFreeCRLContext(crl);
+
+    ctl = CertCreateCTLContext(X509_ASN_ENCODING, signedCTLWithCTLInnerContent, sizeof(signedCTLWithCTLInnerContent));
+    ok(ctl != NULL, "CertCreateCTLContext failed\n");
+    ok(ctl->hCertStore == cert->hCertStore, "unexpected hCertStore\n");
+
+    CertFreeCTLContext(ctl);
+
+    CertFreeCertificateContext(cert);
+}
+
+static void testCloseStore(void)
+{
+    const CERT_CONTEXT *cert;
+    const CRL_CONTEXT *crl;
+    const CTL_CONTEXT *ctl;
+    HCERTSTORE store, store2;
+    BOOL res;
+
+    store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
+    ok(store != NULL, "CertOpenStore failed\n");
+
+    res = CertCloseStore(store, CERT_CLOSE_STORE_CHECK_FLAG);
+    ok(res, "CertCloseStore failed\n");
+
+    store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
+    ok(store != NULL, "CertOpenStore failed\n");
+
+    store2 = CertDuplicateStore(store);
+    ok(store2 != NULL, "CertCloneStore failed\n");
+    ok(store2 == store, "unexpected store2\n");
+
+    res = CertCloseStore(store, CERT_CLOSE_STORE_CHECK_FLAG);
+    ok(!res && GetLastError() == CRYPT_E_PENDING_CLOSE, "CertCloseStore failed\n");
+
+    res = CertCloseStore(store2, CERT_CLOSE_STORE_CHECK_FLAG);
+    ok(res, "CertCloseStore failed\n");
+
+    store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
+    ok(store != NULL, "CertOpenStore failed\n");
+
+    res = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, bigCert,
+     sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &cert);
+    ok(res, "CertAddEncodedCertificateToStore failed\n");
+
+    /* There is still a reference from cert */
+    res = CertCloseStore(store, CERT_CLOSE_STORE_CHECK_FLAG);
+    ok(!res && GetLastError() == CRYPT_E_PENDING_CLOSE, "CertCloseStore failed\n");
+
+    res = CertFreeCertificateContext(cert);
+    ok(res, "CertFreeCertificateContext failed\n");
+
+    store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
+    ok(store != NULL, "CertOpenStore failed\n");
+
+    res = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL,
+     sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, &crl);
+    ok(res, "CertAddEncodedCRLToStore failed\n");
+
+    /* There is still a reference from CRL */
+    res = CertCloseStore(store, CERT_CLOSE_STORE_CHECK_FLAG);
+    ok(!res && GetLastError() == CRYPT_E_PENDING_CLOSE, "CertCloseStore failed\n");
+
+    res = CertFreeCRLContext(crl);
+    ok(res, "CertFreeCRLContext failed\n");
+
+    store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
+    ok(store != NULL, "CertOpenStore failed\n");
+
+    res = CertAddEncodedCTLToStore(store, X509_ASN_ENCODING, signedCTLWithCTLInnerContent,
+     sizeof(signedCTLWithCTLInnerContent), CERT_STORE_ADD_ALWAYS, &ctl);
+    ok(res, "CertAddEncodedCTLToStore failed\n");
+
+    /* There is still a reference from CTL */
+    res = CertCloseStore(store, CERT_CLOSE_STORE_CHECK_FLAG);
+    ok(!res && GetLastError() == CRYPT_E_PENDING_CLOSE, "CertCloseStore returned: %x(%u)\n", res, GetLastError());
+
+    res = CertFreeCTLContext(ctl);
+    ok(res, "CertFreeCTLContext failed\n");
+
+    /* Add all kinds of contexts, then release external references and make sure that store is properly closed. */
+    store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
+    ok(store != NULL, "CertOpenStore failed\n");
+
+    res = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, bigCert,
+     sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &cert);
+    ok(res, "CertAddEncodedCertificateToStore failed\n");
+
+    res = CertAddEncodedCRLToStore(store, X509_ASN_ENCODING, signedCRL,
+     sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, &crl);
+    ok(res, "CertAddEncodedCRLToStore failed\n");
+
+    res = CertAddEncodedCTLToStore(store, X509_ASN_ENCODING, signedCTLWithCTLInnerContent,
+     sizeof(signedCTLWithCTLInnerContent), CERT_STORE_ADD_ALWAYS, &ctl);
+    ok(res, "CertAddEncodedCTLToStore failed\n");
+
+    CertFreeCertificateContext(cert);
+    CertFreeCRLContext(crl);
+    CertFreeCTLContext(ctl);
+
+    res = CertCloseStore(store, CERT_CLOSE_STORE_CHECK_FLAG);
+    ok(res, "CertCloseStore failed\n");
+}
+
 static void test_I_UpdateStore(void)
 {
     HMODULE lib = GetModuleHandleA("crypt32");
@@ -2596,6 +2795,7 @@ START_TEST(store)
     testFileNameStore();
     testMessageStore();
     testSerializedStore();
+    testCloseStore();
 
     testCertOpenSystemStore();
     testCertEnumSystemStore();
@@ -2604,5 +2804,7 @@ START_TEST(store)
     testAddSerialized();
     testAddCertificateLink();
 
+    testEmptyStore();
+
     test_I_UpdateStore();
 }
index 9769dbc..fb49490 100644 (file)
@@ -26,15 +26,15 @@ const struct test winetest_testlist[] =
     { "chain", func_chain },
     { "crl", func_crl },
     { "ctl", func_ctl },
-       { "encode", func_encode },
-       { "main", func_main },
-       { "message", func_message },
-       { "msg", func_msg },
-       { "object", func_object },
-       { "oid", func_oid },
-       { "protectdata", func_protectdata },
-       { "sip", func_sip },
-       { "store", func_store },
-       { "str", func_str },
-       { 0, 0 }
+    { "encode", func_encode },
+    { "main", func_main },
+    { "message", func_message },
+    { "msg", func_msg },
+    { "object", func_object },
+    { "oid", func_oid },
+    { "protectdata", func_protectdata },
+    { "sip", func_sip },
+    { "store", func_store },
+    { "str", func_str },
+    { 0, 0 }
 };