php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
registry.c
Go to the documentation of this file.
1/*
2 +----------------------------------------------------------------------+
3 | Copyright (c) The PHP Group |
4 +----------------------------------------------------------------------+
5 | This source file is subject to version 3.01 of the PHP license, |
6 | that is bundled with this package in the file LICENSE, and is |
7 | available through the world-wide-web at the following url: |
8 | https://www.php.net/license/3_01.txt |
9 | If you did not receive a copy of the PHP license and are unable to |
10 | obtain it through the world-wide-web, please send a note to |
11 | license@php.net so we can mail you a copy immediately. |
12 +----------------------------------------------------------------------+
13 | Author: Zeev Suraski <zeev@php.net> |
14 +----------------------------------------------------------------------+
15 */
16
17#include "php.h"
18#include "php_ini.h"
19#include "php_win32_globals.h"
20
21#define PHP_REGISTRY_KEY "SOFTWARE\\PHP"
22
23#define PHP_VER1(V1) #V1
24#define PHP_VER2(V1,V2) #V1"."#V2
25#define PHP_VER3(V1,V2,V3) #V1"."#V2"."#V3
26
27#define PHP_REGISTRY_KEYV(VER) PHP_REGISTRY_KEY"\\"VER
28#define PHP_REGISTRY_KEY1(V1) PHP_REGISTRY_KEY"\\"PHP_VER1(V1)
29#define PHP_REGISTRY_KEY2(V1,V2) PHP_REGISTRY_KEY"\\"PHP_VER2(V1,V2)
30#define PHP_REGISTRY_KEY3(V1,V2,V3) PHP_REGISTRY_KEY"\\"PHP_VER3(V1,V2,V3)
31
32static const char* registry_keys[] = {
38 NULL
39};
40
41static int OpenPhpRegistryKey(char* sub_key, HKEY *hKey)
42{/*{{{*/
43 const char **key_name = registry_keys;
44
45 if (sub_key) {
46 size_t main_key_len;
47 size_t sub_key_len = strlen(sub_key);
48 char *reg_key;
49
50 while (*key_name) {
51 LONG ret;
52
53 main_key_len = strlen(*key_name);
54 reg_key = emalloc(main_key_len + sub_key_len + 1);
55 memcpy(reg_key, *key_name, main_key_len);
56 memcpy(reg_key + main_key_len, sub_key, sub_key_len + 1);
57 ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, reg_key, 0, KEY_READ, hKey);
58 efree(reg_key);
59
60 if (ret == ERROR_SUCCESS) {
61 return 1;
62 }
63 ++key_name;
64 }
65 } else {
66 while (*key_name) {
67 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, *key_name, 0, KEY_READ, hKey) == ERROR_SUCCESS) {
68 return 1;
69 }
70 ++key_name;
71 }
72 }
73 return 0;
74}/*}}}*/
75
76static int LoadDirectory(HashTable *directories, HKEY key, char *path, int path_len, HashTable *parent_ht)
77{/*{{{*/
78 DWORD keys, values, max_key, max_name, max_value;
79 int ret = 0;
80 HashTable *ht = NULL;
81
82 if (RegQueryInfoKey(key, NULL, NULL, NULL, &keys, &max_key, NULL, &values, &max_name, &max_value, NULL, NULL) == ERROR_SUCCESS) {
83
84 if (values) {
85 DWORD i;
86 char *name = (char*)emalloc(max_name+1);
87 char *value = (char*)emalloc(max_value+1);
88 DWORD name_len, type, value_len;
89
90 for (i = 0; i < values; i++) {
91 name_len = max_name+1;
92 value_len = max_value+1;
93
94 memset(name, '\0', max_name+1);
95 memset(value, '\0', max_value+1);
96
97 if (RegEnumValue(key, i, name, &name_len, NULL, &type, value, &value_len) == ERROR_SUCCESS) {
98 if ((type == REG_SZ) || (type == REG_EXPAND_SZ)) {
99 zval data;
100
101 if (!ht) {
102 ht = (HashTable*)malloc(sizeof(HashTable));
103 if (!ht) {
104 return ret;
105 }
107 }
108 ZVAL_PSTRINGL(&data, value, value_len-1);
109 zend_hash_str_update(ht, name, name_len, &data);
110 }
111 }
112 }
113 if (ht) {
114 if (parent_ht) {
115 zend_string *index;
116 zend_ulong num;
117 zval *tmpdata;
118
119 ZEND_HASH_MAP_FOREACH_KEY_VAL(parent_ht, num, index, tmpdata) {
120 zend_hash_add(ht, index, tmpdata);
122 }
123 zend_hash_str_update_mem(directories, path, path_len, ht, sizeof(HashTable));
124 ret = 1;
125 }
126
127 efree(name);
128 efree(value);
129 }
130
131 if (ht == NULL) {
132 ht = parent_ht;
133 }
134
135 if (keys) {
136 DWORD i;
137 char *name = (char*)emalloc(max_key+1);
138 char *new_path = (char*)emalloc(path_len+max_key+2);
139 DWORD name_len;
140 FILETIME t;
141 HKEY subkey;
142
143 for (i = 0; i < keys; i++) {
144 name_len = max_key+1;
145 if (RegEnumKeyEx(key, i, name, &name_len, NULL, NULL, NULL, &t) == ERROR_SUCCESS) {
146 if (RegOpenKeyEx(key, name, 0, KEY_READ, &subkey) == ERROR_SUCCESS) {
147 if (path_len) {
148 memcpy(new_path, path, path_len);
149 new_path[path_len] = '/';
150 memcpy(new_path+path_len+1, name, name_len+1);
151 zend_str_tolower(new_path, path_len+name_len+1);
152 name_len += path_len+1;
153 } else {
154 memcpy(new_path, name, name_len+1);
155 zend_str_tolower(new_path, name_len);
156 }
157 if (LoadDirectory(directories, subkey, new_path, name_len, ht)) {
158 ret = 1;
159 }
160 RegCloseKey(subkey);
161 }
162 }
163 }
164 efree(new_path);
165 efree(name);
166 }
167 }
168 return ret;
169}/*}}}*/
170
171static void delete_internal_hashtable(zval *zv)
172{/*{{{*/
175 free(ht);
176}/*}}}*/
177
178#define RegNotifyFlags (REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_ATTRIBUTES | REG_NOTIFY_CHANGE_LAST_SET)
179
180void UpdateIniFromRegistry(char *path)
181{/*{{{*/
182 char *p, *orig_path;
183 int path_len;
184
185 if(!path) {
186 return;
187 }
188
189 if (!PW32G(registry_directories)) {
190 PW32G(registry_directories) = (HashTable*)malloc(sizeof(HashTable));
191 if (!PW32G(registry_directories)) {
192 return;
193 }
194 zend_hash_init(PW32G(registry_directories), 0, NULL, delete_internal_hashtable, 1);
195 if (!OpenPhpRegistryKey("\\Per Directory Values", &PW32G(registry_key))) {
196 PW32G(registry_key) = NULL;
197 return;
198 }
199 PW32G(registry_event) = CreateEvent(NULL, TRUE, FALSE, NULL);
200 if (PW32G(registry_event)) {
201 RegNotifyChangeKeyValue(PW32G(registry_key), TRUE, RegNotifyFlags, PW32G(registry_event), TRUE);
202 }
203 if (!LoadDirectory(PW32G(registry_directories), PW32G(registry_key), "", 0, NULL)) {
204 return;
205 }
206 } else if (PW32G(registry_event) && WaitForSingleObject(PW32G(registry_event), 0) == WAIT_OBJECT_0) {
207 RegNotifyChangeKeyValue(PW32G(registry_key), TRUE, RegNotifyFlags, PW32G(registry_event), TRUE);
208 zend_hash_clean(PW32G(registry_directories));
209 if (!LoadDirectory(PW32G(registry_directories), PW32G(registry_key), "", 0, NULL)) {
210 return;
211 }
212 } else if (zend_hash_num_elements(PW32G(registry_directories)) == 0) {
213 return;
214 }
215
216 orig_path = path = estrdup(path);
217
218 /* Get rid of C:, if exists */
219 p = strchr(path, ':');
220 if (p) {
221 *p = path[0]; /* replace the colon with the drive letter */
222 path = p; /* make path point to the drive letter */
223 } else {
224 if (path[0] != '\\' && path[0] != '/') {
225 char tmp_buf[MAXPATHLEN], *cwd;
226 char drive_letter;
227
228 /* get current working directory and prepend it to the path */
229 if (!VCWD_GETCWD(tmp_buf, MAXPATHLEN)) {
230 efree(orig_path);
231 return;
232 }
233 cwd = strchr(tmp_buf, ':');
234 if (!cwd) {
235 drive_letter = 'C';
236 cwd = tmp_buf;
237 } else {
238 drive_letter = tmp_buf[0];
239 cwd++;
240 }
241 while (*cwd == '\\' || *cwd == '/') {
242 cwd++;
243 }
244 spprintf(&path, 0, "%c\\%s\\%s", drive_letter, cwd, orig_path);
245 efree(orig_path);
246 orig_path = path;
247 }
248 }
249
250 path_len = 0;
251 while (path[path_len] != 0) {
252 if (path[path_len] == '\\') {
253 path[path_len] = '/';
254 }
255 path_len++;
256 }
257 zend_str_tolower(path, path_len);
258
259 while (path_len > 0) {
260 HashTable *ht = (HashTable *)zend_hash_str_find_ptr(PW32G(registry_directories), path, path_len);
261
262 if (ht != NULL) {
263 zend_string *index;
264 zval *data;
265
269 }
270
271 do {
272 path_len--;
273 } while (path_len > 0 && path[path_len] != '/');
274 path[path_len] = 0;
275 }
276
277 efree(orig_path);
278}/*}}}*/
279
280#define PHPRC_REGISTRY_NAME "IniFilePath"
281
283{/*{{{*/
284 char *reg_location = NULL;
285 HKEY hKey;
286
287 if (OpenPhpRegistryKey(NULL, &hKey)) {
288 DWORD buflen = MAXPATHLEN;
289 reg_location = emalloc(MAXPATHLEN+1);
290 if(RegQueryValueEx(hKey, PHPRC_REGISTRY_NAME, 0, NULL, reg_location, &buflen) != ERROR_SUCCESS) {
291 RegCloseKey(hKey);
292 efree(reg_location);
293 reg_location = NULL;
294 return reg_location;
295 }
296 RegCloseKey(hKey);
297 }
298 return reg_location;
299}/*}}}*/
strchr(string $haystack, string $needle, bool $before_needle=false)
#define DWORD
Definition exif.c:1762
zend_ffi_type * type
Definition ffi.c:3812
zval * zv
Definition ffi.c:3975
memcpy(ptr1, ptr2, size)
memset(ptr, 0, type->size)
HashTable * ht
Definition ffi.c:4838
#define TRUE
Definition gd_gd.c:7
#define FALSE
Definition gd_gd.c:8
#define NULL
Definition gdcache.h:45
char * cwd
#define PHP_INI_STAGE_ACTIVATE
Definition php_ini.h:73
#define PHP_INI_USER
Definition php_ini.h:41
unsigned char key[REFLECTION_KEY_LEN]
#define PHP_MINOR_VERSION
Definition php_version.h:4
#define PHP_RELEASE_VERSION
Definition php_version.h:5
#define PHP_MAJOR_VERSION
Definition php_version.h:3
#define PHP_VERSION
Definition php_version.h:7
#define PW32G(v)
zend_constant * data
#define PHPRC_REGISTRY_NAME
Definition registry.c:280
#define RegNotifyFlags
Definition registry.c:178
#define PHP_REGISTRY_KEYV(VER)
Definition registry.c:27
#define PHP_REGISTRY_KEY
Definition registry.c:21
char * GetIniPathFromRegistry()
Definition registry.c:282
#define PHP_REGISTRY_KEY2(V1, V2)
Definition registry.c:29
#define PHP_REGISTRY_KEY3(V1, V2, V3)
Definition registry.c:30
void UpdateIniFromRegistry(char *path)
Definition registry.c:180
#define PHP_REGISTRY_KEY1(V1)
Definition registry.c:28
p
Definition session.c:1105
#define spprintf
Definition spprintf.h:29
#define ZVAL_PSTRINGL(z, s, l)
Definition zend_API.h:965
#define efree(ptr)
Definition zend_alloc.h:155
#define estrdup(s)
Definition zend_alloc.h:164
#define emalloc(size)
Definition zend_alloc.h:151
struct _zval_struct zval
strlen(string $string)
ZEND_API void ZEND_FASTCALL zend_hash_destroy(HashTable *ht)
Definition zend_hash.c:1727
ZEND_API void ZEND_FASTCALL zend_hash_clean(HashTable *ht)
Definition zend_hash.c:1869
ZEND_API zval *ZEND_FASTCALL zend_hash_str_update(HashTable *ht, const char *str, size_t len, zval *pData)
Definition zend_hash.c:1031
ZEND_API zval *ZEND_FASTCALL zend_hash_add(HashTable *ht, zend_string *key, zval *pData)
Definition zend_hash.c:992
#define zend_hash_init(ht, nSize, pHashFunction, pDestructor, persistent)
Definition zend_hash.h:108
#define ZEND_HASH_MAP_FOREACH_KEY_VAL(ht, _h, _key, _val)
Definition zend_hash.h:1389
#define ZEND_HASH_FOREACH_END()
Definition zend_hash.h:1086
#define ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(ht, _key, _val)
Definition zend_hash.h:1374
ZEND_API zend_result zend_alter_ini_entry(zend_string *name, zend_string *new_value, int modify_type, int stage)
Definition zend_ini.c:325
uint32_t zend_ulong
Definition zend_long.h:43
struct _zend_string zend_string
ZEND_API void ZEND_FASTCALL zend_str_tolower(char *str, size_t length)
struct _zend_array HashTable
Definition zend_types.h:386
#define Z_STR_P(zval_p)
Definition zend_types.h:972
#define Z_PTR_P(zval_p)
#define ZVAL_INTERNAL_PTR_DTOR
#define VCWD_GETCWD(buff, size)
#define MAXPATHLEN
zend_string * name
zval * ret
value