[PATCH v2 1/1] shell32: Sanitize Program Manager icon and group names
Alex Henrie
wine at gitlab.winehq.org
Tue May 3 23:54:50 CDT 2022
From: Alex Henrie <alexhenrie24 at gmail.com>
All of the new tests that are marked todo_wine fail because Wine's
PathCombineW does not handle ".", "...", "....", or "foobar." correctly.
They will pass once PathCombineW is fixed.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52506
Signed-off-by: Alex Henrie <alexhenrie24 at gmail.com>
---
dlls/shell32/dde.c | 76 +++++---
dlls/shell32/tests/progman_dde.c | 318 ++++++++++++++++++++++++++++++-
2 files changed, 369 insertions(+), 25 deletions(-)
diff --git a/dlls/shell32/dde.c b/dlls/shell32/dde.c
index 5ab63136092..dba6b3dad24 100644
--- a/dlls/shell32/dde.c
+++ b/dlls/shell32/dde.c
@@ -78,19 +78,51 @@ static inline BOOL Dde_OnWildConnect(HSZ hszTopic, HSZ hszService)
return FALSE;
}
+static WCHAR *sanitize_and_combine(const WCHAR *directory, const WCHAR *name, BOOL icon)
+{
+ WCHAR *sanitized_name = strdupW(name);
+ WCHAR *path;
+ int len, i;
+
+ len = lstrlenW(directory) + 1 + lstrlenW(name);
+ if (icon) len += 4;
+ path = heap_alloc((len + 1) * sizeof(WCHAR));
+
+ for (i = 0; i < lstrlenW(name); i++)
+ {
+ if (name[i] < ' ' || StrChrW(L"*/:<>?\\|", name[i]))
+ sanitized_name[i] = '_';
+ }
+
+ PathCombineW(path, directory, sanitized_name);
+
+ if (icon)
+ lstrcatW(path, L".lnk");
+
+ heap_free(sanitized_name);
+ return path;
+}
+
/* Returned string must be freed by caller */
-static WCHAR *get_programs_path(const WCHAR *name)
+static WCHAR *get_programs_path(const WCHAR *name, BOOL sanitize)
{
WCHAR *programs, *path;
int len;
SHGetKnownFolderPath(&FOLDERID_Programs, 0, NULL, &programs);
- len = lstrlenW(programs) + 1 + lstrlenW(name);
- path = heap_alloc((len + 1) * sizeof(*path));
- lstrcpyW(path, programs);
- lstrcatW(path, L"/");
- lstrcatW(path, name);
+ if (sanitize)
+ {
+ path = sanitize_and_combine(programs, name, FALSE);
+ }
+ else
+ {
+ len = lstrlenW(programs) + 1 + lstrlenW(name);
+ path = heap_alloc((len + 1) * sizeof(WCHAR));
+ lstrcpyW(path, programs);
+ lstrcatW(path, L"\\");
+ lstrcatW(path, name);
+ }
CoTaskMemFree(programs);
@@ -111,7 +143,7 @@ static inline HDDEDATA Dde_OnRequest(UINT uFmt, HCONV hconv, HSZ hszTopic,
HDDEDATA ret;
groups_data[0] = 0;
- programs = get_programs_path(L"*");
+ programs = get_programs_path(L"*", FALSE);
hfind = FindFirstFileW(programs, &finddata);
if (hfind)
{
@@ -162,10 +194,10 @@ static DWORD PROGMAN_OnExecute(WCHAR *command, int argc, WCHAR **argv)
if (argc < 1) return DDE_FNOTPROCESSED;
- path = get_programs_path(argv[0]);
+ path = get_programs_path(argv[0], TRUE);
- CreateDirectoryW(path, NULL);
- ShellExecuteW(NULL, NULL, path, NULL, NULL, SW_SHOWNORMAL);
+ if (CreateDirectoryW(path, NULL))
+ ShellExecuteW(NULL, NULL, path, NULL, NULL, SW_SHOWNORMAL);
heap_free(last_group);
last_group = path;
@@ -178,7 +210,7 @@ static DWORD PROGMAN_OnExecute(WCHAR *command, int argc, WCHAR **argv)
if (argc < 1) return DDE_FNOTPROCESSED;
- path = get_programs_path(argv[0]);
+ path = get_programs_path(argv[0], TRUE);
path2 = heap_alloc((lstrlenW(path) + 2) * sizeof(*path));
lstrcpyW(path2, path);
@@ -203,7 +235,7 @@ static DWORD PROGMAN_OnExecute(WCHAR *command, int argc, WCHAR **argv)
* ignore its actual value. */
if (argc < 2) return DDE_FNOTPROCESSED;
- path = get_programs_path(argv[0]);
+ path = get_programs_path(argv[0], TRUE);
ShellExecuteW(NULL, NULL, path, NULL, NULL, SW_SHOWNORMAL);
@@ -250,26 +282,21 @@ static DWORD PROGMAN_OnExecute(WCHAR *command, int argc, WCHAR **argv)
IShellLinkW_Release(link);
return DDE_FNOTPROCESSED;
}
- if (argc >= 2)
+ if (argc >= 2 && argv[1][0])
{
- len = lstrlenW(last_group) + 1 + lstrlenW(argv[1]) + 5;
- name = heap_alloc(len * sizeof(*name));
- swprintf( name, len, L"%s/%s.lnk", last_group, argv[1] );
+ name = sanitize_and_combine(last_group, argv[1], TRUE);
}
else
{
- const WCHAR *filename = PathFindFileNameW(argv[0]);
- len = PathFindExtensionW(filename) - filename;
- name = heap_alloc((lstrlenW(last_group) + 1 + len + 5) * sizeof(*name));
- swprintf( name, lstrlenW(last_group) + 1 + len + 5, L"%s/%.*s.lnk", last_group, len, filename );
+ WCHAR *filename = PathFindFileNameW(argv[0]);
+ *PathFindExtensionW(filename) = '\0';
+ name = sanitize_and_combine(last_group, filename, TRUE);
}
- hres = IPersistFile_Save(file, name, TRUE);
+ IPersistFile_Save(file, name, TRUE);
heap_free(name);
IPersistFile_Release(file);
IShellLinkW_Release(link);
-
- if (FAILED(hres)) return DDE_FNOTPROCESSED;
}
else if (!wcsicmp(command, L"DeleteItem") || !wcsicmp(command, L"ReplaceItem"))
{
@@ -280,7 +307,8 @@ static DWORD PROGMAN_OnExecute(WCHAR *command, int argc, WCHAR **argv)
len = lstrlenW(last_group) + 1 + lstrlenW(argv[0]) + 5;
name = heap_alloc(len * sizeof(*name));
- swprintf( name, len, L"%s/%s.lnk", last_group, argv[0]);
+ PathCombineW(name, last_group, argv[0]);
+ lstrcatW(name, L".lnk");
ret = DeleteFileW(name);
diff --git a/dlls/shell32/tests/progman_dde.c b/dlls/shell32/tests/progman_dde.c
index 5d532f9222f..66b9ed0c87a 100644
--- a/dlls/shell32/tests/progman_dde.c
+++ b/dlls/shell32/tests/progman_dde.c
@@ -23,7 +23,7 @@
* functionality
* - Todo: Handle CommonGroupFlag
* Better AddItem Tests (Lots of parameters to test)
- * Tests for Invalid Characters in Names / Invalid Parameters
+ * Tests for invalid parameters
*/
#include <stdio.h>
@@ -425,6 +425,321 @@ static void test_request_groups(DWORD instance, HCONV hconv)
FindClose(hfind);
}
+static BOOL is_unsanitary(char c)
+{
+ return (c > 0 && c < ' ') || strchr("*/:<>?\\|", c) != NULL;
+}
+
+static void sanitize_name(const char *original_name, char *sanitized_name, BOOL group)
+{
+ BOOL at_end = TRUE;
+ int i;
+
+ i = strlen(original_name);
+ sanitized_name[i] = 0;
+
+ while (--i >= 0)
+ {
+ if (is_unsanitary(original_name[i]))
+ {
+ /* replaced in all positions */
+ sanitized_name[i] = '_';
+ at_end = FALSE;
+ }
+ else if (original_name[i] == '.' || (original_name[i] == ' ' && group))
+ {
+ /* left alone if in the middle of the string, dropped if at the end of the string */
+ sanitized_name[i] = at_end ? '\0' : original_name[i];
+ }
+ else
+ {
+ /* left alone in all positions */
+ sanitized_name[i] = original_name[i];
+ at_end = FALSE;
+ }
+ }
+}
+
+static void test_name_sanitization(DWORD instance, HCONV hConv)
+{
+ static const char test_chars[] = "\x01\x1F !#$%&'*+,-./:;<=>?@[\\]^`{|}~\x7F\x80\xFF";
+ char original_name[16], sanitized_icon_name[16], sanitized_group_name[16];
+ char buf[64];
+ UINT error;
+ int i;
+ char c;
+
+ if (0) /* the directory isn't deleted on windows < 7 */
+ {
+ error = dde_execute(instance, hConv, "[CreateGroup(\" \")]");
+ ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %#x\n", error);
+ ok(check_exists(" "), "directory not created\n");
+ ok(!check_window_exists(" "), "window should not exist\n");
+
+ error = dde_execute(instance, hConv, "[DeleteGroup(\" \")]");
+ ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %#x\n", error);
+ ok(!check_exists(" "), "directory should not exist\n");
+ }
+
+ if (GetUserDefaultUILanguage() == MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT))
+ {
+ error = dde_execute(instance, hConv, "[CreateGroup(\"\")]");
+ ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %#x\n", error);
+ todo_wine ok(check_window_exists("Programs") || broken(TRUE) /* 2003 */, "window not created\n");
+
+ error = dde_execute(instance, hConv, "[CreateGroup(\".\")]");
+ ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %#x\n", error);
+ ok(!check_window_exists("Programs"), "window should not exist\n");
+
+ error = dde_execute(instance, hConv, "[CreateGroup(\"..\")]");
+ ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %#x\n", error);
+ todo_wine ok(check_window_exists("Start Menu") || broken(TRUE) /* 2003 */, "window not created\n");
+
+ error = dde_execute(instance, hConv, "[CreateGroup(\"...\")]");
+ ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %#x\n", error);
+ todo_wine ok(check_window_exists("Programs") || broken(TRUE) /* XP */, "window not created\n");
+
+ error = dde_execute(instance, hConv, "[CreateGroup(\"....\")]");
+ ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %#x\n", error);
+ ok(!check_window_exists("Programs"), "window should not exist\n");
+ }
+ else
+ {
+ skip("Directory names are probably not in English\n");
+ }
+
+ if (0) /* these calls will actually delete the start menu */
+ {
+ error = dde_execute(instance, hConv, "[DeleteGroup(\"\")]");
+ ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %#x\n", error);
+ ok(!check_exists("../Programs"), "directory should not exist\n");
+
+ error = dde_execute(instance, hConv, "[DeleteGroup(\"..\")]");
+ ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %#x\n", error);
+ ok(!check_exists("../../Start Menu"), "directory should not exist\n");
+ }
+
+ error = dde_execute(instance, hConv, "[CreateGroup(Group3)]");
+ ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %#x\n", error);
+ ok(check_exists("Group3"), "directory not created\n");
+ ok(check_window_exists("Group3"), "window not created\n");
+
+ error = dde_execute(instance, hConv, "[AddItem(notepad,\"\")]");
+ ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %#x\n", error);
+ ok(check_exists("Group3/notepad.lnk"), "link not created\n");
+
+ error = dde_execute(instance, hConv, "[DeleteItem(notepad)]");
+ ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %#x\n", error);
+ ok(!check_exists("Group3/notepad.lnk"), "link should not exist\n");
+
+ error = dde_execute(instance, hConv, "[AddItem(notepad,\" \")]");
+ ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %#x\n", error);
+ ok(check_exists("Group3/ .lnk"), "link not created\n");
+
+ error = dde_execute(instance, hConv, "[DeleteItem(\" \")]");
+ ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %#x\n", error);
+ ok(!check_exists("Group3/ .lnk"), "link should not exist\n");
+
+ error = dde_execute(instance, hConv, "[AddItem(notepad,\".\")]");
+ ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %#x\n", error);
+ todo_wine ok(check_exists("Group3.lnk"), "link not created\n");
+
+ error = dde_execute(instance, hConv, "[DeleteItem(\".\")]");
+ ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %#x\n", error);
+ ok(!check_exists("Group3.lnk"), "link should not exist\n");
+
+ error = dde_execute(instance, hConv, "[AddItem(notepad,\"..\")]");
+ ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %#x\n", error);
+ ok(check_exists("../Programs.lnk"), "link not created\n");
+
+ error = dde_execute(instance, hConv, "[DeleteItem(\"..\")]");
+ ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %#x\n", error);
+ ok(!check_exists("../Programs.lnk"), "link should not exist\n");
+
+ error = dde_execute(instance, hConv, "[AddItem(notepad,\"...\")]");
+ ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %#x\n", error);
+ todo_wine ok(check_exists("Group3/.lnk") || broken(TRUE) /* XP */, "link not created\n");
+
+ error = dde_execute(instance, hConv, "[DeleteItem(\"...\")]");
+ ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %#x\n", error);
+ ok(!check_exists("Group3/.lnk"), "link should not exist\n");
+
+ error = dde_execute(instance, hConv, "[AddItem(notepad,\"....\")]");
+ ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %#x\n", error);
+ todo_wine ok(check_exists("Group3/.lnk") || broken(TRUE) /* XP */, "link not created\n");
+
+ error = dde_execute(instance, hConv, "[DeleteItem(\"....\")]");
+ ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %#x\n", error);
+ ok(!check_exists("Group3/.lnk"), "link should not exist\n");
+
+ /* Test sanitary group name with unsanitary icon names */
+
+ for (i = 0; i < sizeof(test_chars) - 1; i++)
+ {
+ c = test_chars[i];
+ winetest_push_context("char %d '%c'", c, c);
+
+ sprintf(original_name, "%03d_%c_.%c", c, c, c);
+ sanitize_name(original_name, sanitized_icon_name, FALSE);
+
+ sprintf(buf, "[AddItem(notepad,\"Notepad%s\")]", original_name);
+ error = dde_execute(instance, hConv, buf);
+ ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %#x\n", error);
+ sprintf(buf, "Group3/Notepad%s.lnk", sanitized_icon_name);
+ todo_wine_if(c == '.') ok(check_exists(buf) || broken(c == '.') /* XP */, "link not created\n");
+ if (!check_exists(buf))
+ {
+ winetest_pop_context();
+ continue;
+ }
+
+ if (is_unsanitary(c))
+ {
+ sprintf(buf, "[ReplaceItem(\"Notepad%s\")]", original_name);
+ error = dde_execute(instance, hConv, buf);
+ ok(error == DMLERR_NOTPROCESSED, "expected DMLERR_NOTPROCESSED, got %#x\n", error);
+ sprintf(buf, "Group3/Notepad%s.lnk", sanitized_icon_name);
+ ok(check_exists(buf), "link should still exist\n");
+
+ sprintf(buf, "[DeleteItem(\"Notepad%s\")]", original_name);
+ error = dde_execute(instance, hConv, buf);
+ ok(error == DMLERR_NOTPROCESSED, "expected DMLERR_NOTPROCESSED, got %#x\n", error);
+ sprintf(buf, "Group3/Notepad%s.lnk", sanitized_icon_name);
+ ok(check_exists(buf), "link should still exist\n");
+ }
+ else
+ {
+ sprintf(buf, "[ReplaceItem(\"Notepad%s\")]", original_name);
+ error = dde_execute(instance, hConv, buf);
+ ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %#x\n", error);
+ sprintf(buf, "Group3/Notepad%s.lnk", sanitized_icon_name);
+ ok(!check_exists(buf), "link should not exist\n");
+
+ sprintf(buf, "[AddItem(notepad,\"Notepad%s\")]", original_name);
+ error = dde_execute(instance, hConv, buf);
+ ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %#x\n", error);
+ sprintf(buf, "Group3/Notepad%s.lnk", sanitized_icon_name);
+ ok(check_exists(buf), "link not created\n");
+
+ sprintf(buf, "[DeleteItem(\"Notepad%s\")]", original_name);
+ error = dde_execute(instance, hConv, buf);
+ ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %#x\n", error);
+ sprintf(buf, "Group3/Notepad%s.lnk", sanitized_icon_name);
+ ok(!check_exists(buf), "link should not exist\n");
+ }
+
+ winetest_pop_context();
+ }
+
+ error = dde_execute(instance, hConv, "[DeleteGroup(Group3)]");
+ ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %#x\n", error);
+ ok(!check_exists("Group3"), "directory should not exist\n");
+
+ for (i = 0; i < sizeof(test_chars) - 1; i++)
+ {
+ c = test_chars[i];
+ winetest_push_context("char %d '%c'", c, c);
+
+ sprintf(original_name, "%03d_%c_.%c", c, c, c);
+ sanitize_name(original_name, sanitized_group_name, TRUE);
+ sanitize_name(original_name, sanitized_icon_name, FALSE);
+
+ sprintf(buf, "[CreateGroup(\"Group%s\")]", original_name);
+ error = dde_execute(instance, hConv, buf);
+ ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %#x\n", error);
+ sprintf(buf, "Group%s", sanitized_group_name);
+ ok(check_exists(buf), "directory not created\n");
+ ok(check_window_exists(buf) || broken(c == ' ') /* vista */, "window not created\n");
+
+ sprintf(buf, "[ShowGroup(\"Group%s\", 0)]", original_name);
+ error = dde_execute(instance, hConv, buf);
+ ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %#x\n", error);
+ sprintf(buf, "Group%s", sanitized_group_name);
+ ok(check_window_exists(buf) || broken(c == ' ') /* vista */, "window not created\n");
+
+ /* Test unsanitary group name with sanitary icon name */
+
+ error = dde_execute(instance, hConv, "[AddItem(notepad,Notepad)]");
+ ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %#x\n", error);
+ sprintf(buf, "Group%s/Notepad.lnk", sanitized_group_name);
+ if (c == ' ')
+ {
+ /* Although no error is reported, no icon is created if the group name ends in a space */
+ ok(!check_exists(buf), "link should not exist\n");
+ goto delete_group;
+ }
+ todo_wine_if(c == '.') ok(check_exists(buf), "link not created\n");
+
+ error = dde_execute(instance, hConv, "[ReplaceItem(Notepad)]");
+ todo_wine_if(c == '.') ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %#x\n", error);
+ sprintf(buf, "Group%s/Notepad.lnk", sanitized_group_name);
+ ok(!check_exists(buf), "link should not exist\n");
+
+ error = dde_execute(instance, hConv, "[AddItem(notepad,Notepad)]");
+ ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %#x\n", error);
+ sprintf(buf, "Group%s/Notepad.lnk", sanitized_group_name);
+ todo_wine_if(c == '.') ok(check_exists(buf), "link not created\n");
+
+ error = dde_execute(instance, hConv, "[DeleteItem(Notepad)]");
+ todo_wine_if(c == '.') ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %#x\n", error);
+ sprintf(buf, "Group%s/Notepad.lnk", sanitized_group_name);
+ ok(!check_exists(buf), "link should not exist\n");
+
+ /* Test unsanitary group name with unsanitary icon name */
+
+ sprintf(buf, "[AddItem(notepad,\"Notepad%s\")]", original_name);
+ error = dde_execute(instance, hConv, buf);
+ ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %#x\n", error);
+ sprintf(buf, "Group%s/Notepad%s.lnk", sanitized_group_name, sanitized_icon_name);
+ todo_wine_if(c == '.') ok(check_exists(buf) || broken(c == '.') /* XP */, "link not created\n");
+ if (!check_exists(buf)) goto delete_group;
+
+ if (is_unsanitary(c))
+ {
+ sprintf(buf, "[ReplaceItem(\"Notepad%s\")]", original_name);
+ error = dde_execute(instance, hConv, buf);
+ ok(error == DMLERR_NOTPROCESSED, "expected DMLERR_NOTPROCESSED, got %#x\n", error);
+ sprintf(buf, "Group%s/Notepad%s.lnk", sanitized_group_name, sanitized_icon_name);
+ ok(check_exists(buf), "link should still exist\n");
+
+ sprintf(buf, "[DeleteItem(\"Notepad%s\")]", original_name);
+ error = dde_execute(instance, hConv, buf);
+ ok(error == DMLERR_NOTPROCESSED, "expected DMLERR_NOTPROCESSED, got %#x\n", error);
+ sprintf(buf, "Group%s/Notepad%s.lnk", sanitized_group_name, sanitized_icon_name);
+ ok(check_exists(buf), "link should still exist\n");
+ }
+ else
+ {
+ sprintf(buf, "[ReplaceItem(\"Notepad%s\")]", original_name);
+ error = dde_execute(instance, hConv, buf);
+ ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %#x\n", error);
+ sprintf(buf, "Group%s/Notepad%s.lnk", sanitized_group_name, sanitized_icon_name);
+ ok(!check_exists(buf), "link should not exist\n");
+
+ sprintf(buf, "[AddItem(notepad,\"Notepad%s\")]", original_name);
+ error = dde_execute(instance, hConv, buf);
+ ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %#x\n", error);
+ sprintf(buf, "Group%s/Notepad%s.lnk", sanitized_group_name, sanitized_icon_name);
+ ok(check_exists(buf), "link not created\n");
+
+ sprintf(buf, "[DeleteItem(\"Notepad%s\")]", original_name);
+ error = dde_execute(instance, hConv, buf);
+ ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %#x\n", error);
+ sprintf(buf, "Group%s/Notepad%s.lnk", sanitized_group_name, sanitized_icon_name);
+ ok(!check_exists(buf), "link should not exist\n");
+ }
+
+delete_group:
+ sprintf(buf, "[DeleteGroup(\"Group%s\")]", original_name);
+ error = dde_execute(instance, hConv, buf);
+ ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %#x\n", error);
+ sprintf(buf, "Group%s", sanitized_group_name);
+ ok(!check_exists(buf), "directory should not exist\n");
+
+ winetest_pop_context();
+ }
+}
+
START_TEST(progman_dde)
{
DWORD instance = 0;
@@ -479,6 +794,7 @@ START_TEST(progman_dde)
/* Run Tests */
test_progman_dde2(instance, hConv);
+ test_name_sanitization(instance, hConv);
/* Cleanup & Exit */
ret = DdeDisconnect(hConv);
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/23
More information about the wine-devel
mailing list