Class: Win32::RegKey

Inherits:
Object
  • Object
show all
Includes:
APIMapper
Defined in:
lib/Win32/Registry.rb

Overview



This class provides some low-level functionality for manipulating the Win32 registry

Constant Summary collapse

HKEY_CLASSES_ROOT =

constsFor: “Predefined Registry Keys” (from WinReg.h)

0x80000000
HKEY_CURRENT_CONFIG =
0x80000005
HKEY_CURRENT_USER =
0x80000001
HKEY_DYN_DATA =

Works only on Win95/98/Me

0x80000006
HKEY_LOCAL_MACHINE =
0x80000002
HKEY_PERFORMANCE_DATA =
0x80000004
HKEY_USERS =
0x80000003
KEY_QUERY_VALUE =

constsFor: “Security and Access Rights (Open, Create)” (from WinReg.h)

1
KEY_SET_VALUE =
2
KEY_CREATE_SUB_KEY =
4
KEY_ENUMERATE_SUB_KEYS =
8
KEY_NOTIFY =
16
32
KEY_WRITE =
131078
KEY_EXECUTE =
131097
KEY_READ =
131097
KEY_ALL_ACCESS =
983103
REG_NONE =

constsFor: “Registry Value Types” (from WinReg.h)

0
REG_SZ =
1
REG_EXPAND_SZ =
2
REG_BINARY =
3
REG_DWORD =
4
REG_DWORD_LITTLE_ENDIAN =
4
REG_DWORD_BIG_ENDIAN =
5
6
REG_MULTI_SZ =
7
REG_OPTION_RESERVED =

constsFor: “Registry Key Creation Options” (from WinReg.h)

0
REG_OPTION_NON_VOLATILE =
0
REG_OPTION_VOLATILE =
1
2
REG_OPTION_BACKUP_RESTORE =
4
8
REG_CREATED_NEW_KEY =

constsFor: “Registry Key Disposition on Create” (from WinReg.h)

1
REG_OPENED_EXISTING_KEY =
2
REG_WHOLE_HIVE_VOLATILE =

constsFor: “Restore Options” (from WinReg.h)

1
REG_REFRESH_HIVE =
2
REG_NO_LAZY_FLUSH =
4
REG_FORCE_RESTORE =

TODO

1234
REG_FULL_RESOURCE_DESCRIPTOR =

constsFor: “miscellaneous” (from WinReg.h)

9
15
15
REG_NOTIFY_CHANGE_ATTRIBUTES =
2
REG_NOTIFY_CHANGE_LAST_SET =
4
REG_NOTIFY_CHANGE_NAME =
1
REG_NOTIFY_CHANGE_SECURITY =
8
REG_RESOURCE_LIST =
8
REG_RESOURCE_REQUIREMENTS_LIST =
10
MAXCHARS =

constsFor: “String buffer size”

256 * 2

Constants included from APIMapper

APIMapper::DLL, APIMapper::HANDLE, APIMapper::IN, APIMapper::NAME, APIMapper::OUT

Class Method Summary collapse

Instance Method Summary collapse

Methods included from APIMapper

Initialize, #WCall, WCall

Constructor Details

#initializeRegKey


class methodsFor: “initialization”



154
155
156
# File 'lib/Win32/Registry.rb', line 154

def initialize()
	@key = nil
end

Class Method Details

.connect(p_strHost, p_key) ⇒ Object



179
180
181
182
183
# File 'lib/Win32/Registry.rb', line 179

def RegKey.connect(p_strHost, p_key)
	key = RegKey.new
	key.connect(p_strHost, p_key)
	return key
end

.create(p_key, p_strSubKey, p_strClass = '', p_nOptions = REG_OPTION_NON_VOLATILE, p_samDesired = 0, p_pSecurityAttributes = nil) ⇒ Object



166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/Win32/Registry.rb', line 166

def RegKey.create(
		p_key,
		p_strSubKey,
		p_strClass            = '',
		p_nOptions            = REG_OPTION_NON_VOLATILE,
		p_samDesired          = 0,
		p_pSecurityAttributes = nil)
	key = RegKey.new
	key.create(	p_key, p_strSubKey, p_strClass,
				p_nOptions, p_samDesired, p_pSecurityAttributes)
	return key
end

.Delete(p_key, p_subKey) ⇒ Object


