Class: OpenC3::Win32

Inherits:
Object show all
Defined in:
lib/openc3/win32/win32.rb,
lib/openc3/win32/win32_main.rb

Overview

Win32 class

This class implements the Win32

Constant Summary collapse

BOOL =

Data Types

'i'
BYTE =
'C'
DWORD =
'L'
HANDLE =
'L'
LP =
'P'
LPSECURITY_ATTRIBUTES =
DWORD
NULL =

Misc Constants

0
INVALID_HANDLE_VALUE =
-1
GENERIC_READ =

Generic Rights (WinNT.h)

0x80000000
GENERIC_WRITE =
0x40000000
GENERIC_EXECUTE =
0x20000000
GENERIC_ALL =
0x10000000
FILE_UNSHARED =

File Sharing (WinNT.h)

0x00000000
FILE_SHARE_READ =

not defined in WinNT.h

0x00000001
FILE_SHARE_WRITE =
0x00000002
FILE_SHARE_DELETE =
0x00000004
CREATE_NEW =

File Open Options (WinBase.h)

1
CREATE_ALWAYS =
2
OPEN_EXISTING =
3
OPEN_ALWAYS =
4
TRUNCATE_EXISTING =
5
FILE_ATTRIBUTE_READONLY =

File Attributes (WinNT.h)

0x00000001
FILE_ATTRIBUTE_HIDDEN =
0x00000002
FILE_ATTRIBUTE_SYSTEM =
0x00000004
FILE_ATTRIBUTE_DIRECTORY =
0x00000010
FILE_ATTRIBUTE_ARCHIVE =
0x00000020
FILE_ATTRIBUTE_DEVICE =
0x00000040
FILE_ATTRIBUTE_NORMAL =
0x00000080
FILE_ATTRIBUTE_TEMPORARY =
0x00000100
FILE_ATTRIBUTE_SPARSE_FILE =
0x00000200
FILE_ATTRIBUTE_REPARSE_POINT =
0x00000400
FILE_ATTRIBUTE_COMPRESSED =
0x00000800
FILE_ATTRIBUTE_OFFLINE =
0x00001000
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED =
0x00002000
FILE_ATTRIBUTE_ENCRYPTED =
0x00004000
FILE_ATTRIBUTE_VIRTUAL =
0x00010000
CBR_110 =

Baud Rates

110
CBR_300 =
300
CBR_600 =
600
CBR_1200 =
1200
CBR_2400 =
2400
CBR_4800 =
4800
CBR_9600 =
9600
CBR_14400 =
14400
CBR_19200 =
19200
CBR_38400 =
38400
CBR_56000 =
56000
CBR_57600 =
57600
CBR_115200 =
115200
CBR_128000 =
128000
CBR_256000 =
256000
BAUD_RATES =
[
  CBR_110, CBR_300, CBR_600, CBR_1200, CBR_2400, CBR_4800, CBR_9600,
  CBR_14400, CBR_19200, CBR_38400, CBR_56000, CBR_57600, CBR_115200,
  CBR_128000, CBR_256000, 230400, 460800, 500000, 576000, 921600,
  1000000, 1152000, 1500000, 2000000, 3000000, 3500000, 4000000
]
NOPARITY =

Parity

0
ODDPARITY =
1
EVENPARITY =
2
MARKPARITY =
3
SPACEPARITY =
4
PARITY_SETTINGS =
[NOPARITY, ODDPARITY, EVENPARITY, MARKPARITY, SPACEPARITY]
ONESTOPBIT =

Stop Bits

0
ONE5STOPBITS =
1
TWOSTOPBITS =
2
STOP_BIT_SETTINGS =
[ONESTOPBIT, ONE5STOPBITS, TWOSTOPBITS]
IDOK =

Dialog Box Command Ids

1
IDCANCEL =
2
IDABORT =
3
IDRETRY =
4
IDIGNORE =
5
IDYES =
6
IDNO =
7
IDCLOSE =
8
IDHELP =
9
MB_OK =

Message Box Types

