Daniel Berger
2008-Nov-22 08:17 UTC
[Win32utils-devel] GetFinalPathNameByHandle for XP and earlier
Hi all, How''s this look? I based it on http://msdn.microsoft.com/en-us/library/aa366789(VS.85).aspx. I''m undecided as to when I should raise an error versus when I should just let it fall through, but this is how it is for now. You''ll need the latest windows-pr from CVS, btw. Regards, Dan PS - Where should I put it? In Windows::File directly? In a separate helper module? require ''windows/file'' require ''windows/file_mapping'' require ''windows/volume'' require ''windows/process'' require ''windows/limits'' require ''windows/handle'' require ''windows/error'' require ''windows/memory'' include Windows::File include Windows::FileMapping include Windows::Volume include Windows::Process include Windows::Limits include Windows::Handle include Windows::Error include Windows::Memory # The buf, buf_size, and flags arguments are ignored, but are # present in order to keep the function parameters identical # to the function defined for Windows Vista and later. # def GetFinalPathNameByHandle(handle, buf, buf_size, flags) size_ptr = [0].pack(''Q'') unless GetFileSizeEx(handle, size_ptr) raise get_last_error end if size_ptr.unpack(''Q'')[0] <= 0 raise ''file size must be greater than zero'' end map = CreateFileMapping(handle, nil, PAGE_READONLY, 0, 1, nil) final_path = nil if map && map > 0 pmem = MapViewOfFile(map, FILE_MAP_READ, 0, 0, 1) if pmem begin buf = 0.chr * MAXPATH # Buf will contain the full path, but with the device name instead # of the drive letter that we ultimately want. if GetMappedFileName(GetCurrentProcess(), pmem, buf, MAXPATH) > 0 buf.strip! dbuf = 0.chr * 512 # Get a list of logical devices if GetLogicalDriveStrings(dbuf.size, dbuf) > 0 devices = dbuf.split("\0") devices.delete_if{ |d| d.empty? || d.size > 3 } # Match the drive letter to a device. Once we find a match to # the device returned by GetMappedFileName, replace the device # name from our original buffer with the drive letter. devices.each{ |device| name = 0.chr * MAXPATH device.chop! # Remove trailing slash if QueryDosDevice(device, name, name.size) > 0 name.strip! if buf.include?(name) final_path = device << buf[name.length..-1] break end end } end else raise get_last_error end ensure UnmapViewOfFile(pmem) end end else raise get_last_error end final_path end # Test program file = File.join(Dir.pwd, ''test.txt'') handle = CreateFile( file, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, nil, OPEN_ALWAYS, nil, nil ) if handle == INVALID_HANDLE_VALUE raise get_last_error end p GetFinalPathNameByHandle(handle, nil, nil, nil) CloseHandle(handle)
Heesob Park
2008-Nov-25 02:06 UTC
[Win32utils-devel] GetFinalPathNameByHandle for XP and earlier
Hi, 2008/11/22 Daniel Berger <djberg96 at gmail.com>:> Hi all, > > How''s this look? I based it on > http://msdn.microsoft.com/en-us/library/aa366789(VS.85).aspx. > > I''m undecided as to when I should raise an error versus when I should just > let it fall through, but this is how it is for now. > > You''ll need the latest windows-pr from CVS, btw. >I remembered that this issue was discussed at May, 2008. Why not use my code in http://rubyforge.org/pipermail/win32utils-devel/2008-May/001091.html ? Regards, Park Heesob
Daniel Berger
2008-Nov-25 04:45 UTC
[Win32utils-devel] GetFinalPathNameByHandle for XP and earlier
Heesob Park wrote:> Hi, > > 2008/11/22 Daniel Berger <djberg96 at gmail.com>: >> Hi all, >> >> How''s this look? I based it on >> http://msdn.microsoft.com/en-us/library/aa366789(VS.85).aspx. >> >> I''m undecided as to when I should raise an error versus when I should just >> let it fall through, but this is how it is for now. >> >> You''ll need the latest windows-pr from CVS, btw. >> > I remembered that this issue was discussed at May, 2008. > > Why not use my code in > http://rubyforge.org/pipermail/win32utils-devel/2008-May/001091.html ?You know, I thought we had talked about it, but when I searched I couldn''t find it. Obviously I didn''t try hard enough. Thanks. I like your implementation better. :) Regards, Dan