class methodsFor: “deleting”

Raises:



254
255
256
257
# File 'lib/Win32/Registry.rb', line 254

def RegKey.Delete(p_key, p_subKey)
	ret = APIMapper.WCall('DeleteKey', p_key.to_i, p_subKey)
	raise RegistryError.new(ret), "Error while deleting #{p_subkey}", caller if 0 != ret
end

.DisablePredefinedCacheObject


class methodsFor: “miscellaneous”

Raises:



261
262
263
264
# File 'lib/Win32/Registry.rb', line 261

def RegKey.DisablePredefinedCache
	ret = APIMapper.WCall('DisablePredefinedCache')
	raise RegistryError.new(ret), "Error while disabling predefined cache", caller if 0 != ret
end

.open(p_key, p_strSubKey, p_samDesired = KEY_QUERY_VALUE) ⇒ Object


class methodsFor: “opening/creating/connecting”



160
161
162
163
164
# File 'lib/Win32/Registry.rb', line 160

def RegKey.open(p_key, p_strSubKey, p_samDesired = KEY_QUERY_VALUE)
	key = RegKey.new
	key.open(p_key, p_strSubKey, p_samDesired)
	return key
end

Instance Method Details

#close(p_bFlush = false) ⇒ Object


methodsFor: “closing”

Raises:



236
237
238
239
240
241
242
# File 'lib/Win32/Registry.rb', line 236

def close(p_bFlush = false)
	return 0 if @key.nil?
	flush() if p_bFlush
	ret = WCall('CloseKey', @key)
	@key = nil
	raise RegistryError.new(ret), "Cannot close key", caller if 0 != ret
end

#connect(p_strHost, p_key) ⇒ Object

Raises:



217
218
219
220
221
222
223
# File 'lib/Win32/Registry.rb', line 217

def connect(p_strHost, p_key)
	self.close if !@key.nil?
	pKey = "\0" * 4		# pointer to long
	ret = WCall('ConnectRegistry', p_strHost.to_ucs2(true), p_key.to_i, pKey)
	raise RegistryError.new(ret), "Cannot connect to #{p_strHost}", caller if 0 != ret
	@key = pKey.unpack("L")[0]
end

#create(p_key, p_strSubKey, p_strClass = '', p_nOptions = REG_OPTION_NON_VOLATILE, p_samDesired = 0, p_pSecurityAttributes = nil) ⇒ Object



195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
# File 'lib/Win32/Registry.rb', line 195

def create(
		p_key,
		p_strSubKey,
		p_strClass            = '',
		p_nOptions            = REG_OPTION_NON_VOLATILE,
		p_samDesired          = 0,
		p_pSecurityAttributes = nil)
	self.close if !@key.nil?
	pKey         = "\0" * 4		# pointer to long
	pDisposition = "\0" * 4		# pointer to long
	ret = WCall('CreateKey',
				p_key.to_i, p_strSubKey.to_ucs2(true), 0, p_strClass.to_ucs2(true),
				p_nOptions, p_samDesired, 0, #p_SecurityAttributes.pack, let's ignore this...
				pKey, pDisposition)
	if 0 == ret or (ERROR_ACCESS_DENIED == ret and
					REG_OPENED_EXISTING_KEY == pDisposition.unpack('L')[0])
		@key = pKey.unpack("L")[0]
	else
		raise RegistryError.new(ret), "Cannot create: #{p_strSubKey}", caller
	end
end

#deleteValue(p_strName) ⇒ Object

Raises:

  • (Registry)


274
275
276
277
278
# File 'lib/Win32/Registry.rb', line 274

def deleteValue(p_strName)
	raise Registry, "Key was not initialized properly", caller if @key.nil?
	ret = WCall('DeleteValue', @key, p_strName.to_ucs2(true))
	raise RegistryError.new(ret), "Error while deleting value #{p_strName}", caller if 0 != ret
end

#eachKeyObject


methodsFor: “enumerating”

Raises:

  • (Registry)


308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
# File 'lib/Win32/Registry.rb', line 308