0x00000000
MB_OKCANCEL =
0x00000001
MB_ABORTRETRYIGNORE =
0x00000002
MB_YESNOCANCEL =
0x00000003
MB_YESNO =
0x00000004
MB_RETRYCANCEL =
0x00000005
MB_ICONHAND =

Message Box Icons

0x00000010
MB_ICONQUESTION =
0x00000020
MB_ICONEXCLAMATION =
0x00000030
MB_ICONASTERISK =
0x00000040
HEAP_COMPATIBILITY_INFORMATION =

Heap Information Types

0
HEAP_ENABLE_TERMINATION_ON_CORRUPTION =
1
HEAP_STANDARD =

Heap Information Values

0
HEAP_LOOKASIDE =
1
HEAP_LOW_FRAGMENTATION =
2
OFN_READONLY =

Open Filename Constants

0x00000001
OFN_OVERWRITEPROMPT =
0x00000002
OFN_HIDEREADONLY =
0x00000004
OFN_NOCHANGEDIR =
0x00000008
OFN_SHOWHELP =
0x00000010
OFN_ENABLEHOOK =
0x00000020
OFN_ENABLETEMPLATE =
0x00000040
OFN_ENABLETEMPLATEHANDLE =
0x00000080
OFN_NOVALIDATE =
0x00000100
OFN_ALLOWMULTISELECT =
0x00000200
OFN_EXTENSIONDIFFERENT =
0x00000400
OFN_PATHMUSTEXIST =
0x00000800
OFN_FILEMUSTEXIST =
0x00001000
OFN_CREATEPROMPT =
0x00002000
OFN_SHAREAWARE =
0x00004000
OFN_NOREADONLYRETURN =
0x00008000
OFN_NOTESTFILECREATE =
0x00010000
OFN_NONETWORKBUTTON =
0x00020000
OFN_NOLONGNAMES =
0x00040000
OFN_EXPLORER =
0x00080000
0x00100000
OFN_LONGNAMES =
0x00200000
OFN_ENABLEINCLUDENOTIFY =
0x00400000
OFN_ENABLESIZING =
0x00800000
OFN_DONTADDTORECENT =
0x02000000
OFN_FORCESHOWHIDDEN =
0x10000000
OFN_EX_NOPLACESBAR =
0x00000001
FORMAT_MESSAGE_ALLOCATE_BUFFER =

Format Message Settings

0x00000100
FORMAT_MESSAGE_IGNORE_INSERTS =
0x00000200
FORMAT_MESSAGE_FROM_STRING =
0x00000400
FORMAT_MESSAGE_FROM_HMODULE =
0x00000800
FORMAT_MESSAGE_FROM_SYSTEM =
0x00001000
FORMAT_MESSAGE_ARGUMENT_ARRAY =
0x00002000
FORMAT_MESSAGE_MAX_WIDTH_MASK =
0x000000FF
LANG_NEUTRAL =

Primary Language Ids

0x00
SUBLANG_DEFAULT =

Sub Language Ids

0x01
SUBLANG_SYS_DEFAULT =
0x02

Class Method Summary collapse

Class Method Details

.build_comm_timeouts(read_interval_timeout = 4294967295, read_total_timeout_multiplier = 0, read_total_timeout_constant = 0, write_total_timeout_multiplier = 0, write_total_timeout_constant = 0) ⇒ Object



130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/openc3/win32/win32.rb', line 130

def self.build_comm_timeouts(read_interval_timeout = 4294967295, read_total_timeout_multiplier = 0, read_total_timeout_constant = 0, write_total_timeout_multiplier = 0, write_total_timeout_constant = 0)
  comm_timeouts = Structure.new(:LITTLE_ENDIAN)
  comm_timeouts.append_item('ReadIntervalTimeout', 32, :UINT)
  comm_timeouts.append_item('ReadTotalTimeoutMultiplier', 32, :UINT)
  comm_timeouts.append_item('ReadTotalTimeoutConstant', 32, :UINT)
  comm_timeouts.append_item('WriteTotalTimeoutMultiplier', 32, :UINT)
  comm_timeouts.append_item('WriteTotalTimeoutConstant', 32, :UINT)
  comm_timeouts.write('ReadIntervalTimeout', read_interval_timeout)
  comm_timeouts.write('ReadTotalTimeoutMultiplier', read_total_timeout_multiplier)
  comm_timeouts.write('ReadTotalTimeoutConstant', read_total_timeout_constant)
  comm_timeouts.write('WriteTotalTimeoutMultiplier', write_total_timeout_multiplier)
  comm_timeouts.write('WriteTotalTimeoutConstant', write_total_timeout_constant)
  comm_timeouts
