Juan Lang : cryptui: Implement saving from the export wizard.

Alexandre Julliard julliard at winehq.org
Mon Jan 26 10:13:47 CST 2009


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

Author: Juan Lang <juan.lang at gmail.com>
Date:   Fri Jan 23 12:50:30 2009 -0800

cryptui: Implement saving from the export wizard.

---

 dlls/cryptui/cryptui_En.rc |    2 +
 dlls/cryptui/cryptuires.h  |    2 +
 dlls/cryptui/main.c        |  176 +++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 179 insertions(+), 1 deletions(-)

diff --git a/dlls/cryptui/cryptui_En.rc b/dlls/cryptui/cryptui_En.rc
index 02dc514..d40d9c1 100644
--- a/dlls/cryptui/cryptui_En.rc
+++ b/dlls/cryptui/cryptui_En.rc
@@ -158,6 +158,8 @@ STRINGTABLE DISCARDABLE
     IDS_EXPORT_KEYS "Export keys"
     IDS_YES "Yes"
     IDS_NO "No"
+    IDS_EXPORT_SUCCEEDED "The export was successful."
+    IDS_EXPORT_FAILED "The export failed."
 }
 
 IDD_GENERAL DIALOG DISCARDABLE 0, 0, 255, 236
diff --git a/dlls/cryptui/cryptuires.h b/dlls/cryptui/cryptuires.h
index bf99375..7b8b4f2 100644
--- a/dlls/cryptui/cryptuires.h
+++ b/dlls/cryptui/cryptuires.h
@@ -157,6 +157,8 @@
 #define IDS_EXPORT_KEYS 1214
 #define IDS_YES 1215
 #define IDS_NO 1216
+#define IDS_EXPORT_SUCCEEDED 1217
+#define IDS_EXPORT_FAILED 1218
 
 #define IDD_GENERAL 100
 #define IDD_DETAIL 101
diff --git a/dlls/cryptui/main.c b/dlls/cryptui/main.c
index aaf6960..e473b4a 100644
--- a/dlls/cryptui/main.c
+++ b/dlls/cryptui/main.c
@@ -5449,6 +5449,7 @@ struct ExportWizData
     BOOL deletePrivateKey;
     LPWSTR fileName;
     HANDLE file;
+    BOOL success;
 };
 
 static LRESULT CALLBACK export_welcome_dlg_proc(HWND hwnd, UINT msg, WPARAM wp,
@@ -5991,6 +5992,147 @@ static void show_export_details(HWND lv, struct ExportWizData *data)
     SendMessageW(lv, LVM_SETITEMTEXTW, item.iItem, (LPARAM)&item);
 }
 
