-- v3: advapi32/tests: Add tests for RegLoadAppKey.
From: Santino Mazza smazza@codeweavers.com
Signed-off-by: Santino Mazza smazza@codeweavers.com --- dlls/advapi32/tests/registry.c | 119 ++++++++++++++++++++++++++++++++- dlls/kernelbase/registry.c | 6 +- 2 files changed, 118 insertions(+), 7 deletions(-)
diff --git a/dlls/advapi32/tests/registry.c b/dlls/advapi32/tests/registry.c index df56b0968ee..6082765f869 100644 --- a/dlls/advapi32/tests/registry.c +++ b/dlls/advapi32/tests/registry.c @@ -41,6 +41,7 @@ static DWORD GLE;
static const char * sTestpath1 = "%LONGSYSTEMVAR%\subdir1"; static const char * sTestpath2 = "%FOO%\subdir1"; +static char temppath[MAX_PATH]; static const DWORD ptr_size = 8 * sizeof(void*);
static DWORD (WINAPI *pRegGetValueA)(HKEY,LPCSTR,LPCSTR,DWORD,LPDWORD,PVOID,LPDWORD); @@ -1600,7 +1601,58 @@ static void test_reg_unload_key(void) DeleteFileA("saved_key.LOG"); }
-/* tests that show that RegConnectRegistry and +static void test_reg_load_app_key(void) +{ + DWORD ret; + DWORD size1; + DWORD size2; + char hivefilepath[MAX_PATH]; + HANDLE hivefile; + HKEY childkey; + HKEY key1 = NULL; + + GetTempFileNameA(temppath, "saved_app_key", 0, hivefilepath); + DeleteFileA(hivefilepath); + + if (!set_privileges(SE_BACKUP_NAME, TRUE) || + !set_privileges(SE_RESTORE_NAME, FALSE)) + { + win_skip("Failed to set SE_BACKUP_NAME privileges, skipping tests\n"); + return; + } + + ret = RegSaveKeyA(hkey_main, hivefilepath, NULL); + if (ret != ERROR_SUCCESS) + { + win_skip("Failed to save test key 0x%lx\n", ret); + return; + } + + set_privileges(SE_BACKUP_NAME, FALSE); + set_privileges(SE_RESTORE_NAME, FALSE); + + /* Test simple key load */ + /* Check if the changes are saved to the file */ + hivefile = CreateFileA(hivefilepath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); + size1 = GetFileSize(hivefile, NULL); + CloseHandle(hivefile); + + ret = RegLoadAppKeyA(hivefilepath, &key1, KEY_READ | KEY_WRITE, 0, 0); + todo_wine ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %ld\n", ret); + todo_wine ok(key1 != NULL, "got a null key\n"); + + ret = RegCreateKeyA(key1, "testkey", &childkey); + RegCloseKey(key1); + + hivefile = CreateFileA(hivefilepath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); + size2 = GetFileSize(hivefile, NULL); + todo_wine ok(size2 > size1, "Expected file to increase size. %ld <= %ld\n", size2, size1); + CloseHandle(hivefile); +} + +/* tests that show that RegConnectRegistry and OpenSCManager accept computer names without the \ prefix (what MSDN says). */ static void test_regconnectregistry( void) @@ -4459,12 +4511,57 @@ static void test_RegRenameKey(void) RegCloseKey(key); }
+static void init_temp_folder(void) +{ + GetTempPathA(sizeof(temppath), temppath); + sprintf(temppath, "%sadvapi32_tests\", temppath); + CreateDirectoryA(temppath, NULL); +} + +static void delete_temp_folder(void) +{ + WIN32_FIND_DATAA findfile; + HANDLE search; + char temppath_wildcard[MAX_PATH], tempfilepath[MAX_PATH]; + sprintf(temppath_wildcard, "%s*.tmp*", temppath); + + if((search = FindFirstFileA(temppath_wildcard, &findfile)) != INVALID_HANDLE_VALUE) + { + do + { + sprintf(tempfilepath, "%s%s", temppath, findfile.cFileName); + DeleteFileA(tempfilepath); + } while (FindNextFileA(search, &findfile)); + } + + temppath_wildcard[strlen(temppath_wildcard) - 1] = 0; + RemoveDirectoryA(temppath_wildcard); +} + START_TEST(registry) { + static const char *test_names[] = + { + "RegLoadAppKey" + }; + char pathname[MAX_PATH]; + char **argv; + int argc; /* Load pointers for functions that are not available in all Windows versions */ InitFunctionPtrs(); - + init_temp_folder(); + argc = winetest_get_mainargs(&argv); setup_main_key(); + + if (argc >= 3) + { + if (!strcmp(argv[2], "RegLoadAppKey")) + test_reg_load_app_key(); + + delete_key( hkey_main ); + return; + } + check_user_privs(); test_set_value(); create_test_entries(); @@ -4500,8 +4597,24 @@ START_TEST(registry) test_perflib_key(); test_RegRenameKey();
+ for (int i = 0; i < ARRAY_SIZE(test_names); ++i) + { + STARTUPINFOA startup; + PROCESS_INFORMATION info; + + memset(&startup, 0, sizeof(startup)); + startup.cb = sizeof(startup); + + sprintf(pathname, "%s registry %s", argv[0], test_names[i]); + ok(CreateProcessA(NULL, pathname, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info), + "Process creation failed\n"); + wait_child_process(info.hProcess); + CloseHandle(info.hProcess); + CloseHandle(info.hThread); + } + /* cleanup */ delete_key( hkey_main ); - + delete_temp_folder(); test_regconnectregistry(); } diff --git a/dlls/kernelbase/registry.c b/dlls/kernelbase/registry.c index 91462d80e06..b05d5b2cf9d 100644 --- a/dlls/kernelbase/registry.c +++ b/dlls/kernelbase/registry.c @@ -3092,8 +3092,7 @@ LSTATUS WINAPI RegLoadAppKeyA(const char *file, HKEY *result, REGSAM sam, DWORD if (!file || reserved) return ERROR_INVALID_PARAMETER;
- *result = (HKEY)0xdeadbeef; - return ERROR_SUCCESS; + return STATUS_NOT_IMPLEMENTED; }
/****************************************************************************** @@ -3107,8 +3106,7 @@ LSTATUS WINAPI RegLoadAppKeyW(const WCHAR *file, HKEY *result, REGSAM sam, DWORD if (!file || reserved) return ERROR_INVALID_PARAMETER;
- *result = (HKEY)0xdeadbeef; - return ERROR_SUCCESS; + return STATUS_NOT_IMPLEMENTED; }
This is not a definitive update, I just pushed the the changes I made so far so you can see where I got stuck.
On Sun Sep 4 22:46:50 2022 +0000, Santino Mazza wrote:
changed this line in [version 3 of the diff](/wine/wine/-/merge_requests/766/diffs?diff_id=9756&start_sha=e6cad6f4afc94d5c30d985ad2dcf9b269e1a2dd1#e58df5d55b7ec627678745bc876541397c298566_1615_1614)
Looks like one needs to wait a little before deleting the files. I'd suggest adding a loop around the `DeleteFile()` in `delete_temp_folder()` with a `Sleep(100)` if the `DeleteFile()` call fails and a limit of say ten attempts.
Huw Davies (@huw) commented about dlls/advapi32/tests/registry.c:
- char pathname[MAX_PATH];
- char **argv;
- int argc; /* Load pointers for functions that are not available in all Windows versions */ InitFunctionPtrs();
- init_temp_folder();
- argc = winetest_get_mainargs(&argv); setup_main_key();
- if (argc >= 3)
- {
if (!strcmp(argv[2], "RegLoadAppKey"))
test_reg_load_app_key();
delete_key( hkey_main );
This is going to delete the main key while the main process is still running.
Huw Davies (@huw) commented about dlls/advapi32/tests/registry.c:
DeleteFileA("saved_key.LOG");
}
-/* tests that show that RegConnectRegistry and +static void test_reg_load_app_key(void) +{
- DWORD ret;
- DWORD size1;
- DWORD size2;
- char hivefilepath[MAX_PATH];
- HANDLE hivefile;
- HKEY childkey;
- HKEY key1 = NULL;
- GetTempFileNameA(temppath, "saved_app_key", 0, hivefilepath);
Note, `GetTempFileName()` only uses the first three characters of the string.