Sync to Wine-0_9_3:
authorGé van Geldorp <ge@gse.nl>
Mon, 12 Dec 2005 22:56:08 +0000 (22:56 +0000)
committerGé van Geldorp <ge@gse.nl>
Mon, 12 Dec 2005 22:56:08 +0000 (22:56 +0000)
Juan Lang <juan_lang@yahoo.com>
- Implement more OID support functions.
  Use the exported OID support functions internally.
  Move OID support functions and stubs to a separate file.
- Fix parameter count on some stubs (thanks to Marcus Meissner for
  spotting that.)  Add a few more stubs.
- Fix some memory leaks.
Stefan Leichter <Stefan.Leichter@camLine.com>
- Added stub for CryptVerifyMessageSignature.

svn path=/trunk/; revision=20131

reactos/lib/crypt32/cert.c
reactos/lib/crypt32/crypt32.spec
reactos/lib/crypt32/crypt32.xml
reactos/lib/crypt32/crypt32_private.h
reactos/lib/crypt32/encode.c
reactos/lib/crypt32/main.c
reactos/lib/crypt32/oid.c [new file with mode: 0644]
reactos/w32api/include/wincrypt.h

index 23e4a3c..9eaaa19 100644 (file)
@@ -3285,15 +3285,12 @@ BOOL WINAPI CryptVerifyCertificateSignatureEx(HCRYPTPROV hCryptProv,
     return ret;
 }
 
-HCRYPTOIDFUNCSET WINAPI CryptInitOIDFunctionSet(LPCSTR pszFuncName, DWORD dwFlags)
+BOOL WINAPI CryptVerifyMessageSignature(/*PCRYPT_VERIFY_MESSAGE_PARA*/ void* pVerifyPara,
+          DWORD dwSignerIndex, const BYTE* pbSignedBlob, DWORD cbSignedBlob,
+          BYTE* pbDecoded, DWORD* pcbDecoded, PCCERT_CONTEXT* ppSignerCert)
 {
-    FIXME("stub: %s %lx\n", debugstr_a(pszFuncName), dwFlags);
-    return NULL;
-}
-
-BOOL WINAPI CryptUnregisterDefaultOIDFunction(DWORD dwEncodingType,
-                                              LPCSTR pszFuncName, LPCWSTR pwszDll)
-{
-    FIXME("stub: %lx %s %s\n", dwEncodingType, debugstr_a(pszFuncName), debugstr_w(pwszDll));
+    FIXME("stub: %p, %ld, %p, %ld, %p, %p, %p\n",
+        pVerifyPara, dwSignerIndex, pbSignedBlob, cbSignedBlob,
+        pbDecoded, pcbDecoded, ppSignerCert);
     return FALSE;
 }
index 5d43e33..897853c 100644 (file)
 @ stdcall CryptExportPublicKeyInfoEx(long long long str long ptr ptr ptr)
 @ stub CryptFindOIDInfo
 @ stub CryptFormatObject
-@ stub CryptFreeOIDFunctionAddress
+@ stdcall CryptFreeOIDFunctionAddress(long long)
 @ stub CryptGetAsyncParam
-@ stub CryptGetDefaultOIDDllList
-@ stub CryptGetDefaultOIDFunctionAddress
+@ stdcall CryptGetDefaultOIDDllList(long long ptr ptr)
+@ stdcall CryptGetDefaultOIDFunctionAddress(long long wstr long ptr ptr)
 @ stub CryptGetMessageCertificates
 @ stub CryptGetMessageSignerCount
-@ stub CryptGetOIDFunctionAddress
+@ stdcall CryptGetOIDFunctionAddress(long long str long ptr ptr)
 @ stdcall CryptGetOIDFunctionValue(long str str wstr ptr ptr ptr)
 @ stdcall CryptHashCertificate(long long long ptr long ptr ptr)
 @ stub CryptHashMessage
 @ stdcall CryptImportPublicKeyInfo(long long ptr ptr)
 @ stdcall CryptImportPublicKeyInfoEx(long long ptr long long ptr ptr)
 @ stdcall CryptInitOIDFunctionSet(str long)
-@ stub CryptInstallOIDFunctionAddress
+@ stdcall CryptInstallOIDFunctionAddress(ptr long str long ptr long)
 @ stub CryptLoadSip
 @ stdcall CryptMemAlloc(long)
 @ stdcall CryptMemFree(ptr)
 @ stub CryptVerifyDetachedMessageHash
 @ stub CryptVerifyDetachedMessageSignature
 @ stub CryptVerifyMessageHash
-@ stub CryptVerifyMessageSignature
+@ stdcall CryptVerifyMessageSignature(ptr long ptr long ptr ptr ptr)
 @ stub CryptVerifyMessageSignatureWithKey
 @ stub CryptVerifySignatureU
 @ stdcall I_CryptAllocTls()
-@ stdcall I_CryptCreateLruCache(long long)
+@ stdcall I_CryptCreateLruCache(ptr ptr)
 @ stub I_CryptCreateLruEntry
 @ stdcall I_CryptDetachTls(long)
-@ stdcall I_CryptFindLruEntryData(long)
-@ stdcall I_CryptFlushLruCache(long)
-@ stdcall I_CryptFreeLruCache(long)
+@ stdcall I_CryptFindLruEntryData(long long long)
+@ stdcall I_CryptFlushLruCache(ptr long long)
+@ stdcall I_CryptFreeLruCache(ptr long long)
 @ stdcall I_CryptFreeTls(long long)
 @ stub I_CryptGetDefaultCryptProv
 @ stub I_CryptGetDefaultCryptProvForEncrypt
index c64f887..c817a0b 100644 (file)
@@ -11,6 +11,7 @@
        <file>main.c</file>
        <file>encode.c</file>
        <file>cert.c</file>
+       <file>oid.c</file>
        <file>protectdata.c</file>
        <file>crypt32.rc</file>
        <file>crypt32.spec</file>
index 9b59353..1bf5f6f 100644 (file)
@@ -24,4 +24,7 @@
  */
 HCRYPTPROV CRYPT_GetDefaultProvider(void);
 
+void CRYPT_InitFunctionSets(void);
+void CRYPT_FreeFunctionSets(void);
+
 #endif
index c65941f..bea24dd 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * Copyright 2002 Mike McCormack for CodeWeavers
  * Copyright 2005 Juan Lang
  *
  * This library is free software; you can redistribute it and/or
@@ -67,8 +66,6 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(crypt);
 
-static const WCHAR szDllName[] = { 'D','l','l',0 };
-
 typedef BOOL (WINAPI *CryptEncodeObjectFunc)(DWORD, LPCSTR, const void *,
  BYTE *, DWORD *);
 typedef BOOL (WINAPI *CryptEncodeObjectExFunc)(DWORD, LPCSTR, const void *,
@@ -182,260 +179,12 @@ static WINE_EXCEPTION_FILTER(page_fault)
     return EXCEPTION_CONTINUE_SEARCH;
 }
 