def eachKey
	raise Registry, "Key was not initialized properly", caller if @key.nil?
	return 0 if !block_given?
	n = 0
	while true
		strKey       = "\0" * MAXCHARS		# UCS2 String Buffer
		pszKey       = [MAXCHARS].pack('L')	# pointer to long
		strClass     = "\0" * MAXCHARS		# UCS2 String Buffer
		pszClass     = [MAXCHARS].pack("L")	# pointer to long
		pftLastWrite = "\0" * 4				# pointer to long
		ret = WCall('EnumKey', @key, n, strKey, pszKey, 0, strClass, pszClass, pftLastWrite)
		case ret
			when 0
				szKey   = pszKey.unpack('L')[0] * 2		# UCS2 characters
				szClass = pszClass.unpack('L')[0] * 2	# UCS2 characters
				yield(	strKey[0, szKey].to_utf8,
						strClass[0, szClass].to_utf8,
						pftLastWrite.unpack('L')[0])
				n += 1
			when ERROR_NO_MORE_ITEMS then break
			else
				raise RegistryError.new(ret), "Cannot access key ##{n} in enumeration", caller
		end
	end
	return n
end

#eachValueObject

Raises:

  • (Registry)


335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
# File 'lib/Win32/Registry.rb', line 335

def eachValue
	raise Registry, "Key was not initialized properly", caller if @key.nil?
	return 0 if !block_given?
	n = 0

	while true
		strName = "\0" * MAXCHARS			# UCS2 String Buffer
		pszName = [MAXCHARS].pack('L')		# pointer to long
		pnType  = " " * 4					# pointer to long
		pszData = " " * 4					# pointer to long

		# First call determines the size of data
		ret = WCall('EnumValue', @key, n, strName, pszName, 0, pnType, 0, pszData)
		case ret
			when 0
				szName = pszName.unpack('L')[0] * 2	# UCS2 characters
				szData = pszData.unpack('L')[0]
				nType  = pnType.unpack('L')[0]
				pData  = nil
				if szData > 0
					pszName = [512].pack('L')	# pointer to long
					pData   = "\0" * szData		# pointer to data
					# Second call retrieves the data
					ret = WCall('EnumValue', @key, n, strName, pszName, 0, 0, pData, pszData)
					raise RegistryError.new(ret), "Cannot access value ##{n} in enumeration", caller if 0 != ret
				end
				yield(	strName[0, szName].to_utf8,
						nType,
						szData,
						convertData(nType, pData, szData))
				n += 1
			when ERROR_NO_MORE_ITEMS then break
			else
				raise RegistryError.new(ret), "Cannot access value ##{n} in enumeration", caller
		end
	end
	return n
end

#flushObject


methodsFor: “flushing”

Raises:

  • (Registry)


246
247
248
249
250
# File 'lib/Win32/Registry.rb', line 246

def flush
	raise Registry, "Key was not initialized properly", caller if @key.nil?
	ret = WCall('FlushKey', @key)
	raise RegistryError.new(ret), "Error while flushing", caller if 0 != ret
end

#load(p_subKey, p_strFilename) ⇒ Object


methodsFor: “loading/unloading”

Raises:

  • (Registry)


282
283
284
285
286
# File 'lib/Win32/Registry.rb', line 282

def load(p_subKey, p_strFilename)
	raise Registry, "Key was not initialized properly", caller if @key.nil?
	ret = WCall('LoadKey', @key, p_subKey, p_strFilename.to_ucs2(true))
	raise RegistryError.new(ret), "Error while loading #{p_strFilename} into #{p_subkey}", caller if 0 != ret
end

#open(p_key, p_strSubKey, p_samDesired = KEY_QUERY_VALUE) ⇒ Object


methodsFor: “opening/creating/connecting”

Raises:



187
188
189
190
191
192
193
# File 'lib/Win32/Registry.rb', line 187

def open(p_key, p_strSubKey, p_samDesired = KEY_QUERY_VALUE)
	self.close if !@key.nil?
	pKey = "\0" * 4		# pointer to long
	ret = WCall('OpenKey', p_key.to_i, p_strSubKey.to_ucs2(true), 0, p_samDesired, pKey)
	raise RegistryError.new(ret), "Cannot Open Key: #{p_strSubKey}", caller if 0 != ret
	@key = pKey.unpack("L")[0]
end

#overridePredefKey(p_key) ⇒ Object


methodsFor: “miscellaneous”

Raises:

  • (Registry)


268
269
270
271
272
# File 'lib/Win32/Registry.rb', line 268

