DEFINITIONS
This source file includes following functions.
1 # -*- ruby -*-
2 # Display a file name and stream names of a file with those size.
3
4 require 'dl'
5 require 'dl/import'
6
7 module NTFS
8 extend DL::Importable
9
10 dlload "kernel32.dll"
11
12 OPEN_EXISTING = 3
13 GENERIC_READ = 0x80000000
14 BACKUP_DATA = 0x00000001
15 BACKUP_ALTERNATE_DATA = 0x00000004
16 FILE_SHARE_READ = 0x00000001
17 FILE_FLAG_BACKUP_SEMANTICS = 0x02000000
18
19 typealias "LPSECURITY_ATTRIBUTES", "void*"
20
21 extern "BOOL BackupRead(HANDLE, PBYTE, DWORD, PDWORD, BOOL, BOOL, PVOID)"
22 extern "BOOL BackupSeek(HANDLE, DWORD, DWORD, PDWORD, PDWORD, PVOID)"
23 extern "BOOL CloseHandle(HANDLE)"
24 extern "HANDLE CreateFile(LPCSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES,
25 DWORD, DWORD, HANDLE)"
26
27 module_function
28
29 def streams(filename)
30 status = []
31 h = createFile(filename,GENERIC_READ,FILE_SHARE_READ,nil,
32 OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,0)
33 if( h != 0 )
34 begin
35 # allocate the memory for backup data used in backupRead().
36 data = DL.malloc(DL.sizeof("L5"))
37 data.struct!("LLLLL", :id, :attrs, :size_low, :size_high, :name_size)
38
39 # allocate memories for references to long values used in backupRead().
40 context = DL.malloc(DL.sizeof("L"))
41 lval = DL.malloc(DL.sizeof("L"))
42
43 while( backupRead(h, data, data.size, lval, false, false, context) )
44 size = data[:size_low] + (data[:size_high] << (DL.sizeof("I") * 8))
45 case data[:id]
46 when BACKUP_ALTERNATE_DATA
47 stream_name = DL.malloc(data[:name_size])
48 backupRead(h, stream_name, stream_name.size,
49 lval, false, false, context)
50 name = stream_name[0, stream_name.size]
51 name.tr!("\000","")
52 if( name =~ /^:(.*?):.*$/ )
53 status.push([$1,size])
54 end
55 when BACKUP_DATA
56 status.push([nil,size])
57 else
58 raise(RuntimeError, "unknown data type #{data[:id]}.")
59 end
60 l1 = DL.malloc(DL.sizeof("L"))
61 l2 = DL.malloc(DL.sizeof("L"))
62 if( !backupSeek(h, data[:size_low], data[:size_high], l1, l2, context) )
63 break
64 end
65 end
66 ensure
67 backupRead(h, nil, 0, lval, true, false, context)
68 closeHandle(h)
69 end
70 return status
71 else
72 raise(RuntimeError, "can't open #{filename}.\n")
73 end
74 end
75 end
76
77 ARGV.each{|filename|
78 if( File.exist?(filename) )
79 NTFS.streams(filename).each{|name,size|
80 if( name )
81 print("#{filename}:#{name}\t#{size}bytes\n")
82 else
83 print("#{filename}\t#{size}bytes\n")
84 end
85 }
86 end
87 }