dbghelp: In dwarf debug functions, use register name instead of register value.
[wine] / dlls / crypt32 / oid.c
index c88d85f..ea7b539 100644 (file)
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
+
+#include "config.h"
+#include "wine/port.h"
+
 #include <stdio.h>
 #include <stdarg.h>
 #define NONAMELESSUNION
@@ -33,15 +37,13 @@ WINE_DEFAULT_DEBUG_CHANNEL(crypt);
 
 static const WCHAR DllW[] = { 'D','l','l',0 };
 
-static void init_function_sets(void);
-static void init_oid_info(HINSTANCE hinst);
+static void init_oid_info(void);
 static void free_function_sets(void);
 static void free_oid_info(void);
 
-void crypt_oid_init(HINSTANCE hinst)
+void crypt_oid_init(void)
 {
-    init_function_sets();
-    init_oid_info(hinst);
+    init_oid_info();
 }
 
 void crypt_oid_free(void)
@@ -51,7 +53,14 @@ void crypt_oid_free(void)
 }
 
 static CRITICAL_SECTION funcSetCS;
-static struct list funcSets;
+static CRITICAL_SECTION_DEBUG funcSetCSDebug =
+{
+    0, 0, &funcSetCS,
+    { &funcSetCSDebug.ProcessLocksList, &funcSetCSDebug.ProcessLocksList },
+    0, 0, { (DWORD_PTR)(__FILE__ ": funcSetCS") }
+};
+static CRITICAL_SECTION funcSetCS = { &funcSetCSDebug, -1, 0, 0, 0, 0 };
+static struct list funcSets = { &funcSets, &funcSets };
 
 struct OIDFunctionSet
 {
@@ -68,11 +77,14 @@ struct OIDFunction
     struct list next;
 };
 
-static void init_function_sets(void)
-{
-    InitializeCriticalSection(&funcSetCS);
-    list_init(&funcSets);
-}
+static const WCHAR ROOT[] = {'R','O','O','T',0};
+static const WCHAR MY[] = {'M','Y',0};
+static const WCHAR CA[] = {'C','A',0};
+static const WCHAR ADDRESSBOOK[] = {'A','D','D','R','E','S','S','B','O','O','K',0};
+static const WCHAR TRUSTEDPUBLISHER[] = {'T','r','u','s','t','e','d','P','u','b','l','i','s','h','e','r',0};
+static const WCHAR DISALLOWED[] = {'D','i','s','a','l','l','o','w','e','d',0};
+static const LPCWSTR LocalizedKeys[] = {ROOT,MY,CA,ADDRESSBOOK,TRUSTEDPUBLISHER,DISALLOWED};
+static WCHAR LocalizedNames[sizeof(LocalizedKeys)/sizeof(LocalizedKeys[0])][256];
 
 static void free_function_sets(void)
 {
@@ -91,10 +103,10 @@ static void free_function_sets(void)
             list_remove(&functionCursor->next);
             CryptMemFree(functionCursor);
         }
+        setCursor->cs.DebugInfo->Spare[0] = 0;
         DeleteCriticalSection(&setCursor->cs);
         CryptMemFree(setCursor);
     }
-    DeleteCriticalSection(&funcSetCS);
 }
 
 /* There is no free function associated with this; therefore, the sets are
@@ -105,14 +117,14 @@ HCRYPTOIDFUNCSET WINAPI CryptInitOIDFunctionSet(LPCSTR pszFuncName,
 {
     struct OIDFunctionSet *cursor, *ret = NULL;
 
-    TRACE("(%s, %lx)\n", debugstr_a(pszFuncName), dwFlags);
+    TRACE("(%s, %x)\n", debugstr_a(pszFuncName), dwFlags);
 
     EnterCriticalSection(&funcSetCS);
     LIST_FOR_EACH_ENTRY(cursor, &funcSets, struct OIDFunctionSet, next)
     {
         if (!strcasecmp(pszFuncName, cursor->name))
         {
-            ret = (HCRYPTOIDFUNCSET)cursor;
+            ret = cursor;
             break;
         }
     }
@@ -126,6 +138,7 @@ HCRYPTOIDFUNCSET WINAPI CryptInitOIDFunctionSet(LPCSTR pszFuncName,
             if (ret->name)
             {
                 InitializeCriticalSection(&ret->cs);
+                ret->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": OIDFunctionSet.cs");
                 list_init(&ret->functions);
                 strcpy(ret->name, pszFuncName);
                 list_add_tail(&funcSets, &ret->next);
@@ -139,14 +152,14 @@ HCRYPTOIDFUNCSET WINAPI CryptInitOIDFunctionSet(LPCSTR pszFuncName,
     }
     LeaveCriticalSection(&funcSetCS);
 
-    return (HCRYPTOIDFUNCSET)ret;
+    return ret;
 }
 
 static char *CRYPT_GetKeyName(DWORD dwEncodingType, LPCSTR pszFuncName,
  LPCSTR pszOID)
 {
     static const char szEncodingTypeFmt[] =
-     "Software\\Microsoft\\Cryptography\\OID\\EncodingType %ld\\%s\\%s";
+     "Software\\Microsoft\\Cryptography\\OID\\EncodingType %d\\%s\\%s";
     UINT len;
     char numericOID[7]; /* enough for "#65535" */
     const char *oid;