+static inline BOOL save_der(HANDLE file, const BYTE *pb, DWORD cb)
+{
+    DWORD bytesWritten;
+
+    return WriteFile(file, pb, cb, &bytesWritten, NULL);
+}
+
+static BOOL save_base64(HANDLE file, const BYTE *pb, DWORD cb)
+{
+    BOOL ret;
+    DWORD size = 0;
+
+    if ((ret = CryptBinaryToStringA(pb, cb, CRYPT_STRING_BASE64, NULL, &size)))
+    {
+        LPSTR buf = HeapAlloc(GetProcessHeap(), 0, size);
+
+        if (buf)
+        {
+            if ((ret = CryptBinaryToStringA(pb, cb, CRYPT_STRING_BASE64, buf,
+             &size)))
+                ret = WriteFile(file, buf, size, &size, NULL);
+            HeapFree(GetProcessHeap(), 0, buf);
+        }
+        else
+        {
+            SetLastError(ERROR_OUTOFMEMORY);
+            ret = FALSE;
+        }
+    }
+    return ret;
+}
+
+static BOOL save_cms(HANDLE file, PCCRYPTUI_WIZ_EXPORT_INFO pExportInfo,
+ BOOL includeChain)
+{
+    BOOL ret;
+    HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
+     CERT_STORE_CREATE_NEW_FLAG, NULL);
+
+    if (store)
+    {
+        if (includeChain)
+        {
+            HCERTSTORE addlStore = CertOpenStore(CERT_STORE_PROV_COLLECTION,
+             0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
+
+            if (addlStore)
+            {
+                DWORD i;
+
+                ret = TRUE;
+                for (i = 0; ret && i < pExportInfo->cStores; i++)
+                    ret = CertAddStoreToCollection(addlStore,
+                     pExportInfo->rghStores, 0, 0);
+                if (ret)
+                {
+                    PCCERT_CHAIN_CONTEXT chain;
+
+                    ret = CertGetCertificateChain(NULL,
+                     pExportInfo->u.pCertContext, NULL, addlStore, NULL, 0,
+                     NULL, &chain);
+                    if (ret)
+                    {
+                        DWORD j;
+
+                        for (i = 0; ret && i < chain->cChain; i++)
+                            for (j = 0; ret && j < chain->rgpChain[i]->cElement;
+                             j++)
+                                ret = CertAddCertificateContextToStore(store,
+                                 chain->rgpChain[i]->rgpElement[j]->pCertContext,
+                                 CERT_STORE_ADD_ALWAYS, NULL);
+                        CertFreeCertificateChain(chain);
+                    }
+                    else
+                    {
+                        /* No chain could be created, just add the individual
+                         * cert to the message.
+                         */
+                        ret = CertAddCertificateContextToStore(store,
+                         pExportInfo->u.pCertContext, CERT_STORE_ADD_ALWAYS,
+                         NULL);
+                    }
+                }
+                CertCloseStore(addlStore, 0);
+            }
+            else
+                ret = FALSE;
+        }
+        else
+            ret = CertAddCertificateContextToStore(store,
+             pExportInfo->u.pCertContext, CERT_STORE_ADD_ALWAYS, NULL);
+        if (ret)
+            ret = CertSaveStore(store, PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
+             CERT_STORE_SAVE_AS_PKCS7, CERT_STORE_SAVE_TO_FILE, file, 0);
+        CertCloseStore(store, 0);
+    }
+    else
+        ret = FALSE;
+    return ret;
+}
+
+static BOOL do_export(struct ExportWizData *data)
+{
+    BOOL ret;
+
+    switch (data->pExportInfo->dwSubjectChoice)
+    {
+    case CRYPTUI_WIZ_EXPORT_CRL_CONTEXT:
+        ret = save_der(data->file,
+         data->pExportInfo->u.pCRLContext->pbCrlEncoded,
+         data->pExportInfo->u.pCRLContext->cbCrlEncoded);
+        break;
+    case CRYPTUI_WIZ_EXPORT_CTL_CONTEXT:
+        ret = save_der(data->file,
+         data->pExportInfo->u.pCTLContext->pbCtlEncoded,
+         data->pExportInfo->u.pCTLContext->cbCtlEncoded);
+        break;
+    default:
+        switch (data->exportFormat)
+        {
+        case CRYPTUI_WIZ_EXPORT_FORMAT_BASE64:
+            ret = save_base64(data->file,
+             data->pExportInfo->u.pCertContext->pbCertEncoded,
+             data->pExportInfo->u.pCertContext->cbCertEncoded);
+            break;
+        case CRYPTUI_WIZ_EXPORT_FORMAT_PKCS7:
+            ret = save_cms(data->file, data->pExportInfo, data->includeChain);
+            break;
+        case CRYPTUI_WIZ_EXPORT_FORMAT_PFX:
+            FIXME("unimplemented for PFX\n");
+            ret = FALSE;
+            break;
+        default:
+            ret = save_der(data->file,
+             data->pExportInfo->u.pCertContext->pbCertEncoded,
+             data->pExportInfo->u.pCertContext->cbCertEncoded);
+        }
+    }
+    return ret;
+}
+
 static LRESULT CALLBACK export_finish_dlg_proc(HWND hwnd, UINT msg, WPARAM wp,
  LPARAM lp)
 {
@@ -6036,6 +6178,37 @@ static LRESULT CALLBACK export_finish_dlg_proc(HWND hwnd, UINT msg, WPARAM wp,
             ret = TRUE;
             break;
         }
+        case PSN_WIZFINISH:
+        {
+            int messageID;
+            WCHAR title[MAX_STRING_LEN], message[MAX_STRING_LEN];
+            LPCWSTR pTitle;
+            DWORD mbFlags;
+
+            data = (struct ExportWizData *)GetWindowLongPtrW(hwnd, DWLP_USER);
+            if ((data->success = do_export(data)))
+            {
+                messageID = IDS_EXPORT_SUCCEEDED;
+                mbFlags = MB_OK;
+            }
+            else
+            {
+                messageID = IDS_EXPORT_FAILED;
+                mbFlags = MB_OK | MB_ICONERROR;
+            }
+            if (data->pwszWizardTitle)
+                pTitle = data->pwszWizardTitle;
+            else
+            {
+                LoadStringW(hInstance, IDS_EXPORT_WIZARD, title,
+                 sizeof(title) / sizeof(title[0]));
+                pTitle = title;
+            }
+            LoadStringW(hInstance, messageID, message,
+             sizeof(message) / sizeof(message[0]));
+            MessageBoxW(hwnd, message, pTitle, mbFlags);
+            break;
+        }
         }
         break;
     }
@@ -6062,6 +6235,7 @@ static BOOL show_export_ui(DWORD dwFlags, HWND hwndParent,
     data.deletePrivateKey = FALSE;
     data.fileName = NULL;
     data.file = INVALID_HANDLE_VALUE;
+    data.success = FALSE;
 
     memset(&pages, 0, sizeof(pages));
 
@@ -6141,7 +6315,7 @@ static BOOL show_export_ui(DWORD dwFlags, HWND hwndParent,
     DeleteObject(data.titleFont);
     CloseHandle(data.file);
     HeapFree(GetProcessHeap(), 0, data.fileName);
-    return FALSE;
+    return data.success;
 }
 
 BOOL WINAPI CryptUIWizExport(DWORD dwFlags, HWND hwndParent,




More information about the wine-cvs mailing list