Juan Lang : crypt32: Implement CryptGetDefaultOIDFunctionAddress.

Alexandre Julliard julliard at winehq.org
Thu Oct 18 07:59:37 CDT 2007


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

Author: Juan Lang <juan.lang at gmail.com>
Date:   Wed Oct 17 09:32:04 2007 -0700

crypt32: Implement CryptGetDefaultOIDFunctionAddress.

---

 dlls/crypt32/oid.c |  131 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 129 insertions(+), 2 deletions(-)

diff --git a/dlls/crypt32/oid.c b/dlls/crypt32/oid.c
index 46c9b05..90c88c3 100644
--- a/dlls/crypt32/oid.c
+++ b/dlls/crypt32/oid.c
@@ -278,6 +278,8 @@ BOOL WINAPI CryptInstallOIDFunctionAddress(HMODULE hModule,
 struct FuncAddr
 {
     HMODULE lib;
+    LPWSTR  dllList;
+    LPWSTR  currentDll;
 };
 
 static BOOL CRYPT_GetFuncFromReg(DWORD dwEncodingType, LPCSTR pszOID,
@@ -333,6 +335,7 @@ static BOOL CRYPT_GetFuncFromReg(DWORD dwEncodingType, LPCSTR pszOID,
                             if (addr)
                             {
                                 addr->lib = lib;
+                                addr->dllList = addr->currentDll = NULL;
                                 *phFuncAddr = addr;
                                 ret = TRUE;
                             }
@@ -430,19 +433,143 @@ BOOL WINAPI CryptFreeOIDFunctionAddress(HCRYPTOIDFUNCADDR hFuncAddr,
     {
         struct FuncAddr *addr = (struct FuncAddr *)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,
  HCRYPTOIDFUNCADDR *phFuncAddr)
 {
-    FIXME("(%p, %d, %s, %08x, %p, %p): stub\n", hFuncSet, dwEncodingType,
+    struct OIDFunctionSet *set = (struct OIDFunctionSet *)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 = (struct FuncAddr *)*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
+                    SetLastError(ERROR_FILE_NOT_FOUND);
+            }
+        }
+    }
+    return ret;
 }
 
 /***********************************************************************




More information about the wine-cvs mailing list