Juan Lang : cryptui: Filter shown certs according to purpose selection in certificate manager dialog .

Alexandre Julliard julliard at winehq.org
Fri Jan 9 09:52:31 CST 2009


Module: wine
Branch: master
Commit: 0a58167b0733a336f22cea14f14f6cf64a2bd168
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=0a58167b0733a336f22cea14f14f6cf64a2bd168

Author: Juan Lang <juan.lang at gmail.com>
Date:   Wed Jan  7 17:02:05 2009 -0800

cryptui: Filter shown certs according to purpose selection in certificate manager dialog.

---

 dlls/cryptui/main.c |  201 +++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 193 insertions(+), 8 deletions(-)

diff --git a/dlls/cryptui/main.c b/dlls/cryptui/main.c
index 68fed92..6383e0c 100644
--- a/dlls/cryptui/main.c
+++ b/dlls/cryptui/main.c
@@ -209,18 +209,27 @@ static LPSTR get_cert_mgr_usages(void)
     return str;
 }
 
+typedef enum {
+    PurposeFilterShowAll = 0,
+    PurposeFilterShowAdvanced = 1,
+    PurposeFilterShowOID = 2
+} PurposeFilter;
+
 static void initialize_purpose_selection(HWND hwnd)
 {
     HWND cb = GetDlgItem(hwnd, IDC_MGR_PURPOSE_SELECTION);
     WCHAR buf[MAX_STRING_LEN];
     LPSTR usages;
+    int index;
 
     LoadStringW(hInstance, IDS_PURPOSE_ALL, buf,
      sizeof(buf) / sizeof(buf[0]));
-    SendMessageW(cb, CB_INSERTSTRING, -1, (LPARAM)buf);
+    index = SendMessageW(cb, CB_INSERTSTRING, -1, (LPARAM)buf);
+    SendMessageW(cb, CB_SETITEMDATA, index, (LPARAM)PurposeFilterShowAll);
     LoadStringW(hInstance, IDS_PURPOSE_ADVANCED, buf,
      sizeof(buf) / sizeof(buf[0]));
-    SendMessageW(cb, CB_INSERTSTRING, -1, (LPARAM)buf);
+    index = SendMessageW(cb, CB_INSERTSTRING, -1, (LPARAM)buf);
+    SendMessageW(cb, CB_SETITEMDATA, index, (LPARAM)PurposeFilterShowAdvanced);
     SendMessageW(cb, CB_SETCURSEL, 0, 0);
     if ((usages = get_cert_mgr_usages()))
     {
@@ -235,26 +244,205 @@ static void initialize_purpose_selection(HWND hwnd)
             if (comma)
                 *comma = 0;
             if ((info = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY, ptr, 0)))
-                SendMessageW(GetDlgItem(hwnd, IDC_MGR_PURPOSE_SELECTION),
-                 CB_INSERTSTRING, 0, (LPARAM)info->pwszName);
+            {
+                index = SendMessageW(cb, CB_INSERTSTRING, 0,
+                 (LPARAM)info->pwszName);
+                SendMessageW(cb, CB_SETITEMDATA, index, (LPARAM)info);
+            }
         }
         HeapFree(GetProcessHeap(), 0, usages);
     }
 }
 
