crypt32: Implement CryptRegisterDefaultOIDFunction and CryptUnregisterDefaultOIDFunction.
This commit is contained in:
parent
3b7fb551ce
commit
15f47b227e
|
@ -404,22 +404,6 @@ BOOL WINAPI CryptFreeOIDFunctionAddress(HCRYPTOIDFUNCADDR 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)
|
||||
|
@ -578,6 +562,234 @@ BOOL WINAPI CryptSetOIDFunctionValue(DWORD dwEncodingType, LPCSTR pszFuncName,
|
|||
return rc ? FALSE : TRUE;
|
||||
}
|
||||
|
||||
static LPCWSTR CRYPT_FindStringInMultiString(LPCWSTR multi, LPCWSTR toFind)
|
||||
{
|
||||
LPCWSTR ret = NULL, ptr;
|
||||
|
||||
for (ptr = multi; ptr && *ptr && !ret; ptr += lstrlenW(ptr) + 1)
|
||||
{
|
||||
if (!lstrcmpiW(ptr, toFind))
|
||||
ret = ptr;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static DWORD CRYPT_GetMultiStringCharacterLen(LPCWSTR multi)
|
||||
{
|
||||
DWORD ret;
|
||||
|
||||
if (multi)
|
||||
{
|
||||
LPCWSTR ptr;
|
||||
|
||||
/* Count terminating empty string */
|
||||
ret = 1;
|
||||
for (ptr = multi; *ptr; ptr += lstrlenW(ptr) + 1)
|
||||
ret += lstrlenW(ptr) + 1;
|
||||
}
|
||||
else
|
||||
ret = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static LPWSTR CRYPT_AddStringToMultiString(LPWSTR multi, LPCWSTR toAdd,
|
||||
DWORD index)
|
||||
{
|
||||
LPWSTR ret;
|
||||
|
||||
if (!multi)
|
||||
{
|
||||
/* FIXME: ignoring index, is that okay? */
|
||||
ret = CryptMemAlloc((lstrlenW(toAdd) + 2) * sizeof(WCHAR));
|
||||
if (ret)
|
||||
{
|
||||
/* copy string, including NULL terminator */
|
||||
memcpy(ret, toAdd, (lstrlenW(toAdd) + 1) * sizeof(WCHAR));
|
||||
/* add terminating empty string */
|
||||
*(ret + lstrlenW(toAdd) + 1) = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD len = CRYPT_GetMultiStringCharacterLen(multi);
|
||||
|
||||
ret = CryptMemRealloc(multi, (len + lstrlenW(toAdd) + 1) *
|
||||
sizeof(WCHAR));
|
||||
if (ret)
|
||||
{
|
||||
LPWSTR spotToAdd;
|
||||
|
||||
if (index == CRYPT_REGISTER_LAST_INDEX)
|
||||
spotToAdd = ret + len - 1;
|
||||
else
|
||||
{
|
||||
DWORD i;
|
||||
|
||||
/* FIXME: if index is too large for the string, toAdd is
|
||||
* added to the end. Is that okay?
|
||||
*/
|
||||
for (i = 0, spotToAdd = ret; i < index && *spotToAdd;
|
||||
spotToAdd += lstrlenW(spotToAdd) + 1)
|
||||
;
|
||||
}
|
||||
if (spotToAdd)
|
||||
{
|
||||
/* Copy existing string "right" */
|
||||
memmove(spotToAdd + lstrlenW(toAdd) + 1, spotToAdd,
|
||||
(len - (spotToAdd - ret)) * sizeof(WCHAR));
|
||||
/* Copy new string */
|
||||
memcpy(spotToAdd, toAdd, (lstrlenW(toAdd) + 1) * sizeof(WCHAR));
|
||||
}
|
||||
else
|
||||
{
|
||||
CryptMemFree(ret);
|
||||
ret = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_RemoveStringFromMultiString(LPWSTR multi, LPCWSTR toRemove)
|
||||
{
|
||||
LPWSTR spotToRemove = (LPWSTR)CRYPT_FindStringInMultiString(multi,
|
||||
toRemove);
|
||||
BOOL ret;
|
||||
|
||||
if (spotToRemove)
|
||||
{
|
||||
DWORD len = CRYPT_GetMultiStringCharacterLen(multi);
|
||||
|
||||
/* Copy remainder of string "left" */
|
||||
memmove(spotToRemove, spotToRemove + lstrlenW(toRemove) + 1,
|
||||
(len - (spotToRemove - multi)) * sizeof(WCHAR));
|
||||
ret = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLastError(ERROR_FILE_NOT_FOUND);
|
||||
ret = FALSE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL CRYPT_GetDefaultOIDKey(DWORD dwEncodingType, LPCSTR pszFuncName,
|
||||
PHKEY key)
|
||||
{
|
||||
LPSTR keyName;
|
||||
LONG r;
|
||||
|
||||
keyName = CRYPT_GetKeyName(dwEncodingType, pszFuncName, "DEFAULT");
|
||||
TRACE("Key name is %s\n", debugstr_a(keyName));
|
||||
|
||||
if (!keyName)
|
||||
return FALSE;
|
||||
|
||||
r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keyName, 0, NULL, 0, KEY_ALL_ACCESS,
|
||||
NULL, key, NULL);
|
||||
CryptMemFree(keyName);
|
||||
if (r != ERROR_SUCCESS)
|
||||
{
|
||||
SetLastError(r);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static LPWSTR CRYPT_GetDefaultOIDDlls(HKEY key)
|
||||
{
|
||||
LONG r;
|
||||
DWORD type, size;
|
||||
LPWSTR dlls;
|
||||
|
||||
r = RegQueryValueExW(key, DllW, NULL, &type, NULL, &size);
|
||||
if (r == ERROR_SUCCESS && type == REG_MULTI_SZ)
|
||||
{
|
||||
dlls = CryptMemAlloc(size);
|
||||
r = RegQueryValueExW(key, DllW, NULL, &type, (LPBYTE)dlls, &size);
|
||||
if (r != ERROR_SUCCESS)
|
||||
{
|
||||
CryptMemFree(dlls);
|
||||
dlls = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
dlls = NULL;
|
||||
return dlls;
|
||||
}
|
||||
|
||||
static inline BOOL CRYPT_SetDefaultOIDDlls(HKEY key, LPCWSTR dlls)
|
||||
{
|
||||
DWORD len = CRYPT_GetMultiStringCharacterLen(dlls);
|
||||
LONG r;
|
||||
|
||||
if ((r = RegSetValueExW(key, DllW, 0, REG_MULTI_SZ, (const BYTE *)dlls,
|
||||
len * sizeof (WCHAR))))
|
||||
SetLastError(r);
|
||||
return r == ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
if (!pwszDll)
|
||||
{
|
||||
SetLastError(E_INVALIDARG);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!CRYPT_GetDefaultOIDKey(dwEncodingType, pszFuncName, &key))
|
||||
return FALSE;
|
||||
|
||||
dlls = CRYPT_GetDefaultOIDDlls(key);
|
||||
if ((existing = CRYPT_FindStringInMultiString(dlls, pwszDll)))
|
||||
SetLastError(ERROR_FILE_EXISTS);
|
||||
else
|
||||
{
|
||||
dlls = CRYPT_AddStringToMultiString(dlls, pwszDll, dwIndex);
|
||||
if (dlls)
|
||||
ret = CRYPT_SetDefaultOIDDlls(key, dlls);
|
||||
}
|
||||
CryptMemFree(dlls);
|
||||
RegCloseKey(key);
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL WINAPI CryptUnregisterDefaultOIDFunction(DWORD dwEncodingType,
|
||||
LPCSTR pszFuncName, LPCWSTR pwszDll)
|
||||
{
|
||||
HKEY key;
|
||||
LPWSTR dlls;
|
||||
BOOL ret;
|
||||
|
||||
TRACE("(%lx, %s, %s)\n", dwEncodingType, debugstr_a(pszFuncName),
|
||||
debugstr_w(pwszDll));
|
||||
|
||||
if (!pwszDll)
|
||||
{
|
||||
SetLastError(E_INVALIDARG);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!CRYPT_GetDefaultOIDKey(dwEncodingType, pszFuncName, &key))
|
||||
return FALSE;
|
||||
|
||||
dlls = CRYPT_GetDefaultOIDDlls(key);
|
||||
if ((ret = CRYPT_RemoveStringFromMultiString(dlls, pwszDll)))
|
||||
ret = CRYPT_SetDefaultOIDDlls(key, dlls);
|
||||
CryptMemFree(dlls);
|
||||
RegCloseKey(key);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static CRITICAL_SECTION oidInfoCS;
|
||||
static struct list oidInfo;
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <winbase.h>
|
||||
#include <winerror.h>
|
||||
#include <wincrypt.h>
|
||||
#include <winreg.h>
|
||||
|
||||
#include "wine/test.h"
|
||||
|
||||
|
@ -314,6 +315,92 @@ static void test_registerOIDFunction(void)
|
|||
ok(ret, "CryptUnregisterOIDFunction failed: %ld\n", GetLastError());
|
||||
}
|
||||
|
||||
static const WCHAR bogusDll[] = { 'b','o','g','u','s','.','d','l','l',0 };
|
||||
static const WCHAR bogus2Dll[] = { 'b','o','g','u','s','2','.','d','l','l',0 };
|
||||
|
||||
static void test_registerDefaultOIDFunction(void)
|
||||
{
|
||||
static const char fmt[] =
|
||||
"Software\\Microsoft\\Cryptography\\OID\\EncodingType %d\\%s\\DEFAULT";
|
||||
static const char func[] = "CertDllOpenStoreProv";
|
||||
char buf[MAX_PATH];
|
||||
BOOL ret;
|
||||
long rc;
|
||||
HKEY key;
|
||||
|
||||
ret = CryptRegisterDefaultOIDFunction(0, NULL, 0, NULL);
|
||||
ok(!ret && GetLastError() == E_INVALIDARG,
|
||||
"Expected E_INVALIDARG, got %08lx\n", GetLastError());
|
||||
/* This succeeds on WinXP, although the bogus entry is unusable.
|
||||
ret = CryptRegisterDefaultOIDFunction(0, NULL, 0, bogusDll);
|
||||
*/
|
||||
/* Register one at index 0 */
|
||||
ret = CryptRegisterDefaultOIDFunction(0, "CertDllOpenStoreProv", 0,
|
||||
bogusDll);
|
||||
ok(ret, "CryptRegisterDefaultOIDFunction failed: %08lx\n", GetLastError());
|
||||
/* Reregistering should fail */
|
||||
ret = CryptRegisterDefaultOIDFunction(0, "CertDllOpenStoreProv", 0,
|
||||
bogusDll);
|
||||
ok(!ret && GetLastError() == ERROR_FILE_EXISTS,
|
||||
"Expected ERROR_FILE_EXISTS, got %08lx\n", GetLastError());
|
||||
/* Registering the same one at index 1 should also fail */
|
||||
ret = CryptRegisterDefaultOIDFunction(0, "CertDllOpenStoreProv", 1,
|
||||
bogusDll);
|
||||
ok(!ret && GetLastError() == ERROR_FILE_EXISTS,
|
||||
"Expected ERROR_FILE_EXISTS, got %08lx\n", GetLastError());
|
||||
/* Registering a different one at index 1 succeeds */
|
||||
ret = CryptRegisterDefaultOIDFunction(0, "CertDllOpenStoreProv", 1,
|
||||
bogus2Dll);
|
||||
ok(ret, "CryptRegisterDefaultOIDFunction failed: %08lx\n", GetLastError());
|
||||
sprintf(buf, fmt, 0, func);
|
||||
rc = RegOpenKeyA(HKEY_LOCAL_MACHINE, buf, &key);
|
||||
ok(rc == 0, "Expected key to exist, RegOpenKeyW failed: %ld\n", rc);
|
||||
if (rc == 0)
|
||||
{
|
||||
static const WCHAR dllW[] = { 'D','l','l',0 };
|
||||
WCHAR dllBuf[MAX_PATH];
|
||||
DWORD type, size;
|
||||
LPWSTR ptr;
|
||||
|
||||
size = sizeof(dllBuf) / sizeof(dllBuf[0]);
|
||||
rc = RegQueryValueExW(key, dllW, NULL, &type, (LPBYTE)dllBuf, &size);
|
||||
ok(rc == 0,
|
||||
"Expected Dll value to exist, RegQueryValueExW failed: %ld\n", rc);
|
||||
ok(type == REG_MULTI_SZ, "Expected type REG_MULTI_SZ, got %ld\n", type);
|
||||
/* bogusDll was registered first, so that should be first */
|
||||
ptr = dllBuf;
|
||||
ok(!lstrcmpiW(ptr, bogusDll), "Unexpected dll\n");
|
||||
ptr += lstrlenW(ptr) + 1;
|
||||
ok(!lstrcmpiW(ptr, bogus2Dll), "Unexpected dll\n");
|
||||
RegCloseKey(key);
|
||||
}
|
||||
/* Unregister both of them */
|
||||
ret = CryptUnregisterDefaultOIDFunction(0, "CertDllOpenStoreProv",
|
||||
bogusDll);
|
||||
ok(ret, "CryptUnregisterDefaultOIDFunction failed: %08lx\n",
|
||||
GetLastError());
|
||||
ret = CryptUnregisterDefaultOIDFunction(0, "CertDllOpenStoreProv",
|
||||
bogus2Dll);
|
||||
ok(ret, "CryptUnregisterDefaultOIDFunction failed: %08lx\n",
|
||||
GetLastError());
|
||||
/* Now that they're both unregistered, unregistering should fail */
|
||||
ret = CryptUnregisterDefaultOIDFunction(0, "CertDllOpenStoreProv",
|
||||
bogusDll);
|
||||
ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
|
||||
"Expected ERROR_FILE_NOT_FOUND, got %ld\n", GetLastError());
|
||||
|
||||
/* Repeat a few tests on the normal encoding type */
|
||||
ret = CryptRegisterDefaultOIDFunction(X509_ASN_ENCODING,
|
||||
"CertDllOpenStoreProv", 0, bogusDll);
|
||||
ret = CryptUnregisterDefaultOIDFunction(X509_ASN_ENCODING,
|
||||
"CertDllOpenStoreProv", bogusDll);
|
||||
ok(ret, "CryptUnregisterDefaultOIDFunction failed\n");
|
||||
ret = CryptUnregisterDefaultOIDFunction(X509_ASN_ENCODING,
|
||||
"CertDllOpenStoreProv", bogusDll);
|
||||
ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
|
||||
"Expected ERROR_FILE_NOT_FOUND, got %08lx\n", GetLastError());
|
||||
}
|
||||
|
||||
static BOOL WINAPI countOidInfo(PCCRYPT_OID_INFO pInfo, void *pvArg)
|
||||
{
|
||||
(*(DWORD *)pvArg)++;
|
||||
|
@ -397,4 +484,5 @@ START_TEST(oid)
|
|||
test_oidFunctionSet();
|
||||
test_installOIDFunctionAddress();
|
||||
test_registerOIDFunction();
|
||||
test_registerDefaultOIDFunction();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue