-
Notifications
You must be signed in to change notification settings - Fork 0
/
winereg.py
185 lines (152 loc) · 5.47 KB
/
winereg.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
"""Preliminary Python support for the Wine registry
winereg is an attempt to provide a module similar, but not identical, to the
existing _winreg (or winreg) on Windows for accessing registry keys.
It is only similar because it works very differently from _winreg, opening the
hive files directly and using standard string editing to manipulate them.
Since it works very differently, attempts have been made to provide some
functions which at least appear to act the same as their _winreg counterparts,
but in fact do not (and exist only so an application can use both).
winereg was written as part of the bxbuild project, and so it may or may not be
expanded further to provide full registry editing access. It only provides
a handful of the functions provided by _winreg.
"""
import os
winePath = os.path.expanduser("~/.wine")
HKEY_CURRENT_USER = "user.reg"
HKEY_LOCAL_MACHINE = "system.reg"
HKEY_USERS = "userdef.reg"
#Some useless _winreg constants that we need to emulate (they don't do anything in winereg (yet))
KEY_ALL_ACCESS = 0
KEY_READ = 1
REG_SZ = 2
class RegistryKey:
"""Class for winereg, this is NOT anything to do with winreg! And therefore behaves more sanely than some wrappers."""
def __init__(self, hiveFile, keyName):
self.hiveFile = hiveFile
self.keyName = keyName
def __str__(self):
return self.keyName + " in " + self.hiveFile
def __repr__(self):
return self.keyName + " in " + self.hiveFile
def getHiveName(self):
"""Return the full path and name of the hive file"""
global winePath
return winePath + "/" + self.hiveFile
def getHive(self, mode):
"""Open the hive file and return a copy in whatever mode is passed"""
try:
hive = open(self.getHiveName(), mode)
return hive
except IOError:
return None
# A dummy error message for problems relating to Wine, may add stuff here later.
class WineError(Exception):
pass
# This is defined by Python, but only on Windows, so we need it for non-win32...
class WindowsError(Exception):
pass
def isWineRunning():
"""Check to see if wine is running... we can't edit the registry if it is"""
# There has *got* to be a better way to do this. This uses os.system and ps, it's awful.
try:
os.system("ps -ef | grep wine > ps.out")
output = open("ps.out", 'rt')
outText = output.read()
output.close()
os.remove("ps.out")
if "wineserver" in outText:
return True
return False
except:
return False
def OpenKey(key, subKey, res=None, sam=None):
"""Opens the specified key. 'key' MUST be a HKEY constant, unlike _winreg."""
global winePath
global HKEY_CURRENT_USER
global HKEY_LOCAL_MACHINE
#_winreg is too complicated for it's own good... fix later
if (key != HKEY_CURRENT_USER and key != HKEY_LOCAL_MACHINE):
print "winereg implementation error: 'key' must be a HKEY constant"
return None
#Fix the double backslash
subKey = subKey.replace('\\' , '\\\\')
#Try to open, if we find something, return a RegistryKey class
hiveName = winePath + "/" + key
try:
hive = open(hiveName, 'rt')
hiveData = hive.read()
if subKey in hiveData:
regKey = RegistryKey(key, subKey)
return regKey
else:
return None
except:
return None
def QueryValue(key, valueName):
"""Retrieves the data for a specified value name associated with an open registry key"""
#Verify that this is a valid key
if key == None:
return None
#Open the hive file in read mode
hive = key.getHive('rt')
hiveText = hive.read()
hive.close()
#Find the subkey name that we're looking for
hiveText = hiveText[hiveText.find(key.keyName):]
hiveText = hiveText[:hiveText.find("\n\n") + 1]
value = hiveText[hiveText.find(valueName) + len(valueName) + 3:]
value = value[:value.find("\n") - 1]
return value
def QueryValueEx(key, valueName):
"""Retrieves the data and datatype for a specified value name associated with an open registry key"""
#I'm too lazy to implement this
value = QueryValue(key, valueName)
return value, 0
def SetValue(key, subKey, type, value):
"""Stores data in the value field of an open registry key."""
global HKEY_CURRENT_USER
global HKEY_LOCAL_MACHINE
#The key can't be none
if key == None:
return False
#Wine can't be running when we try this operation
if isWineRunning():
raise WineError
#_winreg is too complicated for it's own good... fix later
try:
if (key == HKEY_CURRENT_USER or key == HKEY_LOCAL_MACHINE):
print "winereg implementation error: 'key' must NOT be a HKEY constant"
return False
except:
return False
#Now, make a new hive file with the new key (this is an awful way to do it... but whatever)
hive = key.getHive('rt')
newHive = ""
valid = True
for line in hive:
#Verify that we haven't found the key yet
if key.keyName in line:
valid = False
#If we have not found the key, keep adding lines to the new file; if we have, and we've gotten to the end, resume adding lines normally
if valid:
newHive += line
elif line == "\n":
valid = False
#If we've found the key check if we've found the right property; if we HAVE, change it
if not valid:
if subKey in line:
line = line[:line.find(subKey) + len(subKey) + 3]
line += value
line += '"\n'
newHive += line
#Write the new hive file
hive.close()
hive = key.getHive('wt')
hive.write(newHive)
hive.close()
return True
def SetValueEx(key, subKey, datum, type, value):
"""Retrieves the data and datatype for a specified value name associated with an open registry key"""
#I'm too lazy to implement this
value = SetValue(key, subKey, type, value)
return value, 0