end

.build_dcbObject



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/openc3/win32/win32.rb', line 96

def self.build_dcb
  dcb = Structure.new(:LITTLE_ENDIAN)
  dcb.define_item('DCBlength', 0, 32, :UINT)
  dcb.define_item('BaudRate',  32, 32, :UINT)
  dcb.define_item('fBinary', 71, 1, :UINT)
  dcb.define_item('fParity', 70, 1, :UINT)
  dcb.define_item('fOutxCtsFlow', 69, 1, :UINT)
  dcb.define_item('fOutxDsrFlow', 68, 1, :UINT)
  dcb.define_item('fDtrControl', 66, 2, :UINT)
  dcb.define_item('fDsrSensitivity', 65, 1, :UINT)
  dcb.define_item('fTXContinueOnXoff', 64, 1, :UINT)
  dcb.define_item('fOutX', 79, 1, :UINT)
  dcb.define_item('fInX', 78, 1, :UINT)
  dcb.define_item('fErrorChar', 77, 1, :UINT)
  dcb.define_item('fNull', 76, 1, :UINT)
  dcb.define_item('fRtsControl', 74, 2, :UINT)
  dcb.define_item('fAbortOnError', 73, 1, :UINT)
  dcb.define_item('fDummy2', 88, 17, :UINT)
  dcb.define_item('wReserved', 96, 16, :UINT)
  dcb.define_item('XonLim', 112, 16, :UINT)
  dcb.define_item('XoffLim', 128, 16, :UINT)
  dcb.define_item('ByteSize', 144, 8, :UINT)
  dcb.define_item('Parity', 152, 8, :UINT)
  dcb.define_item('StopBits', 160, 8, :UINT)
  dcb.define_item('XonChar', 168, 8, :INT)
  dcb.define_item('XoffChar', 176, 8, :INT)
  dcb.define_item('ErrorChar', 184, 8, :INT)
  dcb.define_item('EofChar', 192, 8, :INT)
  dcb.define_item('EvtChar', 200, 8, :INT)
  dcb.define_item('wReserved1',   208, 16, :UINT)
  dcb.write('DCBlength', 28)
  dcb
end

.close_handle(handle) ⇒ Object

Close a file



35
36
37
38
39
40
41
# File 'lib/openc3/win32/win32.rb', line 35

def self.close_handle(handle)
  api = Win32API.new('Kernel32', 'CloseHandle', [HANDLE], BOOL)
  result = api.call(handle)
  raise "Error closing handle: #{get_last_error_message()}" if result == 0

  result
end

.computer_nameObject

Returns the computer name



287
288
289
290
291
292
# File 'lib/openc3/win32/win32_main.rb', line 287

def self.computer_name
  name = ' ' * 128
  size = [name.length].pack('i')
  Win32API.new('kernel32', 'GetComputerName', ['P', 'P'], 'I').call(name, size)
  name.unpack('A*')[0]
end

.create_file(filename, desired_access, share_mode, security_attributes, creation_disposition, flags_and_attributes, template_file = NULL) ⇒ Object

Create a file



25
26
27
28
29
30
31
32
# File 'lib/openc3/win32/win32.rb', line 25

def self.create_file(filename, desired_access, share_mode, security_attributes, creation_disposition, flags_and_attributes, template_file = NULL)
  api = Win32API.new('Kernel32', 'CreateFile', [LP, DWORD, DWORD, LP, DWORD, DWORD, HANDLE], HANDLE)

  handle = api.call(filename, desired_access, share_mode, security_attributes, creation_disposition, flags_and_attributes, template_file)
  raise "Error during CreateFile: #{get_last_error_message()}" if handle == INVALID_HANDLE_VALUE

  handle
