Berger, Daniel
2008-Apr-30 19:13 UTC
[Win32utils-devel] Playing with NtQueryInformationFile
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? Thanks, Dan This communication is the property of Qwest and may contain confidential or privileged information. Unauthorized use of this communication is strictly prohibited and may be unlawful. If you have received this communication in error, please immediately notify the sender by reply e-mail and destroy all copies of the communication and any attachments.
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
Berger, Daniel
2008-May-06 19:39 UTC
[Win32utils-devel] Playing with NtQueryInformationFile
> -----Original Message----- > From: win32utils-devel-bounces at rubyforge.org > [mailto:win32utils-devel-bounces at rubyforge.org] On Behalf Of > Heesob Park > Sent: Wednesday, April 30, 2008 6:42 PM > To: Development and ideas for win32utils projects > Subject: Re: [Win32utils-devel] Playing with NtQueryInformationFile > > 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%20Fu > nctions/NT%20Objects/File/FILE_INFORMATION_CLASS.htmlMany thanks, that works. The AllocationSize returns the sectors, but I don''t see a structure that gives me bytes per sector. Or is it always 512? Thanks, Dan This communication is the property of Qwest and may contain confidential or privileged information. Unauthorized use of this communication is strictly prohibited and may be unlawful. If you have received this communication in error, please immediately notify the sender by reply e-mail and destroy all copies of the communication and any attachments.
Berger, Daniel
2008-May-06 20:24 UTC
[Win32utils-devel] Playing with NtQueryInformationFile
<snip>> The AllocationSize returns the sectors, but I don''t see a > structure that gives me bytes per sector. Or is it always 512?Hm, I think I can get this with DeviceIoControl + IOCTL_DISK_GET_DRIVE_GEOMETRY actually. Regards, Dan This communication is the property of Qwest and may contain confidential or privileged information. Unauthorized use of this communication is strictly prohibited and may be unlawful. If you have received this communication in error, please immediately notify the sender by reply e-mail and destroy all copies of the communication and any attachments.
Hi, 2008/5/7 Berger, Daniel <Daniel.Berger at qwest.com>:> ><snip>> Many thanks, that works. > > The AllocationSize returns the sectors, but I don''t see a structure that > gives me bytes per sector. Or is it always 512? > >The AllocationSize returns not sectors but bytes. In my case, it returns 4096. A file has two size. One is actual file size and the other is disk allocation size. Why do you want to get allocation size? Regards, Park Heesob
Daniel Berger
2008-May-07 11:57 UTC
[Win32utils-devel] Playing with NtQueryInformationFile
On Wed, May 7, 2008 at 12:51 AM, Heesob Park <phasis at gmail.com> wrote:> Hi, > > 2008/5/7 Berger, Daniel <Daniel.Berger at qwest.com>: > > > > > <snip> > > > Many thanks, that works. > > > > The AllocationSize returns the sectors, but I don''t see a structure that > > gives me bytes per sector. Or is it always 512? > > > > > The AllocationSize returns not sectors but bytes. > In my case, it returns 4096. > > A file has two size. One is actual file size and the other is disk > allocation size. > Why do you want to get allocation size?I''m trying to get File::Stat#blksize working. It''s easy enough when I have the file _name_, but I''d like to get it from the file _handle_ so I can make it work properly. Regards, Dan
Hi, ----- Original Message ----- From: "Daniel Berger" <djberg96 at gmail.com> To: "Development and ideas for win32utils projects" <win32utils-devel at rubyforge.org> Sent: Wednesday, May 07, 2008 8:57 PM Subject: Re: [Win32utils-devel] Playing with NtQueryInformationFile> On Wed, May 7, 2008 at 12:51 AM, Heesob Park <phasis at gmail.com> wrote: >> Hi, >> >> 2008/5/7 Berger, Daniel <Daniel.Berger at qwest.com>: >> > >> > >> <snip> >> >> > Many thanks, that works. >> > >> > The AllocationSize returns the sectors, but I don''t see a structure that >> > gives me bytes per sector. Or is it always 512? >> > >> > >> The AllocationSize returns not sectors but bytes. >> In my case, it returns 4096. >> >> A file has two size. One is actual file size and the other is disk >> allocation size. >> Why do you want to get allocation size? > > I''m trying to get File::Stat#blksize working. It''s easy enough when I > have the file _name_, but I''d like to get it from the file _handle_ so > I can make it work properly. >You must need some function like ''handle_to_fn''. It can be implemented using NtQueryObject with ObjectNameInformation. Regards, Park Heesob
Berger, Daniel
2008-May-07 14:16 UTC
[Win32utils-devel] Playing with NtQueryInformationFile
> -----Original Message----- > From: win32utils-devel-bounces at rubyforge.org > [mailto:win32utils-devel-bounces at rubyforge.org] On Behalf Of > Park Heesob > Sent: Wednesday, May 07, 2008 7:19 AM > To: Development and ideas for win32utils projects > Subject: Re: [Win32utils-devel] Playing with NtQueryInformationFile > > Hi, > ----- Original Message ----- > From: "Daniel Berger" <djberg96 at gmail.com> > To: "Development and ideas for win32utils projects" > <win32utils-devel at rubyforge.org> > Sent: Wednesday, May 07, 2008 8:57 PM > Subject: Re: [Win32utils-devel] Playing with NtQueryInformationFile > > > > On Wed, May 7, 2008 at 12:51 AM, Heesob Park > <phasis at gmail.com> wrote: > >> Hi, > >> > >> 2008/5/7 Berger, Daniel <Daniel.Berger at qwest.com>: > >> > > >> > > >> <snip> > >> > >> > Many thanks, that works. > >> > > >> > The AllocationSize returns the sectors, but I don''t see > a structure that > >> > gives me bytes per sector. Or is it always 512? > >> > > >> > > >> The AllocationSize returns not sectors but bytes. > >> In my case, it returns 4096. > >> > >> A file has two size. One is actual file size and the other is disk > >> allocation size. > >> Why do you want to get allocation size? > > > > I''m trying to get File::Stat#blksize working. It''s easy > enough when I > > have the file _name_, but I''d like to get it from the file > _handle_ so > > I can make it work properly. > > > You must need some function like ''handle_to_fn''. > It can be implemented using NtQueryObject with ObjectNameInformation.I messed around with it a little bit but couldn''t quite make it work. Do you have a code sample? Thanks, Dan This communication is the property of Qwest and may contain confidential or privileged information. Unauthorized use of this communication is strictly prohibited and may be unlawful. If you have received this communication in error, please immediately notify the sender by reply e-mail and destroy all copies of the communication and any attachments.
----- Original Message ----- From: "Berger, Daniel" <Daniel.Berger at qwest.com> To: "Development and ideas for win32utils projects" <win32utils-devel at rubyforge.org> Sent: Wednesday, May 07, 2008 11:16 PM Subject: Re: [Win32utils-devel] Playing with NtQueryInformationFile> > >> -----Original Message----- >> From: win32utils-devel-bounces at rubyforge.org >> [mailto:win32utils-devel-bounces at rubyforge.org] On Behalf Of >> Park Heesob >> Sent: Wednesday, May 07, 2008 7:19 AM >> To: Development and ideas for win32utils projects >> Subject: Re: [Win32utils-devel] Playing with NtQueryInformationFile >> >> Hi, >> ----- Original Message ----- >> From: "Daniel Berger" <djberg96 at gmail.com> >> To: "Development and ideas for win32utils projects" >> <win32utils-devel at rubyforge.org> >> Sent: Wednesday, May 07, 2008 8:57 PM >> Subject: Re: [Win32utils-devel] Playing with NtQueryInformationFile >> >> >> > On Wed, May 7, 2008 at 12:51 AM, Heesob Park >> <phasis at gmail.com> wrote: >> >> Hi, >> >> >> >> 2008/5/7 Berger, Daniel <Daniel.Berger at qwest.com>: >> >> > >> >> > >> >> <snip> >> >> >> >> > Many thanks, that works. >> >> > >> >> > The AllocationSize returns the sectors, but I don''t see >> a structure that >> >> > gives me bytes per sector. Or is it always 512? >> >> > >> >> > >> >> The AllocationSize returns not sectors but bytes. >> >> In my case, it returns 4096. >> >> >> >> A file has two size. One is actual file size and the other is disk >> >> allocation size. >> >> Why do you want to get allocation size? >> > >> > I''m trying to get File::Stat#blksize working. It''s easy >> enough when I >> > have the file _name_, but I''d like to get it from the file >> _handle_ so >> > I can make it work properly. >> > >> You must need some function like ''handle_to_fn''. >> It can be implemented using NtQueryObject with ObjectNameInformation. > > I messed around with it a little bit but couldn''t quite make it work. Do > you have a code sample? >Here is a sample code: require ''windows/handle'' require ''windows/unicode'' require ''windows/error'' include Windows::Handle include Windows::Unicode include Windows::Error NtQueryObject = API.new(''NtQueryObject'', ''LLPLP'', ''L'',''ntdll'') ObjectNameInformation = 1 fh = File.open(''test.txt'', ''r'') handle = get_osfhandle(fh.fileno) MAX_PATH = 256 object_name_information = 0.chr * (8 + MAX_PATH*2) status = NtQueryObject.call( handle, ObjectNameInformation, object_name_information, object_name_information.size, 0 ) puts wide_to_multi(object_name_information[8..-1]) fh.close Regards, Park Heesob