tags:

views:

1437

answers:

5

What's the easiest way to get the filename associated with an open HANDLE in Win32?

A: 

On unixes there is no real way of reliably doing this. In unix with the traditional unix filesystem, you can open a file and then unlink it (remove its entry from the directory) and use it, at which point the name isn't stored anywhere. In addition, because a file may have multiple hardlinks into the filesystem, each of the names are equivalent, so once you've got just the open handle it wouldn't be clear which filename you should map back towards.

So, you may be able to do this on Win32 using the other answers, but should you ever need to port the application to a unix enviornment, you'll be out of luck. My advice to you is to refactor your program, if possible, so that you don't need the OS to be able to maintain an open resource to filename connection.

Daniel Papasian
+3  A: 

Hey Max,

edit Thanks for the comments about this being Vista or Server 2008 only. I missed that in the page. Guess I should have read the whole article ;)

It looks like you can use GetFileInformationByHandleEx() to get this information.

You'll likely want to do something like:

GetFileInformationByHandleEx( fileHandle, FILE_NAME_INFO, lpFileInformation, sizeof(FILE_NAME_INFO));

Double check the MSDN page to make sure I haven't misled you too badly :)

Cheers,

Taylor

Taylor Price
The only problem with this solution is that GetFileInformationByHandleEx requires Windows Vista or Server 2008 (or later).
ChrisN
Love the simplicity of this one but I'm on XP :-(
Max Caceres
A: 

If you need to do this on Win32 pre-Vista or Server 2008, look at the GetMappedFileName(...) function, which is one of the best kept secrets in Win32. WIth a little C/C++-fu, you can memory map a small portion of the file in question, and then pass that handle to this function.

Also, on Win32, you cannot really delete a file that is open (the open/unlink issue mentioned on another answer) - you can mark it for deletion on close, but it will still hang around until its last open handle is closed. Dunno if mapping (via mmap(...)) the file in this case would help, because it has to point back to a physical file...

-=- James.

+3  A: 

MSDN Article: Obtaining a File Name From a File Handle

Prakash
Works perfectly, but GetMappedFileName? rly?
Max Caceres
A: 

FWIW, here's the same solution from the MSDN article suggested by Prakash in Python using the wonderful ctypes:

from ctypes import *
# get handle to  c:\boot.ini to test
handle = windll.kernel32.CreateFileA("c:\\boot.ini", 0x80000000, 3, 0, 3, 0x80, 0)
hfilemap = windll.kernel32.CreateFileMappingA(handle, 0, 2, 0, 1, 0)
pmem = windll.kernel32.MapViewOfFile(hfilemap, 4, 0, 0, 1)
name = create_string_buffer(1024)
windll.psapi.GetMappedFileNameA(windll.kernel32.GetCurrentProcess(), pmem, name, 1024)
print "The name for the handle 0x%08x is %s" % (handle, name.value)
# convert device name to drive letter
buf = create_string_buffer(512)
size = windll.kernel32.GetLogicalDriveStringsA(511, buf)
names = buf.raw[0:size-1].split("\0")
for drive in names:
    windll.kernel32.QueryDosDeviceA(drive[0:2], buf, 512)
    if name.value.startswith(buf.value):
        print "%s%s" % (drive[0:2], name.value[len(buf.value):])
        break
Max Caceres