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