def overridePredefKey(p_key)
	raise Registry, "Key was not initialized properly", caller if @key.nil?
	ret = WCall('OverridePredefKey', p_key, @key)
	raise RegistryError.new(ret), "Error while overriding predefined key", caller if 0 != ret
end

#queryInfoObject


methodsFor: “querying”

Raises:

  • (Registry)


376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
# File 'lib/Win32/Registry.rb', line 376

def queryInfo
	raise Registry, "Key was not initialized properly", caller if @key.nil?
	pszClass             = "\0" * 4		# pointer to long
	pnSubKeys            = "\0" * 4		# pointer to long
	pnMaxSubKeyLen       = "\0" * 4		# pointer to long
	pnMaxClassLen        = "\0" * 4		# pointer to long
	pnValues             = "\0" * 4		# pointer to long
	pnMaxValueNameLen    = "\0" * 4		# pointer to long
	pnMaxValueLen        = "\0" * 4		# pointer to long
	pnSecurityDescriptor = "\0" * 4		# pointer to long
	pftLastWriteTime     = "\0" * 4		# pointer to long
	ret = WCall('QueryInfoKey',
			@key,
			0, pszClass,
			0,
			pnSubKeys, pnMaxSubKeyLen,
			pnMaxClassLen,
			pnValues, pnMaxValueNameLen, pnMaxValueLen,
			pnSecurityDescriptor,
			pftLastWriteTime)
	raise RegistryError.new(ret), "Cannot query info", caller if 0 != ret

	mRet = {}
	szClass                    = pszClass.unpack('L')[0] * 2			# UCS2 characters
	mRet['SubKeys']            = pnSubKeys.unpack('L')[0]
	mRet['MaxSubKeyLen']       = pnMaxSubKeyLen.unpack('L')[0]
	mRet['MaxClassLen']        = pnMaxClassLen.unpack('L')[0]
	mRet['Values']             = pnValues.unpack('L')[0]
	mRet['MaxValueNameLen']    = pnMaxValueNameLen.unpack('L')[0]
	mRet['MaxValueLen']        = pnMaxValueLen.unpack('L')[0]
	mRet['SecurityDescriptor'] = pnSecurityDescriptor.unpack('L')[0]
	mRet['LastWriteTime']      = pftLastWriteTime.unpack('L')[0]

	if szClass > 0
		szClass += 2
		strClass = " " * szClass
		pszClass = [szClass].pack('L')
		ret = WCall('QueryInfoKey', @key, strClass, pszClass, 0, 0, 0, 0, 0, 0, 0, 0, 0)
		raise RegistryError.new(ret), "Cannot query info", caller if 0 != ret
		mRet['Class'] = strClass.to_utf8
		print "class: ", strClass.inspect, "->", strClass, "\n"
	end
	return mRet
end

#queryMultipleValues(p_vstrNames) ⇒ Object

Raises:

  • (Registry)


441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
# File 'lib/Win32/Registry.rb', line 441

def queryMultipleValues(p_vstrNames)
	raise Registry, "Key was not initialized properly", caller if @key.nil?
	pszData  = "\0" * 4		# pointer to long
	pvValues = Array.new()
	p_vstrNames.each {|str| pvValues << str.to_ucs2(true) }
	ret = WCall('QueryMultipleValues', @key, pvValues, pvValues.size, 0, pszData)
	raise RegistryError.new(ret), "Cannot query values #{p_vstrNames}", caller if 0 != ret and ERROR_MORE_DATA != ret

	mRet = {}
	szData = pszData.unpack('L')[0]
	if szData > 0
		pData = "\0" * szData	# pointer to long
		ret = WCall('QueryMultipleValues', @key, pvValues, pvValues.size, pData, pszData)
		raise RegistryError.new(ret), "Cannot query values #{p_vstrNames}", caller if 0 != ret
		mRet['Value'] = convertData(nType, pData, szData)
	end
	return mRet
end

#queryValue(p_strName) ⇒ Object

Raises:

  • (Registry)


421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
# File 'lib/Win32/Registry.rb', line 421

