Reactos
1/*
2 * PROJECT: ReactOS api tests
3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
4 * PURPOSE: Tests for PathMakeUniqueName
5 * COPYRIGHT: Copyright 2025 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
6 */
7
8#include "shelltest.h"
9#include <stdio.h>
10#include <versionhelpers.h>
11
12#define ok_wstri(x, y) \
13 ok(_wcsicmp(x, y) == 0, "Wrong string. Expected '%S', got '%S'\n", y, x)
14
15/* IsLFNDriveW */
16typedef BOOL (WINAPI *FN_IsLFNDriveW)(LPCWSTR);
17
18START_TEST(PathMakeUniqueName)
19{
20 WCHAR szPath[MAX_PATH], szCurDir[MAX_PATH], szTempDir[MAX_PATH];
21 BOOL result, bUseLong = FALSE;
22 FN_IsLFNDriveW pIsLFNDriveW =
23 (FN_IsLFNDriveW)GetProcAddress(GetModuleHandleW(L"shell32"), MAKEINTRESOURCEA(42));
24
25 // Move to temporary folder
26 GetCurrentDirectoryW(_countof(szCurDir), szCurDir);
27 GetEnvironmentVariableW(L"TEMP", szTempDir, _countof(szTempDir));
28 SetCurrentDirectoryW(szTempDir);
29
30 if (pIsLFNDriveW)
31 bUseLong = pIsLFNDriveW(szTempDir) && (GetNTVersion() >= _WIN32_WINNT_WIN10);
32 trace("bUseLong: %d\n", bUseLong);
33
34 DeleteFileW(L"test.txt");
35
36 // Test 1: Basic operation
37 szPath[0] = UNICODE_NULL;
38 result = PathMakeUniqueName(szPath, _countof(szPath), L"test.txt", NULL, NULL);
39 ok_int(result, TRUE);
40 ok_wstri(szPath, L"test (1).txt");
41
42 // Test 2: Specify directory
43 szPath[0] = UNICODE_NULL;
44 result = PathMakeUniqueName(szPath, _countof(szPath), L"test.txt", NULL, L".");
45 ok_int(result, TRUE);
46 ok_wstri(szPath, (bUseLong ? L".\\test (1).txt" : L".\\test1.txt"));
47
48 // Test 3: Duplicated filename
49 CreateFileW(L"test.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
50 szPath[0] = UNICODE_NULL;
51 result = PathMakeUniqueName(szPath, _countof(szPath), L"test.txt", NULL, NULL);
52 ok_int(result, TRUE);
53 ok_wstri(szPath, L"test (1).txt");
54 DeleteFileW(L"test.txt");
55
56 // Build long name
57 WCHAR longName[MAX_PATH + 32];
58 for (auto& ch : longName)
59 ch = L'A';
60 longName[_countof(longName) - 10] = UNICODE_NULL;
61 lstrcatW(longName, L".txt");
62
63 // Test 4: Long filename
64 result = PathMakeUniqueName(szPath, _countof(szPath), longName, NULL, NULL);
65 szPath[0] = UNICODE_NULL;
66 ok_int(result, FALSE);
67 ok_wstri(szPath, L"");
68
69 // Test 5: Invalid parameter
70 szPath[0] = UNICODE_NULL;
71 result = PathMakeUniqueName(NULL, 0, L"test.txt", NULL, NULL);
72 ok_int(result, FALSE);
73
74 // Test 6: Template and longplate
75 szPath[0] = UNICODE_NULL;
76 result = PathMakeUniqueName(szPath, _countof(szPath), L"template.txt", L"longplate.txt", NULL);
77 ok_int(result, TRUE);
78 ok_wstri(szPath, L"longplate (1).txt");
79
80 // Test 7: Template only
81 szPath[0] = UNICODE_NULL;
82 result = PathMakeUniqueName(szPath, _countof(szPath), L"template.txt", NULL, NULL);
83 ok_int(result, TRUE);
84 ok_wstri(szPath, L"template (1).txt");
85
86 // Test 8: Folder and duplicated filename
87 CreateFileW(L".\\temp\\test.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
88 szPath[0] = UNICODE_NULL;
89 result = PathMakeUniqueName(szPath, _countof(szPath), L"test.txt", NULL, L".");
90 ok_int(result, TRUE);
91 ok_wstri(szPath, (bUseLong ? L".\\test (1).txt" : L".\\test1.txt"));
92 DeleteFileW(L".\\test.txt");
93
94 // Test 9: Test extension
95 CreateFileW(L".\\test.hoge", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
96 szPath[0] = UNICODE_NULL;
97 result = PathMakeUniqueName(szPath, _countof(szPath), L"test.hoge", NULL, L".");
98 ok_int(result, TRUE);
99 ok_wstri(szPath, (bUseLong ? L".\\test (1).hoge" : L".\\test1.hoge"));
100 DeleteFileW(L".\\test.hoge");
101
102 // Test 10: Folder in folder
103 CreateDirectoryW(L".\\hoge", NULL);
104 szPath[0] = UNICODE_NULL;
105 result = PathMakeUniqueName(szPath, _countof(szPath), L"test.txt", NULL, L".\\hoge");
106 ok_int(result, TRUE);
107 ok_wstri(szPath, (bUseLong ? L".\\hoge\\test (1).txt" : L".\\hoge\\test1.txt"));
108 RemoveDirectoryW(L".\\hoge");
109
110 // Test 11: File in folder
111 CreateFileW(L".\\hoge.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
112 szPath[0] = UNICODE_NULL;
113 result = PathMakeUniqueName(szPath, _countof(szPath), L"test.txt", NULL, L".");
114 ok_int(result, TRUE);
115 ok_wstri(szPath, (bUseLong ? L".\\test (1).txt" : L".\\test1.txt"));
116 DeleteFileW(L".\\hoge.txt");
117
118 SetCurrentDirectoryW(szCurDir);
119}