[v2 PATCH 4/4] shcore: Add some registry key delete helpers.
Nikolay Sivov
nsivov at codeweavers.com
Wed Nov 28 23:57:11 CST 2018
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
dlls/shcore/main.c | 110 +++++++++++++++++++++++++++++++++++++
dlls/shcore/shcore.spec | 12 ++--
dlls/shcore/tests/shcore.c | 25 +++++++++
3 files changed, 141 insertions(+), 6 deletions(-)
diff --git a/dlls/shcore/main.c b/dlls/shcore/main.c
index 906eb78c72..b332b3c72b 100644
--- a/dlls/shcore/main.c
+++ b/dlls/shcore/main.c
@@ -1775,3 +1775,113 @@ HKEY WINAPI SHRegDuplicateHKey(HKEY hKey)
TRACE("new key is %p\n", newKey);
return newKey;
}
+
+/*************************************************************************
+ * SHDeleteEmptyKeyW [SHCORE.@]
+ */
+DWORD WINAPI SHDeleteEmptyKeyW(HKEY hkey, const WCHAR *subkey)
+{
+ DWORD ret, count = 0;
+ HKEY hsubkey = 0;
+
+ TRACE("(%p, %s)\n", hkey, debugstr_w(subkey));
+
+ ret = RegOpenKeyExW(hkey, subkey, 0, KEY_READ, &hsubkey);
+ if (!ret)
+ {
+ ret = RegQueryInfoKeyW(hsubkey, NULL, NULL, NULL, &count,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+ RegCloseKey(hsubkey);
+ if (!ret)
+ {
+ if (count)
+ ret = ERROR_KEY_HAS_CHILDREN;
+ else
+ ret = RegDeleteKeyW(hkey, subkey);
+ }
+ }
+
+ return ret;
+}
+
+/*************************************************************************
+ * SHDeleteEmptyKeyA [SHCORE.@]
+ */
+DWORD WINAPI SHDeleteEmptyKeyA(HKEY hkey, const char *subkey)
+{
+ WCHAR *subkeyW = NULL;
+ DWORD ret;
+
+ TRACE("(%p, %s)\n", hkey, debugstr_a(subkey));
+
+ if (subkey && FAILED(SHStrDupA(subkey, &subkeyW)))
+ return ERROR_OUTOFMEMORY;
+
+ ret = SHDeleteEmptyKeyW(hkey, subkeyW);
+ CoTaskMemFree(subkeyW);
+ return ret;
+}
+
+/*************************************************************************
+ * SHDeleteKeyW [SHCORE.@]
+ */
+DWORD WINAPI SHDeleteKeyW(HKEY hkey, const WCHAR *subkey)
+{
+ TRACE("(%p, %s)\n", hkey, debugstr_w(subkey));
+
+ return RegDeleteTreeW(hkey, subkey);
+}
+
+/*************************************************************************
+ * SHDeleteKeyA [SHCORE.@]
+ */
+DWORD WINAPI SHDeleteKeyA(HKEY hkey, const char *subkey)
+{
+ TRACE("(%p, %s)\n", hkey, debugstr_a(subkey));
+
+ return RegDeleteTreeA(hkey, subkey);
+}
+
+/*************************************************************************
+ * SHDeleteValueW [SHCORE.@]
+ */
+DWORD WINAPI SHDeleteValueW(HKEY hkey, const WCHAR *subkey, const WCHAR *value)
+{
+ HKEY hsubkey;
+ DWORD ret;
+
+ TRACE("(%p, %s, %s)\n", hkey, debugstr_w(subkey), debugstr_w(value));
+
+ ret = RegOpenKeyExW(hkey, subkey, 0, KEY_SET_VALUE, &hsubkey);
+ if (!ret)
+ {
+ ret = RegDeleteValueW(hsubkey, value);
+ RegCloseKey(hsubkey);
+ }
+
+ return ret;
+}
+
+/*************************************************************************
+ * SHDeleteValueA [SHCORE.@]
+ */
+DWORD WINAPI SHDeleteValueA(HKEY hkey, const char *subkey, const char *value)
+{
+ WCHAR *subkeyW = NULL, *valueW = NULL;
+ DWORD ret;
+
+ TRACE("(%p, %s, %s)\n", hkey, debugstr_a(subkey), debugstr_a(value));
+
+ if (subkey && FAILED(SHStrDupA(subkey, &subkeyW)))
+ return ERROR_OUTOFMEMORY;
+ if (value && FAILED(SHStrDupA(value, &valueW)))
+ {
+ CoTaskMemFree(subkeyW);
+ return ERROR_OUTOFMEMORY;
+ }
+
+ ret = SHDeleteValueW(hkey, subkeyW, valueW);
+ CoTaskMemFree(subkeyW);
+ CoTaskMemFree(valueW);
+ return ret;
+}
diff --git a/dlls/shcore/shcore.spec b/dlls/shcore/shcore.spec
index c7a8744a2c..8b02cfbf21 100644
--- a/dlls/shcore/shcore.spec
+++ b/dlls/shcore/shcore.spec
@@ -40,12 +40,12 @@
@ stdcall SHCreateThread(ptr ptr long ptr)
@ stdcall SHCreateThreadRef(ptr ptr)
@ stub SHCreateThreadWithHandle
-@ stdcall SHDeleteEmptyKeyA(long ptr) shlwapi.SHDeleteEmptyKeyA
-@ stdcall SHDeleteEmptyKeyW(long ptr) shlwapi.SHDeleteEmptyKeyW
-@ stdcall SHDeleteKeyA(long str) shlwapi.SHDeleteKeyA
-@ stdcall SHDeleteKeyW(long wstr) shlwapi.SHDeleteKeyW
-@ stdcall SHDeleteValueA(long str str) shlwapi.SHDeleteValueA
-@ stdcall SHDeleteValueW(long wstr wstr) shlwapi.SHDeleteValueW
+@ stdcall SHDeleteEmptyKeyA(long str)
+@ stdcall SHDeleteEmptyKeyW(long wstr)
+@ stdcall SHDeleteKeyA(long str)
+@ stdcall SHDeleteKeyW(long wstr)
+@ stdcall SHDeleteValueA(long str str)
+@ stdcall SHDeleteValueW(long wstr wstr)
@ stdcall SHEnumKeyExA(long long str ptr) shlwapi.SHEnumKeyExA
@ stdcall SHEnumKeyExW(long long wstr ptr) shlwapi.SHEnumKeyExW
@ stdcall SHEnumValueA(long long str ptr ptr ptr ptr) shlwapi.SHEnumValueA
diff --git a/dlls/shcore/tests/shcore.c b/dlls/shcore/tests/shcore.c
index 7412297804..bf9ad8e505 100644
--- a/dlls/shcore/tests/shcore.c
+++ b/dlls/shcore/tests/shcore.c
@@ -32,6 +32,7 @@ static HRESULT (WINAPI *pSHGetInstanceExplorer)(IUnknown **);
static int (WINAPI *pSHUnicodeToAnsi)(const WCHAR *, char *, int);
static int (WINAPI *pSHAnsiToUnicode)(const char *, WCHAR *, int);
static HKEY (WINAPI *pSHRegDuplicateHKey)(HKEY);
+static DWORD (WINAPI *pSHDeleteKeyA)(HKEY, const char *);
static void init(HMODULE hshcore)
{
@@ -41,6 +42,7 @@ static void init(HMODULE hshcore)
X(SHUnicodeToAnsi);
X(SHAnsiToUnicode);
X(SHRegDuplicateHKey);
+ X(SHDeleteKeyA);
#undef X
}
@@ -234,6 +236,28 @@ static void test_SHRegDuplicateHKey(void)
RegDeleteKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Test");
}
+static void test_SHDeleteKey(void)
+{
+ HKEY hkey, hkey2;
+ DWORD ret;
+
+ ret = RegCreateKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Test", &hkey);
+ ok(!ret, "Failed to create test key, %d.\n", ret);
+
+ ret = RegCreateKeyA(hkey, "delete_key", &hkey2);
+ ok(!ret, "Failed to create test key, %d.\n", ret);
+ RegCloseKey(hkey2);
+
+ ret = RegDeleteKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Test");
+ ok(ret == ERROR_ACCESS_DENIED, "Unexpected return value %d.\n", ret);
+
+ ret = pSHDeleteKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Test");
+ ok(!ret, "Failed to delete a key, %d.\n", ret);
+
+ ret = RegCloseKey(hkey);
+ ok(!ret, "Failed to delete a key, %d.\n", ret);
+}
+
START_TEST(shcore)
{
HMODULE hshcore = LoadLibraryA("shcore.dll");
@@ -250,4 +274,5 @@ START_TEST(shcore)
test_SHUnicodeToAnsi();
test_SHAnsiToUnicode();
test_SHRegDuplicateHKey();
+ test_SHDeleteKey();
}
--
2.19.2
More information about the wine-devel
mailing list