ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

store.c
Go to the documentation of this file.
00001 /*
00002  * Copyright 2002 Mike McCormack for CodeWeavers
00003  * Copyright 2004-2006 Juan Lang
00004  *
00005  * This library is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU Lesser General Public
00007  * License as published by the Free Software Foundation; either
00008  * version 2.1 of the License, or (at your option) any later version.
00009  *
00010  * This library is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Lesser General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU Lesser General Public
00016  * License along with this library; if not, write to the Free Software
00017  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00018  *
00019  * FIXME:
00020  * - The concept of physical stores and locations isn't implemented.  (This
00021  *   doesn't mean registry stores et al aren't implemented.  See the PSDK for
00022  *   registering and enumerating physical stores and locations.)
00023  * - Many flags, options and whatnot are unimplemented.
00024  */
00025 
00026 #include "config.h"
00027 #include "wine/port.h"
00028 
00029 #include <assert.h>
00030 #include <stdarg.h>
00031 #include "windef.h"
00032 #include "winbase.h"
00033 #include "winnls.h"
00034 #include "winreg.h"
00035 #include "winuser.h"
00036 #include "wincrypt.h"
00037 #include "wine/debug.h"
00038 #include "wine/list.h"
00039 #include "wine/exception.h"
00040 #include "crypt32_private.h"
00041 
00042 WINE_DEFAULT_DEBUG_CHANNEL(crypt);
00043 
00044 static const WINE_CONTEXT_INTERFACE gCertInterface = {
00045     (CreateContextFunc)CertCreateCertificateContext,
00046     (AddContextToStoreFunc)CertAddCertificateContextToStore,
00047     (AddEncodedContextToStoreFunc)CertAddEncodedCertificateToStore,
00048     (DuplicateContextFunc)CertDuplicateCertificateContext,
00049     (EnumContextsInStoreFunc)CertEnumCertificatesInStore,
00050     (EnumPropertiesFunc)CertEnumCertificateContextProperties,
00051     (GetContextPropertyFunc)CertGetCertificateContextProperty,
00052     (SetContextPropertyFunc)CertSetCertificateContextProperty,
00053     (SerializeElementFunc)CertSerializeCertificateStoreElement,
00054     (FreeContextFunc)CertFreeCertificateContext,
00055     (DeleteContextFunc)CertDeleteCertificateFromStore,
00056 };
00057 PCWINE_CONTEXT_INTERFACE pCertInterface = &gCertInterface;
00058 
00059 static const WINE_CONTEXT_INTERFACE gCRLInterface = {
00060     (CreateContextFunc)CertCreateCRLContext,
00061     (AddContextToStoreFunc)CertAddCRLContextToStore,
00062     (AddEncodedContextToStoreFunc)CertAddEncodedCRLToStore,
00063     (DuplicateContextFunc)CertDuplicateCRLContext,
00064     (EnumContextsInStoreFunc)CertEnumCRLsInStore,
00065     (EnumPropertiesFunc)CertEnumCRLContextProperties,
00066     (GetContextPropertyFunc)CertGetCRLContextProperty,
00067     (SetContextPropertyFunc)CertSetCRLContextProperty,
00068     (SerializeElementFunc)CertSerializeCRLStoreElement,
00069     (FreeContextFunc)CertFreeCRLContext,
00070     (DeleteContextFunc)CertDeleteCRLFromStore,
00071 };
00072 PCWINE_CONTEXT_INTERFACE pCRLInterface = &gCRLInterface;
00073 
00074 static const WINE_CONTEXT_INTERFACE gCTLInterface = {
00075     (CreateContextFunc)CertCreateCTLContext,
00076     (AddContextToStoreFunc)CertAddCTLContextToStore,
00077     (AddEncodedContextToStoreFunc)CertAddEncodedCTLToStore,
00078     (DuplicateContextFunc)CertDuplicateCTLContext,
00079     (EnumContextsInStoreFunc)CertEnumCTLsInStore,
00080     (EnumPropertiesFunc)CertEnumCTLContextProperties,
00081     (GetContextPropertyFunc)CertGetCTLContextProperty,
00082     (SetContextPropertyFunc)CertSetCTLContextProperty,
00083     (SerializeElementFunc)CertSerializeCTLStoreElement,
00084     (FreeContextFunc)CertFreeCTLContext,
00085     (DeleteContextFunc)CertDeleteCTLFromStore,
00086 };
00087 PCWINE_CONTEXT_INTERFACE pCTLInterface = &gCTLInterface;
00088 
00089 typedef struct _WINE_MEMSTORE
00090 {
00091     WINECRYPT_CERTSTORE hdr;
00092     struct ContextList *certs;
00093     struct ContextList *crls;
00094     struct ContextList *ctls;
00095 } WINE_MEMSTORE, *PWINE_MEMSTORE;
00096 
00097 void CRYPT_InitStore(WINECRYPT_CERTSTORE *store, DWORD dwFlags,
00098  CertStoreType type)
00099 {
00100     store->ref = 1;
00101     store->dwMagic = WINE_CRYPTCERTSTORE_MAGIC;
00102     store->type = type;
00103     store->dwOpenFlags = dwFlags;
00104     store->properties = NULL;
00105 }
00106 
00107 void CRYPT_FreeStore(PWINECRYPT_CERTSTORE store)
00108 {
00109     if (store->properties)
00110         ContextPropertyList_Free(store->properties);
00111     CryptMemFree(store);
00112 }
00113 
00114 BOOL WINAPI I_CertUpdateStore(HCERTSTORE store1, HCERTSTORE store2, DWORD unk0,
00115  DWORD unk1)
00116 {
00117     static BOOL warned = FALSE;
00118     const WINE_CONTEXT_INTERFACE * const interfaces[] = { pCertInterface,
00119      pCRLInterface, pCTLInterface };
00120     DWORD i;
00121 
00122     TRACE("(%p, %p, %08x, %08x)\n", store1, store2, unk0, unk1);
00123     if (!warned)
00124     {
00125         FIXME("semi-stub\n");
00126         warned = TRUE;
00127     }
00128 
00129     /* Poor-man's resync:  empty first store, then add everything from second
00130      * store to it.
00131      */
00132     for (i = 0; i < sizeof(interfaces) / sizeof(interfaces[0]); i++)
00133     {
00134         const void *context;
00135 
00136         do {
00137             context = interfaces[i]->enumContextsInStore(store1, NULL);
00138             if (context)
00139                 interfaces[i]->deleteFromStore(context);
00140         } while (context);
00141         do {
00142             context = interfaces[i]->enumContextsInStore(store2, context);
00143             if (context)
00144                 interfaces[i]->addContextToStore(store1, context,
00145                  CERT_STORE_ADD_ALWAYS, NULL);
00146         } while (context);
00147     }
00148     return TRUE;
00149 }
00150 
00151 static BOOL CRYPT_MemAddCert(PWINECRYPT_CERTSTORE store, void *cert,
00152  void *toReplace, const void **ppStoreContext)
00153 {
00154     WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
00155     PCERT_CONTEXT context;
00156 
00157     TRACE("(%p, %p, %p, %p)\n", store, cert, toReplace, ppStoreContext);
00158 
00159     context = ContextList_Add(ms->certs, cert, toReplace);
00160     if (context)
00161     {
00162         context->hCertStore = store;
00163         if (ppStoreContext)
00164             *ppStoreContext = CertDuplicateCertificateContext(context);
00165     }
00166     return context ? TRUE : FALSE;
00167 }
00168 
00169 static void *CRYPT_MemEnumCert(PWINECRYPT_CERTSTORE store, void *pPrev)
00170 {
00171     WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
00172     void *ret;
00173 
00174     TRACE("(%p, %p)\n", store, pPrev);
00175 
00176     ret = ContextList_Enum(ms->certs, pPrev);
00177     if (!ret)
00178         SetLastError(CRYPT_E_NOT_FOUND);
00179 
00180     TRACE("returning %p\n", ret);
00181     return ret;
00182 }
00183 
00184 static BOOL CRYPT_MemDeleteCert(PWINECRYPT_CERTSTORE store, void *pCertContext)
00185 {
00186     WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
00187     BOOL ret;
00188 
00189     if (ContextList_Remove(ms->certs, pCertContext))
00190         ret = CertFreeCertificateContext(pCertContext);
00191     else
00192         ret = TRUE;
00193     return ret;
00194 }
00195 
00196 static BOOL CRYPT_MemAddCrl(PWINECRYPT_CERTSTORE store, void *crl,
00197  void *toReplace, const void **ppStoreContext)
00198 {
00199     WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
00200     PCRL_CONTEXT context;
00201 
00202     TRACE("(%p, %p, %p, %p)\n", store, crl, toReplace, ppStoreContext);
00203 
00204     context = ContextList_Add(ms->crls, crl, toReplace);
00205     if (context)
00206     {
00207         context->hCertStore = store;
00208         if (ppStoreContext)
00209             *ppStoreContext = CertDuplicateCRLContext(context);
00210     }
00211     return context ? TRUE : FALSE;
00212 }
00213 
00214 static void *CRYPT_MemEnumCrl(PWINECRYPT_CERTSTORE store, void *pPrev)
00215 {
00216     WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
00217     void *ret;
00218 
00219     TRACE("(%p, %p)\n", store, pPrev);
00220 
00221     ret = ContextList_Enum(ms->crls, pPrev);
00222     if (!ret)
00223         SetLastError(CRYPT_E_NOT_FOUND);
00224 
00225     TRACE("returning %p\n", ret);
00226     return ret;
00227 }
00228 
00229 static BOOL CRYPT_MemDeleteCrl(PWINECRYPT_CERTSTORE store, void *pCrlContext)
00230 {
00231     WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
00232     BOOL ret;
00233 
00234     if (ContextList_Remove(ms->crls, pCrlContext))
00235         ret = CertFreeCRLContext(pCrlContext);
00236     else
00237         ret = TRUE;
00238     return ret;
00239 }
00240 
00241 static BOOL CRYPT_MemAddCtl(PWINECRYPT_CERTSTORE store, void *ctl,
00242  void *toReplace, const void **ppStoreContext)
00243 {
00244     WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
00245     PCTL_CONTEXT context;
00246 
00247     TRACE("(%p, %p, %p, %p)\n", store, ctl, toReplace, ppStoreContext);
00248 
00249     context = ContextList_Add(ms->ctls, ctl, toReplace);
00250     if (context)
00251     {
00252         context->hCertStore = store;
00253         if (ppStoreContext)
00254             *ppStoreContext = CertDuplicateCTLContext(context);
00255     }
00256     return context ? TRUE : FALSE;
00257 }
00258 
00259 static void *CRYPT_MemEnumCtl(PWINECRYPT_CERTSTORE store, void *pPrev)
00260 {
00261     WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
00262     void *ret;
00263 
00264     TRACE("(%p, %p)\n", store, pPrev);
00265 
00266     ret = ContextList_Enum(ms->ctls, pPrev);
00267     if (!ret)
00268         SetLastError(CRYPT_E_NOT_FOUND);
00269 
00270     TRACE("returning %p\n", ret);
00271     return ret;
00272 }
00273 
00274 static BOOL CRYPT_MemDeleteCtl(PWINECRYPT_CERTSTORE store, void *pCtlContext)
00275 {
00276     WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store;
00277     BOOL ret;
00278 
00279     if (ContextList_Remove(ms->ctls, pCtlContext))
00280         ret = CertFreeCTLContext(pCtlContext);
00281     else
00282         ret = TRUE;
00283     return ret;
00284 }
00285 
00286 static BOOL WINAPI CRYPT_MemControl(HCERTSTORE hCertStore, DWORD dwFlags,
00287  DWORD dwCtrlType, void const *pvCtrlPara)
00288 {
00289     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
00290     return FALSE;
00291 }
00292 
00293 static void WINAPI CRYPT_MemCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
00294 {
00295     WINE_MEMSTORE *store = hCertStore;
00296 
00297     TRACE("(%p, %08x)\n", store, dwFlags);
00298     if (dwFlags)
00299         FIXME("Unimplemented flags: %08x\n", dwFlags);
00300 
00301     ContextList_Free(store->certs);
00302     ContextList_Free(store->crls);
00303     ContextList_Free(store->ctls);
00304     CRYPT_FreeStore((PWINECRYPT_CERTSTORE)store);
00305 }
00306 
00307 static WINECRYPT_CERTSTORE *CRYPT_MemOpenStore(HCRYPTPROV hCryptProv,
00308  DWORD dwFlags, const void *pvPara)
00309 {
00310     PWINE_MEMSTORE store;
00311 
00312     TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
00313 
00314     if (dwFlags & CERT_STORE_DELETE_FLAG)
00315     {
00316         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
00317         store = NULL;
00318     }
00319     else
00320     {
00321         store = CryptMemAlloc(sizeof(WINE_MEMSTORE));
00322         if (store)
00323         {
00324             memset(store, 0, sizeof(WINE_MEMSTORE));
00325             CRYPT_InitStore(&store->hdr, dwFlags, StoreTypeMem);
00326             store->hdr.closeStore          = CRYPT_MemCloseStore;
00327             store->hdr.certs.addContext    = CRYPT_MemAddCert;
00328             store->hdr.certs.enumContext   = CRYPT_MemEnumCert;
00329             store->hdr.certs.deleteContext = CRYPT_MemDeleteCert;
00330             store->hdr.crls.addContext     = CRYPT_MemAddCrl;
00331             store->hdr.crls.enumContext    = CRYPT_MemEnumCrl;
00332             store->hdr.crls.deleteContext  = CRYPT_MemDeleteCrl;
00333             store->hdr.ctls.addContext     = CRYPT_MemAddCtl;
00334             store->hdr.ctls.enumContext    = CRYPT_MemEnumCtl;
00335             store->hdr.ctls.deleteContext  = CRYPT_MemDeleteCtl;
00336             store->hdr.control             = CRYPT_MemControl;
00337             store->certs = ContextList_Create(pCertInterface,
00338              sizeof(CERT_CONTEXT));
00339             store->crls = ContextList_Create(pCRLInterface,
00340              sizeof(CRL_CONTEXT));
00341             store->ctls = ContextList_Create(pCTLInterface,
00342              sizeof(CTL_CONTEXT));
00343             /* Mem store doesn't need crypto provider, so close it */
00344             if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
00345                 CryptReleaseContext(hCryptProv, 0);
00346         }
00347     }
00348     return (PWINECRYPT_CERTSTORE)store;
00349 }
00350 
00351 static const WCHAR rootW[] = { 'R','o','o','t',0 };
00352 
00353 static PWINECRYPT_CERTSTORE CRYPT_SysRegOpenStoreW(HCRYPTPROV hCryptProv,
00354  DWORD dwFlags, const void *pvPara)
00355 {
00356     static const WCHAR fmt[] = { '%','s','\\','%','s',0 };
00357     LPCWSTR storeName = pvPara;
00358     LPWSTR storePath;
00359     PWINECRYPT_CERTSTORE store = NULL;
00360     HKEY root;
00361     LPCWSTR base;
00362 
00363     TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
00364      debugstr_w(pvPara));
00365 
00366     if (!pvPara)
00367     {
00368         SetLastError(E_INVALIDARG);
00369         return NULL;
00370     }
00371     /* FIXME:  In Windows, the root store (even the current user location) is
00372      * protected:  adding to it or removing from it present a user interface,
00373      * and the keys are owned by the system process, not the current user.
00374      * Wine's registry doesn't implement access controls, so a similar
00375      * mechanism isn't possible yet.
00376      */
00377     if ((dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK) ==
00378      CERT_SYSTEM_STORE_LOCAL_MACHINE && !lstrcmpiW(storeName, rootW))
00379         return CRYPT_RootOpenStore(hCryptProv, dwFlags);
00380 
00381     switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK)
00382     {
00383     case CERT_SYSTEM_STORE_LOCAL_MACHINE:
00384         root = HKEY_LOCAL_MACHINE;
00385         base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH;
00386         break;
00387     case CERT_SYSTEM_STORE_CURRENT_USER:
00388         root = HKEY_CURRENT_USER;
00389         base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH;
00390         break;
00391     case CERT_SYSTEM_STORE_CURRENT_SERVICE:
00392         /* hklm\Software\Microsoft\Cryptography\Services\servicename\
00393          * SystemCertificates
00394          */
00395         FIXME("CERT_SYSTEM_STORE_CURRENT_SERVICE, %s: stub\n",
00396          debugstr_w(storeName));
00397         return NULL;
00398     case CERT_SYSTEM_STORE_SERVICES:
00399         /* hklm\Software\Microsoft\Cryptography\Services\servicename\
00400          * SystemCertificates
00401          */
00402         FIXME("CERT_SYSTEM_STORE_SERVICES, %s: stub\n",
00403          debugstr_w(storeName));
00404         return NULL;
00405     case CERT_SYSTEM_STORE_USERS:
00406         /* hku\user sid\Software\Microsoft\SystemCertificates */
00407         FIXME("CERT_SYSTEM_STORE_USERS, %s: stub\n",
00408          debugstr_w(storeName));
00409         return NULL;
00410     case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY:
00411         root = HKEY_CURRENT_USER;
00412         base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
00413         break;
00414     case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY:
00415         root = HKEY_LOCAL_MACHINE;
00416         base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
00417         break;
00418     case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE:
00419         /* hklm\Software\Microsoft\EnterpriseCertificates */
00420         FIXME("CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE, %s: stub\n",
00421          debugstr_w(storeName));
00422         return NULL;
00423     default:
00424         SetLastError(E_INVALIDARG);
00425         return NULL;
00426     }
00427 
00428     storePath = CryptMemAlloc((lstrlenW(base) + lstrlenW(storeName) + 2) *
00429      sizeof(WCHAR));
00430     if (storePath)
00431     {
00432         LONG rc;
00433         HKEY key;
00434         REGSAM sam = dwFlags & CERT_STORE_READONLY_FLAG ? KEY_READ :
00435             KEY_ALL_ACCESS;
00436 
00437         wsprintfW(storePath, fmt, base, storeName);
00438         if (dwFlags & CERT_STORE_OPEN_EXISTING_FLAG)
00439             rc = RegOpenKeyExW(root, storePath, 0, sam, &key);
00440         else
00441         {
00442             DWORD disp;
00443 
00444             rc = RegCreateKeyExW(root, storePath, 0, NULL, 0, sam, NULL,
00445                                  &key, &disp);
00446             if (!rc && dwFlags & CERT_STORE_CREATE_NEW_FLAG &&
00447                 disp == REG_OPENED_EXISTING_KEY)
00448             {
00449                 RegCloseKey(key);
00450                 rc = ERROR_FILE_EXISTS;
00451             }
00452         }
00453         if (!rc)
00454         {
00455             store = CRYPT_RegOpenStore(hCryptProv, dwFlags, key);
00456             RegCloseKey(key);
00457         }
00458         else
00459             SetLastError(rc);
00460         CryptMemFree(storePath);
00461     }
00462     return store;
00463 }
00464 
00465 static PWINECRYPT_CERTSTORE CRYPT_SysRegOpenStoreA(HCRYPTPROV hCryptProv,
00466  DWORD dwFlags, const void *pvPara)
00467 {
00468     int len;
00469     PWINECRYPT_CERTSTORE ret = NULL;
00470 
00471     TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
00472      debugstr_a(pvPara));
00473 
00474     if (!pvPara)
00475     {
00476         SetLastError(ERROR_FILE_NOT_FOUND);
00477         return NULL;
00478     }
00479     len = MultiByteToWideChar(CP_ACP, 0, pvPara, -1, NULL, 0);
00480     if (len)
00481     {
00482         LPWSTR storeName = CryptMemAlloc(len * sizeof(WCHAR));
00483 
00484         if (storeName)
00485         {
00486             MultiByteToWideChar(CP_ACP, 0, pvPara, -1, storeName, len);
00487             ret = CRYPT_SysRegOpenStoreW(hCryptProv, dwFlags, storeName);
00488             CryptMemFree(storeName);
00489         }
00490     }
00491     return ret;
00492 }
00493 
00494 static PWINECRYPT_CERTSTORE CRYPT_SysOpenStoreW(HCRYPTPROV hCryptProv,
00495  DWORD dwFlags, const void *pvPara)
00496 {
00497     HCERTSTORE store = 0;
00498     BOOL ret;
00499 
00500     TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
00501      debugstr_w(pvPara));
00502 
00503     if (!pvPara)
00504     {
00505         SetLastError(ERROR_FILE_NOT_FOUND);
00506         return NULL;
00507     }
00508     /* This returns a different error than system registry stores if the
00509      * location is invalid.
00510      */
00511     switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK)
00512     {
00513     case CERT_SYSTEM_STORE_LOCAL_MACHINE:
00514     case CERT_SYSTEM_STORE_CURRENT_USER:
00515     case CERT_SYSTEM_STORE_CURRENT_SERVICE:
00516     case CERT_SYSTEM_STORE_SERVICES:
00517     case CERT_SYSTEM_STORE_USERS:
00518     case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY:
00519     case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY:
00520     case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE:
00521         ret = TRUE;
00522         break;
00523     default:
00524         SetLastError(ERROR_FILE_NOT_FOUND);
00525         ret = FALSE;
00526     }
00527     if (ret)
00528     {
00529         HCERTSTORE regStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W,
00530          0, 0, dwFlags, pvPara);
00531 
00532         if (regStore)
00533         {
00534             store = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0,
00535              CERT_STORE_CREATE_NEW_FLAG, NULL);
00536             CertAddStoreToCollection(store, regStore,
00537              dwFlags & CERT_STORE_READONLY_FLAG ? 0 :
00538              CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
00539             CertCloseStore(regStore, 0);
00540             /* CERT_SYSTEM_STORE_CURRENT_USER returns both the HKCU and HKLM
00541              * stores.
00542              */
00543             if ((dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK) ==
00544              CERT_SYSTEM_STORE_CURRENT_USER)
00545             {
00546                 dwFlags &= ~CERT_SYSTEM_STORE_CURRENT_USER;
00547                 dwFlags |= CERT_SYSTEM_STORE_LOCAL_MACHINE;
00548                 regStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W, 0,
00549                  0, dwFlags, pvPara);
00550                 if (regStore)
00551                 {
00552                     CertAddStoreToCollection(store, regStore,
00553                      dwFlags & CERT_STORE_READONLY_FLAG ? 0 :
00554                      CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0);
00555                     CertCloseStore(regStore, 0);
00556                 }
00557             }
00558             /* System store doesn't need crypto provider, so close it */
00559             if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
00560                 CryptReleaseContext(hCryptProv, 0);
00561         }
00562     }
00563     return store;
00564 }
00565 
00566 static PWINECRYPT_CERTSTORE CRYPT_SysOpenStoreA(HCRYPTPROV hCryptProv,
00567  DWORD dwFlags, const void *pvPara)
00568 {
00569     int len;
00570     PWINECRYPT_CERTSTORE ret = NULL;
00571 
00572     TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags,
00573      debugstr_a(pvPara));
00574 
00575     if (!pvPara)
00576     {
00577         SetLastError(ERROR_FILE_NOT_FOUND);
00578         return NULL;
00579     }
00580     len = MultiByteToWideChar(CP_ACP, 0, pvPara, -1, NULL, 0);
00581     if (len)
00582     {
00583         LPWSTR storeName = CryptMemAlloc(len * sizeof(WCHAR));
00584 
00585         if (storeName)
00586         {
00587             MultiByteToWideChar(CP_ACP, 0, pvPara, -1, storeName, len);
00588             ret = CRYPT_SysOpenStoreW(hCryptProv, dwFlags, storeName);
00589             CryptMemFree(storeName);
00590         }
00591     }
00592     return ret;
00593 }
00594 
00595 static void WINAPI CRYPT_MsgCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
00596 {
00597     HCRYPTMSG msg = hCertStore;
00598 
00599     TRACE("(%p, %08x)\n", msg, dwFlags);
00600     CryptMsgClose(msg);
00601 }
00602 
00603 static void *msgProvFuncs[] = {
00604     CRYPT_MsgCloseStore,
00605 };
00606 
00607 static PWINECRYPT_CERTSTORE CRYPT_MsgOpenStore(HCRYPTPROV hCryptProv,
00608  DWORD dwFlags, const void *pvPara)
00609 {
00610     PWINECRYPT_CERTSTORE store = NULL;
00611     HCRYPTMSG msg = (HCRYPTMSG)pvPara;
00612     PWINECRYPT_CERTSTORE memStore;
00613 
00614     TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
00615 
00616     memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
00617      CERT_STORE_CREATE_NEW_FLAG, NULL);
00618     if (memStore)
00619     {
00620         BOOL ret;
00621         DWORD size, count, i;
00622 
00623         size = sizeof(count);
00624         ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &count, &size);
00625         for (i = 0; ret && i < count; i++)
00626         {
00627             size = 0;
00628             ret = CryptMsgGetParam(msg, CMSG_CERT_PARAM, i, NULL, &size);
00629             if (ret)
00630             {
00631                 LPBYTE buf = CryptMemAlloc(size);
00632 
00633                 if (buf)
00634                 {
00635                     ret = CryptMsgGetParam(msg, CMSG_CERT_PARAM, i, buf, &size);
00636                     if (ret)
00637                         ret = CertAddEncodedCertificateToStore(memStore,
00638                          X509_ASN_ENCODING, buf, size, CERT_STORE_ADD_ALWAYS,
00639                          NULL);
00640                     CryptMemFree(buf);
00641                 }
00642             }
00643         }
00644         size = sizeof(count);
00645         ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &count, &size);
00646         for (i = 0; ret && i < count; i++)
00647         {
00648             size = 0;
00649             ret = CryptMsgGetParam(msg, CMSG_CRL_PARAM, i, NULL, &size);
00650             if (ret)
00651             {
00652                 LPBYTE buf = CryptMemAlloc(size);
00653 
00654                 if (buf)
00655                 {
00656                     ret = CryptMsgGetParam(msg, CMSG_CRL_PARAM, i, buf, &size);
00657                     if (ret)
00658                         ret = CertAddEncodedCRLToStore(memStore,
00659                          X509_ASN_ENCODING, buf, size, CERT_STORE_ADD_ALWAYS,
00660                          NULL);
00661                     CryptMemFree(buf);
00662                 }
00663             }
00664         }
00665         if (ret)
00666         {
00667             CERT_STORE_PROV_INFO provInfo = { 0 };
00668 
00669             provInfo.cbSize = sizeof(provInfo);
00670             provInfo.cStoreProvFunc = sizeof(msgProvFuncs) /
00671              sizeof(msgProvFuncs[0]);
00672             provInfo.rgpvStoreProvFunc = msgProvFuncs;
00673             provInfo.hStoreProv = CryptMsgDuplicate(msg);
00674             store = CRYPT_ProvCreateStore(dwFlags, memStore, &provInfo);
00675             /* Msg store doesn't need crypto provider, so close it */
00676             if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
00677                 CryptReleaseContext(hCryptProv, 0);
00678         }
00679         else
00680             CertCloseStore(memStore, 0);
00681     }
00682     TRACE("returning %p\n", store);
00683     return store;
00684 }
00685 
00686 static PWINECRYPT_CERTSTORE CRYPT_PKCSOpenStore(HCRYPTPROV hCryptProv,
00687  DWORD dwFlags, const void *pvPara)
00688 {
00689     HCRYPTMSG msg;
00690     PWINECRYPT_CERTSTORE store = NULL;
00691     const CRYPT_DATA_BLOB *data = pvPara;
00692     BOOL ret;
00693     DWORD msgOpenFlags = dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG ? 0 :
00694      CMSG_CRYPT_RELEASE_CONTEXT_FLAG;
00695 
00696     TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
00697 
00698     msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, msgOpenFlags, CMSG_SIGNED,
00699      hCryptProv, NULL, NULL);
00700     ret = CryptMsgUpdate(msg, data->pbData, data->cbData, TRUE);
00701     if (!ret)
00702     {
00703         CryptMsgClose(msg);
00704         msg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING, msgOpenFlags, 0,
00705          hCryptProv, NULL, NULL);
00706         ret = CryptMsgUpdate(msg, data->pbData, data->cbData, TRUE);
00707         if (ret)
00708         {
00709             DWORD type, size = sizeof(type);
00710 
00711             /* Only signed messages are allowed, check type */
00712             ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &type, &size);
00713             if (ret && type != CMSG_SIGNED)
00714             {
00715                 SetLastError(CRYPT_E_INVALID_MSG_TYPE);
00716                 ret = FALSE;
00717             }
00718         }
00719     }
00720     if (ret)
00721         store = CRYPT_MsgOpenStore(0, dwFlags, msg);
00722     CryptMsgClose(msg);
00723     TRACE("returning %p\n", store);
00724     return store;
00725 }
00726 
00727 static PWINECRYPT_CERTSTORE CRYPT_SerializedOpenStore(HCRYPTPROV hCryptProv,
00728  DWORD dwFlags, const void *pvPara)
00729 {
00730     HCERTSTORE store;
00731     const CRYPT_DATA_BLOB *data = pvPara;
00732 
00733     TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara);
00734 
00735     if (dwFlags & CERT_STORE_DELETE_FLAG)
00736     {
00737         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
00738         return NULL;
00739     }
00740 
00741     store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
00742      CERT_STORE_CREATE_NEW_FLAG, NULL);
00743     if (store)
00744     {
00745         if (!CRYPT_ReadSerializedStoreFromBlob(data, store))
00746         {
00747             CertCloseStore(store, 0);
00748             store = NULL;
00749         }
00750     }
00751     TRACE("returning %p\n", store);
00752     return (PWINECRYPT_CERTSTORE)store;
00753 }
00754 
00755 static PWINECRYPT_CERTSTORE CRYPT_PhysOpenStoreW(HCRYPTPROV hCryptProv,
00756  DWORD dwFlags, const void *pvPara)
00757 {
00758     if (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG)
00759         FIXME("(%ld, %08x, %p): stub\n", hCryptProv, dwFlags, pvPara);
00760     else
00761         FIXME("(%ld, %08x, %s): stub\n", hCryptProv, dwFlags,
00762          debugstr_w(pvPara));
00763     return NULL;
00764 }
00765 
00766 HCERTSTORE WINAPI CertOpenStore(LPCSTR lpszStoreProvider,
00767  DWORD dwMsgAndCertEncodingType, HCRYPTPROV_LEGACY hCryptProv, DWORD dwFlags,
00768  const void* pvPara)
00769 {
00770     WINECRYPT_CERTSTORE *hcs;
00771     StoreOpenFunc openFunc = NULL;
00772 
00773     TRACE("(%s, %08x, %08lx, %08x, %p)\n", debugstr_a(lpszStoreProvider),
00774           dwMsgAndCertEncodingType, hCryptProv, dwFlags, pvPara);
00775 
00776     if (IS_INTOID(lpszStoreProvider))
00777     {
00778         switch (LOWORD(lpszStoreProvider))
00779         {
00780         case LOWORD(CERT_STORE_PROV_MSG):
00781             openFunc = CRYPT_MsgOpenStore;
00782             break;
00783         case LOWORD(CERT_STORE_PROV_MEMORY):
00784             openFunc = CRYPT_MemOpenStore;
00785             break;
00786         case LOWORD(CERT_STORE_PROV_FILE):
00787             openFunc = CRYPT_FileOpenStore;
00788             break;
00789         case LOWORD(CERT_STORE_PROV_PKCS7):
00790             openFunc = CRYPT_PKCSOpenStore;
00791             break;
00792         case LOWORD(CERT_STORE_PROV_SERIALIZED):
00793             openFunc = CRYPT_SerializedOpenStore;
00794             break;
00795         case LOWORD(CERT_STORE_PROV_REG):
00796             openFunc = CRYPT_RegOpenStore;
00797             break;
00798         case LOWORD(CERT_STORE_PROV_FILENAME_A):
00799             openFunc = CRYPT_FileNameOpenStoreA;
00800             break;
00801         case LOWORD(CERT_STORE_PROV_FILENAME_W):
00802             openFunc = CRYPT_FileNameOpenStoreW;
00803             break;
00804         case LOWORD(CERT_STORE_PROV_COLLECTION):
00805             openFunc = CRYPT_CollectionOpenStore;
00806             break;
00807         case LOWORD(CERT_STORE_PROV_SYSTEM_A):
00808             openFunc = CRYPT_SysOpenStoreA;
00809             break;
00810         case LOWORD(CERT_STORE_PROV_SYSTEM_W):
00811             openFunc = CRYPT_SysOpenStoreW;
00812             break;
00813         case LOWORD(CERT_STORE_PROV_SYSTEM_REGISTRY_A):
00814             openFunc = CRYPT_SysRegOpenStoreA;
00815             break;
00816         case LOWORD(CERT_STORE_PROV_SYSTEM_REGISTRY_W):
00817             openFunc = CRYPT_SysRegOpenStoreW;
00818             break;
00819         case LOWORD(CERT_STORE_PROV_PHYSICAL_W):
00820             openFunc = CRYPT_PhysOpenStoreW;
00821             break;
00822         default:
00823             if (LOWORD(lpszStoreProvider))
00824                 FIXME("unimplemented type %d\n", LOWORD(lpszStoreProvider));
00825         }
00826     }
00827     else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_MEMORY))
00828         openFunc = CRYPT_MemOpenStore;
00829     else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_FILENAME_W))
00830         openFunc = CRYPT_FileOpenStore;
00831     else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_SYSTEM))
00832         openFunc = CRYPT_SysOpenStoreW;
00833     else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_PKCS7))
00834         openFunc = CRYPT_PKCSOpenStore;
00835     else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_SERIALIZED))
00836         openFunc = CRYPT_SerializedOpenStore;
00837     else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_COLLECTION))
00838         openFunc = CRYPT_CollectionOpenStore;
00839     else if (!strcasecmp(lpszStoreProvider, sz_CERT_STORE_PROV_SYSTEM_REGISTRY))
00840         openFunc = CRYPT_SysRegOpenStoreW;
00841     else
00842     {
00843         FIXME("unimplemented type %s\n", lpszStoreProvider);
00844         openFunc = NULL;
00845     }
00846 
00847     if (!openFunc)
00848         hcs = CRYPT_ProvOpenStore(lpszStoreProvider, dwMsgAndCertEncodingType,
00849          hCryptProv, dwFlags, pvPara);
00850     else
00851         hcs = openFunc(hCryptProv, dwFlags, pvPara);
00852     return hcs;
00853 }
00854 
00855 HCERTSTORE WINAPI CertOpenSystemStoreA(HCRYPTPROV_LEGACY hProv,
00856  LPCSTR szSubSystemProtocol)
00857 {
00858     if (!szSubSystemProtocol)
00859     {
00860         SetLastError(E_INVALIDARG);
00861         return 0;
00862     }
00863     return CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, hProv,
00864      CERT_SYSTEM_STORE_CURRENT_USER, szSubSystemProtocol);
00865 }
00866 
00867 HCERTSTORE WINAPI CertOpenSystemStoreW(HCRYPTPROV_LEGACY hProv,
00868  LPCWSTR szSubSystemProtocol)
00869 {
00870     if (!szSubSystemProtocol)
00871     {
00872         SetLastError(E_INVALIDARG);
00873         return 0;
00874     }
00875     return CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, hProv,
00876      CERT_SYSTEM_STORE_CURRENT_USER, szSubSystemProtocol);
00877 }
00878 
00879 #define CertContext_CopyProperties(to, from) \
00880  Context_CopyProperties((to), (from), sizeof(CERT_CONTEXT))
00881 
00882 BOOL WINAPI CertAddCertificateContextToStore(HCERTSTORE hCertStore,
00883  PCCERT_CONTEXT pCertContext, DWORD dwAddDisposition,
00884  PCCERT_CONTEXT *ppStoreContext)
00885 {
00886     PWINECRYPT_CERTSTORE store = hCertStore;
00887     BOOL ret = TRUE;
00888     PCCERT_CONTEXT toAdd = NULL, existing = NULL;
00889 
00890     TRACE("(%p, %p, %08x, %p)\n", hCertStore, pCertContext,
00891      dwAddDisposition, ppStoreContext);
00892 
00893     switch (dwAddDisposition)
00894     {
00895     case CERT_STORE_ADD_ALWAYS:
00896         break;
00897     case CERT_STORE_ADD_NEW:
00898     case CERT_STORE_ADD_REPLACE_EXISTING:
00899     case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES:
00900     case CERT_STORE_ADD_USE_EXISTING:
00901     case CERT_STORE_ADD_NEWER:
00902     case CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES:
00903     {
00904         BYTE hashToAdd[20];
00905         DWORD size = sizeof(hashToAdd);
00906 
00907         ret = CertGetCertificateContextProperty(pCertContext, CERT_HASH_PROP_ID,
00908          hashToAdd, &size);
00909         if (ret)
00910         {
00911             CRYPT_HASH_BLOB blob = { sizeof(hashToAdd), hashToAdd };
00912 
00913             existing = CertFindCertificateInStore(hCertStore,
00914              pCertContext->dwCertEncodingType, 0, CERT_FIND_SHA1_HASH, &blob,
00915              NULL);
00916         }
00917         break;
00918     }
00919     default:
00920         FIXME("Unimplemented add disposition %d\n", dwAddDisposition);
00921         SetLastError(E_INVALIDARG);
00922         ret = FALSE;
00923     }
00924 
00925     switch (dwAddDisposition)
00926     {
00927     case CERT_STORE_ADD_ALWAYS:
00928         toAdd = CertDuplicateCertificateContext(pCertContext);
00929         break;
00930     case CERT_STORE_ADD_NEW:
00931         if (existing)
00932         {
00933             TRACE("found matching certificate, not adding\n");
00934             SetLastError(CRYPT_E_EXISTS);
00935             ret = FALSE;
00936         }
00937         else
00938             toAdd = CertDuplicateCertificateContext(pCertContext);
00939         break;
00940     case CERT_STORE_ADD_REPLACE_EXISTING:
00941         toAdd = CertDuplicateCertificateContext(pCertContext);
00942         break;
00943     case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES:
00944         toAdd = CertDuplicateCertificateContext(pCertContext);
00945         if (existing)
00946             CertContext_CopyProperties(toAdd, existing);
00947         break;
00948     case CERT_STORE_ADD_USE_EXISTING:
00949         if (existing)
00950         {
00951             CertContext_CopyProperties(existing, pCertContext);
00952             if (ppStoreContext)
00953                 *ppStoreContext = CertDuplicateCertificateContext(existing);
00954         }
00955         else
00956             toAdd = CertDuplicateCertificateContext(pCertContext);
00957         break;
00958     case CERT_STORE_ADD_NEWER:
00959         if (existing)
00960         {
00961             if (CompareFileTime(&existing->pCertInfo->NotBefore,
00962              &pCertContext->pCertInfo->NotBefore) >= 0)
00963             {
00964                 TRACE("existing certificate is newer, not adding\n");
00965                 SetLastError(CRYPT_E_EXISTS);
00966                 ret = FALSE;
00967             }
00968             else
00969                 toAdd = CertDuplicateCertificateContext(pCertContext);
00970         }
00971         else
00972             toAdd = CertDuplicateCertificateContext(pCertContext);
00973         break;
00974     case CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES:
00975         if (existing)
00976         {
00977             if (CompareFileTime(&existing->pCertInfo->NotBefore,
00978              &pCertContext->pCertInfo->NotBefore) >= 0)
00979             {
00980                 TRACE("existing certificate is newer, not adding\n");
00981                 SetLastError(CRYPT_E_EXISTS);
00982                 ret = FALSE;
00983             }
00984             else
00985             {
00986                 toAdd = CertDuplicateCertificateContext(pCertContext);
00987                 CertContext_CopyProperties(toAdd, existing);
00988             }
00989         }
00990         else
00991             toAdd = CertDuplicateCertificateContext(pCertContext);
00992         break;
00993     }
00994 
00995     if (toAdd)
00996     {
00997         if (store)
00998             ret = store->certs.addContext(store, (void *)toAdd,
00999              (void *)existing, (const void **)ppStoreContext);
01000         else if (ppStoreContext)
01001             *ppStoreContext = CertDuplicateCertificateContext(toAdd);
01002         CertFreeCertificateContext(toAdd);
01003     }
01004     CertFreeCertificateContext(existing);
01005 
01006     TRACE("returning %d\n", ret);
01007     return ret;
01008 }
01009 
01010 PCCERT_CONTEXT WINAPI CertEnumCertificatesInStore(HCERTSTORE hCertStore,
01011  PCCERT_CONTEXT pPrev)
01012 {
01013     WINECRYPT_CERTSTORE *hcs = hCertStore;
01014     PCCERT_CONTEXT ret;
01015 
01016     TRACE("(%p, %p)\n", hCertStore, pPrev);
01017     if (!hCertStore)
01018         ret = NULL;
01019     else if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
01020         ret = NULL;
01021     else
01022         ret = (PCCERT_CONTEXT)hcs->certs.enumContext(hcs, (void *)pPrev);
01023     return ret;
01024 }
01025 
01026 BOOL WINAPI CertDeleteCertificateFromStore(PCCERT_CONTEXT pCertContext)
01027 {
01028     BOOL ret;
01029 
01030     TRACE("(%p)\n", pCertContext);
01031 
01032     if (!pCertContext)
01033         ret = TRUE;
01034     else if (!pCertContext->hCertStore)
01035         ret = CertFreeCertificateContext(pCertContext);
01036     else
01037     {
01038         PWINECRYPT_CERTSTORE hcs = pCertContext->hCertStore;
01039 
01040         if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
01041             ret = FALSE;
01042         else
01043             ret = hcs->certs.deleteContext(hcs, (void *)pCertContext);
01044         if (ret)
01045             ret = CertFreeCertificateContext(pCertContext);
01046     }
01047     return ret;
01048 }
01049 
01050 #define CrlContext_CopyProperties(to, from) \
01051  Context_CopyProperties((to), (from), sizeof(CRL_CONTEXT))
01052 
01053 BOOL WINAPI CertAddCRLContextToStore(HCERTSTORE hCertStore,
01054  PCCRL_CONTEXT pCrlContext, DWORD dwAddDisposition,
01055  PCCRL_CONTEXT* ppStoreContext)
01056 {
01057     PWINECRYPT_CERTSTORE store = hCertStore;
01058     BOOL ret = TRUE;
01059     PCCRL_CONTEXT toAdd = NULL, existing = NULL;
01060 
01061     TRACE("(%p, %p, %08x, %p)\n", hCertStore, pCrlContext,
01062      dwAddDisposition, ppStoreContext);
01063 
01064     /* Weird case to pass a test */
01065     if (dwAddDisposition == 0)
01066     {
01067         SetLastError(STATUS_ACCESS_VIOLATION);
01068         return FALSE;
01069     }
01070     if (dwAddDisposition != CERT_STORE_ADD_ALWAYS)
01071     {
01072         existing = CertFindCRLInStore(hCertStore, 0, 0, CRL_FIND_EXISTING,
01073          pCrlContext, NULL);
01074     }
01075 
01076     switch (dwAddDisposition)
01077     {
01078     case CERT_STORE_ADD_ALWAYS:
01079         toAdd = CertDuplicateCRLContext(pCrlContext);
01080         break;
01081     case CERT_STORE_ADD_NEW:
01082         if (existing)
01083         {
01084             TRACE("found matching CRL, not adding\n");
01085             SetLastError(CRYPT_E_EXISTS);
01086             ret = FALSE;
01087         }
01088         else
01089             toAdd = CertDuplicateCRLContext(pCrlContext);
01090         break;
01091     case CERT_STORE_ADD_NEWER:
01092         if (existing)
01093         {
01094             LONG newer = CompareFileTime(&existing->pCrlInfo->ThisUpdate,
01095              &pCrlContext->pCrlInfo->ThisUpdate);
01096 
01097             if (newer < 0)
01098                 toAdd = CertDuplicateCRLContext(pCrlContext);
01099             else
01100             {
01101                 TRACE("existing CRL is newer, not adding\n");
01102                 SetLastError(CRYPT_E_EXISTS);
01103                 ret = FALSE;
01104             }
01105         }
01106         else
01107             toAdd = CertDuplicateCRLContext(pCrlContext);
01108         break;
01109     case CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES:
01110         if (existing)
01111         {
01112             LONG newer = CompareFileTime(&existing->pCrlInfo->ThisUpdate,
01113              &pCrlContext->pCrlInfo->ThisUpdate);
01114 
01115             if (newer < 0)
01116             {
01117                 toAdd = CertDuplicateCRLContext(pCrlContext);
01118                 CrlContext_CopyProperties(toAdd, existing);
01119             }
01120             else
01121             {
01122                 TRACE("existing CRL is newer, not adding\n");
01123                 SetLastError(CRYPT_E_EXISTS);
01124                 ret = FALSE;
01125             }
01126         }
01127         else
01128             toAdd = CertDuplicateCRLContext(pCrlContext);
01129         break;
01130     case CERT_STORE_ADD_REPLACE_EXISTING:
01131         toAdd = CertDuplicateCRLContext(pCrlContext);
01132         break;
01133     case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES:
01134         toAdd = CertDuplicateCRLContext(pCrlContext);
01135         if (existing)
01136             CrlContext_CopyProperties(toAdd, existing);
01137         break;
01138     case CERT_STORE_ADD_USE_EXISTING:
01139         if (existing)
01140         {
01141             CrlContext_CopyProperties(existing, pCrlContext);
01142             if (ppStoreContext)
01143                 *ppStoreContext = CertDuplicateCRLContext(existing);
01144         }
01145         else
01146             toAdd = CertDuplicateCRLContext(pCrlContext);
01147         break;
01148     default:
01149         FIXME("Unimplemented add disposition %d\n", dwAddDisposition);
01150         ret = FALSE;
01151     }
01152 
01153     if (toAdd)
01154     {
01155         if (store)
01156             ret = store->crls.addContext(store, (void *)toAdd,
01157              (void *)existing, (const void **)ppStoreContext);
01158         else if (ppStoreContext)
01159             *ppStoreContext = CertDuplicateCRLContext(toAdd);
01160         CertFreeCRLContext(toAdd);
01161     }
01162     CertFreeCRLContext(existing);
01163 
01164     TRACE("returning %d\n", ret);
01165     return ret;
01166 }
01167 
01168 BOOL WINAPI CertDeleteCRLFromStore(PCCRL_CONTEXT pCrlContext)
01169 {
01170     BOOL ret;
01171 
01172     TRACE("(%p)\n", pCrlContext);
01173 
01174     if (!pCrlContext)
01175         ret = TRUE;
01176     else if (!pCrlContext->hCertStore)
01177         ret = CertFreeCRLContext(pCrlContext);
01178     else
01179     {
01180         PWINECRYPT_CERTSTORE hcs = pCrlContext->hCertStore;
01181 
01182         if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
01183             ret = FALSE;
01184         else
01185             ret = hcs->crls.deleteContext(hcs, (void *)pCrlContext);
01186         if (ret)
01187             ret = CertFreeCRLContext(pCrlContext);
01188     }
01189     return ret;
01190 }
01191 
01192 PCCRL_CONTEXT WINAPI CertEnumCRLsInStore(HCERTSTORE hCertStore,
01193  PCCRL_CONTEXT pPrev)
01194 {
01195     WINECRYPT_CERTSTORE *hcs = hCertStore;
01196     PCCRL_CONTEXT ret;
01197 
01198     TRACE("(%p, %p)\n", hCertStore, pPrev);
01199     if (!hCertStore)
01200         ret = NULL;
01201     else if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
01202         ret = NULL;
01203     else
01204         ret = (PCCRL_CONTEXT)hcs->crls.enumContext(hcs, (void *)pPrev);
01205     return ret;
01206 }
01207 
01208 HCERTSTORE WINAPI CertDuplicateStore(HCERTSTORE hCertStore)
01209 {
01210     WINECRYPT_CERTSTORE *hcs = hCertStore;
01211 
01212     TRACE("(%p)\n", hCertStore);
01213 
01214     if (hcs && hcs->dwMagic == WINE_CRYPTCERTSTORE_MAGIC)
01215         InterlockedIncrement(&hcs->ref);
01216     return hCertStore;
01217 }
01218 
01219 BOOL WINAPI CertCloseStore(HCERTSTORE hCertStore, DWORD dwFlags)
01220 {
01221     WINECRYPT_CERTSTORE *hcs = hCertStore;
01222 
01223     TRACE("(%p, %08x)\n", hCertStore, dwFlags);
01224 
01225     if( ! hCertStore )
01226         return TRUE;
01227 
01228     if ( hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC )
01229         return FALSE;
01230 
01231     if (hcs->ref <= 0)
01232         ERR("%p's ref count is %d\n", hcs, hcs->ref);
01233     if (InterlockedDecrement(&hcs->ref) == 0)
01234     {
01235         TRACE("%p's ref count is 0, freeing\n", hcs);
01236         hcs->dwMagic = 0;
01237         hcs->closeStore(hcs, dwFlags);
01238     }
01239     else
01240         TRACE("%p's ref count is %d\n", hcs, hcs->ref);
01241     return TRUE;
01242 }
01243 
01244 BOOL WINAPI CertControlStore(HCERTSTORE hCertStore, DWORD dwFlags,
01245  DWORD dwCtrlType, void const *pvCtrlPara)
01246 {
01247     WINECRYPT_CERTSTORE *hcs = hCertStore;
01248     BOOL ret;
01249 
01250     TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType,
01251      pvCtrlPara);
01252 
01253     if (!hcs)
01254         ret = FALSE;
01255     else if (hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC)
01256         ret = FALSE;
01257     else
01258     {
01259         if (hcs->control)
01260             ret = hcs->control(hCertStore, dwFlags, dwCtrlType, pvCtrlPara);
01261         else
01262             ret = TRUE;
01263     }
01264     return ret;
01265 }
01266 
01267 BOOL WINAPI CertGetStoreProperty(HCERTSTORE hCertStore, DWORD dwPropId,
01268  void *pvData, DWORD *pcbData)
01269 {
01270     PWINECRYPT_CERTSTORE store = hCertStore;
01271     BOOL ret = FALSE;
01272 
01273     TRACE("(%p, %d, %p, %p)\n", hCertStore, dwPropId, pvData, pcbData);
01274 
01275     switch (dwPropId)
01276     {
01277     case CERT_ACCESS_STATE_PROP_ID:
01278         if (!pvData)
01279         {
01280             *pcbData = sizeof(DWORD);
01281             ret = TRUE;
01282         }
01283         else if (*pcbData < sizeof(DWORD))
01284         {
01285             SetLastError(ERROR_MORE_DATA);
01286             *pcbData = sizeof(DWORD);
01287         }
01288         else
01289         {
01290             DWORD state = 0;
01291 
01292             if (store->type != StoreTypeMem &&
01293              !(store->dwOpenFlags & CERT_STORE_READONLY_FLAG))
01294                 state |= CERT_ACCESS_STATE_WRITE_PERSIST_FLAG;
01295             *(DWORD *)pvData = state;
01296             ret = TRUE;
01297         }
01298         break;
01299     default:
01300         if (store->properties)
01301         {
01302             CRYPT_DATA_BLOB blob;
01303 
01304             ret = ContextPropertyList_FindProperty(store->properties, dwPropId,
01305              &blob);
01306             if (ret)
01307             {
01308                 if (!pvData)
01309                     *pcbData = blob.cbData;
01310                 else if (*pcbData < blob.cbData)
01311                 {
01312                     SetLastError(ERROR_MORE_DATA);
01313                     *pcbData = blob.cbData;
01314                     ret = FALSE;
01315                 }
01316                 else
01317                 {
01318                     memcpy(pvData, blob.pbData, blob.cbData);
01319                     *pcbData = blob.cbData;
01320                 }
01321             }
01322             else
01323                 SetLastError(CRYPT_E_NOT_FOUND);
01324         }
01325         else
01326             SetLastError(CRYPT_E_NOT_FOUND);
01327     }
01328     return ret;
01329 }
01330 
01331 BOOL WINAPI CertSetStoreProperty(HCERTSTORE hCertStore, DWORD dwPropId,
01332  DWORD dwFlags, const void *pvData)
01333 {
01334     PWINECRYPT_CERTSTORE store = hCertStore;
01335     BOOL ret = FALSE;
01336 
01337     TRACE("(%p, %d, %08x, %p)\n", hCertStore, dwPropId, dwFlags, pvData);
01338 
01339     if (!store->properties)
01340         store->properties = ContextPropertyList_Create();
01341     switch (dwPropId)
01342     {
01343     case CERT_ACCESS_STATE_PROP_ID:
01344         SetLastError(E_INVALIDARG);
01345         break;
01346     default:
01347         if (pvData)
01348         {
01349             const CRYPT_DATA_BLOB *blob = pvData;
01350 
01351             ret = ContextPropertyList_SetProperty(store->properties, dwPropId,
01352              blob->pbData, blob->cbData);
01353         }
01354         else
01355         {
01356             ContextPropertyList_RemoveProperty(store->properties, dwPropId);
01357             ret = TRUE;
01358         }
01359     }
01360     return ret;
01361 }
01362 
01363 static LONG CRYPT_OpenParentStore(DWORD dwFlags,
01364     void *pvSystemStoreLocationPara, HKEY *key)
01365 {
01366     HKEY root;
01367     LPCWSTR base;
01368 
01369     TRACE("(%08x, %p)\n", dwFlags, pvSystemStoreLocationPara);
01370 
01371     switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK)
01372     {
01373     case CERT_SYSTEM_STORE_LOCAL_MACHINE:
01374         root = HKEY_LOCAL_MACHINE;
01375         base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH;
01376         break;
01377     case CERT_SYSTEM_STORE_CURRENT_USER:
01378         root = HKEY_CURRENT_USER;
01379         base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH;
01380         break;
01381     case CERT_SYSTEM_STORE_CURRENT_SERVICE:
01382         /* hklm\Software\Microsoft\Cryptography\Services\servicename\
01383          * SystemCertificates
01384          */
01385         FIXME("CERT_SYSTEM_STORE_CURRENT_SERVICE\n");
01386         return ERROR_FILE_NOT_FOUND;
01387     case CERT_SYSTEM_STORE_SERVICES:
01388         /* hklm\Software\Microsoft\Cryptography\Services\servicename\
01389          * SystemCertificates
01390          */
01391         FIXME("CERT_SYSTEM_STORE_SERVICES\n");
01392         return ERROR_FILE_NOT_FOUND;
01393     case CERT_SYSTEM_STORE_USERS:
01394         /* hku\user sid\Software\Microsoft\SystemCertificates */
01395         FIXME("CERT_SYSTEM_STORE_USERS\n");
01396         return ERROR_FILE_NOT_FOUND;
01397     case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY:
01398         root = HKEY_CURRENT_USER;
01399         base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
01400         break;
01401     case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY:
01402         root = HKEY_LOCAL_MACHINE;
01403         base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH;
01404         break;
01405     case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE:
01406         /* hklm\Software\Microsoft\EnterpriseCertificates */
01407         FIXME("CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE\n");
01408         return ERROR_FILE_NOT_FOUND;
01409     default:
01410         return ERROR_FILE_NOT_FOUND;
01411     }
01412 
01413     return RegOpenKeyExW(root, base, 0, KEY_READ, key);
01414 }
01415 
01416 BOOL WINAPI CertEnumSystemStore(DWORD dwFlags, void *pvSystemStoreLocationPara,
01417     void *pvArg, PFN_CERT_ENUM_SYSTEM_STORE pfnEnum)
01418 {
01419     BOOL ret = FALSE;
01420     LONG rc;
01421     HKEY key;
01422     CERT_SYSTEM_STORE_INFO info = { sizeof(info) };
01423 
01424     TRACE("(%08x, %p, %p, %p)\n", dwFlags, pvSystemStoreLocationPara, pvArg,
01425         pfnEnum);
01426 
01427     rc = CRYPT_OpenParentStore(dwFlags, pvArg, &key);
01428     if (!rc)
01429     {
01430         DWORD index = 0;
01431 
01432         ret = TRUE;
01433         do {
01434             WCHAR name[MAX_PATH];
01435             DWORD size = sizeof(name) / sizeof(name[0]);
01436 
01437             rc = RegEnumKeyExW(key, index++, name, &size, NULL, NULL, NULL,
01438                 NULL);
01439             if (!rc)
01440                 ret = pfnEnum(name, dwFlags, &info, NULL, pvArg);
01441         } while (ret && !rc);
01442         if (ret && rc != ERROR_NO_MORE_ITEMS)
01443             SetLastError(rc);
01444     }
01445     else
01446         SetLastError(rc);
01447     /* Include root store for the local machine location (it isn't in the
01448      * registry)
01449      */
01450     if (ret && (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK) ==
01451      CERT_SYSTEM_STORE_LOCAL_MACHINE)
01452         ret = pfnEnum(rootW, dwFlags, &info, NULL, pvArg);
01453     return ret;
01454 }
01455 
01456 BOOL WINAPI CertEnumPhysicalStore(const void *pvSystemStore, DWORD dwFlags,
01457  void *pvArg, PFN_CERT_ENUM_PHYSICAL_STORE pfnEnum)
01458 {
01459     if (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG)
01460         FIXME("(%p, %08x, %p, %p): stub\n", pvSystemStore, dwFlags, pvArg,
01461          pfnEnum);
01462     else
01463         FIXME("(%s, %08x, %p, %p): stub\n", debugstr_w(pvSystemStore),
01464          dwFlags, pvArg,
01465          pfnEnum);
01466     return FALSE;
01467 }
01468 
01469 BOOL WINAPI CertRegisterPhysicalStore(const void *pvSystemStore, DWORD dwFlags,
01470  LPCWSTR pwszStoreName, PCERT_PHYSICAL_STORE_INFO pStoreInfo, void *pvReserved)
01471 {
01472     if (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG)
01473         FIXME("(%p, %08x, %s, %p, %p): stub\n", pvSystemStore, dwFlags,
01474          debugstr_w(pwszStoreName), pStoreInfo, pvReserved);
01475     else
01476         FIXME("(%s, %08x, %s, %p, %p): stub\n", debugstr_w(pvSystemStore),
01477          dwFlags, debugstr_w(pwszStoreName), pStoreInfo, pvReserved);
01478     return FALSE;
01479 }

Generated on Sun May 27 2012 04:23:19 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.