~ubuntu-branches/ubuntu/quantal/php5/quantal

« back to all changes in this revision

Viewing changes to win32/registry.c

  • Committer: Bazaar Package Importer
  • Author(s): Sean Finney
  • Date: 2009-07-01 09:12:10 UTC
  • mto: (0.9.1) (1.1.17 upstream)
  • mto: This revision was merged to the branch mainline in revision 58.
  • Revision ID: james.westby@ubuntu.com-20090701091210-go0h6506p62on17r
Tags: upstream-5.3.0
ImportĀ upstreamĀ versionĀ 5.3.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "php.h"
 
2
#include "php_ini.h"
 
3
#include "php_win32_globals.h"
 
4
 
 
5
#define PHP_REGISTRY_KEY              "SOFTWARE\\PHP"
 
6
 
 
7
#define PHP_VER1(V1)                  #V1
 
8
#define PHP_VER2(V1,V2)               #V1"."#V2
 
9
#define PHP_VER3(V1,V2,V3)            #V1"."#V2"."#V3
 
10
 
 
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)
 
15
 
 
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),
 
21
        PHP_REGISTRY_KEY,
 
22
        NULL
 
23
};
 
24
 
 
25
static int OpenPhpRegistryKey(char* sub_key, HKEY *hKey)
 
26
{
 
27
        const char **key_name = registry_keys;
 
28
 
 
29
        if (sub_key) {
 
30
                int main_key_len;
 
31
                int sub_key_len = strlen(sub_key);
 
32
                char *reg_key;
 
33
 
 
34
                while (*key_name) {
 
35
                        LONG ret;
 
36
 
 
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);
 
42
                        efree(reg_key);
 
43
                        
 
44
                        if (ret == ERROR_SUCCESS) {
 
45
                                return 1;
 
46
                        }
 
47
                        ++key_name;
 
48
                }
 
49
        } else {
 
50
                while (*key_name) {
 
51
                        if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, *key_name, 0, KEY_READ, hKey) == ERROR_SUCCESS) {
 
52
                                return 1;
 
53
                        }
 
54
                        ++key_name;
 
55
                }
 
56
        }
 
57
        return 0;
 
58
}
 
59
 
 
60
static int LoadDirectory(HashTable *directories, HKEY key, char *path, int path_len, HashTable *parent_ht)
 
61
{
 
62
        DWORD keys, values, max_key, max_name, max_value;
 
63
        int ret = 0;
 
64
        HashTable *ht = NULL;
 
65
 
 
66
        if (RegQueryInfoKey(key, NULL, NULL, NULL, &keys, &max_key, NULL, &values, &max_name, &max_value, NULL, NULL) == ERROR_SUCCESS) {
 
67
                
 
68
                if (values) {
 
69
                        DWORD i;
 
70
                        char *name = (char*)emalloc(max_name+1);
 
71
                        char *value = (char*)emalloc(max_value+1);
 
72
                        DWORD name_len, type, value_len;
 
73
                        zval *data;
 
74
 
 
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)) {
 
80
                                                if (!ht) {
 
81
                                                        ht = (HashTable*)malloc(sizeof(HashTable));
 
82
                                                        zend_hash_init(ht, 0, NULL, ZVAL_INTERNAL_PTR_DTOR, 1);
 
83
                                                }
 
84
                                                data = (zval*)malloc(sizeof(zval));
 
85
                                                INIT_PZVAL(data);
 
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);
 
89
                                        }
 
90
                                }
 
91
                        }
 
92
                        if (ht) {
 
93
                                if (parent_ht) {
 
94
                                        HashPosition pos;
 
95
                                        char *index;
 
96
                                        uint index_len;
 
97
                                        ulong num;
 
98
                                        zval **data;
 
99
 
 
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) {
 
105
                                                    Z_ADDREF_PP(data);
 
106
                                                }
 
107
                                        }
 
108
                                }
 
109
                                zend_hash_update(directories, path, path_len+1, &ht, sizeof(HashTable*), NULL);
 
110
                                ret = 1;
 
111
                        }
 
112
 
 
113
                        efree(name);
 
114
                        efree(value);
 
115
                }
 
116
 
 
117
                if (ht == NULL) {
 
118
                        ht = parent_ht;
 
119
                }
 
