blob: 2694956814de32625c1067b479a75879eeb643c0 [file] [log] [blame]
Fred Drake69218172000-06-29 16:53:06 +00001import winreg
2import sys
3import exceptions
4import array
5from types import *
6import string
7
8class RegType:
9 def __init__( self, msname, friendlyname ):
10 self.msname=msname
11 self.friendlyname=friendlyname
12 self.intval=getattr( winreg, msname )
13
14 def __repr__( self ):
15 return "<RegType %d: %s %s>" % \
16 (self.intval, self.msname, self.friendlyname )
17
18_typeConstants={
19 winreg.REG_NONE:
20 RegType( "REG_NONE", "None" ),
21 winreg.REG_SZ:
22 RegType( "REG_SZ", "String" ),
23 winreg.REG_EXPAND_SZ:
24 RegType("REG_EXPAND_SZ", "Expandable Template String" ),
25 winreg.REG_BINARY:
26 RegType("REG_BINARY", "Binary Data"),
27 winreg.REG_DWORD :
28 RegType("REG_DWORD", "Integer" ),
29# winreg.REG_DWORD_LITTLE_ENDIAN :
30# RegType("REG_DWORD_LITTLE_ENDIAN", "Integer"),
31 winreg.REG_DWORD_BIG_ENDIAN :
32 RegType("REG_DWORD_BIG_ENDIAN", "Big Endian Integer"),
33 winreg.REG_LINK :
34 RegType("REG_LINK", "Link"),
35 winreg.REG_MULTI_SZ :
36 RegType("REG_MULTI_SZ", "List of Strings"),
37 winreg.REG_RESOURCE_LIST :
38 RegType("REG_RESOURCE_LIST", "Resource List"),
39 winreg.REG_FULL_RESOURCE_DESCRIPTOR :
40 RegType( "REG_FULL_RESOURCE_DESCRIPTOR",
41 "Full Resource Descriptor" ),
42 winreg.REG_RESOURCE_REQUIREMENTS_LIST:
43 RegType( "REG_RESOURCE_REQUIREMENTS_LIST",
44 "Resource Requirements List" )
45}
46
47regtypes={}
48for constant in _typeConstants.values():
49 regtypes[constant.msname]=constant
50
51class _DictBase:
52 def __init__( self, key ):
53 self.key=key
54
55 def clear( self ):
56 keys=list( self.keys() )
57 map( self.__delitem__, keys )
58
59 def get( self, item, defaultVal=None ):
60 try:
61 return self.__getitem__( item )
62 except (IndexError, EnvironmentError, WindowsError):
63 return defaultVal
64
65 def has_key( self, item ):
66 try:
67 self.__getitem__( item )
68 return 1
69 except (IndexError, EnvironmentError, WindowsError):
70 return 0
71
72 def keys( self ):
73 keys=[]
74 try:
75 for i in xrange( 0, sys.maxint ):
76 keyname = self._nameFromNum( i )
77 keys.append( keyname )
78 except (IndexError, EnvironmentError, WindowsError):
79 pass
80 return keys
81
82 def values( self ):
83 values=[] # map() doesn't use the IndexError semantics...
84 for i in self:
85 values.append( i )
86 return values
87
88 def items( self ):
89 return map( None, self.keys(), self.values() )
90
91 def __len__( self ):
92 return len( self.keys() )
93
94def _getName( item, nameFromNum ):
95 if type( item ) == IntType:
96 try:
97 keyname = nameFromNum( item )
98 except (WindowsError, EnvironmentError):
99 raise IndexError, item
100
101 elif type( item )==StringType:
102 keyname=item
103 else:
104 raise exceptions.TypeError, \
105 "Requires integer index or string key name"
106 return keyname
107
108
109class RegValuesDict( _DictBase ):
110 def _nameFromNum( self, i ):
111 return self.key._nameFromNum( i )
112
113 def __getitem__( self, item ):
114 return self.key.getValueNameDataAndType( item )
115
116 def __setitem__( self, name, val):
117 if type( val )==TupleType:
118 data, datatype=val
119 assert isinstance( datatype, RegType )
120 self.key.setValue( name, data, datatype )
121 else:
122 self.key.setValue( name, val )
123
124 def __delitem__( self, item ):
125 valname=_getName( item, self._nameFromNum )
126 self.key.deleteValue( valname )
127
128
129class RegKeysDict( _DictBase ):
130 def _nameFromNum( self, item ):
131 return winreg.EnumKey( self.key.handle, item )
132
133 def __getitem__( self, item ):
134 keyname=_getName( item, self._nameFromNum )
135 return self.key.openSubkey( keyname )
136
137 def __delitem__( self, item ):
138 keyname=_getName( item, self._nameFromNum )
139 self.key.deleteSubkey( keyname )
140
141def openKey( keyname, samFlags=None ):
142 lst=string.split( keyname, "\\", 1 )
143 if len( lst )==2:
144 hivename,path=lst
145 return hives[hivename].openSubkey( path )
146 else:
147 hivename=lst[0]
148 return hives[hivename]
149
150def createKey( keyname ):
151 lst=string.split( keyname, "\\", 1 )
152 assert len( lst )==2
153 hivename,path=lst
154 return hives[hivename].createSubkey( path )
155
156def deleteKey( keyname ):
157 lst=string.split( keyname, "\\", 1 )
158 assert len( lst )==2
159 hivename,path=lst
160 return hives[hivename].deleteSubkey( path )
161
162
163class RegKey:
164 def _nameFromNum( self, item ):
165 (name,data,datatype)=winreg.EnumValue( self.handle, item )
166 return name
167
168 def __nonzero__(self):
169 if self.handle:
170 return 1
171 else:
172 return 0
173
174 def __cmp__ (self, other ):
175 if hasattr( other, "handle" ) and hasattr( other, "name" ):
176 return cmp( self.name, other.name )
177 else:
178 return cmp( self.handle, other )
179
180 def __init__( self, name, handle=None ):
181 self.name=name
182 self.handle=handle
183
184 def __repr__( self ):
185 return "<Windows RegKey: %s>"% self.name
186
187 def close(self ):
188 return winreg.CloseKey( self.handle )
189
190 def getSubkeyNames( self ):
191 return self.getSubkeys().keys()
192
193 def getValueNames( self ):
194 return self.getValues().keys()
195
196 def deleteSubkey( self, subkey ):
197 return winreg.DeleteKey( self.handle, subkey )
198
199 def deleteValue( self, valname ):
200 return winreg.DeleteValue( self.handle, valname )
201
202 def createSubkey( self, keyname ):
203 handle=winreg.CreateKey( self.handle, keyname )
204 return RegKey( self.name+"\\"+keyname, handle)
205
206 def openSubkey( self, keyname, samFlags=None ):
207 if samFlags:
208 handle=winreg.OpenKey( self.handle, keyname, 0, samFlags )
209 else:
210 handle=winreg.OpenKey( self.handle, keyname, 0 )
211 return RegKey( self.name+"\\"+keyname, handle )
212
213 def getSubkeys( self ):
214 return RegKeysDict( self )
215
216 def getValues( self ):
217 return RegValuesDict( self )
218
219 def getValueNameDataAndType( self, valname ):
220 try:
221 if type( valname )==IntType:
222 (valname,data,datatype)=winreg.EnumValue( self.handle, valname )
223 else:
224 keyname=_getName( valname, self._nameFromNum )
225 (data,datatype)=winreg.QueryValueEx( self.handle, keyname )
226 except (WindowsError, EnvironmentError):
227 raise IndexError, valname
228
229 if datatype==winreg.REG_BINARY:
230 # use arrays for binary data
231 data=array.array( 'c', data )
232
233 return (valname, data, _typeConstants[datatype] )
234
235 def getValueData( self, valname ):
236 name, data, type=self.getValueNameDataAndType( valname )
237 return data
238
239 def setValue( self, valname, data, regtype=None ):
240 if regtype:
241 typeint=regtype.intval
242 else:
243 if type( data )==StringType:
244 typeint=winreg.REG_SZ
245 elif type( data )==IntType:
246 typeint=winreg.REG_DWORD
247 elif type( data )==array.ArrayType:
248 typeint=winreg.REG_BINARY
249 data=data.tostring()
250 winreg.SetValueEx( self.handle, valname, 0, typeint, data )
251
252 def flush(self ):
253 winreg.FlushKey( self.keyobbj )
254
255 def save( self, filename ):
256 winreg.SaveKey( self.keyobj, filename )
257
258 def load( self, subkey, filename ):
259 return winreg.RegLoadKey( self.handle, subkey, filename )
260
261
262class RemoteKey( RegKey ):
263 def __init__( self, machine, topLevelKey ):
264 assert topLevelKey in _hivenames
265 self.handle = winreg.ConnectRegistry( machine, parentKey )
266 self.name=r"\\%s\%s" % (machine, topLevelKey )
267
268_hivenames = ["HKEY_CLASSES_ROOT","HKEY_CURRENT_USER","HKEY_LOCAL_MACHINE",
269 "HKEY_USERS","HKEY_CURRENT_CONFIG","HKEY_DYN_DATA",
270 "HKEY_PERFORMANCE_DATA"]
271hives={}
272for name in _hivenames:
273 hives[name]=RegKey( name, getattr( winreg, name ) )
274hives["HKLM"]=hives["HKEY_LOCAL_MACHINE"]
275hives["HKCR"]=hives["HKEY_CLASSES_ROOT"]
276hives["HKCU"]=hives["HKEY_CURRENT_USER"]
277
278_flagnames = ["KEY_ALL_ACCESS","KEY_CREATE_LINK", "KEY_CREATE_SUB_KEY",
279 "KEY_ENUMERATE_SUB_KEYS", "KEY_EXECUTE", "KEY_NOTIFY",
280 "KEY_QUERY_VALUE", "KEY_READ", "KEY_SET_VALUE"]
281flags={}
282for name in _flagnames:
283 flags[name]=getattr( winreg, name )
284
285_RegNotifyChangeKeyValueOptions=[ "REG_NOTIFY_CHANGE_ATTRIBUTES",
286 "REG_NOTIFY_CHANGE_SECURITY", "REG_NOTIFY_CHANGE_LAST_SET",
287 "REG_NOTIFY_CHANGE_NAME", "REG_LEGAL_CHANGE_FILTER" ]
288
289_RegRestoreKeyOptions=["REG_WHOLE_HIVE_VOLATILE",
290 "REG_NO_LAZY_FLUSH",
291 "REG_OPTION_VOLATILE",
292 "REG_REFRESH_HIVE",
293 "REG_OPTION_NON_VOLATILE",
294 "REG_OPTION_BACKUP_RESTORE" ]
295
296_RegCreateKeyExOptions=[
297 "REG_LEGAL_OPTION",
298 "REG_OPTION_RESERVED",
299 "REG_OPTION_VOLATILE",
300 "REG_OPTION_NON_VOLATILE",
301 "REG_OPTION_BACKUP_RESTORE",
302 "REG_CREATED_NEW_KEY",
303 "REG_OPENED_EXISTING_KEY",
304 "REG_OPTION_CREATE_LINK"]
305
306def test():
307 import testreg
308
309#unusednames=_RegNotifyChangeKeyValueOptions+_RegRestoreKeyOptions+_RegCreateKeyExOptions
310
311#typeConstantNames=map( lambda x: x.msname, typeConstants.values() )
312
313#allnames=_hivenames+_flagnames+typeConstantNames+unusednames
314#winregnames=winreg.__dict__.keys()
315#for name in winregnames:
316# if name not in allnames:
317# print name
318