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



135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/openc3/win32/win32.rb', line 135

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



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
129
130
131
132
133
# File 'lib/openc3/win32/win32.rb', line 101

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



40
41
42
43
44
45
46
# File 'lib/openc3/win32/win32.rb', line 40

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



292
293
294
295
296
297
# File 'lib/openc3/win32/win32_main.rb', line 292

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



30
31
32
33
34
35
36
37
# File 'lib/openc3/win32/win32.rb', line 30

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



330
331
332
333
334
# File 'lib/openc3/win32/win32_main.rb', line 330

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



273
274
275
276
277
278
279
280
281
282
# File 'lib/openc3/win32/win32_main.rb', line 273

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



49
50
51
52
53
54
55
56
# File 'lib/openc3/win32/win32.rb', line 49

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



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

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

.get_last_errorObject

Gets the error code of the most recent error



268
269
270
# File 'lib/openc3/win32/win32_main.rb', line 268

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

.get_last_error_messageObject

Gets the error message from the last error



285
286
287
288
289
# File 'lib/openc3/win32/win32_main.rb', line 285

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



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

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

.heap_query_information(heap_handle, heap_information_type) ⇒ Object

Get Heap Information



321
322
323
324
325
326
327
# File 'lib/openc3/win32/win32_main.rb', line 321

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



313
314
315
316
317
318
# File 'lib/openc3/win32/win32_main.rb', line 313

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



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

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



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

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



78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/openc3/win32/win32.rb', line 78

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



59
60
61
62
63
64
65
# File 'lib/openc3/win32/win32.rb', line 59

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



68
69
70
71
72
73
74
75
# File 'lib/openc3/win32/win32.rb', line 68

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



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

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



92
93
94
95
96
97
# File 'lib/openc3/win32/win32.rb', line 92

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