pdk 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +50 -0
- data/README.md +3 -9
- data/exe/pdk +1 -1
- data/lib/pdk.rb +5 -4
- data/lib/pdk/cli.rb +62 -59
- data/lib/pdk/cli/errors.rb +1 -1
- data/lib/pdk/cli/exec.rb +154 -29
- data/lib/pdk/cli/input.rb +2 -2
- data/lib/pdk/cli/new.rb +12 -27
- data/lib/pdk/cli/new/class.rb +28 -41
- data/lib/pdk/cli/new/module.rb +30 -41
- data/lib/pdk/cli/test.rb +9 -20
- data/lib/pdk/cli/test/unit.rb +38 -0
- data/lib/pdk/cli/util/option_normalizer.rb +45 -19
- data/lib/pdk/cli/util/option_validator.rb +24 -20
- data/lib/pdk/cli/validate.rb +65 -65
- data/lib/pdk/generate.rb +5 -0
- data/lib/pdk/generators/module.rb +37 -33
- data/lib/pdk/generators/puppet_class.rb +1 -1
- data/lib/pdk/generators/puppet_object.rb +19 -20
- data/lib/pdk/logger.rb +1 -1
- data/lib/pdk/module/metadata.rb +35 -18
- data/lib/pdk/module/templatedir.rb +40 -33
- data/lib/pdk/report.rb +76 -19
- data/lib/pdk/report/event.rb +276 -0
- data/lib/pdk/template_file.rb +8 -6
- data/lib/pdk/tests/unit.rb +8 -3
- data/lib/pdk/util.rb +65 -0
- data/lib/pdk/util/bundler.rb +167 -0
- data/lib/pdk/util/version.rb +34 -0
- data/lib/pdk/validate.rb +3 -4
- data/lib/pdk/validators/base_validator.rb +60 -4
- data/lib/pdk/validators/metadata.rb +29 -0
- data/lib/pdk/validators/puppet/puppet_lint.rb +47 -0
- data/lib/pdk/validators/puppet/puppet_parser.rb +34 -0
- data/lib/pdk/validators/puppet_validator.rb +30 -0
- data/lib/pdk/validators/ruby/rubocop.rb +59 -0
- data/lib/pdk/validators/ruby_validator.rb +29 -0
- data/lib/pdk/version.rb +1 -1
- data/lib/puppet/util/windows.rb +14 -0
- data/lib/puppet/util/windows/api_types.rb +278 -0
- data/lib/puppet/util/windows/file.rb +488 -0
- data/lib/puppet/util/windows/string.rb +16 -0
- data/locales/de/pdk.po +263 -78
- data/locales/pdk.pot +224 -65
- metadata +60 -8
- data/lib/pdk/cli/tests/unit.rb +0 -52
- data/lib/pdk/validators/puppet_lint.rb +0 -17
- data/lib/pdk/validators/puppet_parser.rb +0 -17
- data/lib/pdk/validators/ruby_lint.rb +0 -17
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'pdk'
|
2
|
+
require 'pdk/util'
|
3
|
+
require 'pdk/cli/exec'
|
4
|
+
require 'pdk/validators/base_validator'
|
5
|
+
|
6
|
+
module PDK
|
7
|
+
module Validate
|
8
|
+
class PuppetLint < BaseValidator
|
9
|
+
def self.name
|
10
|
+
'puppet-lint'
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.cmd
|
14
|
+
'puppet-lint'
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.pattern
|
18
|
+
'**/*.pp'
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.spinner_text
|
22
|
+
_('Checking Puppet manifest style')
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.parse_options(_options, targets)
|
26
|
+
cmd_options = ['--json']
|
27
|
+
|
28
|
+
cmd_options.concat(targets)
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.parse_output(report, json_data)
|
32
|
+
json_data.each do |offense|
|
33
|
+
report.add_event(
|
34
|
+
file: offense['path'],
|
35
|
+
source: 'puppet-lint',
|
36
|
+
line: offense['line'],
|
37
|
+
column: offense['column'],
|
38
|
+
message: offense['message'],
|
39
|
+
test: offense['check'],
|
40
|
+
severity: offense['kind'],
|
41
|
+
state: :failure,
|
42
|
+
)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'pdk'
|
2
|
+
require 'pdk/cli/exec'
|
3
|
+
require 'pdk/validators/base_validator'
|
4
|
+
|
5
|
+
module PDK
|
6
|
+
module Validate
|
7
|
+
class PuppetParser < BaseValidator
|
8
|
+
def self.name
|
9
|
+
'puppet-parser'
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.cmd
|
13
|
+
'puppet'
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.pattern
|
17
|
+
'**/**.pp'
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.spinner_text
|
21
|
+
_('Checking Puppet manifest syntax')
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.parse_options(_options, targets)
|
25
|
+
%w[parser validate].concat(targets)
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.parse_output(_report, _json_data)
|
29
|
+
# TODO: handle outputs
|
30
|
+
# report.add_event(result.merge(state: :passed, severity: :ok))
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'pdk'
|
2
|
+
require 'pdk/cli/exec'
|
3
|
+
require 'pdk/validators/base_validator'
|
4
|
+
require 'pdk/validators/puppet/puppet_lint'
|
5
|
+
require 'pdk/validators/puppet/puppet_parser'
|
6
|
+
|
7
|
+
module PDK
|
8
|
+
module Validate
|
9
|
+
class PuppetValidator < BaseValidator
|
10
|
+
def self.name
|
11
|
+
'puppet'
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.puppet_validators
|
15
|
+
[PuppetLint, PuppetParser]
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.invoke(report, options = {})
|
19
|
+
exit_code = 0
|
20
|
+
|
21
|
+
puppet_validators.each do |validator|
|
22
|
+
exit_code = validator.invoke(report, options)
|
23
|
+
break if exit_code != 0
|
24
|
+
end
|
25
|
+
|
26
|
+
exit_code
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'pdk'
|
2
|
+
require 'pdk/cli/exec'
|
3
|
+
require 'pdk/util'
|
4
|
+
require 'pdk/util/bundler'
|
5
|
+
require 'pdk/validators/base_validator'
|
6
|
+
require 'pdk/validators/ruby_validator'
|
7
|
+
|
8
|
+
module PDK
|
9
|
+
module Validate
|
10
|
+
class Rubocop < BaseValidator
|
11
|
+
def self.name
|
12
|
+
'rubocop'
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.cmd
|
16
|
+
'rubocop'
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.spinner_text
|
20
|
+
_('Checking Ruby code style')
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.parse_options(_options, targets)
|
24
|
+
cmd_options = ['--format', 'json']
|
25
|
+
|
26
|
+
cmd_options.concat(targets)
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.parse_output(report, json_data)
|
30
|
+
return unless json_data.key?('files')
|
31
|
+
|
32
|
+
json_data['files'].each do |file_info|
|
33
|
+
next unless file_info.key?('offenses')
|
34
|
+
result = {
|
35
|
+
file: file_info['path'],
|
36
|
+
source: 'rubocop',
|
37
|
+
}
|
38
|
+
|
39
|
+
if file_info['offenses'].empty?
|
40
|
+
report.add_event(result.merge(state: :passed, severity: :ok))
|
41
|
+
else
|
42
|
+
file_info['offenses'].each do |offense|
|
43
|
+
report.add_event(
|
44
|
+
result.merge(
|
45
|
+
line: offense['location']['line'],
|
46
|
+
column: offense['location']['column'],
|
47
|
+
message: offense['message'],
|
48
|
+
severity: offense['severity'],
|
49
|
+
test: offense['cop_name'],
|
50
|
+
state: :failure,
|
51
|
+
),
|
52
|
+
)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'pdk'
|
2
|
+
require 'pdk/cli/exec'
|
3
|
+
require 'pdk/validators/base_validator'
|
4
|
+
require 'pdk/validators/ruby/rubocop'
|
5
|
+
|
6
|
+
module PDK
|
7
|
+
module Validate
|
8
|
+
class RubyValidator < BaseValidator
|
9
|
+
def self.name
|
10
|
+
'ruby'
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.ruby_validators
|
14
|
+
[Rubocop]
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.invoke(report, options = {})
|
18
|
+
exit_code = 0
|
19
|
+
|
20
|
+
ruby_validators.each do |validator|
|
21
|
+
exit_code = validator.invoke(report, options)
|
22
|
+
break if exit_code != 0
|
23
|
+
end
|
24
|
+
|
25
|
+
exit_code
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/pdk/version.rb
CHANGED
@@ -0,0 +1,14 @@
|
|
1
|
+
module Puppet
|
2
|
+
module Util
|
3
|
+
module Windows
|
4
|
+
module File; end
|
5
|
+
|
6
|
+
if Gem.win_platform?
|
7
|
+
# these reference platform specific gems
|
8
|
+
require 'puppet/util/windows/api_types'
|
9
|
+
require 'puppet/util/windows/string'
|
10
|
+
require 'puppet/util/windows/file'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,278 @@
|
|
1
|
+
require 'ffi'
|
2
|
+
require 'puppet/util/windows/string'
|
3
|
+
|
4
|
+
module Puppet::Util::Windows::APITypes
|
5
|
+
module ::FFI
|
6
|
+
WIN32_FALSE = 0
|
7
|
+
|
8
|
+
# standard Win32 error codes
|
9
|
+
ERROR_SUCCESS = 0
|
10
|
+
end
|
11
|
+
|
12
|
+
module ::FFI::Library
|
13
|
+
# Wrapper method for attach_function + private
|
14
|
+
def attach_function_private(*args)
|
15
|
+
attach_function(*args)
|
16
|
+
private args[0]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class ::FFI::Pointer
|
21
|
+
NULL_HANDLE = 0
|
22
|
+
|
23
|
+
def self.from_string_to_wide_string(str, &block)
|
24
|
+
str = Puppet::Util::Windows::String.wide_string(str)
|
25
|
+
FFI::MemoryPointer.new(:byte, str.bytesize) do |ptr|
|
26
|
+
# uchar here is synonymous with byte
|
27
|
+
ptr.put_array_of_uchar(0, str.bytes.to_a)
|
28
|
+
|
29
|
+
yield ptr
|
30
|
+
end
|
31
|
+
|
32
|
+
# ptr has already had free called, so nothing to return
|
33
|
+
nil
|
34
|
+
end
|
35
|
+
|
36
|
+
def read_win32_bool
|
37
|
+
# BOOL is always a 32-bit integer in Win32
|
38
|
+
# some Win32 APIs return 1 for true, while others are non-0
|
39
|
+
read_int32 != FFI::WIN32_FALSE
|
40
|
+
end
|
41
|
+
|
42
|
+
alias_method :read_dword, :read_uint32
|
43
|
+
alias_method :read_win32_ulong, :read_uint32
|
44
|
+
alias_method :read_qword, :read_uint64
|
45
|
+
|
46
|
+
alias_method :read_hresult, :read_int32
|
47
|
+
|
48
|
+
def read_handle
|
49
|
+
type_size == 4 ? read_uint32 : read_uint64
|
50
|
+
end
|
51
|
+
|
52
|
+
alias_method :read_wchar, :read_uint16
|
53
|
+
alias_method :read_word, :read_uint16
|
54
|
+
alias_method :read_array_of_wchar, :read_array_of_uint16
|
55
|
+
|
56
|
+
def read_wide_string(char_length, dst_encoding = Encoding::UTF_8)
|
57
|
+
# char_length is number of wide chars (typically excluding NULLs), *not* bytes
|
58
|
+
str = get_bytes(0, char_length * 2).force_encoding('UTF-16LE')
|
59
|
+
str.encode(dst_encoding)
|
60
|
+
end
|
61
|
+
|
62
|
+
# @param max_char_length [Integer] Maximum number of wide chars to return (typically excluding NULLs), *not* bytes
|
63
|
+
# @param null_terminator [Symbol] Number of number of null wchar characters, *not* bytes, that determine the end of the string
|
64
|
+
# null_terminator = :single_null, then the terminating sequence is two bytes of zero. This is UNIT16 = 0
|
65
|
+
# null_terminator = :double_null, then the terminating sequence is four bytes of zero. This is UNIT32 = 0
|
66
|
+
def read_arbitrary_wide_string_up_to(max_char_length = 512, null_terminator = :single_null)
|
67
|
+
if null_terminator != :single_null && null_terminator != :double_null
|
68
|
+
raise _("Unable to read wide strings with %{null_terminator} terminal nulls") % { null_terminator: null_terminator }
|
69
|
+
end
|
70
|
+
|
71
|
+
terminator_width = null_terminator == :single_null ? 1 : 2
|
72
|
+
reader_method = null_terminator == :single_null ? :get_uint16 : :get_uint32
|
73
|
+
|
74
|
+
# Look for a null terminating characters; if found, read up to that null (exclusive)
|
75
|
+
(0...max_char_length - terminator_width).each do |i|
|
76
|
+
return read_wide_string(i) if send(reader_method, (i * 2)) == 0
|
77
|
+
end
|
78
|
+
|
79
|
+
# String is longer than the max; read just to the max
|
80
|
+
read_wide_string(max_char_length)
|
81
|
+
end
|
82
|
+
|
83
|
+
def read_win32_local_pointer(&block)
|
84
|
+
ptr = nil
|
85
|
+
begin
|
86
|
+
ptr = read_pointer
|
87
|
+
yield ptr
|
88
|
+
ensure
|
89
|
+
if ptr && ! ptr.null?
|
90
|
+
if FFI::WIN32::LocalFree(ptr.address) != FFI::Pointer::NULL_HANDLE
|
91
|
+
Puppet.debug "LocalFree memory leak"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# ptr has already had LocalFree called, so nothing to return
|
97
|
+
nil
|
98
|
+
end
|
99
|
+
|
100
|
+
def read_com_memory_pointer(&block)
|
101
|
+
ptr = nil
|
102
|
+
begin
|
103
|
+
ptr = read_pointer
|
104
|
+
yield ptr
|
105
|
+
ensure
|
106
|
+
FFI::WIN32::CoTaskMemFree(ptr) if ptr && ! ptr.null?
|
107
|
+
end
|
108
|
+
|
109
|
+
# ptr has already had CoTaskMemFree called, so nothing to return
|
110
|
+
nil
|
111
|
+
end
|
112
|
+
|
113
|
+
|
114
|
+
alias_method :write_dword, :write_uint32
|
115
|
+
alias_method :write_word, :write_uint16
|
116
|
+
end
|
117
|
+
|
118
|
+
# FFI Types
|
119
|
+
# https://github.com/ffi/ffi/wiki/Types
|
120
|
+
|
121
|
+
# Windows - Common Data Types
|
122
|
+
# https://msdn.microsoft.com/en-us/library/cc230309.aspx
|
123
|
+
|
124
|
+
# Windows Data Types
|
125
|
+
# https://msdn.microsoft.com/en-us/library/windows/desktop/aa383751(v=vs.85).aspx
|
126
|
+
|
127
|
+
FFI.typedef :uint16, :word
|
128
|
+
FFI.typedef :uint32, :dword
|
129
|
+
# uintptr_t is defined in an FFI conf as platform specific, either
|
130
|
+
# ulong_long on x64 or just ulong on x86
|
131
|
+
FFI.typedef :uintptr_t, :handle
|
132
|
+
FFI.typedef :uintptr_t, :hwnd
|
133
|
+
|
134
|
+
# buffer_inout is similar to pointer (platform specific), but optimized for buffers
|
135
|
+
FFI.typedef :buffer_inout, :lpwstr
|
136
|
+
# buffer_in is similar to pointer (platform specific), but optimized for CONST read only buffers
|
137
|
+
FFI.typedef :buffer_in, :lpcwstr
|
138
|
+
FFI.typedef :buffer_in, :lpcolestr
|
139
|
+
|
140
|
+
# string is also similar to pointer, but should be used for const char *
|
141
|
+
# NOTE that this is not wide, useful only for A suffixed functions
|
142
|
+
FFI.typedef :string, :lpcstr
|
143
|
+
|
144
|
+
# pointer in FFI is platform specific
|
145
|
+
# NOTE: for API calls with reserved lpvoid parameters, pass a FFI::Pointer::NULL
|
146
|
+
FFI.typedef :pointer, :lpcvoid
|
147
|
+
FFI.typedef :pointer, :lpvoid
|
148
|
+
FFI.typedef :pointer, :lpword
|
149
|
+
FFI.typedef :pointer, :lpbyte
|
150
|
+
FFI.typedef :pointer, :lpdword
|
151
|
+
FFI.typedef :pointer, :pdword
|
152
|
+
FFI.typedef :pointer, :phandle
|
153
|
+
FFI.typedef :pointer, :ulong_ptr
|
154
|
+
FFI.typedef :pointer, :pbool
|
155
|
+
FFI.typedef :pointer, :lpunknown
|
156
|
+
|
157
|
+
# any time LONG / ULONG is in a win32 API definition DO NOT USE platform specific width
|
158
|
+
# which is what FFI uses by default
|
159
|
+
# instead create new aliases for these very special cases
|
160
|
+
# NOTE: not a good idea to redefine FFI :ulong since other typedefs may rely on it
|
161
|
+
FFI.typedef :uint32, :win32_ulong
|
162
|
+
FFI.typedef :int32, :win32_long
|
163
|
+
# FFI bool can be only 1 byte at times,
|
164
|
+
# Win32 BOOL is a signed int, and is always 4 bytes, even on x64
|
165
|
+
# https://blogs.msdn.com/b/oldnewthing/archive/2011/03/28/10146459.aspx
|
166
|
+
FFI.typedef :int32, :win32_bool
|
167
|
+
|
168
|
+
# BOOLEAN (unlike BOOL) is a BYTE - typedef unsigned char BYTE;
|
169
|
+
FFI.typedef :uchar, :boolean
|
170
|
+
|
171
|
+
# Same as a LONG, a 32-bit signed integer
|
172
|
+
FFI.typedef :int32, :hresult
|
173
|
+
|
174
|
+
# NOTE: FFI already defines (u)short as a 16-bit (un)signed like this:
|
175
|
+
# FFI.typedef :uint16, :ushort
|
176
|
+
# FFI.typedef :int16, :short
|
177
|
+
|
178
|
+
# 8 bits per byte
|
179
|
+
FFI.typedef :uchar, :byte
|
180
|
+
FFI.typedef :uint16, :wchar
|
181
|
+
|
182
|
+
module ::FFI::WIN32
|
183
|
+
extend ::FFI::Library
|
184
|
+
|
185
|
+
# https://msdn.microsoft.com/en-us/library/windows/desktop/aa373931(v=vs.85).aspx
|
186
|
+
# typedef struct _GUID {
|
187
|
+
# DWORD Data1;
|
188
|
+
# WORD Data2;
|
189
|
+
# WORD Data3;
|
190
|
+
# BYTE Data4[8];
|
191
|
+
# } GUID;
|
192
|
+
class GUID < FFI::Struct
|
193
|
+
layout :Data1, :dword,
|
194
|
+
:Data2, :word,
|
195
|
+
:Data3, :word,
|
196
|
+
:Data4, [:byte, 8]
|
197
|
+
|
198
|
+
def self.[](s)
|
199
|
+
raise _('Bad GUID format.') unless s =~ /^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$/i
|
200
|
+
|
201
|
+
new.tap do |guid|
|
202
|
+
guid[:Data1] = s[0, 8].to_i(16)
|
203
|
+
guid[:Data2] = s[9, 4].to_i(16)
|
204
|
+
guid[:Data3] = s[14, 4].to_i(16)
|
205
|
+
guid[:Data4][0] = s[19, 2].to_i(16)
|
206
|
+
guid[:Data4][1] = s[21, 2].to_i(16)
|
207
|
+
s[24, 12].split('').each_slice(2).with_index do |a, i|
|
208
|
+
guid[:Data4][i + 2] = a.join('').to_i(16)
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
def ==(other) Windows.memcmp(other, self, size) == 0 end
|
214
|
+
end
|
215
|
+
|
216
|
+
# https://msdn.microsoft.com/en-us/library/windows/desktop/ms724950(v=vs.85).aspx
|
217
|
+
# typedef struct _SYSTEMTIME {
|
218
|
+
# WORD wYear;
|
219
|
+
# WORD wMonth;
|
220
|
+
# WORD wDayOfWeek;
|
221
|
+
# WORD wDay;
|
222
|
+
# WORD wHour;
|
223
|
+
# WORD wMinute;
|
224
|
+
# WORD wSecond;
|
225
|
+
# WORD wMilliseconds;
|
226
|
+
# } SYSTEMTIME, *PSYSTEMTIME;
|
227
|
+
class SYSTEMTIME < FFI::Struct
|
228
|
+
layout :wYear, :word,
|
229
|
+
:wMonth, :word,
|
230
|
+
:wDayOfWeek, :word,
|
231
|
+
:wDay, :word,
|
232
|
+
:wHour, :word,
|
233
|
+
:wMinute, :word,
|
234
|
+
:wSecond, :word,
|
235
|
+
:wMilliseconds, :word
|
236
|
+
|
237
|
+
def to_local_time
|
238
|
+
Time.local(self[:wYear], self[:wMonth], self[:wDay],
|
239
|
+
self[:wHour], self[:wMinute], self[:wSecond], self[:wMilliseconds] * 1000)
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
# https://msdn.microsoft.com/en-us/library/windows/desktop/ms724284(v=vs.85).aspx
|
244
|
+
# Contains a 64-bit value representing the number of 100-nanosecond
|
245
|
+
# intervals since January 1, 1601 (UTC).
|
246
|
+
# typedef struct _FILETIME {
|
247
|
+
# DWORD dwLowDateTime;
|
248
|
+
# DWORD dwHighDateTime;
|
249
|
+
# } FILETIME, *PFILETIME;
|
250
|
+
class FILETIME < FFI::Struct
|
251
|
+
layout :dwLowDateTime, :dword,
|
252
|
+
:dwHighDateTime, :dword
|
253
|
+
end
|
254
|
+
|
255
|
+
ffi_convention :stdcall
|
256
|
+
|
257
|
+
# https://msdn.microsoft.com/en-us/library/windows/desktop/aa366730(v=vs.85).aspx
|
258
|
+
# HLOCAL WINAPI LocalFree(
|
259
|
+
# _In_ HLOCAL hMem
|
260
|
+
# );
|
261
|
+
ffi_lib :kernel32
|
262
|
+
attach_function :LocalFree, [:handle], :handle
|
263
|
+
|
264
|
+
# https://msdn.microsoft.com/en-us/library/windows/desktop/ms724211(v=vs.85).aspx
|
265
|
+
# BOOL WINAPI CloseHandle(
|
266
|
+
# _In_ HANDLE hObject
|
267
|
+
# );
|
268
|
+
ffi_lib :kernel32
|
269
|
+
attach_function_private :CloseHandle, [:handle], :win32_bool
|
270
|
+
|
271
|
+
# https://msdn.microsoft.com/en-us/library/windows/desktop/ms680722(v=vs.85).aspx
|
272
|
+
# void CoTaskMemFree(
|
273
|
+
# _In_opt_ LPVOID pv
|
274
|
+
# );
|
275
|
+
ffi_lib :ole32
|
276
|
+
attach_function :CoTaskMemFree, [:lpvoid], :void
|
277
|
+
end
|
278
|
+
end
|