-static char *CRYPT_GetKeyName(DWORD dwEncodingType, LPCSTR pszFuncName,
- LPCSTR pszOID)
-{
-    static const char szEncodingTypeFmt[] =
-     "Software\\Microsoft\\Cryptography\\OID\\EncodingType %ld\\%s\\%s";
-    UINT len;
-    char numericOID[7]; /* enough for "#65535" */
-    const char *oid;
-    LPSTR szKey;
-
-    /* MSDN says the encoding type is a mask, but it isn't treated that way.
-     * (E.g., if dwEncodingType were 3, the key names "EncodingType 1" and
-     * "EncodingType 2" would be expected if it were a mask.  Instead native
-     * stores values in "EncodingType 3".
-     */
-    if (!HIWORD(pszOID))
-    {
-        snprintf(numericOID, sizeof(numericOID), "#%d", LOWORD(pszOID));
-        oid = numericOID;
-    }
-    else
-        oid = pszOID;
-
-    /* This is enough: the lengths of the two string parameters are explicitly
-     * counted, and we need up to five additional characters for the encoding
-     * type.  These are covered by the "%d", "%s", and "%s" characters in the
-     * format specifier that are removed by sprintf.
-     */
-    len = sizeof(szEncodingTypeFmt) + lstrlenA(pszFuncName) + lstrlenA(oid);
-    szKey = CryptMemAlloc(len);
-    if (szKey)
-        sprintf(szKey, szEncodingTypeFmt, dwEncodingType, pszFuncName, oid);
-    return szKey;
-}
-
-BOOL WINAPI CryptRegisterOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName,
-                  LPCSTR pszOID, LPCWSTR pwszDll, LPCSTR pszOverrideFuncName)
-{
-    LONG r;
-    HKEY hKey;
-    LPSTR szKey;
-
-    TRACE("%lx %s %s %s %s\n", dwEncodingType, pszFuncName, pszOID,
-          debugstr_w(pwszDll), pszOverrideFuncName);
-
-    /* This only registers functions for encoding certs, not messages */
-    if (!GET_CERT_ENCODING_TYPE(dwEncodingType))
-        return TRUE;
-
-    /* Native does nothing pwszDll is NULL */
-    if (!pwszDll)
-        return TRUE;
-
-    /* I'm not matching MS bug for bug here, because I doubt any app depends on
-     * it:
-     * - native "succeeds" if pszFuncName is NULL, but the nonsensical entry
-     *   it creates would never be used
-     * - native returns an HRESULT rather than a Win32 error if pszOID is NULL.
-     * Instead I disallow both of these with ERROR_INVALID_PARAMETER.
-     */
-    if (!pszFuncName || !pszOID)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-
-    szKey = CRYPT_GetKeyName(dwEncodingType, pszFuncName, pszOID);
-    TRACE("Key name is %s\n", debugstr_a(szKey));
-
-    if (!szKey)
-        return FALSE;
-
-    r = RegCreateKeyA(HKEY_LOCAL_MACHINE, szKey, &hKey);
-    CryptMemFree(szKey);
-    if(r != ERROR_SUCCESS)
-        return FALSE;
-
-    /* write the values */
-    if (pszOverrideFuncName)
-        RegSetValueExA(hKey, "FuncName", 0, REG_SZ, (const BYTE*)pszOverrideFuncName,
-         lstrlenA(pszOverrideFuncName) + 1);
-    RegSetValueExW(hKey, szDllName, 0, REG_SZ, (const BYTE*) pwszDll,
-                    (lstrlenW(pwszDll) + 1) * sizeof (WCHAR));
-
-    RegCloseKey(hKey);
-    return TRUE;
-}
-
-BOOL WINAPI CryptUnregisterOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName,
- LPCSTR pszOID)
-{
-    LPSTR szKey;
-    LONG rc;
-
-    TRACE("%lx %s %s\n", dwEncodingType, pszFuncName, pszOID);
-
-    if (!GET_CERT_ENCODING_TYPE(dwEncodingType))
-        return TRUE;
-
-    if (!pszFuncName || !pszOID)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-
-    szKey = CRYPT_GetKeyName(dwEncodingType, pszFuncName, pszOID);
-    rc = RegDeleteKeyA(HKEY_LOCAL_MACHINE, szKey);
-    CryptMemFree(szKey);
-    if (rc)
-        SetLastError(rc);
-    return rc ? FALSE : TRUE;
-}
-
-BOOL WINAPI CryptGetOIDFunctionValue(DWORD dwEncodingType, LPCSTR pszFuncName,
- LPCSTR pszOID, LPCWSTR pwszValueName, DWORD *pdwValueType, BYTE *pbValueData,
- DWORD *pcbValueData)
-{
-    LPSTR szKey;
-    LONG rc;
-    HKEY hKey;
-
-    TRACE("%lx %s %s %s %p %p %p\n", dwEncodingType, debugstr_a(pszFuncName),
-     debugstr_a(pszOID), debugstr_w(pwszValueName), pdwValueType, pbValueData,
-     pcbValueData);
-
-    if (!GET_CERT_ENCODING_TYPE(dwEncodingType))
-        return TRUE;
-
-    if (!pszFuncName || !pszOID || !pwszValueName)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-
-    szKey = CRYPT_GetKeyName(dwEncodingType, pszFuncName, pszOID);
-    rc = RegOpenKeyA(HKEY_LOCAL_MACHINE, szKey, &hKey);
-    CryptMemFree(szKey);
-    if (rc)
-        SetLastError(rc);
-    else
-    {
-        rc = RegQueryValueExW(hKey, pwszValueName, NULL, pdwValueType,
-         pbValueData, pcbValueData);
-        if (rc)
-            SetLastError(rc);
-        RegCloseKey(hKey);
-    }
-    return rc ? FALSE : TRUE;
-}
-
-BOOL WINAPI CryptSetOIDFunctionValue(DWORD dwEncodingType, LPCSTR pszFuncName,
- LPCSTR pszOID, LPCWSTR pwszValueName, DWORD dwValueType,
- const BYTE *pbValueData, DWORD cbValueData)
-{
-    LPSTR szKey;
-    LONG rc;
-    HKEY hKey;
-
-    TRACE("%lx %s %s %s %ld %p %ld\n", dwEncodingType, debugstr_a(pszFuncName),
-     debugstr_a(pszOID), debugstr_w(pwszValueName), dwValueType, pbValueData,
-     cbValueData);
-
-    if (!GET_CERT_ENCODING_TYPE(dwEncodingType))
-        return TRUE;
-
-    if (!pszFuncName || !pszOID || !pwszValueName)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-
-    szKey = CRYPT_GetKeyName(dwEncodingType, pszFuncName, pszOID);
-    rc = RegOpenKeyA(HKEY_LOCAL_MACHINE, szKey, &hKey);
-    CryptMemFree(szKey);
-    if (rc)
-        SetLastError(rc);
-    else
-    {
-        rc = RegSetValueExW(hKey, pwszValueName, 0, dwValueType, pbValueData,
-         cbValueData);
-        if (rc)
-            SetLastError(rc);
-        RegCloseKey(hKey);
-    }
-    return rc ? FALSE : TRUE;
-}
-
-/* Gets the registered function named szFuncName for dwCertEncodingType and
- * lpszStructType, or NULL if one could not be found.  *lib will be set to the
- * handle of the module it's in, or NULL if no module was loaded.  If the
- * return value is NULL, *lib will also be NULL, to simplify error handling.
- */
-static void *CRYPT_GetFunc(DWORD dwCertEncodingType, LPCSTR lpszStructType,
- LPCSTR szFuncName, HMODULE *lib)
-{
-    void *ret = NULL;
-    char *szKey = CRYPT_GetKeyName(dwCertEncodingType, szFuncName,
-     lpszStructType);
-    const char *funcName;
-    long r;
-    HKEY hKey;
-    DWORD type, size = 0;
-
-    TRACE("(%08lx %s %s %p)\n", dwCertEncodingType, debugstr_a(lpszStructType),
-     debugstr_a(szFuncName), lib);
-
-    *lib = NULL;
-    r = RegOpenKeyA(HKEY_LOCAL_MACHINE, szKey, &hKey);
-    CryptMemFree(szKey);
-    if(r != ERROR_SUCCESS)
-        return NULL;
-
-    RegQueryValueExA(hKey, "FuncName", NULL, &type, NULL, &size);
-    if (GetLastError() == ERROR_MORE_DATA && type == REG_SZ)
-    {
-        funcName = CryptMemAlloc(size);
-        RegQueryValueExA(hKey, "FuncName", NULL, &type, (LPBYTE)funcName,
-         &size);
-    }
-    else
-        funcName = szFuncName;
-    RegQueryValueExW(hKey, szDllName, NULL, &type, NULL, &size);
-    if (GetLastError() == ERROR_MORE_DATA && type == REG_SZ)
-    {
-        LPWSTR dllName = CryptMemAlloc(size);
-
-        RegQueryValueExW(hKey, szDllName, NULL, &type, (LPBYTE)dllName,
-         &size);
-        *lib = LoadLibraryW(dllName);
-        if (*lib)
-        {
-             ret = GetProcAddress(*lib, funcName);
-             if (!ret)
-             {
-                 /* Unload the library, the caller doesn't want to unload it
-                  * when the return value is NULL.
-                  */
-                 FreeLibrary(*lib);
-                 *lib = NULL;
-             }
-        }
-        CryptMemFree(dllName);
-    }
-    if (funcName != szFuncName)
-        CryptMemFree((char *)funcName);
-    TRACE("returning %p\n", ret);
-    return ret;
-}
-
 BOOL WINAPI CryptEncodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType,
  const void *pvStructInfo, BYTE *pbEncoded, DWORD *pcbEncoded)
 {
+    static HCRYPTOIDFUNCSET set = NULL;
     BOOL ret = FALSE;
-    HMODULE lib;
+    HCRYPTOIDFUNCADDR hFunc;
     CryptEncodeObjectFunc pCryptEncodeObject;
 
     TRACE("(0x%08lx, %s, %p, %p, %p)\n", dwCertEncodingType,
@@ -449,14 +198,15 @@ BOOL WINAPI CryptEncodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType,
     }
 
     /* Try registered DLL first.. */
-    pCryptEncodeObject =
-     (CryptEncodeObjectFunc)CRYPT_GetFunc(dwCertEncodingType,
-     lpszStructType, CRYPT_OID_ENCODE_OBJECT_FUNC, &lib);
+    if (!set)
+        set = CryptInitOIDFunctionSet(CRYPT_OID_ENCODE_OBJECT_FUNC, 0);
+    CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0,
+     (void **)&pCryptEncodeObject, &hFunc);
     if (pCryptEncodeObject)
     {
         ret = pCryptEncodeObject(dwCertEncodingType, lpszStructType,
          pvStructInfo, pbEncoded, pcbEncoded);
-        FreeLibrary(lib);
+        CryptFreeOIDFunctionAddress(hFunc, 0);
     }
     else
     {
@@ -2272,9 +2022,10 @@ BOOL WINAPI CryptEncodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType,
  const void *pvStructInfo, DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara,
  void *pvEncoded, DWORD *pcbEncoded)
 {
+    static HCRYPTOIDFUNCSET set = NULL;
     BOOL ret = FALSE;
-    HMODULE lib = NULL;
     CryptEncodeObjectExFunc encodeFunc = NULL;
+    HCRYPTOIDFUNCADDR hFunc = NULL;
 
     TRACE("(0x%08lx, %s, %p, 0x%08lx, %p, %p, %p)\n", dwCertEncodingType,
      debugstr_a(lpszStructType), pvStructInfo, dwFlags, pEncodePara,
@@ -2384,15 +2135,19 @@ BOOL WINAPI CryptEncodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType,
         TRACE("OID %s not found or unimplemented, looking for DLL\n",
          debugstr_a(lpszStructType));
     if (!encodeFunc)
-        encodeFunc = (CryptEncodeObjectExFunc)CRYPT_GetFunc(dwCertEncodingType,
-         lpszStructType, CRYPT_OID_ENCODE_OBJECT_EX_FUNC, &lib);
+    {
+        if (!set)
+            set = CryptInitOIDFunctionSet(CRYPT_OID_ENCODE_OBJECT_EX_FUNC, 0);
+        CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0,
+         (void **)&encodeFunc, &hFunc);
+    }
     if (encodeFunc)
         ret = encodeFunc(dwCertEncodingType, lpszStructType, pvStructInfo,
          dwFlags, pEncodePara, pvEncoded, pcbEncoded);
     else
         SetLastError(ERROR_FILE_NOT_FOUND);
-    if (lib)
-        FreeLibrary(lib);
+    if (hFunc)
+        CryptFreeOIDFunctionAddress(hFunc, 0);
     return ret;
 }
 
