pdk 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|