diff options
Diffstat (limited to 'ext/dl/sample')
-rw-r--r-- | ext/dl/sample/drives.rb | 70 | ||||
-rw-r--r-- | ext/dl/sample/getch.rb | 5 | ||||
-rw-r--r-- | ext/dl/sample/libc.rb | 84 | ||||
-rw-r--r-- | ext/dl/sample/msgbox.rb | 19 | ||||
-rw-r--r-- | ext/dl/sample/msgbox2.rb | 18 | ||||
-rw-r--r-- | ext/dl/sample/stream.rb | 87 |
6 files changed, 283 insertions, 0 deletions
diff --git a/ext/dl/sample/drives.rb b/ext/dl/sample/drives.rb new file mode 100644 index 0000000000..8a590404b1 --- /dev/null +++ b/ext/dl/sample/drives.rb @@ -0,0 +1,70 @@ +# -*- ruby -*- +# drives.rb -- find existing drives and show the drive type. + +require 'dl' +require 'dl/import' + +module Kernel32 + extend DL::Importable + + dlload "kernel32" + + extern "long GetLogicalDrives()" + extern "int GetDriveType(char*)" + extern "long GetDiskFreeSpace(char*, long ref, long ref, long ref, long ref)" +end + +include Kernel32 + +buff = Kernel32.getLogicalDrives() + +i = 0 +ds = [] +while( i < 26 ) + mask = (1 << i) + if( buff & mask > 0 ) + ds.push((65+i).chr) + end + i += 1 +end + +=begin +From the cygwin's /usr/include/w32api/winbase.h: +#define DRIVE_UNKNOWN 0 +#define DRIVE_NO_ROOT_DIR 1 +#define DRIVE_REMOVABLE 2 +#define DRIVE_FIXED 3 +#define DRIVE_REMOTE 4 +#define DRIVE_CDROM 5 +#define DRIVE_RAMDISK 6 +=end + +types = [ + "unknown", + "no root dir", + "Removable", + "Fixed", + "Remote", + "CDROM", + "RAM", +] +print("Drive : Type (Free Space/Available Space)\n") +ds.each{|d| + t = Kernel32.getDriveType(d + ":\\") + Kernel32.getDiskFreeSpace(d + ":\\", 0, 0, 0, 0) + _,sec_per_clus,byte_per_sec,free_clus,total_clus = Kernel32._args_ + fbytes = sec_per_clus * byte_per_sec * free_clus + tbytes = sec_per_clus * byte_per_sec * total_clus + unit = "B" + if( fbytes > 1024 && tbytes > 1024 ) + fbytes = fbytes / 1024 + tbytes = tbytes / 1024 + unit = "K" + end + if( fbytes > 1024 && tbytes > 1024 ) + fbytes = fbytes / 1024 + tbytes = tbytes / 1024 + unit = "M" + end + print("#{d} : #{types[t]} (#{fbytes} #{unit}/#{tbytes} #{unit})\n") +} diff --git a/ext/dl/sample/getch.rb b/ext/dl/sample/getch.rb new file mode 100644 index 0000000000..3f7261c979 --- /dev/null +++ b/ext/dl/sample/getch.rb @@ -0,0 +1,5 @@ +require 'dl' + +crtdll = DL::dlopen("crtdll") +getch = crtdll['_getch', 'L'] +print(getch.call, "\n") diff --git a/ext/dl/sample/libc.rb b/ext/dl/sample/libc.rb new file mode 100644 index 0000000000..c88fc687f2 --- /dev/null +++ b/ext/dl/sample/libc.rb @@ -0,0 +1,84 @@ +require 'dl' + +module LIBC + begin + LIB = DL.dlopen('libc.so.6') + rescue RuntimeError + LIB = DL.dlopen('libc.so.5') + end + + SYM = { + :atoi => LIB['atoi', 'IS'], + :isdigit => LIB['isdigit', 'II'], + } + + def atoi(str) + r,rs = SYM[:atoi].call(str) + return r + end + + def isdigit(c) + r,rs = SYM[:isdigit].call(c) + return (r != 0) + end +end + +module LIBC + SYM[:strcat] = LIB['strcat', 'SsS'] + def strcat(str1,str2) + r,rs = SYM[:strcat].call(str1 + "\0#{str2}",str2) + return rs[0] + end +end + +module LIBC + SYM[:fopen] = LIB['fopen', 'PSS'] + SYM[:fclose] = LIB['fclose', '0P'] + SYM[:fgetc] = LIB['fgetc', 'IP'] + + def fopen(filename, mode) + r,rs = SYM[:fopen].call(filename, mode) + return r + end + + def fclose(ptr) + SYM[:fclose].call(ptr) + return nil + end + + def fgetc(ptr) + r,rs = SYM[:fgetc].call(ptr) + return r + end +end + +module LIBC + SYM[:strlen] = LIB['strlen', 'IP'] + def strlen(str) + r,rs = SYM[:strlen].call(str) + return r + end +end + +$cb1 = DL.set_callback('IPP', 0){|ptr1, ptr2| + str1 = ptr1.ptr.to_s + str2 = ptr2.ptr.to_s + str1 <=> str2 +} + +module LIBC + SYM[:qsort] = LIB['qsort', '0aIIP'] + def qsort(ary, comp) + len = ary.length + r,rs = SYM[:qsort].call(ary, len, DL.sizeof('P'), comp) + return rs[0].to_a('S', len) + end +end + +include LIBC + +p atoi("10") +p isdigit(?1) +p isdigit(?a) +p strcat("a", "b") +p qsort(["a","c","b"],$cb1) diff --git a/ext/dl/sample/msgbox.rb b/ext/dl/sample/msgbox.rb new file mode 100644 index 0000000000..091e646091 --- /dev/null +++ b/ext/dl/sample/msgbox.rb @@ -0,0 +1,19 @@ +# This script works on Windows. + +require 'dl' + +User32 = DL.dlopen("user32") +Kernel32 = DL.dlopen("kernel32") + +MB_OK = 0 +MB_OKCANCEL = 1 + +message_box = User32['MessageBoxA', 'ILSSI'] +r,rs = message_box.call(0, 'ok?', 'error', MB_OKCANCEL) + +case r +when 1 + print("OK!\n") +when 2 + print("Cancel!\n") +end diff --git a/ext/dl/sample/msgbox2.rb b/ext/dl/sample/msgbox2.rb new file mode 100644 index 0000000000..e49846cc5e --- /dev/null +++ b/ext/dl/sample/msgbox2.rb @@ -0,0 +1,18 @@ +# This script works on Windows. + +require 'dl/win32' + +MB_OK = 0 +MB_OKCANCEL = 1 + +message_box = Win32API.new("user32",'MessageBoxA', 'ISSI', 'I') +r = message_box.call(0, 'ok?', 'error', MB_OKCANCEL) + +case r +when 1 + print("OK!\n") +when 2 + print("Cancel!\n") +else + p r +end diff --git a/ext/dl/sample/stream.rb b/ext/dl/sample/stream.rb new file mode 100644 index 0000000000..179836999d --- /dev/null +++ b/ext/dl/sample/stream.rb @@ -0,0 +1,87 @@ +# -*- ruby -*- +# Display a file name and stream names of a file with those size. + +require 'dl' +require 'dl/import' + +module NTFS + extend DL::Importable + + dlload "kernel32.dll" + + OPEN_EXISTING = 3 + GENERIC_READ = 0x80000000 + BACKUP_DATA = 0x00000001 + BACKUP_ALTERNATE_DATA = 0x00000004 + FILE_SHARE_READ = 0x00000001 + FILE_FLAG_BACKUP_SEMANTICS = 0x02000000 + + typealias "LPSECURITY_ATTRIBUTES", "void*" + + extern "BOOL BackupRead(HANDLE, PBYTE, DWORD, PDWORD, BOOL, BOOL, PVOID)" + extern "BOOL BackupSeek(HANDLE, DWORD, DWORD, PDWORD, PDWORD, PVOID)" + extern "BOOL CloseHandle(HANDLE)" + extern "HANDLE CreateFile(LPCSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, + DWORD, DWORD, HANDLE)" + + module_function + + def streams(filename) + status = [] + h = createFile(filename,GENERIC_READ,FILE_SHARE_READ,nil, + OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,0) + if( h != 0 ) + begin + # allocate the memory for backup data used in backupRead(). + data = DL.malloc(DL.sizeof("L5")) + data.struct!("LLLLL", :id, :attrs, :size_low, :size_high, :name_size) + + # allocate memories for references to long values used in backupRead(). + context = DL.malloc(DL.sizeof("L")) + lval = DL.malloc(DL.sizeof("L")) + + while( backupRead(h, data, data.size, lval, false, false, context) ) + size = data[:size_low] + (data[:size_high] << (DL.sizeof("I") * 8)) + case data[:id] + when BACKUP_ALTERNATE_DATA + stream_name = DL.malloc(data[:name_size]) + backupRead(h, stream_name, stream_name.size, + lval, false, false, context) + name = stream_name[0, stream_name.size] + name.tr!("\000","") + if( name =~ /^:(.*?):.*$/ ) + status.push([$1,size]) + end + when BACKUP_DATA + status.push([nil,size]) + else + raise(RuntimeError, "unknown data type #{data[:id]}.") + end + l1 = DL.malloc(DL.sizeof("L")) + l2 = DL.malloc(DL.sizeof("L")) + if( !backupSeek(h, data[:size_low], data[:size_high], l1, l2, context) ) + break + end + end + ensure + backupRead(h, nil, 0, lval, true, false, context) + closeHandle(h) + end + return status + else + raise(RuntimeError, "can't open #{filename}.\n") + end + end +end + +ARGV.each{|filename| + if( File.exist?(filename) ) + NTFS.streams(filename).each{|name,size| + if( name ) + print("#{filename}:#{name}\t#{size}bytes\n") + else + print("#{filename}\t#{size}bytes\n") + end + } + end +} |