@@ -157,7 +170,7 @@ static char *CRYPT_GetKeyName(DWORD dwEncodingType, LPCSTR pszFuncName,
      * "EncodingType 2" would be expected if it were a mask.  Instead native
      * stores values in "EncodingType 3".
      */
-    if (!HIWORD(pszOID))
+    if (IS_INTOID(pszOID))
     {
         snprintf(numericOID, sizeof(numericOID), "#%d", LOWORD(pszOID));
         oid = numericOID;
@@ -173,7 +186,8 @@ static char *CRYPT_GetKeyName(DWORD dwEncodingType, LPCSTR pszFuncName,
     len = sizeof(szEncodingTypeFmt) + lstrlenA(pszFuncName) + lstrlenA(oid);
     szKey = CryptMemAlloc(len);
     if (szKey)
-        sprintf(szKey, szEncodingTypeFmt, dwEncodingType, pszFuncName, oid);
+        sprintf(szKey, szEncodingTypeFmt,
+         GET_CERT_ENCODING_TYPE(dwEncodingType), pszFuncName, oid);
     return szKey;
 }
 
@@ -181,12 +195,12 @@ BOOL WINAPI CryptGetDefaultOIDDllList(HCRYPTOIDFUNCSET hFuncSet,
  DWORD dwEncodingType, LPWSTR pwszDllList, DWORD *pcchDllList)
 {
     BOOL ret = TRUE;
-    struct OIDFunctionSet *set = (struct OIDFunctionSet *)hFuncSet;
+    struct OIDFunctionSet *set = hFuncSet;
     char *keyName;
     HKEY key;
-    long rc;
+    LSTATUS rc;
 
-    TRACE("(%p, %ld, %p, %p)\n", hFuncSet, dwEncodingType, pwszDllList,
+    TRACE("(%p, %d, %p, %p)\n", hFuncSet, dwEncodingType, pwszDllList,
      pcchDllList);
 
     keyName = CRYPT_GetKeyName(dwEncodingType, set->name, "DEFAULT");
@@ -203,7 +217,7 @@ BOOL WINAPI CryptGetDefaultOIDDllList(HCRYPTOIDFUNCSET hFuncSet,
         else
         {
             /* No value, return an empty list */
-            if (*pcchDllList)
+            if (pwszDllList && *pcchDllList)
                 *pwszDllList = '\0';
             *pcchDllList = 1;
         }
@@ -211,8 +225,10 @@ BOOL WINAPI CryptGetDefaultOIDDllList(HCRYPTOIDFUNCSET hFuncSet,
     }
     else
     {
-        SetLastError(rc);
-        ret = FALSE;
+        /* No value, return an empty list */
+        if (pwszDllList && *pcchDllList)
+            *pwszDllList = '\0';
+        *pcchDllList = 1;
     }
     CryptMemFree(keyName);
 
@@ -226,10 +242,10 @@ BOOL WINAPI CryptInstallOIDFunctionAddress(HMODULE hModule,
     BOOL ret = TRUE;
     struct OIDFunctionSet *set;
 
-    TRACE("(%p, %ld, %s, %ld, %p, %08lx)\n", hModule, dwEncodingType,
+    TRACE("(%p, %d, %s, %d, %p, %08x)\n", hModule, dwEncodingType,
      debugstr_a(pszFuncName), cFuncEntry, rgFuncEntry, dwFlags);
 
-    set = (struct OIDFunctionSet *)CryptInitOIDFunctionSet(pszFuncName, 0);
+    set = CryptInitOIDFunctionSet(pszFuncName, 0);
     if (set)
     {
         DWORD i;
@@ -239,18 +255,21 @@ BOOL WINAPI CryptInstallOIDFunctionAddress(HMODULE hModule,
         {
             struct OIDFunction *func;
 
-            if (HIWORD(rgFuncEntry[i].pszOID))
+            if (!IS_INTOID(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->encoding = GET_CERT_ENCODING_TYPE(dwEncodingType);
+                if (!IS_INTOID(rgFuncEntry[i].pszOID))
                 {
-                    func->entry.pszOID = (LPSTR)((LPBYTE)func + sizeof(*func));
-                    strcpy((LPSTR)func->entry.pszOID, rgFuncEntry[i].pszOID);
+                    LPSTR oid;
+
+                    oid = (LPSTR)((LPBYTE)func + sizeof(*func));
+                    strcpy(oid, rgFuncEntry[i].pszOID);
+                    func->entry.pszOID = oid;
                 }
                 else
                     func->entry.pszOID = rgFuncEntry[i].pszOID;
@@ -267,6 +286,13 @@ BOOL WINAPI CryptInstallOIDFunctionAddress(HMODULE hModule,
     return ret;
 }
 
+struct FuncAddr
+{
+    HMODULE lib;
+    LPWSTR  dllList;
+    LPWSTR  currentDll;
+};
+
 static BOOL CRYPT_GetFuncFromReg(DWORD dwEncodingType, LPCSTR pszOID,
  LPCSTR szFuncName, LPVOID *ppvFuncAddr, HCRYPTOIDFUNCADDR *phFuncAddr)
 {
@@ -274,7 +300,7 @@ static BOOL CRYPT_GetFuncFromReg(DWORD dwEncodingType, LPCSTR pszOID,
     char *keyName;
     const char *funcName;
     HKEY key;
-    long rc;
+    LSTATUS rc;
 
     keyName = CRYPT_GetKeyName(dwEncodingType, szFuncName, pszOID);
     rc = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keyName, 0, KEY_READ, &key);
@@ -283,7 +309,7 @@ static BOOL CRYPT_GetFuncFromReg(DWORD dwEncodingType, LPCSTR pszOID,
         DWORD type, size = 0;
 
         rc = RegQueryValueExA(key, "FuncName", NULL, &type, NULL, &size);
-        if (rc == ERROR_MORE_DATA && type == REG_SZ)
+        if ((!rc || rc == ERROR_MORE_DATA) && type == REG_SZ)
         {
             funcName = CryptMemAlloc(size);
             rc = RegQueryValueExA(key, "FuncName", NULL, &type,
@@ -292,7 +318,7 @@ static BOOL CRYPT_GetFuncFromReg(DWORD dwEncodingType, LPCSTR pszOID,
         else
             funcName = szFuncName;
         rc = RegQueryValueExW(key, DllW, NULL, &type, NULL, &size);
-        if (rc == ERROR_MORE_DATA && type == REG_SZ)
+        if ((!rc || rc == ERROR_MORE_DATA) && type == REG_SZ)
         {
             LPWSTR dllName = CryptMemAlloc(size);
 
@@ -311,11 +337,24 @@ static BOOL CRYPT_GetFuncFromReg(DWORD dwEncodingType, LPCSTR pszOID,
                     lib = LoadLibraryW(dllName);
                     if (lib)
                     {
-                        *ppvFuncAddr = GetProcAddress(lib, szFuncName);
+                        *ppvFuncAddr = GetProcAddress(lib, funcName);
                         if (*ppvFuncAddr)
                         {
-                            *phFuncAddr = (HCRYPTOIDFUNCADDR)lib;
-                            ret = TRUE;
+                            struct FuncAddr *addr =
+                             CryptMemAlloc(sizeof(struct FuncAddr));
+
+                            if (addr)
+                            {
+                                addr->lib = lib;
+                                addr->dllList = addr->currentDll = NULL;
+                                *phFuncAddr = addr;
+                                ret = TRUE;
+                            }
+                            else
+                            {
+                                *phFuncAddr = NULL;
+                                FreeLibrary(lib);
+                            }
                         }
                         else
                         {
@@ -348,9 +387,9 @@ BOOL WINAPI CryptGetOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet,
  HCRYPTOIDFUNCADDR *phFuncAddr)
 {
     BOOL ret = FALSE;
-    struct OIDFunctionSet *set = (struct OIDFunctionSet *)hFuncSet;
+    struct OIDFunctionSet *set = hFuncSet;
 
-    TRACE("(%p, %ld, %s, %08lx, %p, %p)\n", hFuncSet, dwEncodingType,
+    TRACE("(%p, %d, %s, %08x, %p, %p)\n", hFuncSet, dwEncodingType,
      debugstr_a(pszOID), dwFlags, ppvFuncAddr, phFuncAddr);
 
     *ppvFuncAddr = NULL;
@@ -361,11 +400,11 @@ BOOL WINAPI CryptGetOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet,
         EnterCriticalSection(&set->cs);
         LIST_FOR_EACH_ENTRY(function, &set->functions, struct OIDFunction, next)
         {
-            if (function->encoding == dwEncodingType)
+            if (function->encoding == GET_CERT_ENCODING_TYPE(dwEncodingType))
             {
-                if (HIWORD(pszOID))
+                if (!IS_INTOID(pszOID))
                 {
-                    if (HIWORD(function->entry.pszOID) &&
+                    if (!IS_INTOID(function->entry.pszOID) &&
                      !strcasecmp(function->entry.pszOID, pszOID))
                     {
                         *ppvFuncAddr = function->entry.pvFuncAddr;
@@ -388,29 +427,164 @@ BOOL WINAPI CryptGetOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet,
     if (!*ppvFuncAddr)
         ret = CRYPT_GetFuncFromReg(dwEncodingType, pszOID, set->name,
          ppvFuncAddr, phFuncAddr);
+    TRACE("returning %d\n", ret);
     return ret;
 }
 
 BOOL WINAPI CryptFreeOIDFunctionAddress(HCRYPTOIDFUNCADDR hFuncAddr,
  DWORD dwFlags)
 {
-    TRACE("(%p, %08lx)\n", hFuncAddr, dwFlags);
+    TRACE("(%p, %08x)\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);
+    if (hFuncAddr)
+    {
+        struct FuncAddr *addr = hFuncAddr;
+
+        CryptMemFree(addr->dllList);
+        FreeLibrary(addr->lib);
+        CryptMemFree(addr);
+    }
     return TRUE;
 }
 
+static BOOL CRYPT_GetFuncFromDll(LPCWSTR dll, LPCSTR func, HMODULE *lib,
+ void **ppvFuncAddr)
+{
+    BOOL ret = FALSE;
+
+    *lib = LoadLibraryW(dll);
+    if (*lib)
+    {
+        *ppvFuncAddr = GetProcAddress(*lib, func);
+        if (*ppvFuncAddr)
+            ret = TRUE;
+        else
+        {
+            FreeLibrary(*lib);
+            *lib = NULL;
+        }
+    }
+    return ret;
+}
+
 BOOL WINAPI CryptGetDefaultOIDFunctionAddress(HCRYPTOIDFUNCSET hFuncSet,
- DWORD dwEncodingType, LPCWSTR pwszDll, DWORD dwFlags, void *ppvFuncAddr,
+ DWORD dwEncodingType, LPCWSTR pwszDll, DWORD dwFlags, void **ppvFuncAddr,
  HCRYPTOIDFUNCADDR *phFuncAddr)
 {
-    FIXME("(%p, %ld, %s, %08lx, %p, %p): stub\n", hFuncSet, dwEncodingType,
+    struct OIDFunctionSet *set = hFuncSet;
+    BOOL ret = FALSE;
+
+    TRACE("(%p, %d, %s, %08x, %p, %p)\n", hFuncSet, dwEncodingType,
      debugstr_w(pwszDll), dwFlags, ppvFuncAddr, phFuncAddr);
-    return FALSE;
+
+    if (pwszDll)
+    {
+        HMODULE lib;
+
+        *phFuncAddr = NULL;
+        ret = CRYPT_GetFuncFromDll(pwszDll, set->name, &lib, ppvFuncAddr);
+        if (ret)
+        {
+            struct FuncAddr *addr = CryptMemAlloc(sizeof(struct FuncAddr));
+
+            if (addr)
+            {
+                addr->lib = lib;
+                addr->dllList = addr->currentDll = NULL;
+                *phFuncAddr = addr;
+            }
+            else
+            {
+                FreeLibrary(lib);
+                *ppvFuncAddr = NULL;
+                SetLastError(ERROR_OUTOFMEMORY);
+                ret = FALSE;
+            }
+        }
+        else
+            SetLastError(ERROR_FILE_NOT_FOUND);
+    }
+    else
+    {
+        struct FuncAddr *addr = *phFuncAddr;
+
+        if (!addr)
+        {
+            DWORD size;
+
+            ret = CryptGetDefaultOIDDllList(hFuncSet, dwEncodingType, NULL,
+             &size);
+            if (ret)
+            {
+                LPWSTR dllList = CryptMemAlloc(size * sizeof(WCHAR));
+
+                if (dllList)
+                {
+                    ret = CryptGetDefaultOIDDllList(hFuncSet, dwEncodingType,
+                     dllList, &size);
+                    if (ret)
+                    {
+                        addr = CryptMemAlloc(sizeof(struct FuncAddr));
+                        if (addr)
+                        {
+                            addr->dllList = dllList;
+                            addr->currentDll = dllList;
+                            addr->lib = NULL;
+                            *phFuncAddr = addr;
+                        }
+                        else
+                        {
+                            CryptMemFree(dllList);
+                            SetLastError(ERROR_OUTOFMEMORY);
+                            ret = FALSE;
+                        }
+                    }
+                }
+                else
+                {
+                    SetLastError(ERROR_OUTOFMEMORY);
+                    ret = FALSE;
+                }
+            }
+        }
+        if (addr)
+        {
+            if (!*addr->currentDll)
+            {
+                CryptFreeOIDFunctionAddress(*phFuncAddr, 0);
+                SetLastError(ERROR_FILE_NOT_FOUND);
+                *phFuncAddr = NULL;
+                ret = FALSE;
+            }
+            else
+            {
+                /* FIXME: as elsewhere, can't free until DllCanUnloadNow says
+                 * it's possible, and should defer unloading for some time to
+                 * avoid repeated LoadLibrary/FreeLibrary on the same dll.
+                 */
+                FreeLibrary(addr->lib);
+                ret = CRYPT_GetFuncFromDll(addr->currentDll, set->name,
+                 &addr->lib, ppvFuncAddr);
+                if (ret)
+                {
+                    /* Move past the current DLL */
+                    addr->currentDll += lstrlenW(addr->currentDll) + 1;
+                    *phFuncAddr = addr;
+                }
+                else
+                {
+                    CryptFreeOIDFunctionAddress(*phFuncAddr, 0);
+                    SetLastError(ERROR_FILE_NOT_FOUND);
+                    *phFuncAddr = NULL;
+                }
+            }
+        }
+    }
+    return ret;
 }
 
 /***********************************************************************
@@ -440,12 +614,8 @@ BOOL WINAPI CryptRegisterOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName,
     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;
+    TRACE("(%x, %s, %s, %s, %s)\n", dwEncodingType, pszFuncName,
+     debugstr_a(pszOID), debugstr_w(pwszDll), pszOverrideFuncName);
 
     /* Native does nothing pwszDll is NULL */
     if (!pwszDll)
@@ -470,38 +640,52 @@ BOOL WINAPI CryptRegisterOIDFunction(DWORD dwEncodingType, LPCSTR pszFuncName,
     r = RegCreateKeyA(HKEY_LOCAL_MACHINE, szKey, &hKey);
     CryptMemFree(szKey);
 
-    /* Testing on native shows that registry errors are reported */
-    if(r != ERROR_SUCCESS)
-    {
-        SetLastError(r);
-        return FALSE;
-    }
+    if (r != ERROR_SUCCESS) goto error_close_key;
 
     /* write the values */
     if (pszOverrideFuncName)
     {
         r = RegSetValueExA(hKey, "FuncName", 0, REG_SZ,
              (const BYTE*)pszOverrideFuncName, lstrlenA(pszOverrideFuncName) + 1);
-        if (r != ERROR_SUCCESS) SetLastError(r);
+        if (r != ERROR_SUCCESS) goto error_close_key;
     }
     r = RegSetValueExW(hKey, DllW, 0, REG_SZ, (const BYTE*) pwszDll,
          (lstrlenW(pwszDll) + 1) * sizeof (WCHAR));
-    if (r != ERROR_SUCCESS) SetLastError(r);
+
+error_close_key:
 
     RegCloseKey(hKey);
+
+    if (r != ERROR_SUCCESS) 
+    {
+        SetLastError(r);
+        return FALSE;
+    }
+
     return TRUE;
 }
 
+/***********************************************************************
+ *             CryptRegisterOIDInfo (CRYPT32.@)
+ */
+BOOL WINAPI CryptRegisterOIDInfo(PCCRYPT_OID_INFO pInfo, DWORD dwFlags)
+{
+    FIXME("(%p, %x): stub\n", pInfo, dwFlags );
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
+}
+
+/***********************************************************************
+ *             CryptUnregisterOIDFunction (CRYPT32.@)
+ */
 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;
+    TRACE("%x %s %s\n", dwEncodingType, debugstr_a(pszFuncName),
+     debugstr_a(pszOID));
 
     if (!pszFuncName || !pszOID)
     {
@@ -525,7 +709,7 @@ BOOL WINAPI CryptGetOIDFunctionValue(DWORD dwEncodingType, LPCSTR pszFuncName,
     LONG rc;
     HKEY hKey;
 
-    TRACE("%lx %s %s %s %p %p %p\n", dwEncodingType, debugstr_a(pszFuncName),
+    TRACE("%x %s %s %s %p %p %p\n", dwEncodingType, debugstr_a(pszFuncName),
      debugstr_a(pszOID), debugstr_w(pwszValueName), pdwValueType, pbValueData,
      pcbValueData);
 
@@ -562,7 +746,7 @@ BOOL WINAPI CryptSetOIDFunctionValue(DWORD dwEncodingType, LPCSTR pszFuncName,
     LONG rc;
     HKEY hKey;
 
-    TRACE("%lx %s %s %s %ld %p %ld\n", dwEncodingType, debugstr_a(pszFuncName),
+    TRACE("%x %s %s %s %d %p %d\n", dwEncodingType, debugstr_a(pszFuncName),
      debugstr_a(pszOID), debugstr_w(pwszValueName), dwValueType, pbValueData,
      cbValueData);
 
@@ -689,9 +873,20 @@ static BOOL CRYPT_RemoveStringFromMultiString(LPWSTR multi, LPCWSTR toRemove)
     {
         DWORD len = CRYPT_GetMultiStringCharacterLen(multi);
 
-        /* Copy remainder of string "left" */
-        memmove(spotToRemove, spotToRemove + lstrlenW(toRemove) + 1,
-         (len - (spotToRemove - multi)) * sizeof(WCHAR));
+        if (spotToRemove + lstrlenW(toRemove) + 2 >= multi + len)
+        {
+            /* Removing last string in list, terminate multi string directly */
+            *spotToRemove = 0;
+            *(spotToRemove + 1) = 0;
+        }
+        else
+        {
+            LPCWSTR nextStr = spotToRemove + lstrlenW(toRemove) + 1;
+
+            /* Copy remainder of string "left" */
+            memmove(spotToRemove, nextStr,
+             (len - (nextStr - multi)) * sizeof(WCHAR));
+        }
         ret = TRUE;
     }
     else
@@ -758,16 +953,18 @@ static inline BOOL CRYPT_SetDefaultOIDDlls(HKEY key, LPCWSTR dlls)
     return r == ERROR_SUCCESS;
 }
 
+/***********************************************************************
+ *             CryptRegisterDefaultOIDFunction (CRYPT32.@)
+ */
 BOOL WINAPI CryptRegisterDefaultOIDFunction(DWORD dwEncodingType,
  LPCSTR pszFuncName, DWORD dwIndex, LPCWSTR pwszDll)
 {
     HKEY key;
     LPWSTR dlls;
-    LPCWSTR existing;
     BOOL ret = FALSE;
 
-    TRACE("(%lx, %s, %lx, %s)\n", dwEncodingType, pszFuncName, dwIndex,
-     debugstr_w(pwszDll));
+    TRACE("(%x, %s, %d, %s)\n", dwEncodingType, debugstr_a(pszFuncName),
+     dwIndex, debugstr_w(pwszDll));
 
     if (!pwszDll)
     {
@@ -779,7 +976,7 @@ BOOL WINAPI CryptRegisterDefaultOIDFunction(DWORD dwEncodingType,
         return FALSE;
 
     dlls = CRYPT_GetDefaultOIDDlls(key);
-    if ((existing = CRYPT_FindStringInMultiString(dlls, pwszDll)))
+    if (CRYPT_FindStringInMultiString(dlls, pwszDll))
         SetLastError(ERROR_FILE_EXISTS);
     else
     {
@@ -799,7 +996,7 @@ BOOL WINAPI CryptUnregisterDefaultOIDFunction(DWORD dwEncodingType,
     LPWSTR dlls;
     BOOL ret;
 
-    TRACE("(%lx, %s, %s)\n", dwEncodingType, debugstr_a(pszFuncName),
+    TRACE("(%x, %s, %s)\n", dwEncodingType, debugstr_a(pszFuncName),
      debugstr_w(pwszDll));
 
     if (!pwszDll)
@@ -819,8 +1016,44 @@ BOOL WINAPI CryptUnregisterDefaultOIDFunction(DWORD dwEncodingType,
     return ret;
 }
 
+static void oid_init_localizednames(void)
+{
+    unsigned int i;
+
+    for(i = 0; i < sizeof(LocalizedKeys)/sizeof(LPCWSTR); i++)
+    {
+        LoadStringW(hInstance, IDS_LOCALIZEDNAME_ROOT+i, LocalizedNames[i], 256);
+    }
+}
+
+/********************************************************************
+ *              CryptFindLocalizedName (CRYPT32.@)
+ */
+LPCWSTR WINAPI CryptFindLocalizedName(LPCWSTR pwszCryptName)
+{
+    unsigned int i;
+
+    for(i = 0; i < sizeof(LocalizedKeys)/sizeof(LPCWSTR); i++)
+    {
+        if(!lstrcmpiW(LocalizedKeys[i], pwszCryptName))
+        {
+            return LocalizedNames[i];
+        }
+    }
+
+    FIXME("No name for: %s - stub\n",debugstr_w(pwszCryptName));
+    return NULL;
+}
+
 static CRITICAL_SECTION oidInfoCS;
-static struct list oidInfo;
+static CRITICAL_SECTION_DEBUG oidInfoCSDebug =
+{
+    0, 0, &oidInfoCS,
+    { &oidInfoCSDebug.ProcessLocksList, &oidInfoCSDebug.ProcessLocksList },
+    0, 0, { (DWORD_PTR)(__FILE__ ": oidInfoCS") }
+};
+static CRITICAL_SECTION oidInfoCS = { &oidInfoCSDebug, -1, 0, 0, 0, 0 };
+static struct list oidInfo = { &oidInfo, &oidInfo };
 
 static const WCHAR tripledes[] = { '3','d','e','s',0 };
 static const WCHAR cms3deswrap[] = { 'C','M','S','3','D','E','S','w','r','a',
@@ -834,6 +1067,9 @@ static const WCHAR rc2[] = { 'r','c','2',0 };
 static const WCHAR rc4[] = { 'r','c','4',0 };
 static const WCHAR sha[] = { 's','h','a',0 };
 static const WCHAR sha1[] = { 's','h','a','1',0 };
+static const WCHAR sha256[] = { 's','h','a','2','5','6',0 };
+static const WCHAR sha384[] = { 's','h','a','3','8','4',0 };
+static const WCHAR sha512[] = { 's','h','a','5','1','2',0 };
 static const WCHAR RSA[] = { 'R','S','A',0 };
 static const WCHAR RSA_KEYX[] = { 'R','S','A','_','K','E','Y','X',0 };
 static const WCHAR RSA_SIGN[] = { 'R','S','A','_','S','I','G','N',0 };
@@ -853,6 +1089,9 @@ static const WCHAR shaDSA[] = { 's','h','a','D','S','A',0 };
 static const WCHAR sha1DSA[] = { 's','h','a','1','D','S','A',0 };
 static const WCHAR shaRSA[] = { 's','h','a','R','S','A',0 };
 static const WCHAR sha1RSA[] = { 's','h','a','1','R','S','A',0 };
+static const WCHAR sha256RSA[] = { 's','h','a','2','5','6','R','S','A',0 };
+static const WCHAR sha384RSA[] = { 's','h','a','3','8','4','R','S','A',0 };
+static const WCHAR sha512RSA[] = { 's','h','a','5','1','2','R','S','A',0 };
 static const WCHAR mosaicUpdatedSig[] =
  { 'm','o','s','a','i','c','U','p','d','a','t','e','d','S','i','g',0 };
 static const WCHAR CN[] = { 'C','N',0 };
@@ -956,6 +1195,9 @@ static const struct OIDInfoConstructor {
  { 3, szOID_PKIX_NO_SIGNATURE,         CALG_NO_SIGN,  NO_SIGN, NULL },
 
  { 4, szOID_RSA_SHA1RSA,               CALG_SHA1,     sha1RSA, &rsaSignBlob },
+ { 4, szOID_RSA_SHA256RSA,             CALG_SHA_256,  sha256RSA, &rsaSignBlob },
+ { 4, szOID_RSA_SHA384RSA,             CALG_SHA_384,  sha384RSA, &rsaSignBlob },
+ { 4, szOID_RSA_SHA512RSA,             CALG_SHA_512,  sha512RSA, &rsaSignBlob },
  { 4, szOID_RSA_MD5RSA,                CALG_MD5,      md5RSA, &rsaSignBlob },
  { 4, szOID_X957_SHA1DSA,              CALG_SHA1,     sha1DSA, &dssSignBlob },
  { 4, szOID_OIWSEC_sha1RSASign,        CALG_SHA1,     sha1RSA, &rsaSignBlob },
@@ -1157,16 +1399,15 @@ struct OIDInfo {
     struct list entry;
 };
 
-static void init_oid_info(HINSTANCE hinst)
+static void init_oid_info(void)
 {
     DWORD i;
 
-    InitializeCriticalSection(&oidInfoCS);
-    list_init(&oidInfo);
+    oid_init_localizednames();
     for (i = 0; i < sizeof(oidInfoConstructors) /
      sizeof(oidInfoConstructors[0]); i++)
     {
-        if (HIWORD(oidInfoConstructors[i].pwszName))
+        if (!IS_INTRESOURCE(oidInfoConstructors[i].pwszName))
         {
             struct OIDInfo *info;
 
@@ -1192,8 +1433,10 @@ static void init_oid_info(HINSTANCE hinst)
         }
         else
         {
-            int len = LoadStringW(hinst, (UINT_PTR)oidInfoConstructors[i].pwszName,
-             NULL, 0);
+            LPCWSTR stringresource;
+            int len = LoadStringW(hInstance,
+             (UINT_PTR)oidInfoConstructors[i].pwszName,
+             (LPWSTR)&stringresource, 0);
 
             if (len)
             {
@@ -1205,12 +1448,11 @@ static void init_oid_info(HINSTANCE hinst)
                     memset(info, 0, sizeof(*info));
                     info->info.cbSize = sizeof(CRYPT_OID_INFO);
                     info->info.pszOID = oidInfoConstructors[i].pszOID;
-                    info->info.pwszName =
-                     (LPWSTR)((LPBYTE)info + sizeof(struct OIDInfo));
+                    info->info.pwszName = (LPWSTR)(info + 1);
                     info->info.dwGroupId = oidInfoConstructors[i].dwGroupId;
                     info->info.u.Algid = oidInfoConstructors[i].Algid;
-                    LoadStringW(hinst, (UINT_PTR)oidInfoConstructors[i].pwszName,
-                     (LPWSTR)info->info.pwszName, len + 1);
+                    memcpy(info + 1, stringresource, len*sizeof(WCHAR));
+                    ((LPWSTR)(info + 1))[len] = 0;
                     if (oidInfoConstructors[i].blob)
                     {
                         info->info.ExtraInfo.cbData =
@@ -1234,16 +1476,18 @@ static void free_oid_info(void)
         list_remove(&info->entry);
         CryptMemFree(info);
     }
-    DeleteCriticalSection(&oidInfoCS);
 }
 
+/***********************************************************************
+ *             CryptEnumOIDInfo (CRYPT32.@)
+ */
 BOOL WINAPI CryptEnumOIDInfo(DWORD dwGroupId, DWORD dwFlags, void *pvArg,
  PFN_CRYPT_ENUM_OID_INFO pfnEnumOIDInfo)
 {
     BOOL ret = TRUE;
     struct OIDInfo *info;
 
-    TRACE("(%ld, %08lx, %p, %p)\n", dwGroupId, dwFlags, pvArg,
+    TRACE("(%d, %08x, %p, %p)\n", dwGroupId, dwFlags, pvArg,
      pfnEnumOIDInfo);
 
     EnterCriticalSection(&oidInfoCS);
@@ -1265,7 +1509,7 @@ PCCRYPT_OID_INFO WINAPI CryptFindOIDInfo(DWORD dwKeyType, void *pvKey,
 {
     PCCRYPT_OID_INFO ret = NULL;
 
-    TRACE("(%ld, %p, %ld)\n", dwKeyType, pvKey, dwGroupId);
+    TRACE("(%d, %p, %d)\n", dwKeyType, pvKey, dwGroupId);
 
     switch(dwKeyType)
     {
@@ -1273,7 +1517,7 @@ PCCRYPT_OID_INFO WINAPI CryptFindOIDInfo(DWORD dwKeyType, void *pvKey,
     {
         struct OIDInfo *info;
 
-        TRACE("CRYPT_OID_INFO_ALGID_KEY: %ld\n", *(DWORD *)pvKey);
+        TRACE("CRYPT_OID_INFO_ALGID_KEY: %d\n", *(DWORD *)pvKey);
         EnterCriticalSection(&oidInfoCS);
         LIST_FOR_EACH_ENTRY(info, &oidInfo, struct OIDInfo, entry)
         {
@@ -1291,11 +1535,11 @@ PCCRYPT_OID_INFO WINAPI CryptFindOIDInfo(DWORD dwKeyType, void *pvKey,
     {
         struct OIDInfo *info;
 
-        TRACE("CRYPT_OID_INFO_NAME_KEY: %s\n", debugstr_w((LPWSTR)pvKey));
+        TRACE("CRYPT_OID_INFO_NAME_KEY: %s\n", debugstr_w(pvKey));
         EnterCriticalSection(&oidInfoCS);
         LIST_FOR_EACH_ENTRY(info, &oidInfo, struct OIDInfo, entry)
         {
-            if (!lstrcmpW(info->info.pwszName, (LPWSTR)pvKey) &&
+            if (!lstrcmpW(info->info.pwszName, pvKey) &&
              (!dwGroupId || info->info.dwGroupId == dwGroupId))
             {
                 ret = &info->info;
@@ -1308,7 +1552,7 @@ PCCRYPT_OID_INFO WINAPI CryptFindOIDInfo(DWORD dwKeyType, void *pvKey,
     case CRYPT_OID_INFO_OID_KEY:
     {
         struct OIDInfo *info;
-        LPSTR oid = (LPSTR)pvKey;
+        LPSTR oid = pvKey;
 
         TRACE("CRYPT_OID_INFO_OID_KEY: %s\n", debugstr_a(oid));
         EnterCriticalSection(&oidInfoCS);
@@ -1328,7 +1572,7 @@ PCCRYPT_OID_INFO WINAPI CryptFindOIDInfo(DWORD dwKeyType, void *pvKey,
     {
         struct OIDInfo *info;
 
-        TRACE("CRYPT_OID_INFO_SIGN_KEY: %ld\n", *(DWORD *)pvKey);
+        TRACE("CRYPT_OID_INFO_SIGN_KEY: %d\n", *(DWORD *)pvKey);
         EnterCriticalSection(&oidInfoCS);
         LIST_FOR_EACH_ENTRY(info, &oidInfo, struct OIDInfo, entry)
         {