@@ -2400,9 +2155,10 @@ BOOL WINAPI CryptDecodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType,
  const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo,
  DWORD *pcbStructInfo)
 {
+    static HCRYPTOIDFUNCSET set = NULL;
     BOOL ret = FALSE;
-    HMODULE lib;
     CryptDecodeObjectFunc pCryptDecodeObject;
+    HCRYPTOIDFUNCADDR hFunc;
 
     TRACE("(0x%08lx, %s, %p, %ld, 0x%08lx, %p, %p)\n", dwCertEncodingType,
      debugstr_a(lpszStructType), pbEncoded, cbEncoded, dwFlags,
@@ -2415,14 +2171,15 @@ BOOL WINAPI CryptDecodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType,
     }
 
     /* Try registered DLL first.. */
-    pCryptDecodeObject =
-     (CryptDecodeObjectFunc)CRYPT_GetFunc(dwCertEncodingType,
-     lpszStructType, CRYPT_OID_DECODE_OBJECT_FUNC, &lib);
+    if (!set)
+        set = CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC, 0);
+    CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0,
+     (void **)&pCryptDecodeObject, &hFunc);
     if (pCryptDecodeObject)
     {
         ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType,
          pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo);
-        FreeLibrary(lib);
+        CryptFreeOIDFunctionAddress(hFunc, 0);
     }
     else
     {
@@ -5386,9 +5143,10 @@ BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType,
  const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
 {
+    static HCRYPTOIDFUNCSET set = NULL;
     BOOL ret = FALSE;
-    HMODULE lib = NULL;
     CryptDecodeObjectExFunc decodeFunc = NULL;
+    HCRYPTOIDFUNCADDR hFunc = NULL;
 
     TRACE("(0x%08lx, %s, %p, %ld, 0x%08lx, %p, %p, %p)\n",
      dwCertEncodingType, debugstr_a(lpszStructType), pbEncoded,
@@ -5508,15 +5266,19 @@ BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType,
         TRACE("OID %s not found or unimplemented, looking for DLL\n",
          debugstr_a(lpszStructType));
     if (!decodeFunc)
-        decodeFunc = (CryptDecodeObjectExFunc)CRYPT_GetFunc(dwCertEncodingType,
-         lpszStructType, CRYPT_OID_DECODE_OBJECT_EX_FUNC, &lib);
+    {
+        if (!set)
+            set = CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC, 0);
+        CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0,
+         (void **)&decodeFunc, &hFunc);
+    }
     if (decodeFunc)
         ret = decodeFunc(dwCertEncodingType, lpszStructType, pbEncoded,
          cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo);
     else
         SetLastError(ERROR_FILE_NOT_FOUND);
-    if (lib)
-        FreeLibrary(lib);
+    if (hFunc)
+        CryptFreeOIDFunctionAddress(hFunc, 0);
     return ret;
 }
 
