vrvirtualdesktop 0.0.1

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