def queryValue(p_strName)
	raise Registry, "Key was not initialized properly", caller if @key.nil?
	strName = p_strName.to_ucs2(true)
	pnType  = " " * 4		# pointer to long
	pszData = " " * 4		# pointer to long
	ret = WCall('QueryValue', @key, strName, 0, pnType, 0, pszData)
	raise RegistryError.new(ret), "Cannot query value #{p_strName}", caller if 0 != ret

	mRet         = {}
	mRet['Type'] = nType = pnType.unpack('L')[0]
	szData       = pszData.unpack('L')[0]
	if szData > 0
		pData = "\0" * szData	# pointer to long
		ret = WCall('QueryValue', @key, strName, 0, 0, pData, pszData)
		raise RegistryError.new(ret), "Cannot query value #{p_strName}", caller if 0 != ret
		mRet['Value'] = convertData(nType, pData, szData)
	end
	return mRet
end

#replace(p_subKey, p_strNewFilename, p_strOldFilename) ⇒ Object


methodsFor: “replacing”

Raises:

  • (Registry)


227
228
229
230
231
232
# File 'lib/Win32/Registry.rb', line 227

def replace(p_subKey, p_strNewFilename, p_strOldFilename)
	raise Registry, "Key was not initialized properly", caller if @key.nil?
	ret = WCall('ReplaceKey', @key, p_subKey,
				p_strNewFilename.to_ucs2(true), p_strOldFilename.to_ucs2(true))
	raise RegistryError.new(ret), "Cannot replace #{p_subKey}", caller if 0 != ret
end

#restore(p_strFilename, p_options) ⇒ Object

Raises:

  • (Registry)


300
301
302
303
304
# File 'lib/Win32/Registry.rb', line 300

def restore(p_strFilename, p_options)
	raise Registry, "Key was not initialized properly", caller if @key.nil?
	ret = WCall('RestoreKey', @key, p_strFilename.to_ucs2(true), p_options)
	raise RegistryError.new(ret), "Error while restoring from #{p_strFilename}", caller if 0 != ret
end

#save(p_strFilename, p_security = 0) ⇒ Object

Raises:

  • (Registry)


294
295
296
297
298
# File 'lib/Win32/Registry.rb', line 294

def save(p_strFilename, p_security = 0)
	raise Registry, "Key was not initialized properly", caller if @key.nil?
	ret = WCall('SaveKey', @key, p_strFilename.to_ucs2(true), pSecurity)
	raise RegistryError.new(ret), "Error while saving to #{p_strFilename}", caller if 0 != ret
end

#setValue(p_strName, p_nType, p_pData) ⇒ Object

Raises:

  • (Registry)


460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
# File 'lib/Win32/Registry.rb', line 460

def setValue(p_strName, p_nType, p_pData)
	raise Registry, "Key was not initialized properly", caller if @key.nil?
	case p_nType
		when REG_BINARY					then pData = [p_pData].pack('C*')
		when REG_DWORD					then pData = [p_pData].pack('L')
		when REG_DWORD_BIG_ENDIAN		then pData = [p_pData].pack('L')
		when REG_DWORD_LITTLE_ENDIAN	then pData = [p_pData].pack('V')
		when REG_EXPAND_SZ				then pData = p_pData.to_ucs2(true)
		when REG_LINK					then pData = p_pData
		when REG_NONE					then pData = p_pData
		when REG_SZ						then pData = p_pData.to_ucs2(true)
		when REG_MULTI_SZ
			pData = []
			p_pData.each {|str| pData << str.to_ucs2(true) }
			pData << "\000\000"
		else							return -2
	end
	strName = p_strName.to_ucs2(true)
	ret = WCall('SetValue', @key, strName, 0, p_nType, pData, pData.size)
	raise RegistryError.new(ret), "Cannot set value #{p_strName}", caller if 0 != ret
end

#to_iObject


methodsFor: “accessing”



484
485
486
# File 'lib/Win32/Registry.rb', line 484

def to_i
	return @key
end

#to_sObject


methodsFor: “printing”



490
491
492
# File 'lib/Win32/Registry.rb', line 490

def to_s
	return super + " Key: #{@key}"
end

#unLoad(p_subKey) ⇒ Object

Raises:



288
289
290
291
292
# File 'lib/Win32/Registry.rb', line 288

def unLoad(p_subKey)
	return -1 if @key.nil?
	ret = WCall('UnLoadKey', @key, p_subKey)
	raise RegistryError.new(ret), "Error while unloading #{p_subkey}", caller if 0 != ret
end