vrvirtualdesktop 0.0.1
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.
- data/CHANGES +4 -0
- data/LICENSE +1 -0
- data/README +37 -0
- data/TODO +3 -0
- data/bin/vrdesk.rbw +55 -0
- data/lib/VRVirtualDesktopForm.rb +267 -0
- data/lib/Win32/APIMapper.rb +62 -0
- data/lib/Win32/Base-consts.rb +891 -0
- data/lib/Win32/Base.rb +275 -0
- data/lib/Win32/Encoding.rb +68 -0
- data/lib/Win32/GetSystemMetrics.rb +107 -0
- data/lib/Win32/NetResources.rb +160 -0
- data/lib/Win32/Process.rb +468 -0
- data/lib/Win32/Registry.rb +515 -0
- data/lib/Win32/User32.rb +142 -0
- data/lib/Win32/VirtualDesktop.rb +418 -0
- data/lib/Win32/WindowManager.rb +177 -0
- data/lib/resources/desktops.ico +0 -0
- data/lib/resources/five_down.ico +0 -0
- data/lib/resources/five_up.ico +0 -0
- data/lib/resources/four_down.ico +0 -0
- data/lib/resources/four_up.ico +0 -0
- data/lib/resources/obdb.ico +0 -0
- data/lib/resources/one_down.ico +0 -0
- data/lib/resources/one_up.ico +0 -0
- data/lib/resources/six_down.ico +0 -0
- data/lib/resources/six_up.ico +0 -0
- data/lib/resources/three_down.ico +0 -0
- data/lib/resources/three_up.ico +0 -0
- data/lib/resources/two_down.ico +0 -0
- data/lib/resources/two_up.ico +0 -0
- metadata +97 -0
@@ -0,0 +1,515 @@
|
|
1
|
+
##################################################################################################
|
2
|
+
#
|
3
|
+
# $Author: Steve $
|
4
|
+
# $Date: 2005/12/16 18:35:42 $
|
5
|
+
# $Version: 0.99 $
|
6
|
+
# $Change: $
|
7
|
+
#
|
8
|
+
##################################################################################################
|
9
|
+
|
10
|
+
module Win32
|
11
|
+
|
12
|
+
require 'Win32/Base'
|
13
|
+
require 'Win32/APIMapper'
|
14
|
+
require 'Win32/Encoding'
|
15
|
+
|
16
|
+
#---------------------------------------------------------------------------------------------
|
17
|
+
#---------------------------------------------------------------------------------------------
|
18
|
+
# Win32 Exceptions
|
19
|
+
class RegistryError < Win32::Error
|
20
|
+
end
|
21
|
+
|
22
|
+
#---------------------------------------------------------------------------------------------
|
23
|
+
#---------------------------------------------------------------------------------------------
|
24
|
+
# This class provides some low-level functionality for manipulating the Win32 registry
|
25
|
+
class RegKey
|
26
|
+
#-----------------------------------------------------------------------------------------
|
27
|
+
# constsFor: "Predefined Registry Keys"
|
28
|
+
# (from WinReg.h)
|
29
|
+
HKEY_CLASSES_ROOT = 0x80000000
|
30
|
+
HKEY_CURRENT_CONFIG = 0x80000005
|
31
|
+
HKEY_CURRENT_USER = 0x80000001
|
32
|
+
HKEY_DYN_DATA = 0x80000006 # Works only on Win95/98/Me
|
33
|
+
HKEY_LOCAL_MACHINE = 0x80000002
|
34
|
+
HKEY_PERFORMANCE_DATA = 0x80000004
|
35
|
+
HKEY_USERS = 0x80000003
|
36
|
+
|
37
|
+
#-----------------------------------------------------------------------------------------
|
38
|
+
# constsFor: "Security and Access Rights (Open, Create)"
|
39
|
+
# (from WinReg.h)
|
40
|
+
KEY_QUERY_VALUE = 1
|
41
|
+
KEY_SET_VALUE = 2
|
42
|
+
KEY_CREATE_SUB_KEY = 4
|
43
|
+
KEY_ENUMERATE_SUB_KEYS = 8
|
44
|
+
KEY_NOTIFY = 16
|
45
|
+
KEY_CREATE_LINK = 32
|
46
|
+
KEY_WRITE = 131078
|
47
|
+
KEY_EXECUTE = 131097
|
48
|
+
KEY_READ = 131097
|
49
|
+
KEY_ALL_ACCESS = 983103
|
50
|
+
|
51
|
+
#-----------------------------------------------------------------------------------------
|
52
|
+
# constsFor: "Registry Value Types"
|
53
|
+
# (from WinReg.h)
|
54
|
+
REG_NONE = 0
|
55
|
+
REG_SZ = 1
|
56
|
+
REG_EXPAND_SZ = 2
|
57
|
+
REG_BINARY = 3
|
58
|
+
REG_DWORD = 4
|
59
|
+
REG_DWORD_LITTLE_ENDIAN = 4
|
60
|
+
REG_DWORD_BIG_ENDIAN = 5
|
61
|
+
REG_LINK = 6
|
62
|
+
REG_MULTI_SZ = 7
|
63
|
+
|
64
|
+
#-----------------------------------------------------------------------------------------
|
65
|
+
# constsFor: "Registry Key Creation Options"
|
66
|
+
# (from WinReg.h)
|
67
|
+
REG_OPTION_RESERVED = 0
|
68
|
+
REG_OPTION_NON_VOLATILE = 0
|
69
|
+
REG_OPTION_VOLATILE = 1
|
70
|
+
REG_OPTION_CREATE_LINK = 2
|
71
|
+
REG_OPTION_BACKUP_RESTORE = 4
|
72
|
+
REG_OPTION_OPEN_LINK = 8
|
73
|
+
|
74
|
+
#-----------------------------------------------------------------------------------------
|
75
|
+
# constsFor: "Registry Key Disposition on Create"
|
76
|
+
# (from WinReg.h)
|
77
|
+
REG_CREATED_NEW_KEY = 1
|
78
|
+
REG_OPENED_EXISTING_KEY = 2
|
79
|
+
|
80
|
+
#-----------------------------------------------------------------------------------------
|
81
|
+
# constsFor: "Restore Options"
|
82
|
+
# (from WinReg.h)
|
83
|
+
REG_WHOLE_HIVE_VOLATILE = 1
|
84
|
+
REG_REFRESH_HIVE = 2
|
85
|
+
REG_NO_LAZY_FLUSH = 4
|
86
|
+
REG_FORCE_RESTORE = 1234 #TODO
|
87
|
+
|
88
|
+
#-----------------------------------------------------------------------------------------
|
89
|
+
# constsFor: "miscellaneous"
|
90
|
+
# (from WinReg.h)
|
91
|
+
REG_FULL_RESOURCE_DESCRIPTOR = 9
|
92
|
+
REG_LEGAL_CHANGE_FILTER = 15
|
93
|
+
REG_LEGAL_OPTION = 15
|
94
|
+
REG_NOTIFY_CHANGE_ATTRIBUTES = 2
|
95
|
+
REG_NOTIFY_CHANGE_LAST_SET = 4
|
96
|
+
REG_NOTIFY_CHANGE_NAME = 1
|
97
|
+
REG_NOTIFY_CHANGE_SECURITY = 8
|
98
|
+
|
99
|
+
REG_RESOURCE_LIST = 8
|
100
|
+
REG_RESOURCE_REQUIREMENTS_LIST = 10
|
101
|
+
|
102
|
+
#-----------------------------------------------------------------------------------------
|
103
|
+
# constsFor: "String buffer size"
|
104
|
+
MAXCHARS = 256 * 2 # We exchange UCS2 characters with Windows
|
105
|
+
|
106
|
+
#-----------------------------------------------------------------------------------------
|
107
|
+
include APIMapper
|
108
|
+
|
109
|
+
APIMapper.Initialize(
|
110
|
+
'OpenKey' => { DLL => 'advapi32', NAME => 'RegOpenKeyExW',
|
111
|
+
IN => ['L', 'P', 'L', 'L', 'P'], OUT => 'L'},
|
112
|
+
'ConnectRegistry' => { DLL => 'advapi32', NAME => 'RegConnectRegistryW',
|
113
|
+
IN => ['P', 'L', 'P'], OUT => 'L'},
|
114
|
+
'CreateKey' => { DLL => 'advapi32', NAME => 'RegCreateKeyExW',
|
115
|
+
IN => ['L', 'P']*2 + ['L']*2 + ['P']*3, OUT => 'L'},
|
116
|
+
'CloseKey' => { DLL => 'advapi32', NAME => 'RegCloseKey',
|
117
|
+
IN => ['L'], OUT => 'L'},
|
118
|
+
'DeleteKey' => { DLL => 'advapi32', NAME => 'RegDeleteKey',
|
119
|
+
IN => ['L', 'P'], OUT => 'L'},
|
120
|
+
'DeleteValue' => { DLL => 'advapi32', NAME => 'RegDeleteValue',
|
121
|
+
IN => ['L', 'P'], OUT => 'L'},
|
122
|
+
'DisablePredefinedCache' => { DLL => 'advapi32', NAME => 'RegDisablePredefinedCache',
|
123
|
+
IN => [], OUT => 'L'},
|
124
|
+
'EnumKey' => { DLL => 'advapi32', NAME => 'RegEnumKeyExW',
|
125
|
+
IN => ['L', 'L'] + ['P']*6, OUT => 'L'},
|
126
|
+
'EnumValue' => { DLL => 'advapi32', NAME => 'RegEnumValueW',
|
127
|
+
IN => ['L', 'L'] + ['P']*6, OUT => 'L'},
|
128
|
+
'FlushKey' => { DLL => 'advapi32', NAME => 'RegFlushKey',
|
129
|
+
IN => ['L'], OUT => 'L'},
|
130
|
+
'LoadKey' => { DLL => 'advapi32', NAME => 'RegLoadKeyW',
|
131
|
+
IN => ['L', 'P', 'P'], OUT => 'L'},
|
132
|
+
'OverridePredefKey' => { DLL => 'advapi32', NAME => 'RegOverridePredefKey',
|
133
|
+
IN => ['L', 'L'], OUT => 'L'},
|
134
|
+
'QueryInfoKey' => { DLL => 'advapi32', NAME => 'RegQueryInfoKeyW',
|
135
|
+
IN => ['L'] + ['P']*11, OUT => 'L'},
|
136
|
+
'QueryValue' => { DLL => 'advapi32', NAME => 'RegQueryValueExW',
|
137
|
+
IN => ['L'] + ['P']*5, OUT => 'L'},
|
138
|
+
'QueryMultipleValues' => { DLL => 'advapi32', NAME => 'RegQueryMultipleValuesW',
|
139
|
+
IN => ['L'] + ['P', 'L', 'P', 'P'] , OUT => 'L'},
|
140
|
+
'ReplaceKey' => { DLL => 'advapi32', NAME => 'RegReplaceKeyW',
|
141
|
+
IN => ['L', 'L', 'P', 'P'], OUT => 'L'},
|
142
|
+
'RestoreKey' => { DLL => 'advapi32', NAME => 'RegRestoreKeyW',
|
143
|
+
IN => ['L', 'P', 'L'], OUT => 'L'},
|
144
|
+
'SaveKey' => { DLL => 'advapi32', NAME => 'RegSaveKeyW',
|
145
|
+
IN => ['L', 'P', 'P'], OUT => 'L'},
|
146
|
+
'SetValue' => { DLL => 'advapi32', NAME => 'RegSetValueExW',
|
147
|
+
IN => ['L', 'P', 'L', 'L', 'P', 'L'], OUT => 'L'},
|
148
|
+
'UnLoadKey' => { DLL => 'advapi32', NAME => 'RegUnLoadKey',
|
149
|
+
IN => ['L', 'P'], OUT => 'L'}
|
150
|
+
)
|
151
|
+
|
152
|
+
#-----------------------------------------------------------------------------------------
|
153
|
+
# class methodsFor: "initialization"
|
154
|
+
def initialize()
|
155
|
+
@key = nil
|
156
|
+
end
|
157
|
+
|
158
|
+
#-----------------------------------------------------------------------------------------
|
159
|
+
# class methodsFor: "opening/creating/connecting"
|
160
|
+
def RegKey.open(p_key, p_strSubKey, p_samDesired = KEY_QUERY_VALUE)
|
161
|
+
key = RegKey.new
|
162
|
+
key.open(p_key, p_strSubKey, p_samDesired)
|
163
|
+
return key
|
164
|
+
end
|
165
|
+
|
166
|
+
def RegKey.create(
|
167
|
+
p_key,
|
168
|
+
p_strSubKey,
|
169
|
+
p_strClass = '',
|
170
|
+
p_nOptions = REG_OPTION_NON_VOLATILE,
|
171
|
+
p_samDesired = 0,
|
172
|
+
p_pSecurityAttributes = nil)
|
173
|
+
key = RegKey.new
|
174
|
+
key.create( p_key, p_strSubKey, p_strClass,
|
175
|
+
p_nOptions, p_samDesired, p_pSecurityAttributes)
|
176
|
+
return key
|
177
|
+
end
|
178
|
+
|
179
|
+
def RegKey.connect(p_strHost, p_key)
|
180
|
+
key = RegKey.new
|
181
|
+
key.connect(p_strHost, p_key)
|
182
|
+
return key
|
183
|
+
end
|
184
|
+
|
185
|
+
#-----------------------------------------------------------------------------------------
|
186
|
+
# methodsFor: "opening/creating/connecting"
|
187
|
+
def open(p_key, p_strSubKey, p_samDesired = KEY_QUERY_VALUE)
|
188
|
+
self.close if !@key.nil?
|
189
|
+
pKey = "\0" * 4 # pointer to long
|
190
|
+
ret = WCall('OpenKey', p_key.to_i, p_strSubKey.to_ucs2(true), 0, p_samDesired, pKey)
|
191
|
+
raise RegistryError.new(ret), "Cannot Open Key: #{p_strSubKey}", caller if 0 != ret
|
192
|
+
@key = pKey.unpack("L")[0]
|
193
|
+
end
|
194
|
+
|
195
|
+
def create(
|
196
|
+
p_key,
|
197
|
+
p_strSubKey,
|
198
|
+
p_strClass = '',
|
199
|
+
p_nOptions = REG_OPTION_NON_VOLATILE,
|
200
|
+
p_samDesired = 0,
|
201
|
+
p_pSecurityAttributes = nil)
|
202
|
+
self.close if !@key.nil?
|
203
|
+
pKey = "\0" * 4 # pointer to long
|
204
|
+
pDisposition = "\0" * 4 # pointer to long
|
205
|
+
ret = WCall('CreateKey',
|
206
|
+
p_key.to_i, p_strSubKey.to_ucs2(true), 0, p_strClass.to_ucs2(true),
|
207
|
+
p_nOptions, p_samDesired, 0, #p_SecurityAttributes.pack, let's ignore this...
|
208
|
+
pKey, pDisposition)
|
209
|
+
if 0 == ret or (ERROR_ACCESS_DENIED == ret and
|
210
|
+
REG_OPENED_EXISTING_KEY == pDisposition.unpack('L')[0])
|
211
|
+
@key = pKey.unpack("L")[0]
|
212
|
+
else
|
213
|
+
raise RegistryError.new(ret), "Cannot create: #{p_strSubKey}", caller
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
def connect(p_strHost, p_key)
|
218
|
+
self.close if !@key.nil?
|
219
|
+
pKey = "\0" * 4 # pointer to long
|
220
|
+
ret = WCall('ConnectRegistry', p_strHost.to_ucs2(true), p_key.to_i, pKey)
|
221
|
+
raise RegistryError.new(ret), "Cannot connect to #{p_strHost}", caller if 0 != ret
|
222
|
+
@key = pKey.unpack("L")[0]
|
223
|
+
end
|
224
|
+
|
225
|
+
#-----------------------------------------------------------------------------------------
|
226
|
+
# methodsFor: "replacing"
|
227
|
+
def replace(p_subKey, p_strNewFilename, p_strOldFilename)
|
228
|
+
raise Registry, "Key was not initialized properly", caller if @key.nil?
|
229
|
+
ret = WCall('ReplaceKey', @key, p_subKey,
|
230
|
+
p_strNewFilename.to_ucs2(true), p_strOldFilename.to_ucs2(true))
|
231
|
+
raise RegistryError.new(ret), "Cannot replace #{p_subKey}", caller if 0 != ret
|
232
|
+
end
|
233
|
+
|
234
|
+
#-----------------------------------------------------------------------------------------
|
235
|
+
# methodsFor: "closing"
|
236
|
+
def close(p_bFlush = false)
|
237
|
+
return 0 if @key.nil?
|
238
|
+
flush() if p_bFlush
|
239
|
+
ret = WCall('CloseKey', @key)
|
240
|
+
@key = nil
|
241
|
+
raise RegistryError.new(ret), "Cannot close key", caller if 0 != ret
|
242
|
+
end
|
243
|
+
|
244
|
+
#-----------------------------------------------------------------------------------------
|
245
|
+
# methodsFor: "flushing"
|
246
|
+
def flush
|
247
|
+
raise Registry, "Key was not initialized properly", caller if @key.nil?
|
248
|
+
ret = WCall('FlushKey', @key)
|
249
|
+
raise RegistryError.new(ret), "Error while flushing", caller if 0 != ret
|
250
|
+
end
|
251
|
+
|
252
|
+
#-----------------------------------------------------------------------------------------
|
253
|
+
# class methodsFor: "deleting"
|
254
|
+
def RegKey.Delete(p_key, p_subKey)
|
255
|
+
ret = APIMapper.WCall('DeleteKey', p_key.to_i, p_subKey)
|
256
|
+
raise RegistryError.new(ret), "Error while deleting #{p_subkey}", caller if 0 != ret
|
257
|
+
end
|
258
|
+
|
259
|
+
#-----------------------------------------------------------------------------------------
|
260
|
+
# class methodsFor: "miscellaneous"
|
261
|
+
def RegKey.DisablePredefinedCache
|
262
|
+
ret = APIMapper.WCall('DisablePredefinedCache')
|
263
|
+
raise RegistryError.new(ret), "Error while disabling predefined cache", caller if 0 != ret
|
264
|
+
end
|
265
|
+
|
266
|
+
#-----------------------------------------------------------------------------------------
|
267
|
+
# methodsFor: "miscellaneous"
|
268
|
+
def overridePredefKey(p_key)
|
269
|
+
raise Registry, "Key was not initialized properly", caller if @key.nil?
|
270
|
+
ret = WCall('OverridePredefKey', p_key, @key)
|
271
|
+
raise RegistryError.new(ret), "Error while overriding predefined key", caller if 0 != ret
|
272
|
+
end
|
273
|
+
|
274
|
+
def deleteValue(p_strName)
|
275
|
+
raise Registry, "Key was not initialized properly", caller if @key.nil?
|
276
|
+
ret = WCall('DeleteValue', @key, p_strName.to_ucs2(true))
|
277
|
+
raise RegistryError.new(ret), "Error while deleting value #{p_strName}", caller if 0 != ret
|
278
|
+
end
|
279
|
+
|
280
|
+
#-----------------------------------------------------------------------------------------
|
281
|
+
# methodsFor: "loading/unloading"
|
282
|
+
def load(p_subKey, p_strFilename)
|
283
|
+
raise Registry, "Key was not initialized properly", caller if @key.nil?
|
284
|
+
ret = WCall('LoadKey', @key, p_subKey, p_strFilename.to_ucs2(true))
|
285
|
+
raise RegistryError.new(ret), "Error while loading #{p_strFilename} into #{p_subkey}", caller if 0 != ret
|
286
|
+
end
|
287
|
+
|
288
|
+
def unLoad(p_subKey)
|
289
|
+
return -1 if @key.nil?
|
290
|
+
ret = WCall('UnLoadKey', @key, p_subKey)
|
291
|
+
raise RegistryError.new(ret), "Error while unloading #{p_subkey}", caller if 0 != ret
|
292
|
+
end
|
293
|
+
|
294
|
+
def save(p_strFilename, p_security = 0)
|
295
|
+
raise Registry, "Key was not initialized properly", caller if @key.nil?
|
296
|
+
ret = WCall('SaveKey', @key, p_strFilename.to_ucs2(true), pSecurity)
|
297
|
+
raise RegistryError.new(ret), "Error while saving to #{p_strFilename}", caller if 0 != ret
|
298
|
+
end
|
299
|
+
|
300
|
+
def restore(p_strFilename, p_options)
|
301
|
+
raise Registry, "Key was not initialized properly", caller if @key.nil?
|
302
|
+
ret = WCall('RestoreKey', @key, p_strFilename.to_ucs2(true), p_options)
|
303
|
+
raise RegistryError.new(ret), "Error while restoring from #{p_strFilename}", caller if 0 != ret
|
304
|
+
end
|
305
|
+
|
306
|
+
#-----------------------------------------------------------------------------------------
|
307
|
+
# methodsFor: "enumerating"
|
308
|
+
def eachKey
|
309
|
+
raise Registry, "Key was not initialized properly", caller if @key.nil?
|
310
|
+
return 0 if !block_given?
|
311
|
+
n = 0
|
312
|
+
while true
|
313
|
+
strKey = "\0" * MAXCHARS # UCS2 String Buffer
|
314
|
+
pszKey = [MAXCHARS].pack('L') # pointer to long
|
315
|
+
strClass = "\0" * MAXCHARS # UCS2 String Buffer
|
316
|
+
pszClass = [MAXCHARS].pack("L") # pointer to long
|
317
|
+
pftLastWrite = "\0" * 4 # pointer to long
|
318
|
+
ret = WCall('EnumKey', @key, n, strKey, pszKey, 0, strClass, pszClass, pftLastWrite)
|
319
|
+
case ret
|
320
|
+
when 0
|
321
|
+
szKey = pszKey.unpack('L')[0] * 2 # UCS2 characters
|
322
|
+
szClass = pszClass.unpack('L')[0] * 2 # UCS2 characters
|
323
|
+
yield( strKey[0, szKey].to_utf8,
|
324
|
+
strClass[0, szClass].to_utf8,
|
325
|
+
pftLastWrite.unpack('L')[0])
|
326
|
+
n += 1
|
327
|
+
when ERROR_NO_MORE_ITEMS then break
|
328
|
+
else
|
329
|
+
raise RegistryError.new(ret), "Cannot access key ##{n} in enumeration", caller
|
330
|
+
end
|
331
|
+
end
|
332
|
+
return n
|
333
|
+
end
|
334
|
+
|
335
|
+
def eachValue
|
336
|
+
raise Registry, "Key was not initialized properly", caller if @key.nil?
|
337
|
+
return 0 if !block_given?
|
338
|
+
n = 0
|
339
|
+
|
340
|
+
while true
|
341
|
+
strName = "\0" * MAXCHARS # UCS2 String Buffer
|
342
|
+
pszName = [MAXCHARS].pack('L') # pointer to long
|
343
|
+
pnType = " " * 4 # pointer to long
|
344
|
+
pszData = " " * 4 # pointer to long
|
345
|
+
|
346
|
+
# First call determines the size of data
|
347
|
+
ret = WCall('EnumValue', @key, n, strName, pszName, 0, pnType, 0, pszData)
|
348
|
+
case ret
|
349
|
+
when 0
|
350
|
+
szName = pszName.unpack('L')[0] * 2 # UCS2 characters
|
351
|
+
szData = pszData.unpack('L')[0]
|
352
|
+
nType = pnType.unpack('L')[0]
|
353
|
+
pData = nil
|
354
|
+
if szData > 0
|
355
|
+
pszName = [512].pack('L') # pointer to long
|
356
|
+
pData = "\0" * szData # pointer to data
|
357
|
+
# Second call retrieves the data
|
358
|
+
ret = WCall('EnumValue', @key, n, strName, pszName, 0, 0, pData, pszData)
|
359
|
+
raise RegistryError.new(ret), "Cannot access value ##{n} in enumeration", caller if 0 != ret
|
360
|
+
end
|
361
|
+
yield( strName[0, szName].to_utf8,
|
362
|
+
nType,
|
363
|
+
szData,
|
364
|
+
convertData(nType, pData, szData))
|
365
|
+
n += 1
|
366
|
+
when ERROR_NO_MORE_ITEMS then break
|
367
|
+
else
|
368
|
+
raise RegistryError.new(ret), "Cannot access value ##{n} in enumeration", caller
|
369
|
+
end
|
370
|
+
end
|
371
|
+
return n
|
372
|
+
end
|
373
|
+
|
374
|
+
#-----------------------------------------------------------------------------------------
|
375
|
+
# methodsFor: "querying"
|
376
|
+
def queryInfo
|
377
|
+
raise Registry, "Key was not initialized properly", caller if @key.nil?
|
378
|
+
pszClass = "\0" * 4 # pointer to long
|
379
|
+
pnSubKeys = "\0" * 4 # pointer to long
|
380
|
+
pnMaxSubKeyLen = "\0" * 4 # pointer to long
|
381
|
+
pnMaxClassLen = "\0" * 4 # pointer to long
|
382
|
+
pnValues = "\0" * 4 # pointer to long
|
383
|
+
pnMaxValueNameLen = "\0" * 4 # pointer to long
|
384
|
+
pnMaxValueLen = "\0" * 4 # pointer to long
|
385
|
+
pnSecurityDescriptor = "\0" * 4 # pointer to long
|
386
|
+
pftLastWriteTime = "\0" * 4 # pointer to long
|
387
|
+
ret = WCall('QueryInfoKey',
|
388
|
+
@key,
|
389
|
+
0, pszClass,
|
390
|
+
0,
|
391
|
+
pnSubKeys, pnMaxSubKeyLen,
|
392
|
+
pnMaxClassLen,
|
393
|
+
pnValues, pnMaxValueNameLen, pnMaxValueLen,
|
394
|
+
pnSecurityDescriptor,
|
395
|
+
pftLastWriteTime)
|
396
|
+
raise RegistryError.new(ret), "Cannot query info", caller if 0 != ret
|
397
|
+
|
398
|
+
mRet = {}
|
399
|
+
szClass = pszClass.unpack('L')[0] * 2 # UCS2 characters
|
400
|
+
mRet['SubKeys'] = pnSubKeys.unpack('L')[0]
|
401
|
+
mRet['MaxSubKeyLen'] = pnMaxSubKeyLen.unpack('L')[0]
|
402
|
+
mRet['MaxClassLen'] = pnMaxClassLen.unpack('L')[0]
|
403
|
+
mRet['Values'] = pnValues.unpack('L')[0]
|
404
|
+
mRet['MaxValueNameLen'] = pnMaxValueNameLen.unpack('L')[0]
|
405
|
+
mRet['MaxValueLen'] = pnMaxValueLen.unpack('L')[0]
|
406
|
+
mRet['SecurityDescriptor'] = pnSecurityDescriptor.unpack('L')[0]
|
407
|
+
mRet['LastWriteTime'] = pftLastWriteTime.unpack('L')[0]
|
408
|
+
|
409
|
+
if szClass > 0
|
410
|
+
szClass += 2
|
411
|
+
strClass = " " * szClass
|
412
|
+
pszClass = [szClass].pack('L')
|
413
|
+
ret = WCall('QueryInfoKey', @key, strClass, pszClass, 0, 0, 0, 0, 0, 0, 0, 0, 0)
|
414
|
+
raise RegistryError.new(ret), "Cannot query info", caller if 0 != ret
|
415
|
+
mRet['Class'] = strClass.to_utf8
|
416
|
+
print "class: ", strClass.inspect, "->", strClass, "\n"
|
417
|
+
end
|
418
|
+
return mRet
|
419
|
+
end
|
420
|
+
|
421
|
+
def queryValue(p_strName)
|
422
|
+
raise Registry, "Key was not initialized properly", caller if @key.nil?
|
423
|
+
strName = p_strName.to_ucs2(true)
|
424
|
+
pnType = " " * 4 # pointer to long
|
425
|
+
pszData = " " * 4 # pointer to long
|
426
|
+
ret = WCall('QueryValue', @key, strName, 0, pnType, 0, pszData)
|
427
|
+
raise RegistryError.new(ret), "Cannot query value #{p_strName}", caller if 0 != ret
|
428
|
+
|
429
|
+
mRet = {}
|
430
|
+
mRet['Type'] = nType = pnType.unpack('L')[0]
|
431
|
+
szData = pszData.unpack('L')[0]
|
432
|
+
if szData > 0
|
433
|
+
pData = "\0" * szData # pointer to long
|
434
|
+
ret = WCall('QueryValue', @key, strName, 0, 0, pData, pszData)
|
435
|
+
raise RegistryError.new(ret), "Cannot query value #{p_strName}", caller if 0 != ret
|
436
|
+
mRet['Value'] = convertData(nType, pData, szData)
|
437
|
+
end
|
438
|
+
return mRet
|
439
|
+
end
|
440
|
+
|
441
|
+
def queryMultipleValues(p_vstrNames)
|
442
|
+
raise Registry, "Key was not initialized properly", caller if @key.nil?
|
443
|
+
pszData = "\0" * 4 # pointer to long
|
444
|
+
pvValues = Array.new()
|
445
|
+
p_vstrNames.each {|str| pvValues << str.to_ucs2(true) }
|
446
|
+
ret = WCall('QueryMultipleValues', @key, pvValues, pvValues.size, 0, pszData)
|
447
|
+
raise RegistryError.new(ret), "Cannot query values #{p_vstrNames}", caller if 0 != ret and ERROR_MORE_DATA != ret
|
448
|
+
|
449
|
+
mRet = {}
|
450
|
+
szData = pszData.unpack('L')[0]
|
451
|
+
if szData > 0
|
452
|
+
pData = "\0" * szData # pointer to long
|
453
|
+
ret = WCall('QueryMultipleValues', @key, pvValues, pvValues.size, pData, pszData)
|
454
|
+
raise RegistryError.new(ret), "Cannot query values #{p_vstrNames}", caller if 0 != ret
|
455
|
+
mRet['Value'] = convertData(nType, pData, szData)
|
456
|
+
end
|
457
|
+
return mRet
|
458
|
+
end
|
459
|
+
|
460
|
+
def setValue(p_strName, p_nType, p_pData)
|
461
|
+
raise Registry, "Key was not initialized properly", caller if @key.nil?
|
462
|
+
case p_nType
|
463
|
+
when REG_BINARY then pData = [p_pData].pack('C*')
|
464
|
+
when REG_DWORD then pData = [p_pData].pack('L')
|
465
|
+
when REG_DWORD_BIG_ENDIAN then pData = [p_pData].pack('L')
|
466
|
+
when REG_DWORD_LITTLE_ENDIAN then pData = [p_pData].pack('V')
|
467
|
+
when REG_EXPAND_SZ then pData = p_pData.to_ucs2(true)
|
468
|
+
when REG_LINK then pData = p_pData
|
469
|
+
when REG_NONE then pData = p_pData
|
470
|
+
when REG_SZ then pData = p_pData.to_ucs2(true)
|
471
|
+
when REG_MULTI_SZ
|
472
|
+
pData = []
|
473
|
+
p_pData.each {|str| pData << str.to_ucs2(true) }
|
474
|
+
pData << "\000\000"
|
475
|
+
else return -2
|
476
|
+
end
|
477
|
+
strName = p_strName.to_ucs2(true)
|
478
|
+
ret = WCall('SetValue', @key, strName, 0, p_nType, pData, pData.size)
|
479
|
+
raise RegistryError.new(ret), "Cannot set value #{p_strName}", caller if 0 != ret
|
480
|
+
end
|
481
|
+
|
482
|
+
#-----------------------------------------------------------------------------------------
|
483
|
+
# methodsFor: "accessing"
|
484
|
+
def to_i
|
485
|
+
return @key
|
486
|
+
end
|
487
|
+
|
488
|
+
#-----------------------------------------------------------------------------------------
|
489
|
+
# methodsFor: "printing"
|
490
|
+
def to_s
|
491
|
+
return super + " Key: #{@key}"
|
492
|
+
end
|
493
|
+
|
494
|
+
#-----------------------------------------------------------------------------------------
|
495
|
+
private
|
496
|
+
|
497
|
+
#-----------------------------------------------------------------------------------------
|
498
|
+
# methodsFor: "data conversion"
|
499
|
+
def convertData(p_nType, p_pData, p_szData)
|
500
|
+
return nil if p_pData.nil?
|
501
|
+
case p_nType
|
502
|
+
when REG_BINARY then return p_pData.unpack('C*')
|
503
|
+
when REG_DWORD then return p_pData.unpack('L')[0]
|
504
|
+
when REG_DWORD_BIG_ENDIAN then return p_pData.unpack('L')[0]
|
505
|
+
when REG_DWORD_LITTLE_ENDIAN then return p_pData.unpack('V')[0]
|
506
|
+
when REG_EXPAND_SZ then return p_pData[0, p_szData - 2].to_utf8
|
507
|
+
when REG_LINK then return p_pData
|
508
|
+
when REG_NONE then return p_pData
|
509
|
+
when REG_SZ then return p_pData[0, p_szData - 2].to_utf8
|
510
|
+
when REG_MULTI_SZ then return p_pData.to_utf8.unpack('Z*')
|
511
|
+
else return nil
|
512
|
+
end
|
513
|
+
end
|
514
|
+
end
|
515
|
+
end
|