@@ -5609,9 +5371,10 @@ BOOL WINAPI CryptExportPublicKeyInfoEx(HCRYPTPROV hCryptProv, DWORD dwKeySpec,
  DWORD dwCertEncodingType, LPSTR pszPublicKeyObjId, DWORD dwFlags,
  void *pvAuxInfo, PCERT_PUBLIC_KEY_INFO pInfo, DWORD *pcbInfo)
 {
+    static HCRYPTOIDFUNCSET set = NULL;
     BOOL ret;
     ExportPublicKeyInfoExFunc exportFunc = NULL;
-    HMODULE lib = NULL;
+    HCRYPTOIDFUNCADDR hFunc = NULL;
 
     TRACE("(%ld, %ld, %08lx, %s, %08lx, %p, %p, %p)\n", hCryptProv, dwKeySpec,
      dwCertEncodingType, debugstr_a(pszPublicKeyObjId), dwFlags, pvAuxInfo,
@@ -5624,14 +5387,19 @@ BOOL WINAPI CryptExportPublicKeyInfoEx(HCRYPTPROV hCryptProv, DWORD dwKeySpec,
     }
 
     if (pszPublicKeyObjId)
-        exportFunc = CRYPT_GetFunc(dwCertEncodingType, pszPublicKeyObjId,
-         CRYPT_OID_EXPORT_PUBLIC_KEY_INFO_FUNC, &lib);
+    {
+        if (!set)
+            set = CryptInitOIDFunctionSet(CRYPT_OID_EXPORT_PUBLIC_KEY_INFO_FUNC,
+             0);
+        CryptGetOIDFunctionAddress(set, dwCertEncodingType, pszPublicKeyObjId,
+         0, (void **)&exportFunc, &hFunc);
+    }
     if (!exportFunc)
         exportFunc = CRYPT_ExportRsaPublicKeyInfoEx;
     ret = exportFunc(hCryptProv, dwKeySpec, dwCertEncodingType,
      pszPublicKeyObjId, dwFlags, pvAuxInfo, pInfo, pcbInfo);
-    if (lib)
-        FreeLibrary(lib);
+    if (hFunc)
+        CryptFreeOIDFunctionAddress(hFunc, 0);
     return ret;
 }
 
@@ -5682,20 +5450,23 @@ BOOL WINAPI CryptImportPublicKeyInfoEx(HCRYPTPROV hCryptProv,
  DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pInfo, ALG_ID aiKeyAlg,
  DWORD dwFlags, void *pvAuxInfo, HCRYPTKEY *phKey)
 {
+    static HCRYPTOIDFUNCSET set = NULL;
     BOOL ret;
     ImportPublicKeyInfoExFunc importFunc = NULL;
-    HMODULE lib = NULL;
+    HCRYPTOIDFUNCADDR hFunc = NULL;
 
     TRACE("(%ld, %ld, %p, %d, %08lx, %p, %p)\n", hCryptProv,
      dwCertEncodingType, pInfo, aiKeyAlg, dwFlags, pvAuxInfo, phKey);
 
-    importFunc = CRYPT_GetFunc(dwCertEncodingType, pInfo->Algorithm.pszObjId,
-     CRYPT_OID_IMPORT_PUBLIC_KEY_INFO_FUNC, &lib);
+    if (!set)
+        set = CryptInitOIDFunctionSet(CRYPT_OID_IMPORT_PUBLIC_KEY_INFO_FUNC, 0);
+    CryptGetOIDFunctionAddress(set, dwCertEncodingType,
+     pInfo->Algorithm.pszObjId, 0, (void **)&importFunc, &hFunc);
     if (!importFunc)
         importFunc = CRYPT_ImportRsaPublicKeyInfoEx;
     ret = importFunc(hCryptProv, dwCertEncodingType, pInfo, aiKeyAlg, dwFlags,
      pvAuxInfo, phKey);
-    if (lib)
-        FreeLibrary(lib);
+    if (hFunc)
+        CryptFreeOIDFunctionAddress(hFunc, 0);
     return ret;
 }
index 039449f..df30206 100644 (file)
@@ -38,7 +38,11 @@ BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved)
 {
     switch (fdwReason)
     {
+        case DLL_PROCESS_ATTACH:
+            CRYPT_InitFunctionSets();
+            break;
         case DLL_PROCESS_DETACH:
+            CRYPT_FreeFunctionSets();
             if (hDefProv) CryptReleaseContext(hDefProv, 0);
             break;
     }
@@ -53,30 +57,37 @@ HCRYPTPROV CRYPT_GetDefaultProvider(void)
     return hDefProv;
 }
 
-/* this function is called by Internet Explorer when it is about to verify a downloaded component */
-BOOL WINAPI I_CryptCreateLruCache(DWORD x, DWORD y)
+typedef void * HLRUCACHE;
+
+/* this function is called by Internet Explorer when it is about to verify a
+ * downloaded component.  The first parameter appears to be a pointer to an
+ * unknown type, native fails unless it points to a buffer of at least 20 bytes.
+ * The second parameter appears to be an out parameter, whatever it's set to is
+ * passed (by cryptnet.dll) to I_CryptFlushLruCache.
+ */
+BOOL WINAPI I_CryptCreateLruCache(void *unknown, HLRUCACHE *out)
 {
-    FIXME("stub!\n");
-    return FALSE;
+    FIXME("(%p, %p): stub!\n", unknown, out);
+    *out = (void *)0xbaadf00d;
+    return TRUE;
 }
 
