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
34const WCHAR szSeperator[] = {'\\','\\','\0'};
35#else
36const WCHAR szSeperator[] = {'/','/','\0'};
37#endif
38
39const WCHAR szDotDot[] = {'.','.','\0'};
40const WCHAR szFileName[] = {'t','e','s','t','i','n','g','.','t','m','p','\0'};
41
42int __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
204cleanUpThree:
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
215cleanUpTwo:
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
226cleanUpOne:
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