end

.enable_low_fragmentation_heap(heap_handle) ⇒ Object

Enable the Low Fragmentation Heap



325
326
327
328
329
# File 'lib/openc3/win32/win32_main.rb', line 325

def self.enable_low_fragmentation_heap(heap_handle)
  heap_set_information(heap_handle, HEAP_COMPATIBILITY_INFORMATION, HEAP_LOW_FRAGMENTATION)
  heap_info = heap_query_information(heap_handle, HEAP_COMPATIBILITY_INFORMATION)
  raise "Unable to enable Low Fragmentation Heap" if heap_info != HEAP_LOW_FRAGMENTATION
end

.format_message(flags, source, message_id, language_id) ⇒ Object

Formats a message



268
269
270
271
272
273
274
275
276
277
# File 'lib/openc3/win32/win32_main.rb', line 268

def self.format_message(flags, source, message_id, language_id)
  buffer = ' ' * 1024
  api = Win32API.new('Kernel32', 'FormatMessage', [DWORD, LP, DWORD, DWORD, LP, DWORD, LP], DWORD)
  buffer_length = api.call(flags, source, message_id, language_id, buffer, buffer.length, NULL)
  if buffer_length == 0
    ''
  else
    buffer[0..(buffer_length - 1)]
  end
end

.get_comm_state(handle) ⇒ Object

Get Comm State



44
45
46
47
48
49
50
51
# File 'lib/openc3/win32/win32.rb', line 44

def self.get_comm_state(handle)
  dcb = build_dcb()
  api = Win32API.new('Kernel32', 'GetCommState', [HANDLE, LP], BOOL)
  result = api.call(handle, dcb.buffer)
  raise "GetCommState Error: #{get_last_error_message()}" if result == 0

  dcb
end

.get_foreground_windowObject

Gets the window handle for the foreground window or NULL



258
259
260
# File 'lib/openc3/win32/win32_main.rb', line 258

def self.get_foreground_window
  Win32API.new('user32', 'GetForegroundWindow', [], 'I').call()
end

.get_last_errorObject

Gets the error code of the most recent error



263
264
265
# File 'lib/openc3/win32/win32_main.rb', line 263

def self.get_last_error
  Win32API.new("Kernel32", "GetLastError", [], "I").call
end

.get_last_error_messageObject

Gets the error message from the last error



280
281
282
283
284
# File 'lib/openc3/win32/win32_main.rb', line 280

def self.get_last_error_message
  last_error = Win32.get_last_error
  language_id = Win32.make_lang_id(LANG_NEUTRAL, SUBLANG_DEFAULT)
  Win32.format_message(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, last_error, language_id)
end

.get_process_heapObject

Get the Process’s Heap Handle



303
304
305
# File 'lib/openc3/win32/win32_main.rb', line 303

def self.get_process_heap
  Win32API.new('Kernel32', 'GetProcessHeap', [], 'i').call
end

.heap_query_information(heap_handle, heap_information_type) ⇒ Object

Get Heap Information



316
317
318
319
320
321
322
# File 'lib/openc3/win32/win32_main.rb', line 316

def self.heap_query_information(heap_handle, heap_information_type)
  heap_info = ' ' * 8
  size      = ' ' * 8
  api = Win32API.new('Kernel32', 'HeapQueryInformation', ['i', 'i', 'P', 'i', 'P'], 'i')
  api.call(heap_handle, heap_information_type, heap_info, heap_info.length, size)
  heap_info.unpack("i")[0]
end

.heap_set_information(heap_handle, heap_information_type, value) ⇒ Object

Set Heap Information



308
309
310
311
312
313
# File 'lib/openc3/win32/win32_main.rb', line 308