+extern BOOL WINAPI WTHelperGetKnownUsages(DWORD action,
+ PCCRYPT_OID_INFO **usages);
+
+static CERT_ENHKEY_USAGE *add_oid_to_usage(CERT_ENHKEY_USAGE *usage, LPSTR oid)
+{
+    if (!usage->cUsageIdentifier)
+        usage->rgpszUsageIdentifier = HeapAlloc(GetProcessHeap(), 0,
+         sizeof(LPSTR));
+    else
+        usage->rgpszUsageIdentifier = HeapReAlloc(GetProcessHeap(), 0,
+         usage->rgpszUsageIdentifier,
+         (usage->cUsageIdentifier + 1) * sizeof(LPSTR));
+    if (usage->rgpszUsageIdentifier)
+        usage->rgpszUsageIdentifier[usage->cUsageIdentifier++] = oid;
+    else
+    {
+        HeapFree(GetProcessHeap(), 0, usage);
+        usage = NULL;
+    }
+    return usage;
+}
+
+static CERT_ENHKEY_USAGE *convert_usages_str_to_usage(LPSTR usageStr)
+{
+    CERT_ENHKEY_USAGE *usage = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+     sizeof(CERT_ENHKEY_USAGE));
+
+    if (usage)
+    {
+        LPSTR ptr, comma;
+
+        for (ptr = usageStr, comma = strchr(ptr, ','); usage && ptr && *ptr;
+         ptr = comma ? comma + 1 : NULL,
+         comma = ptr ? strchr(ptr, ',') : NULL)
+        {
+            if (comma)
+                *comma = 0;
+            add_oid_to_usage(usage, ptr);
+        }
+    }
+    return usage;
+}
+
+static CERT_ENHKEY_USAGE *create_advanced_filter(void)
+{
+    CERT_ENHKEY_USAGE *advancedUsage = HeapAlloc(GetProcessHeap(),
+     HEAP_ZERO_MEMORY, sizeof(CERT_ENHKEY_USAGE));
+
+    if (advancedUsage)
+    {
+        PCCRYPT_OID_INFO *usages;
+
+        if (WTHelperGetKnownUsages(1, &usages))
+        {
+            LPSTR disabledUsagesStr;
+
+            if ((disabledUsagesStr = get_cert_mgr_usages()))
+            {
+                CERT_ENHKEY_USAGE *disabledUsages =
+                 convert_usages_str_to_usage(disabledUsagesStr);
+
+                if (disabledUsages)
+                {
+                    PCCRYPT_OID_INFO *ptr;
+
+                    for (ptr = usages; *ptr; ptr++)
+                    {
+                        DWORD i;
+                        BOOL disabled = FALSE;
+
+                        for (i = 0; !disabled &&
+                         i < disabledUsages->cUsageIdentifier; i++)
+                            if (!strcmp(disabledUsages->rgpszUsageIdentifier[i],
+                             (*ptr)->pszOID))
+                                disabled = TRUE;
+                        if (!disabled)
+                            add_oid_to_usage(advancedUsage,
+                             (LPSTR)(*ptr)->pszOID);
+                    }
+                    /* The individual strings are pointers to disabledUsagesStr,
+                     * so they're freed when it is.
+                     */
+                    HeapFree(GetProcessHeap(), 0,
+                     disabledUsages->rgpszUsageIdentifier);
+                    HeapFree(GetProcessHeap(), 0, disabledUsages);
+                }
+                HeapFree(GetProcessHeap(), 0, disabledUsagesStr);
+            }
+            WTHelperGetKnownUsages(2, &usages);
+        }
+    }
+    return advancedUsage;
+}
+
 static void show_store_certs(HWND hwnd, HCERTSTORE store)
 {
     HWND lv = GetDlgItem(hwnd, IDC_MGR_CERTS);
+    HWND cb = GetDlgItem(hwnd, IDC_MGR_PURPOSE_SELECTION);
     PCCERT_CONTEXT cert = NULL;
     DWORD allocatedLen = 0;
     LPWSTR str = NULL;
+    int index;
+    PurposeFilter filter = PurposeFilterShowAll;
+    LPCSTR oid = NULL;
+    CERT_ENHKEY_USAGE *advanced = NULL;
 
+    index = SendMessageW(cb, CB_GETCURSEL, 0, 0);
+    if (index >= 0)
+    {
+        INT_PTR data = SendMessageW(cb, CB_GETITEMDATA, index, 0);
+
+        if (!HIWORD(data))
+            filter = data;
+        else
+        {
+            PCCRYPT_OID_INFO info = (PCCRYPT_OID_INFO)data;
+
+            filter = PurposeFilterShowOID;
+            oid = info->pszOID;
+        }
+    }
+    if (filter == PurposeFilterShowAdvanced)
+        advanced = create_advanced_filter();
     do {
         cert = CertEnumCertificatesInStore(store, cert);
         if (cert)
-            add_cert_to_view(lv, cert, &allocatedLen, &str);
+        {
+            BOOL show = FALSE;
+
+            if (filter == PurposeFilterShowAll)
+                show = TRUE;
+            else
+            {
+                int numOIDs;
+                DWORD cbOIDs = 0;
+
+                if (CertGetValidUsages(1, &cert, &numOIDs, NULL, &cbOIDs))
+                {
+                    if (numOIDs == -1)
+                    {
+                        /* -1 implies all usages are valid */
+                        show = TRUE;
+                    }
+                    else
+                    {
+                        LPSTR *oids = HeapAlloc(GetProcessHeap(), 0, cbOIDs);
+
+                        if (oids)
+                        {
+                            if (CertGetValidUsages(1, &cert, &numOIDs, oids,
+                             &cbOIDs))
+                            {
+                                int i;
+
+                                if (filter == PurposeFilterShowOID)
+                                {
+                                    for (i = 0; !show && i < numOIDs; i++)
+                                        if (!strcmp(oids[i], oid))
+                                            show = TRUE;
+                                }
+                                else
+                                {
+                                    for (i = 0; !show && i < numOIDs; i++)
+                                    {
+                                        DWORD j;
+
+                                        for (j = 0; !show &&
+                                         j < advanced->cUsageIdentifier; j++)
+                                            if (!strcmp(oids[i],
+                                             advanced->rgpszUsageIdentifier[j]))
+                                                show = TRUE;
+                                    }
+                                }
+                            }
+                            HeapFree(GetProcessHeap(), 0, oids);
+                        }
+                    }
+                }
+            }
+            if (show)
+                add_cert_to_view(lv, cert, &allocatedLen, &str);
+        }
     } while (cert);
     HeapFree(GetProcessHeap(), 0, str);
+    if (advanced)
+    {
+        HeapFree(GetProcessHeap(), 0, advanced->rgpszUsageIdentifier);
+        HeapFree(GetProcessHeap(), 0, advanced);
+    }
 }
 
 static const WCHAR my[] = { 'M','y',0 };
@@ -375,9 +563,6 @@ static void add_known_usage(HWND lv, PCCRYPT_OID_INFO info,
     SendMessageW(lv, LVM_INSERTITEMW, 0, (LPARAM)&item);
 }
 
-extern BOOL WINAPI WTHelperGetKnownUsages(DWORD action,
- PCCRYPT_OID_INFO **usages);
-
 static void add_known_usages_to_list(HWND lv, CheckBitmapIndex state)
 {
     PCCRYPT_OID_INFO *usages;




More information about the wine-cvs mailing list