-/* these functions all have an unknown number of args */
-BOOL WINAPI I_CryptFindLruEntryData(DWORD x)
+BOOL WINAPI I_CryptFindLruEntryData(DWORD unk0, DWORD unk1, DWORD unk2)
 {
-    FIXME("stub!\n");
+    FIXME("(%08lx, %08lx, %08lx): stub!\n", unk0, unk1, unk2);
     return FALSE;
 }
 
-BOOL WINAPI I_CryptFlushLruCache(DWORD x)
+DWORD WINAPI I_CryptFlushLruCache(HLRUCACHE h, DWORD unk0, DWORD unk1)
 {
-    FIXME("stub!\n");
-    return FALSE;
+    FIXME("(%p, %08lx, %08lx): stub!\n", h, unk0, unk1);
+    return 0;
 }
 
-BOOL WINAPI I_CryptFreeLruCache(DWORD x)
+HLRUCACHE WINAPI I_CryptFreeLruCache(HLRUCACHE h, DWORD unk0, DWORD unk1)
 {
-    FIXME("stub!\n");
-    return FALSE;
+    FIXME("(%p, %08lx, %08lx): stub!\n", h, unk0, unk1);
+    return h;
 }
 
 BOOL WINAPI CryptSIPRemoveProvider(GUID *pgProv)
@@ -206,15 +217,6 @@ BOOL WINAPI CryptSIPLoad
     return FALSE;
 }
 
