ReactOS 0.4.16-dev-1643-gf0ba726
GetFinalPathNameByHandle.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS api tests
3 * LICENSE: MIT (https://spdx.org/licenses/MIT)
4 * PURPOSE: Tests for GetFinalPathNameByHandleW
5 * COPYRIGHT: Copyright 2025 Timo Kreuzer <timo.kreuzer@reactos.org>
6 */
7
8#include "precomp.h"
9#include <lm.h>
10#include <ndk/obfuncs.h>
11#include <ndk/iofuncs.h>
12
13typedef
18 _Out_writes_(cchFilePath) LPWSTR lpszFilePath,
19 _In_ DWORD cchFilePath,
22
23#define VOLUME_NAME_DOS 0x0
24#define VOLUME_NAME_GUID 0x1
25#define VOLUME_NAME_NT 0x2
26#define VOLUME_NAME_NONE 0x4
27#define FILE_NAME_NORMALIZED 0x0
28#define FILE_NAME_OPENED 0x8
29
30static void Test_File(void)
31{
34 WCHAR VolumeBuffer[4];
35 PWSTR VolumeRelativePath;
36 WCHAR ExpectedString[MAX_PATH];
38 SIZE_T ExpectedStringLength;
41
42 /* Get the full path name of the current executable */
44 ok(Result != 0, "GetModuleFileNameW failed: %ld\n", GetLastError());
45 if (Result == 0)
46 {
47 skip("GetModuleFileNameW failed\n");
48 return;
49 }
50
51 /* Open the executable file */
55 NULL,
58 NULL);
59 ok(hFile != INVALID_HANDLE_VALUE, "File '%S': Opening failed\n", FilePath);
61 {
62 skip("File '%S': Opening failed\n", FilePath);
63 return;
64 }
65
66 /* Expected string for VOLUME_NAME_DOS:
67 L"\\\\?\\C:\\ReactOS\\bin\\kernel32_apitest.exe" */
68 wcscpy(ExpectedString, L"\\\\?\\");
69 wcscat(ExpectedString, FilePath);
70 ExpectedStringLength = wcslen(ExpectedString);
71
72 SetLastError(0xdeadbeef);
73 StartSeh()
76
77 SetLastError(0xdeadbeef);
78 memset(Buffer, 0xCC, sizeof(Buffer));
80 ok_eq_ulong(Result, ExpectedStringLength + 1);
81 ok_eq_wchar(Buffer[0], 0xCCCC);
83
84 SetLastError(0xdeadbeef);
85 memset(Buffer, 0xCC, sizeof(Buffer));
87 ok_eq_ulong(Result, ExpectedStringLength + 1);
88 ok_eq_wchar(Buffer[0], 0xCCCC);
90
91 SetLastError(0xdeadbeef);
92 memset(Buffer, 0xCC, sizeof(Buffer));
94 ok_eq_ulong(Result, ExpectedStringLength + 1);
96
97 SetLastError(0xdeadbeef);
98 memset(Buffer, 0xCC, sizeof(Buffer));
100 ok_eq_ulong(Result, ExpectedStringLength);
101 ok_eq_wstr(Buffer, ExpectedString);
102 ok_err(0);
103
104 SetLastError(0xdeadbeef);
105 memset(Buffer, 0xCC, sizeof(Buffer));
107 ok_eq_ulong(Result, 0ul);
108 ok_eq_wchar(Buffer[0], 0xCCCC);
110
111 SetLastError(0xdeadbeef);
112 memset(Buffer, 0xCC, sizeof(Buffer));
114 ok_eq_ulong(Result, ExpectedStringLength);
115 ok_eq_wstr(Buffer, ExpectedString);
116 ok_err(0);
117
118 SetLastError(0xdeadbeef);
119 memset(Buffer, 0xCC, sizeof(Buffer));
121 ok_eq_ulong(Result, ExpectedStringLength);
122 ok_eq_wstr(Buffer, ExpectedString);
123 ok_err(0);
124
125 /* Query the GUID based volume name */
126 memcpy(VolumeBuffer, FilePath, 3 * sizeof(WCHAR));
127 VolumeBuffer[3] = UNICODE_NULL;
129 ExpectedString,
130 ARRAYSIZE(ExpectedString));
131 if (!Success)
132 {
133 skip("GetVolumeNameForVolumeMountPointW failed: %ld\n", GetLastError());
134 return;
135 }
136
137 /* Expected string for VOLUME_NAME_GUID:
138 L"\\\\?\\Volume{cd4317d4-A62f-53d7-b36c-73f935c37280}\\ReactOS\\bin\\kernel32_apitest.exe" */
139 VolumeRelativePath = &FilePath[wcslen(L"C:\\")];
140 wcscat(ExpectedString, VolumeRelativePath);
141 ExpectedStringLength = wcslen(ExpectedString);
142
143 SetLastError(0xdeadbeef);
144 memset(Buffer, 0xCC, sizeof(Buffer));
146 ok_eq_ulong(Result, ExpectedStringLength);
147 ok_eq_wstr(Buffer, ExpectedString);
148 ok_err(0);
149
150 SetLastError(0xdeadbeef);
151 memset(Buffer, 0xCC, sizeof(Buffer));
153 ok_eq_ulong(Result, ExpectedStringLength);
154 ok_eq_wstr(Buffer, ExpectedString);
155 ok_err(0);
156
157 /* Expected string for VOLUME_NAME_NT (2):
158 L"\\Device\\HarddiskVolume1\\ReactOS\\bin\\kernel32_apitest.exe" */
159 ExpectedStringLength = wcslen(L"\\Device\\HarddiskVolume*\\") +
160 wcslen(VolumeRelativePath);
161
162 SetLastError(0xdeadbeef);
163 memset(Buffer, 0xCC, sizeof(Buffer));
165 ok_eq_ulong(Result, ExpectedStringLength);
166 ok_int(wcsncmp(Buffer, L"\\Device\\HarddiskVolume", 22), 0);
167 ok_int(wcscmp(Buffer + 24, VolumeRelativePath), 0);
168 ok_err(0xdeadbeef);
169
170 SetLastError(0xdeadbeef);
171 memset(Buffer, 0xCC, sizeof(Buffer));
173 ok_eq_ulong(Result, ExpectedStringLength);
174 ok_int(wcsncmp(Buffer, L"\\Device\\HarddiskVolume", 22), 0);
175 ok_int(wcscmp(Buffer + 24, VolumeRelativePath), 0);
176 ok_err(0xdeadbeef);
177
178 /* Expected string for VOLUME_NAME_NONE:
179 L"\\ReactOS\\bin\\kernel32_apitest.exe" */
180 ExpectedStringLength = wcslen(VolumeRelativePath - 1);
181
182 SetLastError(0xdeadbeef);
183 memset(Buffer, 0xCC, sizeof(Buffer));
185 ok_eq_ulong(Result, ExpectedStringLength);
186 ok_eq_wstr(Buffer, VolumeRelativePath - 1);
187 ok_err(0xdeadbeef);
188
189 SetLastError(0xdeadbeef);
190 memset(Buffer, 0xCC, sizeof(Buffer));
192 ok_eq_ulong(Result, ExpectedStringLength);
193 ok_eq_wstr(Buffer, VolumeRelativePath - 1);
194 ok_err(0xdeadbeef);
195
196 SetLastError(0xdeadbeef);
197 memset(Buffer, 0xCC, sizeof(Buffer));
199 ok_eq_ulong(Result, ExpectedStringLength + 1);
200 ok_eq_wchar(Buffer[0], 0xCCCC);
202
204}
205
206static void Test_NetworkShare(void)
207{
208 WCHAR PathBuffer[MAX_PATH];
209 WCHAR RemotePathBuffer[MAX_PATH];
211 WCHAR ExpectedString[MAX_PATH];
214 SIZE_T ExpectedStringLength;
215 DWORD dwError = 0;
218
219 /* Get the full path name of the current executable */
220 Result = GetModuleFileNameW(NULL, PathBuffer, ARRAYSIZE(PathBuffer));
221 ok(Result != 0, "GetModuleFileNameW failed: %ld\n", GetLastError());
222 if (Result == 0)
223 {
224 skip("GetModuleFileNameW failed: %ld\n", GetLastError());
225 return;
226 }
227
228 /* Reduce to the containing folder */
229 FileName = wcsrchr(PathBuffer, L'\\');
230 *FileName = L'\0';
231 FileName++;
232
233 // Define the share parameters
234 static WCHAR ShareName[] = L"TestShare"; // Name of the share
235
236 NetShareDel(L"", ShareName, 0);
237
238 // Set up the SHARE_INFO_2 structure
239 SHARE_INFO_2 shareInfo = { 0 };
240 shareInfo.shi2_netname = ShareName;
241 shareInfo.shi2_type = STYPE_DISKTREE; // Disk directory share
242 shareInfo.shi2_remark = L"";
243 shareInfo.shi2_permissions = ACCESS_ALL; // Full access (adjust as needed)
244 shareInfo.shi2_max_uses = -1; // Unlimited connections
245 shareInfo.shi2_current_uses = 0; // 0 for new share
246 shareInfo.shi2_path = PathBuffer;
247 shareInfo.shi2_passwd = NULL; // No password
248
249 // Call NetShareAdd to create the share
250 Status = NetShareAdd(L"", // Empty string for local machine
251 2, // Level 2 for SHARE_INFO_2
252 (LPBYTE)&shareInfo, // Share info structure
253 &dwError); // Error code if applicable
254 if (Status != NERR_Success)
255 {
256 skip("Failed to create share. Error code: %ld\n", Status);
258 {
259 wprintf(L"Error: Access denied. Ensure you have administrative privileges.\n");
260 }
261
262 return;
263 }
264
265 swprintf(RemotePathBuffer, L"\\\\localhost\\%s\\%s", ShareName, FileName);
266 hFile = CreateFileW(RemotePathBuffer,
269 NULL,
272 NULL);
273 ok(hFile != INVALID_HANDLE_VALUE, "Failed to open file '%S'. Error: %ld\n",
274 RemotePathBuffer, GetLastError());
276 {
277 skip("Failed to open file '%S'. Error: %ld\n", RemotePathBuffer, GetLastError());
278 /* Clean up by deleting the share */
279 NetShareDel(L"", ShareName, 0);
280 return;
281 }
282
283 /* Expected string for VOLUME_NAME_DOS:
284 L"\\\\?\\UNC\\localhost\\TestShare\\kernel32_apitest.exe" */
285 swprintf(ExpectedString, L"\\\\?\\UNC\\localhost\\%s\\%s", ShareName, FileName);
286 ExpectedStringLength = wcslen(ExpectedString);
287 SetLastError(0xdeadbeef);
288 memset(Buffer, 0xCC, sizeof(Buffer));
290 ok_eq_ulong(Result, ExpectedStringLength);
291 ok_eq_wstr(Buffer, ExpectedString);
292 ok_err(0xdeadbeef);
293
294 SetLastError(0xdeadbeef);
295 memset(Buffer, 0xCC, sizeof(Buffer));
297 ok_eq_ulong(Result, ExpectedStringLength);
298 ok_eq_wstr(Buffer, ExpectedString);
299 ok_err(0xdeadbeef);
300
301 // VOLUME_NAME_GUID doesn't work for network shares
302 SetLastError(0xdeadbeef);
303 memset(Buffer, 0xCC, sizeof(Buffer));
305 ok_eq_ulong(Result, 0ul);
306 ok_eq_wchar(Buffer[0], 0xCCCC);
308
309 SetLastError(0xdeadbeef);
310 memset(Buffer, 0xCC, sizeof(Buffer));
312 ok_eq_ulong(Result, 0ul);
313 ok_eq_wchar(Buffer[0], 0xCCCC);
315
316 /* Expected string for VOLUME_NAME_NT (2):
317 L"\\Device\\Mup\\localhost\\TestShare\\kernel32_apitest.exe" */
318 swprintf(ExpectedString, L"\\Device\\Mup\\localhost\\%s\\%s", ShareName, FileName);
319 ExpectedStringLength = wcslen(ExpectedString);
320 SetLastError(0xdeadbeef);
321 memset(Buffer, 0xCC, sizeof(Buffer));
323 ok_eq_ulong(Result, ExpectedStringLength);
324 ok_eq_wstr(Buffer, ExpectedString);
325 ok_err(0xdeadbeef);
326
327 SetLastError(0xdeadbeef);
328 memset(Buffer, 0xCC, sizeof(Buffer));
330 ok_eq_ulong(Result, ExpectedStringLength);
331 ok_eq_wstr(Buffer, ExpectedString);
332 ok_err(0xdeadbeef);
333
334 /* Expected string for VOLUME_NAME_NONE:
335 L"\\localhost\\TestShare\\kernel32_apitest.exe" */
336 swprintf(ExpectedString, L"\\localhost\\%s\\%s", ShareName, FileName);
337 ExpectedStringLength = wcslen(ExpectedString);
338 SetLastError(0xdeadbeef);
339 memset(Buffer, 0xCC, sizeof(Buffer));
341 ok_eq_ulong(Result, ExpectedStringLength);
342 ok_eq_wstr(Buffer, ExpectedString);
343 ok_err(0xdeadbeef);
344
345 SetLastError(0xdeadbeef);
346 memset(Buffer, 0xCC, sizeof(Buffer));
348 ok_eq_ulong(Result, ExpectedStringLength);
349 ok_eq_wstr(Buffer, ExpectedString);
350 ok_err(0xdeadbeef);
351
352 /* Clean up */
354 Status = NetShareDel(L"", ShareName, 0);
356}
357
358static void Test_Other(void)
359{
367
368 /* Test NULL handle */
369 SetLastError(0xdeadbeef);
371 ok_eq_ulong(Result, 0ul);
373
374 /* Test NULL handle and NULL buffer */
375 SetLastError(0xdeadbeef);
377 ok_eq_ulong(Result, 0ul);
379
380 /* Test NULL handle and invalid volume type */
381 SetLastError(0xdeadbeef);
383 ok_eq_ulong(Result, 0ul);
385
386 /* Test INVALID_HANDLE_VALUE */
387 SetLastError(0xdeadbeef);
388 memset(Buffer, 0xCC, sizeof(Buffer));
390 ok_eq_ulong(Result, 0ul);
391 ok_eq_wchar(Buffer[0], 0xCCCC);
393
394 /* Test NtCurrentProcess */
395 SetLastError(0xdeadbeef);
396 memset(Buffer, 0xCC, sizeof(Buffer));
398 ok_eq_ulong(Result, 0ul);
399 ok_eq_wchar(Buffer[0], 0xCCCC);
401
402 /* Open a handle to the Beep device */
403 RtlInitUnicodeString(&DeviceName, L"\\Device\\Beep");
407 if (!NT_SUCCESS(Status))
408 {
409 skip("Opening Beep device failed\n");
410 }
411 else
412 {
413 SetLastError(0xdeadbeef);
414 memset(Buffer, 0xCC, sizeof(Buffer));
416 ok_eq_ulong(Result, 0ul);
417 ok_eq_wchar(Buffer[0], 0xCCCC);
420 }
421
422 /* Open a handle to the Null device */
423 RtlInitUnicodeString(&DeviceName, L"\\Device\\Null");
427 if (!NT_SUCCESS(Status))
428 {
429 skip("Opening Null device failed\n");
430 }
431 else
432 {
433 SetLastError(0xdeadbeef);
434 memset(Buffer, 0xCC, sizeof(Buffer));
436 ok_eq_ulong(Result, 0ul);
437 ok_eq_wchar(Buffer[0], 0xCCCC);
440 }
441}
442
443
444START_TEST(GetFinalPathNameByHandle)
445{
446 HMODULE hmodKernel32 = GetModuleHandleW(L"kernel32.dll");
448 GetProcAddress(hmodKernel32, "GetFinalPathNameByHandleW");
450 {
451 hmodKernel32 = GetModuleHandleW(L"kernel32_vista.dll");
453 GetProcAddress(hmodKernel32, "GetFinalPathNameByHandleW");
455 {
456 skip("GetFinalPathNameByHandleW not available\n");
457 return;
458 }
459 }
460
461 Test_File();
463 Test_Other();
464}
PCWSTR FilePath
#define StartSeh()
Definition: _sntprintf.h:16
#define EndSeh(ExpectedStatus)
Definition: _sntprintf.h:17
#define ok_eq_ulong(value, expected)
Definition: apitest.h:48
#define ok_eq_wstr(value, expected)
Definition: apitest.h:69
#define ok_eq_wchar(value, expected)
Definition: apitest.h:52
#define ok_ntstatus(status, expected)
Definition: atltest.h:135
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define ok_err(error)
Definition: atltest.h:124
#define START_TEST(x)
Definition: atltest.h:75
#define ok_int(expression, result)
Definition: atltest.h:134
LONG NTSTATUS
Definition: precomp.h:26
Definition: bufpool.h:45
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
wcscat
wcscpy
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define ERROR_INVALID_FUNCTION
Definition: dderror.h:6
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define CloseHandle
Definition: compat.h:739
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define wcsrchr
Definition: compat.h:16
#define OPEN_EXISTING
Definition: compat.h:775
#define SetLastError(x)
Definition: compat.h:752
#define GetProcAddress(x, y)
Definition: compat.h:753
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define GENERIC_READ
Definition: compat.h:135
#define MAX_PATH
Definition: compat.h:34
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define CreateFileW
Definition: compat.h:741
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
#define FILE_SHARE_READ
Definition: compat.h:136
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:600
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:838
NET_API_STATUS WINAPI NetShareDel(_In_ LMSTR servername, _In_ LMSTR netname, _In_ DWORD reserved)
Definition: srvsvc.c:911
NET_API_STATUS WINAPI NetShareAdd(_In_ LMSTR servername, _In_ DWORD level, _In_ LPBYTE buf, _Out_ LPDWORD parm_err)
Definition: srvsvc.c:850
#define swprintf
Definition: precomp.h:40
#define L(x)
Definition: resources.c:13
@ Success
Definition: eventcreate.c:712
struct _FileName FileName
Definition: fatprocs.h:897
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
#define STATUS_ACCESS_VIOLATION
ULONG Handle
Definition: gdb_input.c:15
Status
Definition: gdiplustypes.h:25
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define ACCESS_ALL
Definition: lmaccess.h:167
#define NERR_Success
Definition: lmerr.h:5
#define STYPE_DISKTREE
Definition: lmshare.h:22
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
BOOL WINAPI GetVolumeNameForVolumeMountPointW(IN LPCWSTR VolumeMountPoint, OUT LPWSTR VolumeName, IN DWORD VolumeNameLength)
Definition: mntpoint.c:496
LPCWSTR LPCWSTR LPCWSTR DWORD dwFlags
Definition: env.c:37
static void Test_NetworkShare(void)
#define FILE_NAME_OPENED
#define VOLUME_NAME_GUID
FN_GetFinalPathNameByHandleW * pGetFinalPathNameByHandleW
static void Test_File(void)
#define VOLUME_NAME_NONE
#define VOLUME_NAME_NT
DWORD WINAPI FN_GetFinalPathNameByHandleW(_In_ HANDLE hFile, _Out_writes_(cchFilePath) LPWSTR lpszFilePath, _In_ DWORD cchFilePath, _In_ DWORD dwFlags)
static void Test_Other(void)
#define VOLUME_NAME_DOS
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
DWORD NET_API_STATUS
Definition: ms-dtyp.idl:91
_In_ HANDLE hFile
Definition: mswsock.h:90
#define _Out_writes_(s)
Definition: no_sal2.h:176
#define _In_
Definition: no_sal2.h:158
NTSYSAPI NTSTATUS NTAPI NtOpenFile(OUT PHANDLE phFile, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG ShareMode, IN ULONG OpenMode)
Definition: file.c:3953
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define NtCurrentProcess()
Definition: nt_native.h:1657
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
#define UNICODE_NULL
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
_Check_return_ _CRTIMP int __cdecl wcsncmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
#define memset(x, y, z)
Definition: compat.h:39
#define STATUS_SUCCESS
Definition: shellext.h:65
DWORD shi2_permissions
Definition: lmshare.h:68
LMSTR shi2_passwd
Definition: lmshare.h:72
LMSTR shi2_netname
Definition: lmshare.h:65
LMSTR shi2_remark
Definition: lmshare.h:67
DWORD shi2_current_uses
Definition: lmshare.h:70
LMSTR shi2_path
Definition: lmshare.h:71
DWORD shi2_type
Definition: lmshare.h:66
DWORD shi2_max_uses
Definition: lmshare.h:69
uint16_t * PWSTR
Definition: typedefs.h:56
unsigned char * LPBYTE
Definition: typedefs.h:53
ULONG_PTR SIZE_T
Definition: typedefs.h:80
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3275
#define wprintf(...)
Definition: whoami.c:18
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define WINAPI
Definition: msvc.h:6
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:228
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184