120
 
 
121
                if (keys) {
 
122
                        DWORD i;
 
123
                        char *name = (char*)emalloc(max_key+1);
 
124
                        char *new_path = (char*)emalloc(path_len+max_key+2);
 
125
                        DWORD name_len;
 
126
                        FILETIME t;
 
127
                        HKEY subkey;
 
128
 
 
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) {
 
133
                                                if (path_len) {
 
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;
 
139
                                                } else {
 
140
                                                        memcpy(new_path, name, name_len+1);
 
141
                                                        zend_str_tolower(new_path, name_len);
 
142
                                                }
 
143
                                                if (LoadDirectory(directories, subkey, new_path, name_len, ht)) {
 
144
                                                        ret = 1;
 
145
                                                }
 
146
                                                RegCloseKey(subkey);
 
147
                                        }
 
148
                                }
 
149
                        }
 
150
                        efree(new_path);
 
151
                        efree(name);
 
152
                }
 
153
        }
 
154
        return ret;
 
155
}
 
156
 
 
157
static void delete_internal_hashtable(void *data)
 
158
{
 
159
        zend_hash_destroy(*(HashTable**)data);
 
160
        free(*(HashTable**)data);
 
161
}
 
162
 
 
163
#define RegNotifyFlags (REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_ATTRIBUTES | REG_NOTIFY_CHANGE_LAST_SET)
 
164
 
 
165
void UpdateIniFromRegistry(char *path TSRMLS_DC)
 
166
{
 
167
        char *p, *orig_path;
 
168
        int path_len;
 
169
        HashTable **pht;
 
170
 
 
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;
 
176
                        return;
 
177
                }
 
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);
 
181
                }
 
182
                if (!LoadDirectory(PW32G(registry_directories), PW32G(registry_key), "", 0, NULL)) {
 
183
                        return;
 
184
                }
 
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)) {
 
189
                        return;
 
190
                }
 
191
        } else if (zend_hash_num_elements(PW32G(registry_directories)) == 0) {
 
192
                return;
 
193
        }
 
194
 
 
195
        orig_path = path = estrdup(path);
 
196
 
 
197
        /* Get rid of C:, if exists */
 
198
        p = strchr(path, ':');
 
199
        if (p) {
 
200
                *p = path[0];   /* replace the colon with the drive letter */
 
201
                path = p;               /* make path point to the drive letter */
 
202
        } else {
 
203
                if (path[0] != '\\' && path[0] != '/') {
 
204
                        char tmp_buf[MAXPATHLEN], *cwd;
 
205
                        char drive_letter;
 
206
 
 
207
                        /* get current working directory and prepend it to the path */
 
208
                        if (!VCWD_GETCWD(tmp_buf, MAXPATHLEN)) {
 
209
                                efree(orig_path);
 
210
                                return;
 
211
                        }
 
212
                        cwd = strchr(tmp_buf, ':');
 
213
                        if (!cwd) {
 
214
                                drive_letter = 'C';
 
215
                                cwd = tmp_buf;
 
216
                        } else {
 
217
                                drive_letter = tmp_buf[0];
 
218
                                cwd++;
 
219
                        }
 
220
                        while (*cwd == '\\' || *cwd == '/') {
 
221
                                cwd++;
 
222
                        }
 
223
                        spprintf(&path, 0, "%c\\%s\\%s", drive_letter, cwd, orig_path);
 
224
                        efree(orig_path);
 
225
                        orig_path = path;
 
226
                }
 
227
        }
 
228
 
 
229
        path_len = 0;
 
230
        while (path[path_len] != 0) {
 
231
                if (path[path_len] == '\\') {
 
232
                        path[path_len] = '/';
 
233
                }
 
234
                path_len++;
 
235
        }
 
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;
 
240
                        HashPosition pos;
 
241
                        char *index;
 
242
                        uint index_len;
 
243
                        ulong num;
 
244
                        zval **data;
 
245
 
 
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);
 
251
                        }
 
252
                        break;
 
253
                }
 
254
                if (--path_len > 0) {
 
255
                        while (path_len > 0 && path[path_len] != '/') {
 
256
                                path_len--;
 
257
                        }
 
258
                }
 
259
                path[path_len] = 0;
 
260
        }
 
261
 
 
262
        efree(orig_path);
 
263
}
 
264
 
 
265
#define PHPRC_REGISTRY_NAME "IniFilePath"
 
266
 
 
267
char *GetIniPathFromRegistry()
 
268
{
 
269
        char *reg_location = NULL;
 
270
        HKEY hKey;
 
271
        
 
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) {
 
276
                        efree(reg_location);
 
277
                        reg_location = NULL;
 
278
                        return reg_location;
 
279
                }
 
280
                RegCloseKey(hKey);
 
281
        }
 
282
        return reg_location;
 
283
}