-BOOL WINAPI CryptRegisterDefaultOIDFunction(DWORD dwEncodingType,
-                                     LPCSTR pszFuncName, DWORD dwIndex,
-                                    LPCWSTR pwszDll)
-{
-    FIXME("(%lx,%s,%lx,%s) stub!\n", dwEncodingType, pszFuncName, dwIndex,
-          debugstr_w(pwszDll));
-    return FALSE;
-}
-
 struct OIDToAlgID
 {
     LPCSTR oid;
diff --git a/reactos/lib/crypt32/oid.c b/reactos/lib/crypt32/oid.c
new file mode 100644 (file)
index 0000000..e9733a1
--- /dev/null
@@ -0,0 +1,558 @@
+/*
+ * Copyright 2002 Mike McCormack for CodeWeavers
+ * Copyright 2005 Juan Lang
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <stdio.h>
+#include <stdarg.h>
+#include "windef.h"
+#include "winbase.h"
+#include "wincrypt.h"
+#include "winreg.h"
+#include "wine/debug.h"
+#include "wine/list.h"
+#include "crypt32_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(crypt);
+
+static const WCHAR DllW[] = { 'D','l','l',0 };
+CRITICAL_SECTION funcSetCS;
+struct list funcSets;
+
+struct OIDFunctionSet
+{
+    LPSTR name;
+    CRITICAL_SECTION cs; /* protects functions */
+    struct list functions;
+    struct list next;
+};
+
+struct OIDFunction
+{
+    DWORD encoding;
+    CRYPT_OID_FUNC_ENTRY entry;
+    struct list next;
+};
+
+void CRYPT_InitFunctionSets(void)
+{
+    InitializeCriticalSection(&funcSetCS);
+    list_init(&funcSets);
+}
+
+void CRYPT_FreeFunctionSets(void)
+{
+    struct OIDFunctionSet *setCursor, *setNext;
+
+    LIST_FOR_EACH_ENTRY_SAFE(setCursor, setNext, &funcSets,
+     struct OIDFunctionSet, next)
+    {
+        struct OIDFunction *functionCursor, *funcNext;
+
+        list_remove(&setCursor->next);
+        CryptMemFree(setCursor->name);
+        CryptMemFree(setCursor);
+        LIST_FOR_EACH_ENTRY_SAFE(functionCursor, funcNext,
+         &setCursor->functions, struct OIDFunction, next)
+        {
+            list_remove(&functionCursor->next);
+            CryptMemFree(functionCursor);
+        }
+        DeleteCriticalSection(&setCursor->cs);
+    }
+    DeleteCriticalSection(&funcSetCS);
+}
+
+/* There is no free function associated with this; therefore, the sets are
+ * freed when crypt32.dll is unloaded.
+ */
+HCRYPTOIDFUNCSET WINAPI CryptInitOIDFunctionSet(LPCSTR pszFuncName,
+ DWORD dwFlags)
+{
+    struct OIDFunctionSet *cursor, *ret = NULL;
+
+    TRACE("(%s, %lx)\n", debugstr_a(pszFuncName), dwFlags);
+
+    EnterCriticalSection(&funcSetCS);
+    LIST_FOR_EACH_ENTRY(cursor, &funcSets, struct OIDFunctionSet, next)
+    {
+        if (!strcasecmp(pszFuncName, cursor->name))
+        {
+            ret = (HCRYPTOIDFUNCSET)cursor;
+            break;
+        }
+    }
+    if (!ret)
+    {
+        ret = CryptMemAlloc(sizeof(struct OIDFunctionSet));
+        if (ret)
+        {
+            memset(ret, 0, sizeof(*ret));
+            ret->name = CryptMemAlloc(strlen(pszFuncName) + 1);
+            if (ret->name)
+            {
+                InitializeCriticalSection(&ret->cs);
+                list_init(&ret->functions);
+                strcpy(ret->name, pszFuncName);
+                list_add_tail(&funcSets, &ret->next);
+            }
+            else
+            {
+                CryptMemFree(ret);
+                ret = NULL;
+            }
+        }
+    }
+    LeaveCriticalSection(&funcSetCS);
+
+    return (HCRYPTOIDFUNCSET)ret;
+}
+
+static char *CRYPT_GetKeyName(DWORD dwEncodingType, LPCSTR pszFuncName,
+ LPCSTR pszOID)
+{
+    static const char szEncodingTypeFmt[] =
+     "Software\\Microsoft\\Cryptography\\OID\\EncodingType %ld\\%s\\%s";
+    UINT len;
+    char numericOID[7]; /* enough for "#65535" */
+    const char *oid;
+    LPSTR szKey;
+
+    /* MSDN says the encoding type is a mask, but it isn't treated that way.
+     * (E.g., if dwEncodingType were 3, the key names "EncodingType 1" and
+     * "EncodingType 2" would be expected if it were a mask.  Instead native
+     * stores values in "EncodingType 3".
+     */
+    if (!HIWORD(pszOID))
+    {
+        snprintf(numericOID, sizeof(numericOID), "#%d", LOWORD(pszOID));
+        oid = numericOID;
+    }
+    else
+        oid = pszOID;
+
+    /* This is enough: the lengths of the two string parameters are explicitly
+     * counted, and we need up to five additional characters for the encoding
+     * type.  These are covered by the "%d", "%s", and "%s" characters in the
+     * format specifier that are removed by sprintf.
+     */
+    len = sizeof(szEncodingTypeFmt) + lstrlenA(pszFuncName) + lstrlenA(oid);
+    szKey = CryptMemAlloc(len);
+    if (szKey)
+        sprintf(szKey, szEncodingTypeFmt, dwEncodingType, pszFuncName, oid);
+    return szKey;
+}
+
+BOOL WINAPI CryptGetDefaultOIDDllList(HCRYPTOIDFUNCSET hFuncSet,
+ DWORD dwEncodingType, LPWSTR pwszDllList, DWORD *pcchDllList)
+{
+    BOOL ret = TRUE;
+    struct OIDFunctionSet *set = (struct OIDFunctionSet *)hFuncSet;
+    char *keyName;
+    HKEY key;
+    long rc;
+
+    TRACE("(%p, %ld, %p, %p)\n", hFuncSet, dwEncodingType, pwszDllList,
+     pcchDllList);
+
+    keyName = CRYPT_GetKeyName(dwEncodingType, set->name, "DEFAULT");
+    rc = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keyName, 0, NULL, 0,
+     KEY_READ, NULL, &key, NULL);
+    if (!rc)
+    {
+        DWORD size = *pcchDllList * sizeof(WCHAR);
+
+        rc = RegQueryValueExW(key, DllW, NULL, NULL, (LPBYTE)pwszDllList,
+         &size);
+        if (!rc)
+            *pcchDllList = size / sizeof(WCHAR);
+        else
+        {
+            /* No value, return an empty list */
+            if (*pcchDllList)
+                *pwszDllList = '\0';
+            *pcchDllList = 1;
+        }
+        RegCloseKey(key);
+    }
+    else
+    {
+        SetLastError(rc);
+        ret = FALSE;
+    }
+    CryptMemFree(keyName);
+
+    return ret;
+}
+
+BOOL WINAPI CryptInstallOIDFunctionAddress(HMODULE hModule,
+ DWORD dwEncodingType, LPCSTR pszFuncName, DWORD cFuncEntry,
+ const CRYPT_OID_FUNC_ENTRY rgFuncEntry[], DWORD dwFlags)
+{
+    BOOL ret = TRUE;
+    struct OIDFunctionSet *set;
+
+    TRACE("(%p, %ld, %s, %ld, %p, %08lx)\n", hModule, dwEncodingType,
+     debugstr_a(pszFuncName), cFuncEntry, rgFuncEntry, dwFlags);
+
+    set = (struct OIDFunctionSet *)CryptInitOIDFunctionSet(pszFuncName, 0);
+    if (set)
+    {
+        DWORD i;
+
+        EnterCriticalSection(&set->cs);
+        for (i = 0; ret && i < cFuncEntry; i++)
+        {
+            struct OIDFunction *func;
+
+            if (HIWORD(rgFuncEntry[i].pszOID))
+                func = CryptMemAlloc(sizeof(struct OIDFunction)
+                 + strlen(rgFuncEntry[i].pszOID) + 1);
+            else
+                func = CryptMemAlloc(sizeof(struct OIDFunction));
+            if (func)
+            {
+                func->encoding = dwEncodingType;
+                if (HIWORD(rgFuncEntry[i].pszOID))
+                {
+                    func->entry.pszOID = (LPSTR)((LPBYTE)func + sizeof(*func));
+                    strcpy((LPSTR)func->entry.pszOID, rgFuncEntry[i].pszOID);
+                }
+                else
+                    func->entry.pszOID = rgFuncEntry[i].pszOID;
+                func->entry.pvFuncAddr = rgFuncEntry[i].pvFuncAddr;
+                list_add_tail(&set->functions, &func->next);
+            }
+            else
+                ret = FALSE;
+        }
+        LeaveCriticalSection(&set->cs);
+    }
+    else
+        ret = FALSE;
+    return ret;
+}
+
+static BOOL CRYPT_GetFuncFromReg(DWORD dwEncodingType, LPCSTR pszOID,
+ LPCSTR szFuncName, LPVOID *ppvFuncAddr, HCRYPTOIDFUNCADDR *phFuncAddr)
+{
+    BOOL ret = FALSE;
+    char *keyName;
+    const char *funcName;
+    HKEY key;
+    long rc;
+
+    keyName = CRYPT_GetKeyName(dwEncodingType, szFuncName, pszOID);
+    rc = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keyName, 0, KEY_READ, &key);
+    if (!rc)
+    {
+        DWORD type, size = 0;
+
+        rc = RegQueryValueExA(key, "FuncName", NULL, &type, NULL, &size);
+        if (rc == ERROR_MORE_DATA && type == REG_SZ)
+        {
+            funcName = CryptMemAlloc(size);
+            rc = RegQueryValueExA(key, "FuncName", NULL, &type,
+             (LPBYTE)funcName, &size);
+        }
+        else
+            funcName = szFuncName;
+        rc = RegQueryValueExW(key, DllW, NULL, &type, NULL, &size);
+        if (rc == ERROR_MORE_DATA && type == REG_SZ)
+        {
+            LPWSTR dllName = CryptMemAlloc(size);
+
+            if (dllName)
+            {
+                rc = RegQueryValueExW(key, DllW, NULL, NULL,
+                 (LPBYTE)dllName, &size);
+                if (!rc)
+                {
+                    HMODULE lib;
+
+                    /* This is a bit of a hack; MSDN describes a more
+                     * complicated unload routine than this will allow.
+                     * Still, this seems to suffice for now.
+                     */
+                    lib = LoadLibraryW(dllName);
+                    if (lib)
+                    {
+                        *ppvFuncAddr = GetProcAddress(lib, szFuncName);
+                        if (*ppvFuncAddr)
+                        {
+                            *phFuncAddr = (HCRYPTOIDFUNCADDR)lib;
+                            ret = TRUE;
+                        }
+                        else
+                        {
+                            /* Unload the library, the caller doesn't want
+                             * to unload it when the return value is NULL.
+                             */
+                            FreeLibrary(lib);
+                        }
+                    }
+                }
+                else
+                    SetLastError(rc);
+                CryptMemFree(dllName);
+            }
+        }
+        else
+            SetLastError(rc);
+        if (funcName != szFuncName)
+            CryptMemFree((char *)funcName);
+        RegCloseKey(key);
+    }
+    else
+        SetLastError(rc);
+    CryptMemFree(keyName);
+    return ret;
+}
+
+BOOL WINAPI CryptGetOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet,
+ DWORD dwEncodingType, LPCSTR pszOID, DWORD dwFlags, void **ppvFuncAddr,
+ HCRYPTOIDFUNCADDR *phFuncAddr)
+{
+    BOOL ret = FALSE;
+    struct OIDFunctionSet *set = (struct OIDFunctionSet *)hFuncSet;
+
+    TRACE("(%p, %ld, %s, %08lx, %p, %p)\n", hFuncSet, dwEncodingType,
+     debugstr_a(pszOID), dwFlags, ppvFuncAddr, phFuncAddr);
+
+    *ppvFuncAddr = NULL;
+    if (!(dwFlags & CRYPT_GET_INSTALLED_OID_FUNC_FLAG))
+    {
+        struct OIDFunction *function;
+
+        EnterCriticalSection(&set->cs);
+        LIST_FOR_EACH_ENTRY(function, &set->functions, struct OIDFunction, next)
+        {
+            if (function->encoding == dwEncodingType)
+            {
+                if (HIWORD(pszOID))
+                {
+                    if (HIWORD(function->entry.pszOID &&
+                     !strcasecmp(function->entry.pszOID, pszOID)))
+                    {
+                        *ppvFuncAddr = function->entry.pvFuncAddr;
+                        *phFuncAddr = NULL; /* FIXME: what should it be? */
+                        ret = TRUE;
+                        break;
+                    }
+                }
+                else if (function->entry.pszOID == pszOID)
+                {
+                    *ppvFuncAddr = function->entry.pvFuncAddr;
+                    *phFuncAddr = NULL; /* FIXME: what should it be? */
+                    ret = TRUE;
+                    break;
+                }
+            }
+        }
+        LeaveCriticalSection(&set->cs);
+    }
+    if (!*ppvFuncAddr)
+        ret = CRYPT_GetFuncFromReg(dwEncodingType, pszOID, set->name,
+         ppvFuncAddr, phFuncAddr);
+    return ret;
+}
+
+BOOL WINAPI CryptFreeOIDFunctionAddress(HCRYPTOIDFUNCADDR hFuncAddr,
+ DWORD dwFlags)
+{
+    TRACE("(%p, %08lx)\n", hFuncAddr, dwFlags);
+
+    /* FIXME: as MSDN states, need to check for DllCanUnloadNow in the DLL,
+     * and only unload it if it can be unloaded.  Also need to implement ref
+     * counting on the functions.
+     */
+    FreeLibrary((HMODULE)hFuncAddr);
+    return TRUE;
+}
+
+BOOL WINAPI CryptRegisterDefaultOIDFunction(DWORD dwEncodingType,
+ LPCSTR pszFuncName, DWORD dwIndex, LPCWSTR pwszDll)
+{
+    FIXME("(%lx,%s,%lx,%s) stub!\n", dwEncodingType, pszFuncName, dwIndex,
+          debugstr_w(pwszDll));
+    return FALSE;
+}
+
+BOOL WINAPI CryptUnregisterDefaultOIDFunction(DWORD dwEncodingType,
+ LPCSTR pszFuncName, LPCWSTR pwszDll)
+{
+    FIXME("(%lx %s %s): stub\n", dwEncodingType, debugstr_a(pszFuncName),
+     debugstr_w(pwszDll));
+    return FALSE;
+}
+
+BOOL WINAPI CryptGetDefaultOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet,
+ DWORD dwEncodingType, LPCWSTR pwszDll, DWORD dwFlags, void *ppvFuncAddr,
+ HCRYPTOIDFUNCADDR *phFuncAddr)
+{
+    FIXME("(%p, %ld, %s, %08lx, %p, %p): stub\n", hFuncSet, dwEncodingType,
+     debugstr_w(pwszDll), dwFlags, ppvFuncAddr, phFuncAddr);
+    return FALSE;
+}
+
+BOOL WINAPI CryptRegisterOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName,
+                  LPCSTR pszOID, LPCWSTR pwszDll, LPCSTR pszOverrideFuncName)
+{
+    LONG r;
+    HKEY hKey;
+    LPSTR szKey;
+
+    TRACE("(%lx, %s, %s, %s, %s)\n", dwEncodingType, pszFuncName, pszOID,
+     debugstr_w(pwszDll), pszOverrideFuncName);
+
+    /* This only registers functions for encoding certs, not messages */
+    if (!GET_CERT_ENCODING_TYPE(dwEncodingType))
+        return TRUE;
+
+    /* Native does nothing pwszDll is NULL */
+    if (!pwszDll)
+        return TRUE;
+
+    /* I'm not matching MS bug for bug here, because I doubt any app depends on
+     * it:  native "succeeds" if pszFuncName is NULL, but the nonsensical entry
+     * it creates would never be used.
+     */
+    if (!pszFuncName || !pszOID)
+    {
+        SetLastError(HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER));
+        return FALSE;
+    }
+
+    szKey = CRYPT_GetKeyName(dwEncodingType, pszFuncName, pszOID);
+    TRACE("Key name is %s\n", debugstr_a(szKey));
+
+    if (!szKey)
+        return FALSE;
+
+    r = RegCreateKeyA(HKEY_LOCAL_MACHINE, szKey, &hKey);
+    CryptMemFree(szKey);
+    if(r != ERROR_SUCCESS)
+        return FALSE;
+
+    /* write the values */
+    if (pszOverrideFuncName)
+        RegSetValueExA(hKey, "FuncName", 0, REG_SZ,
+         (const BYTE*)pszOverrideFuncName, lstrlenA(pszOverrideFuncName) + 1);
+    RegSetValueExW(hKey, DllW, 0, REG_SZ, (const BYTE*) pwszDll,
+     (lstrlenW(pwszDll) + 1) * sizeof (WCHAR));
+
+    RegCloseKey(hKey);
+    return TRUE;
+}
+
+BOOL WINAPI CryptUnregisterOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName,
+ LPCSTR pszOID)
+{
+    LPSTR szKey;
+    LONG rc;
+
+    TRACE("%lx %s %s\n", dwEncodingType, pszFuncName, pszOID);
+
+    if (!GET_CERT_ENCODING_TYPE(dwEncodingType))
+        return TRUE;
+
+    if (!pszFuncName || !pszOID)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    szKey = CRYPT_GetKeyName(dwEncodingType, pszFuncName, pszOID);
+    rc = RegDeleteKeyA(HKEY_LOCAL_MACHINE, szKey);
+    CryptMemFree(szKey);
+    if (rc)
+        SetLastError(rc);
+    return rc ? FALSE : TRUE;
+}
+
+BOOL WINAPI CryptGetOIDFunctionValue(DWORD dwEncodingType, LPCSTR pszFuncName,
+ LPCSTR pszOID, LPCWSTR pwszValueName, DWORD *pdwValueType, BYTE *pbValueData,
+ DWORD *pcbValueData)
+{
+    LPSTR szKey;
+    LONG rc;
+    HKEY hKey;
+
+    TRACE("%lx %s %s %s %p %p %p\n", dwEncodingType, debugstr_a(pszFuncName),
+     debugstr_a(pszOID), debugstr_w(pwszValueName), pdwValueType, pbValueData,
+     pcbValueData);
+
+    if (!GET_CERT_ENCODING_TYPE(dwEncodingType))
+        return TRUE;
+
+    if (!pszFuncName || !pszOID || !pwszValueName)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    szKey = CRYPT_GetKeyName(dwEncodingType, pszFuncName, pszOID);
+    rc = RegOpenKeyA(HKEY_LOCAL_MACHINE, szKey, &hKey);
+    CryptMemFree(szKey);
+    if (rc)
+        SetLastError(rc);
+    else
+    {
+        rc = RegQueryValueExW(hKey, pwszValueName, NULL, pdwValueType,
+         pbValueData, pcbValueData);
+        if (rc)
+            SetLastError(rc);
+        RegCloseKey(hKey);
+    }
+    return rc ? FALSE : TRUE;
+}
+
+BOOL WINAPI CryptSetOIDFunctionValue(DWORD dwEncodingType, LPCSTR pszFuncName,
+ LPCSTR pszOID, LPCWSTR pwszValueName, DWORD dwValueType,
+ const BYTE *pbValueData, DWORD cbValueData)
+{
+    LPSTR szKey;
+    LONG rc;
+    HKEY hKey;
+
+    TRACE("%lx %s %s %s %ld %p %ld\n", dwEncodingType, debugstr_a(pszFuncName),
+     debugstr_a(pszOID), debugstr_w(pwszValueName), dwValueType, pbValueData,
+     cbValueData);
+
+    if (!GET_CERT_ENCODING_TYPE(dwEncodingType))
+        return TRUE;
+
+    if (!pszFuncName || !pszOID || !pwszValueName)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    szKey = CRYPT_GetKeyName(dwEncodingType, pszFuncName, pszOID);
+    rc = RegOpenKeyA(HKEY_LOCAL_MACHINE, szKey, &hKey);
+    CryptMemFree(szKey);
+    if (rc)
+        SetLastError(rc);
+    else
+    {
+        rc = RegSetValueExW(hKey, pwszValueName, 0, dwValueType, pbValueData,
+         cbValueData);
+        if (rc)
+            SetLastError(rc);
+        RegCloseKey(hKey);
+    }
+    return rc ? FALSE : TRUE;
+}
index 8e0f777..782371f 100644 (file)
@@ -967,6 +967,8 @@ static const WCHAR CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH[] =
 #define CRYPT_UNICODE_NAME_DECODE_DISABLE_IE4_UTF8_FLAG \
  CERT_RDN_DISABLE_IE4_UTF8_FLAG
 
