GetFinalPathNameByHandle function
Applies to: desktop apps only
Retrieves the final path for the specified file.
For more information about file and path names, see Naming a File.
Syntax
DWORD WINAPI GetFinalPathNameByHandle( __in HANDLE hFile, __out LPTSTR lpszFilePath, __in DWORD cchFilePath, __in DWORD dwFlags );
Parameters
- hFile [in]
-
A handle to a file or directory.
- lpszFilePath [out]
-
A pointer to a buffer that receives the path of hFile.
- cchFilePath [in]
-
The size of lpszFilePath, in TCHARs. This value does not include a NULL termination character.
- dwFlags [in]
-
The type of result to return. This parameter can be one of the following values.
Value Meaning - FILE_NAME_NORMALIZED
- 0x0
Return the normalized drive name. This is the default.
- FILE_NAME_OPENED
- 0x8
Return the opened file name (not normalized).
This parameter can also include one of the following values.
Return value
If the function succeeds, the return value is the length of the string received by lpszFilePath, in TCHARs. This value does not include the size of the terminating null character.
Windows Server 2008 and Windows Vista: For the ANSI version of this function, GetFinalPathNameByHandleA, the return value includes the size of the terminating null character.
If the function fails because lpszFilePath is too small to hold the string plus the terminating null character, the return value is the required buffer size, in TCHARs. This value includes the size of the terminating null character.
If the function fails for any other reason, the return value is zero. To get extended error information, call GetLastError.
| Return code | Description |
|---|---|
|
Can be returned if you are searching for a drive letter and one does not exist. For example, the handle was opened on a drive that is not currently mounted, or if you create a volume and do not assign it a drive letter. If a volume has no drive letter, you can use the volume GUID path to identify it. This return value can also be returned if you are searching for a volume GUID path on a network share. Volume GUID paths are not created for network shares. |
|
Insufficient memory to complete the operation. |
|
Invalid flags were specified for dwFlags. |
Remarks
A final path is the path that is returned when a path is fully resolved. For example, for a symbolic link named "C:\tmp\mydir" that points to "D:\yourdir", the final path would be "D:\yourdir".
The string that is returned by this function uses the \\?\ syntax. For more information, see CreateFile.
Examples
The following example demonstrates the us of the GetFinalPathNameByHandle function.
#include <windows.h> #include <tchar.h> #include <stdio.h> #define BUFSIZE MAX_PATH void __cdecl _tmain(int argc, TCHAR *argv[]) { TCHAR Path[BUFSIZE]; HANDLE hFile; DWORD dwRet; printf("\n"); if( argc != 2 ) { printf("ERROR:\tIncorrect number of arguments\n\n"); printf("%s <file_name>\n", argv[0]); return; } hFile = CreateFile(argv[1], // file to open GENERIC_READ, // open for reading FILE_SHARE_READ, // share for reading NULL, // default security OPEN_EXISTING, // existing file only FILE_ATTRIBUTE_NORMAL, // normal file NULL); // no attr. template if( hFile == INVALID_HANDLE_VALUE) { printf("Could not open file (error %d\n)", GetLastError()); return; } dwRet = GetFinalPathNameByHandle( hFile, Path, BUFSIZE, VOLUME_NAME_NT ); if(dwRet < BUFSIZE) { _tprintf(TEXT("\nThe final path is: %s\n"), Path); } else printf("\nThe required buffer size is %d.\n", dwRet); CloseHandle(hFile); }
Requirements
|
Minimum supported client | Windows Vista |
|---|---|
|
Minimum supported server | Windows Server 2008 |
|
Header |
|
|
Library |
|
|
DLL |
|
|
Unicode and ANSI names | GetFinalPathNameByHandleW (Unicode) and GetFinalPathNameByHandleA (ANSI) |
See also
Send comments about this topic to Microsoft
Build date: 4/17/2012
This is not always possible. Consider a symlink to c:\pagefile.sys (called c:\link_to_pagefile). It appears to not be possible to determine the final path of c:\link_to_pagefile without reading the reparse point manually.
[conrad]
I believe that this is the point of using reparse points, this api normalizes names, which excludes reparsing by design. Finding the Symlink/Junction/Hard are just 2 or 3 more calls to crack open. Search for NtCreateFile + FILE_OPEN_REPARSE_POINT + NtFsControlFile keywords.
[jaraco]
Ultimately, I implemented the symlink traversal using this Python routine: https://bitbucket.org/jaraco/jaraco.windows/src/c7a4c31fc737/jaraco/windows/filesystem.py#cl-252
- 11/30/2009
- Jason R. Coombs
- 8/18/2011
- Jason R. Coombs