def self.heap_set_information(heap_handle, heap_information_type, value)
  heap_info = [value].pack('i')
  api = Win32API.new('Kernel32', 'HeapSetInformation', ['i', 'i', 'P', 'i'], 'i')
  return_value = api.call(heap_handle, heap_information_type, heap_info, heap_info.length)
  raise "HeapSetInformation Error: #{get_last_error_message()}" if return_value == 0
end

.make_lang_id(primary_language_id, sub_language_id) ⇒ Object

Calculate a language id



248
249
250
# File 'lib/openc3/win32/win32_main.rb', line 248

def self.make_lang_id(primary_language_id, sub_language_id)
  (sub_language_id << 10) | primary_language_id
end

.message_box(message, title = 'Error', options = 0) ⇒ Object

Creates a Message Box



253
254
255
# File 'lib/openc3/win32/win32_main.rb', line 253

def self.message_box(message, title = 'Error', options = 0)
  Win32API.new('user32', 'MessageBox', ['L', 'P', 'P', 'L'], 'I').call(0, message, title, options)
end

.read_file(handle, bytes_to_read, overlapped = NULL) ⇒ Object

Read File



73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/openc3/win32/win32.rb', line 73

def self.read_file(handle, bytes_to_read, overlapped = NULL)
  buffer     = ' ' * (bytes_to_read + 1)
  bytes_read = ' ' * 8
  api = Win32API.new('Kernel32', 'ReadFile', [HANDLE, LP, DWORD, LP, LP], BOOL)
  api.call(handle, buffer, bytes_to_read, bytes_read, overlapped)
  bytes_read = bytes_read.unpack(DWORD)[0]
  if bytes_read > 0
    buffer[0..(bytes_read - 1)]
  else
    ''
  end
end

.set_comm_state(handle, dcb) ⇒ Object

Set Comm State



54
55
56
57
58
59
60
# File 'lib/openc3/win32/win32.rb', line 54

def self.set_comm_state(handle, dcb)
  api = Win32API.new('Kernel32', 'SetCommState', [HANDLE, LP], BOOL)
  result = api.call(handle, dcb.buffer)
  raise "SetCommState Error: #{get_last_error_message()}" if result == 0

  result
end

.set_comm_timeouts(handle, read_interval_timeout = 4294967295, read_total_timeout_multiplier = 0, read_total_timeout_constant = 0, write_total_timeout_multiplier = 0, write_total_timeout_constant = 0) ⇒ Object

Set Comm Timeouts - Values in Ms



63
64
65
66
67
68
69
70
# File 'lib/openc3/win32/win32.rb', line 63

def self.set_comm_timeouts(handle, read_interval_timeout = 4294967295, read_total_timeout_multiplier = 0, read_total_timeout_constant = 0, write_total_timeout_multiplier = 0, write_total_timeout_constant = 0)
  comm_timeouts = build_comm_timeouts(read_interval_timeout, read_total_timeout_multiplier, read_total_timeout_constant, write_total_timeout_multiplier, write_total_timeout_constant)
  api = Win32API.new('Kernel32', 'SetCommTimeouts', [HANDLE, LP], BOOL)
  result = api.call(handle, comm_timeouts.buffer)
  raise "SetCommTimeouts Error: #{get_last_error_message()}" if result == 0

  result
end

.user_nameObject

Returns current logged in Windows user name



295
296
297
298
299
300
# File 'lib/openc3/win32/win32_main.rb', line 295

def self.user_name
  name = ' ' * 128
  size = [name.length].pack('i')
  Win32API.new('advapi32', 'GetUserName', ['P', 'P'], 'I').call(name, size)
  name.unpack('A*')[0]
end

.write_file(handle, buffer, bytes_to_write, overlapped = NULL) ⇒ Object

Write File



87
88
89
90
91
92
# File 'lib/openc3/win32/win32.rb', line 87

def self.write_file(handle, buffer, bytes_to_write, overlapped = NULL)
  bytes_written = ' ' * 8
  api = Win32API.new('Kernel32', 'WriteFile', [HANDLE, LP, DWORD, LP, LP], BOOL)
  api.call(handle, buffer, bytes_to_write, bytes_written, overlapped)
  bytes_written.unpack(DWORD)[0]
end