[Win32utils-devel] Playing with NtQueryInformationFile

Heesob Park phasis at gmail.com
Wed Apr 30 20:41:42 EDT 2008


Hi,

2008/5/1 Berger, Daniel <Daniel.Berger at qwest.com>:
> Hi all,
>
> I'm trying to get the allocation size of a file via a file handle
> (rather than its name). The example below works for FileNameInformation
> but I can't get it to work as expected for FileStandardInformation.
>
> Here's some sample code:
>
> # query_test.rb
> require 'windows/handle'
> require 'windows/error'
> include Windows::Handle
> include Windows::Error
>
> NtQueryInformationFile = API.new('NtQueryInformationFile', 'LPPLL', 'L',
> 'ntdll')
>
> # http://msdn.microsoft.com/en-us/library/cc232064.aspx
> FileNameInformation     = 9
> FileStandardInformation = 5
> STATUS_SUCCESS          = 0
>
> fh = File.open('test.txt', 'w')
> fh.puts "hello"
>
> handle = get_osfhandle(fh.fileno)
>
> if handle == INVALID_HANDLE_VALUE
>   puts "ERROR, get_osfhandle() : " + get_last_error
>   fh.close rescue nil
>   File.delete('test.txt')
>   exit
> end
>
> # Excessive but harmless (?)
> io_status_block  = 0.chr * 512
> file_information = 0.chr * 512
>
> status = NtQueryInformationFile.call(
>   handle,
>   io_status_block,
>   file_information,
>   file_information.size,
>   # FileStandardInformation # Doesn't work as expected
>   FileNameInformation       # But this does
> )
>
> if status != STATUS_SUCCESS
>   puts "ERROR, NtQueryInformationFile() : #{status}"
>   fh.close
>   File.delete('test.txt')
>   exit
> end
>
> # p file_information[0, 8].unpack('L')[0] # Zero ??? # Use with
> FileStandardInformation
>
> p file_information[0,4].unpack('L')[0] / 2 # Unicode
> p file_information[4,file_information.length].tr("\000",'').strip
>
> fh.close
>
> # end query_test.rb
>
> The above will print the file name (without the drive letter) as well as
> the length of the file name, which varies depending on whatever path you
> created 'test.txt' on.
>
> However, if I try to replace "FileNameInformation" with
> "FileStandardInformation" and inspect the first 8 bytes of
> file_information (the AllocationSize), it's always zero. The only thing
> I get out of the buffer at all is the NumberOfLinks, which is always 1.
>
> What am I doing wrong?
>

Insert fh.flush atfer fh.puts "hello" must be required.
Following code will work for you:

fh = File.open('test.txt', 'w')
fh.puts "hello"
fh.flush
handle = get_osfhandle(fh.fileno)
io_status_block  = 0.chr * 8
file_information = 0.chr * 0x18
status = NtQueryInformationFile.call(
   handle,
   io_status_block,
   file_information,
   file_information.size,
   FileStandardInformation
)

For the actual buffer size, Reter to

http://undocumented.ntinternals.net/
http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/File/FILE_INFORMATION_CLASS.html

Regards,

Park Heesob


More information about the win32utils-devel mailing list