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