+#define CRYPT_GET_INSTALLED_OID_FUNC_FLAG  0x1
+
 /* types for CertOpenStore dwEncodingType */
 #define CERT_ENCODING_TYPE_MASK 0x0000ffff
 #define CMSG_ENCODING_TYPE_MASK 0xffff0000
@@ -1699,6 +1701,16 @@ typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_SET_CTL_PROPERTY)(
 typedef BOOL (WINAPI *PFN_CERT_STORE_PROV_CONTROL)(HCERTSTOREPROV hStoreProv,
  DWORD dwFlags, DWORD dwCtrlType, void const *pvCtrlPara);
 
+typedef struct _CRYPT_OID_FUNC_ENTRY {
+    LPCSTR pszOID;
+    void  *pvFuncAddr;
+} CRYPT_OID_FUNC_ENTRY, *PCRYPT_OID_FUNC_ENTRY;
+
+typedef BOOL (WINAPI *PFN_CRYPT_ENUM_OID_FUNC)(DWORD dwEncodingType,
+ LPCSTR pszFuncName, LPCSTR pszOID, DWORD cValue, const DWORD rgdwValueType[],
+ LPCWSTR const rgpwszValueName[], const BYTE * const rgpbValueData[],
+ const DWORD rgcbValueData[], void *pvArg);
+
 /* subject types for CryptVerifyCertificateSignatureEx */
 #define CRYPT_VERIFY_CERT_SIGN_SUBJECT_BLOB 1
 #define CRYPT_VERIFY_CERT_SIGN_SUBJECT_CERT 2
@@ -1817,6 +1829,34 @@ BOOL WINAPI CryptSetProviderExW(LPCWSTR,DWORD,DWORD*,DWORD);
 BOOL WINAPI CryptEncodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType, const void *pvStructInfo, BYTE *pbEncoded, DWORD *pcbEncoded);
 BOOL WINAPI CryptEncodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara, void *pvEncoded, DWORD *pcbEncoded);
 
