3
#include "php_win32_globals.h"
5
#define PHP_REGISTRY_KEY "SOFTWARE\\PHP"
7
#define PHP_VER1(V1) #V1
8
#define PHP_VER2(V1,V2) #V1"."#V2
9
#define PHP_VER3(V1,V2,V3) #V1"."#V2"."#V3
11
#define PHP_REGISTRY_KEYV(VER) PHP_REGISTRY_KEY"\\"VER
12
#define PHP_REGISTRY_KEY1(V1) PHP_REGISTRY_KEY"\\"PHP_VER1(V1)
13
#define PHP_REGISTRY_KEY2(V1,V2) PHP_REGISTRY_KEY"\\"PHP_VER2(V1,V2)
14
#define PHP_REGISTRY_KEY3(V1,V2,V3) PHP_REGISTRY_KEY"\\"PHP_VER3(V1,V2,V3)
16
static const char* registry_keys[] = {
17
PHP_REGISTRY_KEYV(PHP_VERSION),
18
PHP_REGISTRY_KEY3(PHP_MAJOR_VERSION, PHP_MINOR_VERSION, PHP_RELEASE_VERSION),
19
PHP_REGISTRY_KEY2(PHP_MAJOR_VERSION, PHP_MINOR_VERSION),
20
PHP_REGISTRY_KEY1(PHP_MAJOR_VERSION),
25
static int OpenPhpRegistryKey(char* sub_key, HKEY *hKey)
27
const char **key_name = registry_keys;
31
int sub_key_len = strlen(sub_key);
37
main_key_len = strlen(*key_name);
38
reg_key = emalloc(main_key_len + sub_key_len + 1);
39
memcpy(reg_key, *key_name, main_key_len);
40
memcpy(reg_key + main_key_len, sub_key, sub_key_len + 1);
41
ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, reg_key, 0, KEY_READ, hKey);
44
if (ret == ERROR_SUCCESS) {
51
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, *key_name, 0, KEY_READ, hKey) == ERROR_SUCCESS) {
60
static int LoadDirectory(HashTable *directories, HKEY key, char *path, int path_len, HashTable *parent_ht)
62
DWORD keys, values, max_key, max_name, max_value;
66
if (RegQueryInfoKey(key, NULL, NULL, NULL, &keys, &max_key, NULL, &values, &max_name, &max_value, NULL, NULL) == ERROR_SUCCESS) {
70
char *name = (char*)emalloc(max_name+1);
71
char *value = (char*)emalloc(max_value+1);
72
DWORD name_len, type, value_len;
75
for (i = 0; i < values; i++) {
76
name_len = max_name+1;
77
value_len = max_value+1;
78
if (RegEnumValue(key, i, name, &name_len, NULL, &type, value, &value_len) == ERROR_SUCCESS) {
79
if ((type == REG_SZ) || (type == REG_EXPAND_SZ)) {
81
ht = (HashTable*)malloc(sizeof(HashTable));
82
zend_hash_init(ht, 0, NULL, ZVAL_INTERNAL_PTR_DTOR, 1);
84
data = (zval*)malloc(sizeof(zval));
86
Z_STRVAL_P(data) = zend_strndup(value, value_len-1);
87
Z_STRLEN_P(data) = value_len-1;
88
zend_hash_update(ht, name, name_len+1, &data, sizeof(zval*), NULL);
100
for (zend_hash_internal_pointer_reset_ex(parent_ht, &pos);
101
zend_hash_get_current_data_ex(parent_ht, (void**)&data, &pos) == SUCCESS &&
102
zend_hash_get_current_key_ex(parent_ht, &index, &index_len, &num, 0, &pos) == HASH_KEY_IS_STRING;
103
zend_hash_move_forward_ex(parent_ht, &pos)) {
104
if (zend_hash_add(ht, index, index_len, data, sizeof(zval*), NULL) == SUCCESS) {
109
zend_hash_update(directories, path, path_len+1, &ht, sizeof(HashTable*), NULL);
123
char *name = (char*)emalloc(max_key+1);
124
char *new_path = (char*)emalloc(path_len+max_key+2);
129
for (i = 0; i < keys; i++) {
130
name_len = max_key+1;
131
if (RegEnumKeyEx(key, i, name, &name_len, NULL, NULL, NULL, &t) == ERROR_SUCCESS) {
132
if (RegOpenKeyEx(key, name, 0, KEY_READ, &subkey) == ERROR_SUCCESS) {
134
memcpy(new_path, path, path_len);
135
new_path[path_len] = '/';
136
memcpy(new_path+path_len+1, name, name_len+1);
137
zend_str_tolower(new_path, path_len+name_len+1);
138
name_len += path_len+1;
140
memcpy(new_path, name, name_len+1);
141
zend_str_tolower(new_path, name_len);
143
if (LoadDirectory(directories, subkey, new_path, name_len, ht)) {
157
static void delete_internal_hashtable(void *data)
159
zend_hash_destroy(*(HashTable**)data);
160
free(*(HashTable**)data);
163
#define RegNotifyFlags (REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_ATTRIBUTES | REG_NOTIFY_CHANGE_LAST_SET)
165
void UpdateIniFromRegistry(char *path TSRMLS_DC)
171
if (!PW32G(registry_directories)) {
172
PW32G(registry_directories) = (HashTable*)malloc(sizeof(HashTable));
173
zend_hash_init(PW32G(registry_directories), 0, NULL, delete_internal_hashtable, 1);
174
if (!OpenPhpRegistryKey("\\Per Directory Values", &PW32G(registry_key))) {
175
PW32G(registry_key) = NULL;
178
PW32G(registry_event) = CreateEvent(NULL, TRUE, FALSE, NULL);
179
if (PW32G(registry_event)) {
180
RegNotifyChangeKeyValue(PW32G(registry_key), TRUE, RegNotifyFlags, PW32G(registry_event), TRUE);
182
if (!LoadDirectory(PW32G(registry_directories), PW32G(registry_key), "", 0, NULL)) {
185
} else if (PW32G(registry_event) && WaitForSingleObject(PW32G(registry_event), 0) == WAIT_OBJECT_0) {
186
RegNotifyChangeKeyValue(PW32G(registry_key), TRUE, RegNotifyFlags, PW32G(registry_event), TRUE);
187
zend_hash_clean(PW32G(registry_directories));
188
if (!LoadDirectory(PW32G(registry_directories), PW32G(registry_key), "", 0, NULL)) {
191
} else if (zend_hash_num_elements(PW32G(registry_directories)) == 0) {
195
orig_path = path = estrdup(path);
197
/* Get rid of C:, if exists */
198
p = strchr(path, ':');
200
*p = path[0]; /* replace the colon with the drive letter */
201
path = p; /* make path point to the drive letter */
203
if (path[0] != '\\' && path[0] != '/') {
204
char tmp_buf[MAXPATHLEN], *cwd;
207
/* get current working directory and prepend it to the path */
208
if (!VCWD_GETCWD(tmp_buf, MAXPATHLEN)) {
212
cwd = strchr(tmp_buf, ':');
217
drive_letter = tmp_buf[0];
220
while (*cwd == '\\' || *cwd == '/') {
223
spprintf(&path, 0, "%c\\%s\\%s", drive_letter, cwd, orig_path);
230
while (path[path_len] != 0) {
231
if (path[path_len] == '\\') {
232
path[path_len] = '/';
236
zend_str_tolower(path, path_len);
237
while (path_len >= 0) {
238
if (zend_hash_find(PW32G(registry_directories), path, path_len+1, (void**)&pht) == SUCCESS) {
239
HashTable *ht = *pht;
246
for (zend_hash_internal_pointer_reset_ex(ht, &pos);
247
zend_hash_get_current_data_ex(ht, (void**)&data, &pos) == SUCCESS &&
248
zend_hash_get_current_key_ex(ht, &index, &index_len, &num, 0, &pos) == HASH_KEY_IS_STRING;
249
zend_hash_move_forward_ex(ht, &pos)) {
250
zend_alter_ini_entry(index, index_len, Z_STRVAL_PP(data), Z_STRLEN_PP(data), PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE);
254
if (--path_len > 0) {
255
while (path_len > 0 && path[path_len] != '/') {
265
#define PHPRC_REGISTRY_NAME "IniFilePath"
267
char *GetIniPathFromRegistry()
269
char *reg_location = NULL;
272
if (OpenPhpRegistryKey(NULL, &hKey)) {
273
DWORD buflen = MAXPATHLEN;
274
reg_location = emalloc(MAXPATHLEN+1);
275
if(RegQueryValueEx(hKey, PHPRC_REGISTRY_NAME, 0, NULL, reg_location, &buflen) != ERROR_SUCCESS) {