2024.8.23
Loading...
Searching...
No Matches
class.registry.php
Go to the documentation of this file.
1<?php
2/*
3 * Copyright (c) 2021-2024 Bearsampp
4 * License: GNU General Public License version 3 or later; see LICENSE.txt
5 * Author: Bear
6 * Website: https://bearsampp.com
7 * Github: https://github.com/Bearsampp
8 */
9
10/**
11 * Class Registry
12 *
13 * This class provides methods to interact with the Windows Registry using VBScript.
14 * It includes functionalities to check the existence of registry keys, get and set values,
15 * and delete registry entries. The class also logs operations and errors.
16 */
18{
19 const END_PROCESS_STR = 'FINISHED!';
20
21 const HKEY_CLASSES_ROOT = 'HKCR';
22 const HKEY_CURRENT_USER = 'HKCU';
23 const HKEY_LOCAL_MACHINE = 'HKLM';
24 const HKEY_USERS = 'HKEY_USERS';
25
26 const REG_SZ = 'REG_SZ';
27 const REG_EXPAND_SZ = 'REG_EXPAND_SZ';
28 const REG_BINARY = 'REG_BINARY';
29 const REG_DWORD = 'REG_DWORD';
30 const REG_MULTI_SZ = 'REG_MULTI_SZ';
31
32 const REG_ERROR_ENTRY = 'REG_ERROR_ENTRY';
33 const REG_ERROR_SET = 'REG_ERROR_SET';
34 const REG_NO_ERROR = 'REG_NO_ERROR';
35
36 const ENV_KEY = 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment';
37
38 // App bins entry
39 const APP_BINS_REG_ENTRY = 'BEARSAMPP_BINS';
40
41 // App path entry
42 const APP_PATH_REG_ENTRY = 'BEARSAMPP_PATH';
43
44 // System path entry
45 const SYSPATH_REG_ENTRY = 'Path';
46
47 // Processor architecture
48 const PROCESSOR_REG_SUBKEY = 'HARDWARE\DESCRIPTION\System\CentralProcessor\0';
49 const PROCESSOR_REG_ENTRY = 'Identifier';
50
51 private $latestError;
52
53 /**
54 * Registry constructor.
55 * Initializes the Registry class and logs the initialization.
56 */
57 public function __construct()
58 {
59 Util::logInitClass($this);
60 $this->latestError = null;
61 }
62
63 /**
64 * Writes a log entry.
65 *
66 * @param string $log The log message to write.
67 */
68 private function writeLog($log)
69 {
70 global $bearsamppRoot;
71 Util::logDebug($log, $bearsamppRoot->getRegistryLogFilePath());
72 }
73
74 /**
75 * Checks if a registry key or entry exists.
76 *
77 * @param string $key The root key (e.g., HKEY_LOCAL_MACHINE).
78 * @param string $subkey The subkey path.
79 * @param string|null $entry The entry name (optional).
80 * @return bool True if the key or entry exists, false otherwise.
81 */
82 public function exists($key, $subkey, $entry = null)
83 {
84 $basename = 'registryExists';
85 $resultFile = Vbs::getResultFile($basename);
86
87 $scriptContent = 'On Error Resume Next' . PHP_EOL;
88 $scriptContent .= 'Err.Clear' . PHP_EOL . PHP_EOL;
89
90 $scriptContent .= 'Dim objShell, objFso, objFile, outFile, bExists' . PHP_EOL . PHP_EOL;
91
92 $scriptContent .= 'outFile = "' . $resultFile . '"' . PHP_EOL;
93 $scriptContent .= 'Set objShell = WScript.CreateObject("WScript.Shell")' . PHP_EOL;
94 $scriptContent .= 'Set objFso = CreateObject("Scripting.FileSystemObject")' . PHP_EOL;
95 $scriptContent .= 'Set objFile = objFso.CreateTextFile(outFile, True)' . PHP_EOL . PHP_EOL;
96
97 $scriptContent .= 'strKey = "' . $key . '\\' . $subkey . '\\' . $entry . '"' . PHP_EOL;
98 $scriptContent .= 'entryValue = objShell.RegRead(strKey)' . PHP_EOL;
99 $scriptContent .= 'If Err.Number <> 0 Then' . PHP_EOL;
100 $scriptContent .= ' If Right(strKey,1) = "\" Then' . PHP_EOL;
101 $scriptContent .= ' If Instr(1, Err.Description, ssig, 1) <> 0 Then' . PHP_EOL;
102 $scriptContent .= ' bExists = true' . PHP_EOL;
103 $scriptContent .= ' Else' . PHP_EOL;
104 $scriptContent .= ' bExists = false' . PHP_EOL;
105 $scriptContent .= ' End If' . PHP_EOL;
106 $scriptContent .= ' Else' . PHP_EOL;
107 $scriptContent .= ' bExists = false' . PHP_EOL;
108 $scriptContent .= ' End If' . PHP_EOL;
109 $scriptContent .= ' Err.Clear' . PHP_EOL;
110 $scriptContent .= 'Else' . PHP_EOL;
111 $scriptContent .= ' bExists = true' . PHP_EOL;
112 $scriptContent .= 'End If' . PHP_EOL . PHP_EOL;
113
114 $scriptContent .= 'On Error Goto 0' . PHP_EOL;
115 $scriptContent .= 'If bExists = vbFalse Then' . PHP_EOL;
116 $scriptContent .= ' objFile.Write "0"' . PHP_EOL;
117 $scriptContent .= 'Else' . PHP_EOL;
118 $scriptContent .= ' objFile.Write "1"' . PHP_EOL;
119 $scriptContent .= 'End If' . PHP_EOL;
120 $scriptContent .= 'objFile.Close' . PHP_EOL;
121
122 $result = Vbs::exec($basename, $resultFile, $scriptContent);
123 $result = isset($result[0]) ? $result[0] : null;
124
125 $this->writeLog('Exists ' . $key . '\\' . $subkey . '\\' . $entry);
126 $this->writeLog('-> result: ' . $result);
127
128 return !empty($result) && intval($result) == 1;
129 }
130
131 /**
132 * Retrieves the value of a registry entry.
133 *
134 * @param string $key The root key (e.g., HKEY_LOCAL_MACHINE).
135 * @param string $subkey The subkey path.
136 * @param string|null $entry The entry name (optional).
137 * @return mixed The value of the registry entry, or false on error.
138 */
139 public function getValue($key, $subkey, $entry = null)
140 {
141 global $bearsamppLang;
142
143 $basename = 'registryGetValue';
144 $resultFile = Vbs::getResultFile($basename);
145 $this->latestError = null;
146
147 $scriptContent = 'On Error Resume Next' . PHP_EOL;
148 $scriptContent .= 'Err.Clear' . PHP_EOL . PHP_EOL;
149
150 $scriptContent .= 'Dim objShell, objFso, objFile, outFile, entryValue' . PHP_EOL . PHP_EOL;
151
152 $scriptContent .= 'outFile = "' . $resultFile . '"' . PHP_EOL;
153 $scriptContent .= 'Set objShell = WScript.CreateObject("WScript.Shell")' . PHP_EOL;
154 $scriptContent .= 'Set objFso = CreateObject("Scripting.FileSystemObject")' . PHP_EOL;
155 $scriptContent .= 'Set objFile = objFso.CreateTextFile(outFile, True)' . PHP_EOL . PHP_EOL;
156
157 $scriptContent .= 'entryValue = objShell.RegRead("' . $key . '\\' . $subkey . '\\' . $entry . '")' . PHP_EOL;
158 $scriptContent .= 'If Err.Number <> 0 Then' . PHP_EOL;
159 $scriptContent .= ' objFile.Write "' . self::REG_ERROR_ENTRY . '" & Err.Number & ": " & Err.Description' . PHP_EOL;
160 $scriptContent .= 'Else' . PHP_EOL;
161 $scriptContent .= ' objFile.Write entryValue' . PHP_EOL;
162 $scriptContent .= 'End If' . PHP_EOL;
163 $scriptContent .= 'objFile.Close' . PHP_EOL;
164
165 $result = Vbs::exec($basename, $resultFile, $scriptContent);
166 $result = isset($result[0]) ? $result[0] : null;
167 $this->writeLog('GetValue ' . $key . '\\' . $subkey . '\\' . $entry);
168 $this->writeLog('-> result: ' . $result);
169 if (Util::startWith($result, self::REG_ERROR_ENTRY)) {
170 $this->latestError = $bearsamppLang->getValue(Lang::ERROR) . ' ' . str_replace(self::REG_ERROR_ENTRY, '', $result);
171 return false;
172 }
173
174 return $result;
175 }
176
177 /**
178 * Sets a string value in the registry.
179 *
180 * @param string $key The root key (e.g., HKEY_LOCAL_MACHINE).
181 * @param string $subkey The subkey path.
182 * @param string $entry The entry name.
183 * @param string $value The value to set.
184 * @return bool True if the value was set successfully, false otherwise.
185 */
186 public function setStringValue($key, $subkey, $entry, $value)
187 {
188 return $this->setValue($key, $subkey, $entry, $value, 'SetStringValue');
189 }
190
191 /**
192 * Sets an expanded string value in the registry.
193 *
194 * @param string $key The root key (e.g., HKEY_LOCAL_MACHINE).
195 * @param string $subkey The subkey path.
196 * @param string $entry The entry name.
197 * @param string $value The value to set.
198 * @return bool True if the value was set successfully, false otherwise.
199 */
200 public function setExpandStringValue($key, $subkey, $entry, $value)
201 {
202 return $this->setValue($key, $subkey, $entry, $value, 'SetExpandedStringValue');
203 }
204
205 /**
206 * Deletes a registry entry.
207 *
208 * @param string $key The root key (e.g., HKEY_LOCAL_MACHINE).
209 * @param string $subkey The subkey path.
210 * @param string $entry The entry name.
211 * @return bool True if the entry was deleted successfully, false otherwise.
212 */
213 public function deleteValue($key, $subkey, $entry)
214 {
215 $this->writeLog('delete');
216 return $this->setValue($key, $subkey, $entry, null, 'DeleteValue');
217 }
218
219 /**
220 * Sets a value in the registry.
221 *
222 * @param string $key The root key (e.g., HKEY_LOCAL_MACHINE).
223 * @param string $subkey The subkey path.
224 * @param string $entry The entry name.
225 * @param string|null $value The value to set (optional).
226 * @param string $type The type of value to set (e.g., SetStringValue).
227 * @return bool True if the value was set successfully, false otherwise.
228 */
229 private function setValue($key, $subkey, $entry, $value, $type)
230 {
231 global $bearsamppLang;
232
233 $basename = 'registrySetValue';
234 $resultFile = Vbs::getResultFile($basename);
235 $this->latestError = null;
236
237 $strKey = $key;
238 if ($key == self::HKEY_CLASSES_ROOT) {
239 $key = '&H80000000';
240 } elseif ($key == self::HKEY_CURRENT_USER) {
241 $key = '&H80000001';
242 } elseif ($key == self::HKEY_LOCAL_MACHINE) {
243 $key = '&H80000002';
244 } elseif ($key == self::HKEY_LOCAL_MACHINE) {
245 $key = '&H80000003';
246 }
247
248 $scriptContent = 'On Error Resume Next' . PHP_EOL;
249 $scriptContent .= 'Err.Clear' . PHP_EOL . PHP_EOL;
250
251 $scriptContent .= 'Const HKEY = ' . $key . PHP_EOL . PHP_EOL;
252
253 $scriptContent .= 'Dim objShell, objRegistry, objFso, objFile, outFile, entryValue, newValue' . PHP_EOL . PHP_EOL;
254
255 $scriptContent .= 'newValue = "' . (!empty($value) ? str_replace('"', '""', $value) : '') . '"' . PHP_EOL;
256 $scriptContent .= 'outFile = "' . $resultFile . '"' . PHP_EOL;
257 $scriptContent .= 'Set objShell = WScript.CreateObject("WScript.Shell")' . PHP_EOL;
258 $scriptContent .= 'Set objRegistry = GetObject("winmgmts://./root/default:StdRegProv")' . PHP_EOL;
259 $scriptContent .= 'Set objFso = CreateObject("Scripting.FileSystemObject")' . PHP_EOL;
260 $scriptContent .= 'Set objFile = objFso.CreateTextFile(outFile, True)' . PHP_EOL . PHP_EOL;
261
262 if (!empty($value)) {
263 $scriptContent .= 'objRegistry.' . $type . ' HKEY, "' . $subkey . '", "' . $entry . '", newValue' . PHP_EOL;
264 } elseif (!empty($entry)) {
265 $scriptContent .= 'objRegistry.' . $type . ' HKEY, "' . $subkey . '", "' . $entry . '"' . PHP_EOL;
266 } else {
267 $scriptContent .= 'objRegistry.' . $type . ' HKEY, "' . $subkey . '"' . PHP_EOL;
268 }
269 $scriptContent .= 'If Err.Number <> 0 Then' . PHP_EOL;
270 $scriptContent .= ' objFile.Write "' . self::REG_ERROR_ENTRY . '" & Err.Number & ": " & Err.Description' . PHP_EOL;
271 $scriptContent .= 'Else' . PHP_EOL;
272 if (!empty($value)) {
273 $scriptContent .= ' entryValue = objShell.RegRead("' . $strKey . '\\' . $subkey . '\\' . $entry . '")' . PHP_EOL;
274 $scriptContent .= ' If entryValue = newValue Then' . PHP_EOL;
275 $scriptContent .= ' objFile.Write "' . self::REG_NO_ERROR . '"' . PHP_EOL;
276 $scriptContent .= ' Else' . PHP_EOL;
277 $scriptContent .= ' objFile.Write "' . self::REG_ERROR_SET . '" & newValue' . PHP_EOL;
278 $scriptContent .= ' End If' . PHP_EOL;
279 } else {
280 $scriptContent .= ' objFile.Write "' . self::REG_NO_ERROR . '"' . PHP_EOL;
281 }
282 $scriptContent .= 'End If' . PHP_EOL;
283 $scriptContent .= 'objFile.Close' . PHP_EOL;
284
285 $result = Vbs::exec($basename, $resultFile, $scriptContent);
286 $result = isset($result[0]) ? $result[0] : null;
287
288 if ($subkey == self::ENV_KEY) {
290 }
291
292 $this->writeLog('SetValue ' . $strKey . '\\' . $subkey . '\\' . $entry);
293 $this->writeLog('-> value: ' . $value);
294 $this->writeLog('-> result: ' . $result);
295 if (Util::startWith($result, self::REG_ERROR_SET)) {
296 $this->latestError = sprintf($bearsamppLang->getValue(Lang::REGISTRY_SET_ERROR_TEXT), str_replace(self::REG_ERROR_SET, '', $result));
297 return false;
298 } elseif (Util::startWith($result, self::REG_ERROR_ENTRY)) {
299 $this->latestError = $bearsamppLang->getValue(Lang::ERROR) . ' ' . str_replace(self::REG_ERROR_ENTRY, '', $result);
300 return false;
301 }
302
303 return $result == self::REG_NO_ERROR;
304 }
305
306 /**
307 * Retrieves the latest error message.
308 *
309 * @return string|null The latest error message, or null if no error occurred.
310 */
311 public function getLatestError()
312 {
313 return $this->latestError;
314 }
315}
$result
global $bearsamppLang
global $bearsamppRoot
static refreshEnvVars()
const ERROR
const REGISTRY_SET_ERROR_TEXT
const REG_ERROR_ENTRY
exists($key, $subkey, $entry=null)
const END_PROCESS_STR
setValue($key, $subkey, $entry, $value, $type)
const REG_BINARY
const HKEY_CURRENT_USER
getValue($key, $subkey, $entry=null)
setStringValue($key, $subkey, $entry, $value)
const HKEY_USERS
const APP_BINS_REG_ENTRY
const PROCESSOR_REG_ENTRY
const REG_ERROR_SET
const REG_NO_ERROR
setExpandStringValue($key, $subkey, $entry, $value)
const SYSPATH_REG_ENTRY
const REG_MULTI_SZ
const HKEY_CLASSES_ROOT
const PROCESSOR_REG_SUBKEY
const APP_PATH_REG_ENTRY
const REG_DWORD
deleteValue($key, $subkey, $entry)
const REG_EXPAND_SZ
const HKEY_LOCAL_MACHINE
static startWith($string, $search)
static logDebug($data, $file=null)
static logInitClass($classInstance)
static exec($basename, $resultFile, $content, $timeout=true)
static getResultFile($basename)