+BOOL WINAPI CryptRegisterDefaultOIDFunction(DWORD,LPCSTR,DWORD,LPCWSTR);
+BOOL WINAPI CryptRegisterOIDFunction(DWORD,LPCSTR,LPCSTR,LPCWSTR,LPCSTR);
+BOOL WINAPI CryptGetOIDFunctionValue(DWORD dwEncodingType, LPCSTR pszFuncName,
+                                     LPCSTR pszOID, LPCWSTR szValueName, DWORD *pdwValueType,
+                                     BYTE *pbValueData, DWORD *pcbValueData);
+BOOL WINAPI CryptSetOIDFunctionValue(DWORD dwEncodingType, LPCSTR pszFuncName,
+                                     LPCSTR pszOID, LPCWSTR pwszValueName, DWORD dwValueType,
+                                     const BYTE *pbValueData, DWORD cbValueData);
+BOOL WINAPI CryptUnregisterDefaultOIDFunction(DWORD,LPCSTR,LPCWSTR);
+BOOL WINAPI CryptUnregisterOIDFunction(DWORD,LPCSTR,LPCSTR);
+BOOL WINAPI CryptEnumOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName,
+ LPCSTR pszOID, DWORD dwFlags, void *pvArg,
+ PFN_CRYPT_ENUM_OID_FUNC pfnEnumOIDFunc);
+HCRYPTOIDFUNCSET WINAPI CryptInitOIDFunctionSet(LPCSTR,DWORD);
+BOOL WINAPI CryptGetDefaultOIDDllList(HCRYPTOIDFUNCSET hFuncSet,
+ DWORD dwEncodingType, LPWSTR pwszDllList, DWORD *pcchDllList);
+BOOL WINAPI CryptGetDefaultOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet,
+ DWORD dwEncodingType, LPCWSTR pwszDll, DWORD dwFlags, void *ppvFuncAddr,
+ HCRYPTOIDFUNCADDR *phFuncAddr);
+BOOL WINAPI CryptGetOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet,
+ DWORD dwEncodingType, LPCSTR pszOID, DWORD dwFlags, void **ppvFuncAddr,
+ HCRYPTOIDFUNCADDR *phFuncAddr);
+BOOL WINAPI CryptFreeOIDFunctionAddress(HCRYPTOIDFUNCADDR hFuncAddr,
+ DWORD dwFlags);
+BOOL WINAPI CryptInstallOIDFunctionAddress(HMODULE hModule,
+ DWORD dwEncodingType, LPCSTR pszFuncName, DWORD cFuncEntry,
+ const CRYPT_OID_FUNC_ENTRY rgFuncEntry[], DWORD dwFlags);
+
 #ifdef UNICODE
 #define CertNameToStr CertNameToStrW
 #define CryptAcquireContext CryptAcquireContextW