1 | // Licensed to the .NET Foundation under one or more agreements. |
2 | // The .NET Foundation licenses this file to you under the MIT license. |
3 | // See the LICENSE file in the project root for more information. |
4 | |
5 | /*===================================================================== |
6 | ** |
7 | ** Source: test3.c |
8 | ** |
9 | ** Purpose: Tests the PAL implementation of the GetFullPathNameW API. |
10 | ** GetFullPathW will be passed a directory that contains '..'. |
11 | ** Example: test_directory\level1\..\testing.tmp. |
12 | ** To add to this test, we will also call SetCurrentDirectory to |
13 | ** ensure this is handled properly. |
14 | ** The test will create a file with in the parent directory |
15 | ** to verify that the returned directory is valid. |
16 | ** |
17 | ** Depends: SetCurrentDirectory, |
18 | ** CreateDirectory, |
19 | ** strcat, |
20 | ** memset, |
21 | ** CreateFile, |
22 | ** CloseHandle, |
23 | ** strcmp, |
24 | ** DeleteFileW, |
25 | ** RemoveDirectory. |
26 | ** |
27 | |
28 | ** |
29 | **===================================================================*/ |
30 | #define UNICODE |
31 | #include <palsuite.h> |
32 | |
33 | #ifdef WIN32 |
34 | const WCHAR szSeperator[] = {'\\','\\','\0'}; |
35 | #else |
36 | const WCHAR szSeperator[] = {'/','/','\0'}; |
37 | #endif |
38 | |
39 | const WCHAR szDotDot[] = {'.','.','\0'}; |
40 | const WCHAR szFileName[] = {'t','e','s','t','i','n','g','.','t','m','p','\0'}; |
41 | |
42 | int __cdecl main(int argc, char *argv[]) |
43 | { |
44 | DWORD dwRc = 0; |
45 | |
46 | WCHAR szReturnedPath[_MAX_DIR+1]; |
47 | WCHAR szFullFileName[_MAX_DIR+1]; |
48 | WCHAR szDirectory[256]; |
49 | WCHAR szCreatedDir[] = {'t','e','s','t','_','d','i','r','\0'}; |
50 | WCHAR szCreatedNextDir[] = {'l','e','v','e','l','1','\0'}; |
51 | |
52 | LPWSTR pPathPtr; |
53 | HANDLE hFile = NULL; |
54 | BOOL bRetVal = FAIL; |
55 | |
56 | /* Initialize the PAL. |
57 | */ |
58 | if ( 0 != PAL_Initialize(argc,argv) ) |
59 | { |
60 | return (FAIL); |
61 | } |
62 | |
63 | /* Initialize the buffer. |
64 | */ |
65 | memset( szDirectory, '\0', 256 ); |
66 | |
67 | /* Change the current working directory. |
68 | */ |
69 | if ( !SetCurrentDirectoryW(szDotDot) ) |
70 | { |
71 | Fail("ERROR: SetCurrentDirectoryA failed with error code %u " |
72 | "when passed \"%S\".\n" , |
73 | GetLastError(), |
74 | szDotDot); |
75 | } |
76 | |
77 | /* Create the path to the next level of directory to create. |
78 | */ |
79 | wcscat(szDirectory, szCreatedDir); /* test_dir */ |
80 | |
81 | |
82 | /* Create a test directory. |
83 | */ |
84 | if (!CreateDirectoryW(szDirectory, NULL)) |
85 | { |
86 | Fail("ERROR:%u: Unable to create directories \"%S\".\n" , |
87 | GetLastError(), |
88 | szDirectory); |
89 | } |
90 | |
91 | /* Create the path to the next level of directory to create. |
92 | */ |
93 | wcscat(szDirectory, szSeperator); /* / */ |
94 | wcscat(szDirectory, szCreatedNextDir); /* /level1 */ |
95 | |
96 | /* Create a test directory. |
97 | */ |
98 | if (!CreateDirectoryW(szDirectory, NULL)) |
99 | { |
100 | Trace("ERROR:%u: Unable to create directories \"%S\".\n" , |
101 | GetLastError(), |
102 | szDirectory); |
103 | bRetVal = FAIL; |
104 | goto cleanUpOne; |
105 | } |
106 | |
107 | /* Initialize the receiving char buffers. |
108 | */ |
109 | memset(szReturnedPath, 0, _MAX_DIR+1); |
110 | memset(szFullFileName, 0, _MAX_DIR+1); |
111 | |
112 | /* Create Full filename to pass, will include '..\' |
113 | * in the middle of the path. |
114 | */ |
115 | wcscat(szFullFileName, szCreatedDir); /*test_dir */ |
116 | wcscat(szFullFileName, szSeperator); /*test_dir/ */ |
117 | wcscat(szFullFileName, szCreatedNextDir);/*test_dir/level1 */ |
118 | wcscat(szFullFileName, szSeperator); /*test_dir/level1/ */ |
119 | wcscat(szFullFileName, szDotDot); /*test_dir/level1/.. */ |
120 | wcscat(szFullFileName, szSeperator); /*test_dir/level1/../ */ |
121 | wcscat(szFullFileName, szFileName); /*test_dir/level1/../testing.tmp */ |
122 | |
123 | /* Get the full path to the filename. |
124 | */ |
125 | dwRc = GetFullPathNameW(szFullFileName, |
126 | _MAX_DIR, |
127 | szReturnedPath, |
128 | &pPathPtr); |
129 | if (dwRc == 0) |
130 | { |
131 | Trace("ERROR :%ld: GetFullPathNameW failed to " |
132 | "retrieve the path of \"%S\".\n" , |
133 | GetLastError(), |
134 | szFileName); |
135 | bRetVal = FAIL; |
136 | goto cleanUpTwo; |
137 | } |
138 | |
139 | /* The returned value should be the parent directory with the |
140 | * file name appended. */ |
141 | hFile = CreateFileW(szReturnedPath, |
142 | GENERIC_READ, |
143 | FILE_SHARE_READ, |
144 | NULL, |
145 | CREATE_ALWAYS, |
146 | FILE_ATTRIBUTE_NORMAL, |
147 | NULL); |
148 | |
149 | if (hFile == INVALID_HANDLE_VALUE) |
150 | { |
151 | Trace("ERROR :%ld: CreateFileA failed to create \"%S\".\n" , |
152 | GetLastError(), |
153 | szReturnedPath); |
154 | bRetVal = FAIL; |
155 | goto cleanUpTwo; |
156 | } |
157 | |
158 | /* Close the handle to the created file. |
159 | */ |
160 | if (CloseHandle(hFile) != TRUE) |
161 | { |
162 | Trace("ERROR :%ld: CloseHandle failed close hFile=0x%lx.\n" , |
163 | GetLastError()); |
164 | bRetVal = FAIL; |
165 | goto cleanUpThree; |
166 | } |
167 | |
168 | /* Verify that the file was created, attempt to create |
169 | * the file again. */ |
170 | hFile = CreateFileW(szReturnedPath, |
171 | GENERIC_READ, |
172 | FILE_SHARE_READ, |
173 | NULL, |
174 | CREATE_NEW, |
175 | FILE_ATTRIBUTE_NORMAL, |
176 | NULL); |
177 | if ((hFile != INVALID_HANDLE_VALUE) && |
178 | (GetLastError() != ERROR_ALREADY_EXISTS)) |
179 | { |
180 | Trace("ERROR :%ld: CreateFileA succeeded to create file " |
181 | "\"%S\", that already existed.\n" , |
182 | GetLastError(), |
183 | szFullFileName); |
184 | bRetVal = FAIL; |
185 | goto cleanUpThree; |
186 | } |
187 | |
188 | /* Verify that the returned filename is the same as the supplied. |
189 | */ |
190 | if (wcscmp(pPathPtr, szFileName) != 0) |
191 | { |
192 | Trace("ERROR : Returned filename \"%s\" is not equal to " |
193 | "supplied filename \"%s\".\n" , |
194 | pPathPtr, |
195 | szFileName); |
196 | bRetVal = FAIL; |
197 | goto cleanUpThree; |
198 | } |
199 | |
200 | /* Successful test. |
201 | */ |
202 | bRetVal = PASS; |
203 | |
204 | cleanUpThree: |
205 | |
206 | /* Delete the create file. |
207 | */ |
208 | if (DeleteFileW(szReturnedPath) != TRUE) |
209 | { |
210 | Fail("ERROR :%ld: DeleteFileA failed to delete \"%S\".\n" , |
211 | GetLastError(), |
212 | szFileName); |
213 | } |
214 | |
215 | cleanUpTwo: |
216 | |
217 | /* Remove the empty directory. |
218 | */ |
219 | if (!RemoveDirectoryW(szDirectory)) |
220 | { |
221 | Fail("ERROR:%u: Unable to remove directory \"%S\".\n" , |
222 | GetLastError(), |
223 | szCreatedDir); |
224 | } |
225 | |
226 | cleanUpOne: |
227 | |
228 | /* Remove the empty directory. |
229 | */ |
230 | if (!RemoveDirectoryW(szCreatedDir)) |
231 | { |
232 | Fail("ERROR:%u: Unable to remove directory \"%s\".\n" , |
233 | GetLastError(), |
234 | szCreatedDir); |
235 | } |
236 | |
237 | /* Terminate the PAL.*/ |
238 | PAL_TerminateEx(bRetVal); |
239 | return bRetVal; |
240 | } |
241 | |