123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297 |
- #include "php.h"
- #include "php_ini.h"
- #include "php_win32_globals.h"
- #define PHP_REGISTRY_KEY "SOFTWARE\\PHP"
- #define PHP_VER1(V1) #V1
- #define PHP_VER2(V1,V2) #V1"."#V2
- #define PHP_VER3(V1,V2,V3) #V1"."#V2"."#V3
- #define PHP_REGISTRY_KEYV(VER) PHP_REGISTRY_KEY"\\"VER
- #define PHP_REGISTRY_KEY1(V1) PHP_REGISTRY_KEY"\\"PHP_VER1(V1)
- #define PHP_REGISTRY_KEY2(V1,V2) PHP_REGISTRY_KEY"\\"PHP_VER2(V1,V2)
- #define PHP_REGISTRY_KEY3(V1,V2,V3) PHP_REGISTRY_KEY"\\"PHP_VER3(V1,V2,V3)
- static const char* registry_keys[] = {
- PHP_REGISTRY_KEYV(PHP_VERSION),
- PHP_REGISTRY_KEY3(PHP_MAJOR_VERSION, PHP_MINOR_VERSION, PHP_RELEASE_VERSION),
- PHP_REGISTRY_KEY2(PHP_MAJOR_VERSION, PHP_MINOR_VERSION),
- PHP_REGISTRY_KEY1(PHP_MAJOR_VERSION),
- PHP_REGISTRY_KEY,
- NULL
- };
- static int OpenPhpRegistryKey(char* sub_key, HKEY *hKey)
- {
- const char **key_name = registry_keys;
- if (sub_key) {
- int main_key_len;
- int sub_key_len = strlen(sub_key);
- char *reg_key;
- while (*key_name) {
- LONG ret;
- main_key_len = strlen(*key_name);
- reg_key = emalloc(main_key_len + sub_key_len + 1);
- memcpy(reg_key, *key_name, main_key_len);
- memcpy(reg_key + main_key_len, sub_key, sub_key_len + 1);
- ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, reg_key, 0, KEY_READ, hKey);
- efree(reg_key);
-
- if (ret == ERROR_SUCCESS) {
- return 1;
- }
- ++key_name;
- }
- } else {
- while (*key_name) {
- if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, *key_name, 0, KEY_READ, hKey) == ERROR_SUCCESS) {
- return 1;
- }
- ++key_name;
- }
- }
- return 0;
- }
- static int LoadDirectory(HashTable *directories, HKEY key, char *path, int path_len, HashTable *parent_ht)
- {
- DWORD keys, values, max_key, max_name, max_value;
- int ret = 0;
- HashTable *ht = NULL;
- if (RegQueryInfoKey(key, NULL, NULL, NULL, &keys, &max_key, NULL, &values, &max_name, &max_value, NULL, NULL) == ERROR_SUCCESS) {
-
- if (values) {
- DWORD i;
- char *name = (char*)emalloc(max_name+1);
- char *value = (char*)emalloc(max_value+1);
- DWORD name_len, type, value_len;
- zval *data;
- for (i = 0; i < values; i++) {
- name_len = max_name+1;
- value_len = max_value+1;
- if (RegEnumValue(key, i, name, &name_len, NULL, &type, value, &value_len) == ERROR_SUCCESS) {
- if ((type == REG_SZ) || (type == REG_EXPAND_SZ)) {
- if (!ht) {
- ht = (HashTable*)malloc(sizeof(HashTable));
- if (!ht) {
- return ret;
- }
- zend_hash_init(ht, 0, NULL, ZVAL_INTERNAL_PTR_DTOR, 1);
- }
- data = (zval*)malloc(sizeof(zval));
- if (!data) {
- return ret;
- }
- INIT_PZVAL(data);
- Z_STRVAL_P(data) = zend_strndup(value, value_len-1);
- Z_STRLEN_P(data) = value_len-1;
- Z_TYPE_P(data) = IS_STRING;
- zend_hash_update(ht, name, name_len+1, &data, sizeof(zval*), NULL);
- }
- }
- }
- if (ht) {
- if (parent_ht) {
- HashPosition pos;
- char *index;
- uint index_len;
- ulong num;
- zval **tmpdata;
- for (zend_hash_internal_pointer_reset_ex(parent_ht, &pos);
- zend_hash_get_current_data_ex(parent_ht, (void**)&tmpdata, &pos) == SUCCESS &&
- zend_hash_get_current_key_ex(parent_ht, &index, &index_len, &num, 0, &pos) == HASH_KEY_IS_STRING;
- zend_hash_move_forward_ex(parent_ht, &pos)) {
- if (zend_hash_add(ht, index, index_len, tmpdata, sizeof(zval*), NULL) == SUCCESS) {
- Z_ADDREF_PP(tmpdata);
- }
- }
- }
- zend_hash_update(directories, path, path_len+1, &ht, sizeof(HashTable*), NULL);
- ret = 1;
- }
- efree(name);
- efree(value);
- }
- if (ht == NULL) {
- ht = parent_ht;
- }
- if (keys) {
- DWORD i;
- char *name = (char*)emalloc(max_key+1);
- char *new_path = (char*)emalloc(path_len+max_key+2);
- DWORD name_len;
- FILETIME t;
- HKEY subkey;
- for (i = 0; i < keys; i++) {
- name_len = max_key+1;
- if (RegEnumKeyEx(key, i, name, &name_len, NULL, NULL, NULL, &t) == ERROR_SUCCESS) {
- if (RegOpenKeyEx(key, name, 0, KEY_READ, &subkey) == ERROR_SUCCESS) {
- if (path_len) {
- memcpy(new_path, path, path_len);
- new_path[path_len] = '/';
- memcpy(new_path+path_len+1, name, name_len+1);
- zend_str_tolower(new_path, path_len+name_len+1);
- name_len += path_len+1;
- } else {
- memcpy(new_path, name, name_len+1);
- zend_str_tolower(new_path, name_len);
- }
- if (LoadDirectory(directories, subkey, new_path, name_len, ht)) {
- ret = 1;
- }
- RegCloseKey(subkey);
- }
- }
- }
- efree(new_path);
- efree(name);
- }
- }
- return ret;
- }
- static void delete_internal_hashtable(void *data)
- {
- zend_hash_destroy(*(HashTable**)data);
- free(*(HashTable**)data);
- }
- #define RegNotifyFlags (REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_ATTRIBUTES | REG_NOTIFY_CHANGE_LAST_SET)
- void UpdateIniFromRegistry(char *path TSRMLS_DC)
- {
- char *p, *orig_path;
- int path_len;
- HashTable **pht;
- if(!path) {
- return;
- }
- if (!PW32G(registry_directories)) {
- PW32G(registry_directories) = (HashTable*)malloc(sizeof(HashTable));
- if (!PW32G(registry_directories)) {
- return;
- }
- zend_hash_init(PW32G(registry_directories), 0, NULL, delete_internal_hashtable, 1);
- if (!OpenPhpRegistryKey("\\Per Directory Values", &PW32G(registry_key))) {
- PW32G(registry_key) = NULL;
- return;
- }
- PW32G(registry_event) = CreateEvent(NULL, TRUE, FALSE, NULL);
- if (PW32G(registry_event)) {
- RegNotifyChangeKeyValue(PW32G(registry_key), TRUE, RegNotifyFlags, PW32G(registry_event), TRUE);
- }
- if (!LoadDirectory(PW32G(registry_directories), PW32G(registry_key), "", 0, NULL)) {
- return;
- }
- } else if (PW32G(registry_event) && WaitForSingleObject(PW32G(registry_event), 0) == WAIT_OBJECT_0) {
- RegNotifyChangeKeyValue(PW32G(registry_key), TRUE, RegNotifyFlags, PW32G(registry_event), TRUE);
- zend_hash_clean(PW32G(registry_directories));
- if (!LoadDirectory(PW32G(registry_directories), PW32G(registry_key), "", 0, NULL)) {
- return;
- }
- } else if (zend_hash_num_elements(PW32G(registry_directories)) == 0) {
- return;
- }
- orig_path = path = estrdup(path);
- /* Get rid of C:, if exists */
- p = strchr(path, ':');
- if (p) {
- *p = path[0]; /* replace the colon with the drive letter */
- path = p; /* make path point to the drive letter */
- } else {
- if (path[0] != '\\' && path[0] != '/') {
- char tmp_buf[MAXPATHLEN], *cwd;
- char drive_letter;
- /* get current working directory and prepend it to the path */
- if (!VCWD_GETCWD(tmp_buf, MAXPATHLEN)) {
- efree(orig_path);
- return;
- }
- cwd = strchr(tmp_buf, ':');
- if (!cwd) {
- drive_letter = 'C';
- cwd = tmp_buf;
- } else {
- drive_letter = tmp_buf[0];
- cwd++;
- }
- while (*cwd == '\\' || *cwd == '/') {
- cwd++;
- }
- spprintf(&path, 0, "%c\\%s\\%s", drive_letter, cwd, orig_path);
- efree(orig_path);
- orig_path = path;
- }
- }
- path_len = 0;
- while (path[path_len] != 0) {
- if (path[path_len] == '\\') {
- path[path_len] = '/';
- }
- path_len++;
- }
- zend_str_tolower(path, path_len);
- while (path_len >= 0) {
- if (zend_hash_find(PW32G(registry_directories), path, path_len+1, (void**)&pht) == SUCCESS) {
- HashTable *ht = *pht;
- HashPosition pos;
- char *index;
- uint index_len;
- ulong num;
- zval **data;
- for (zend_hash_internal_pointer_reset_ex(ht, &pos);
- zend_hash_get_current_data_ex(ht, (void**)&data, &pos) == SUCCESS &&
- zend_hash_get_current_key_ex(ht, &index, &index_len, &num, 0, &pos) == HASH_KEY_IS_STRING;
- zend_hash_move_forward_ex(ht, &pos)) {
- zend_alter_ini_entry(index, index_len, Z_STRVAL_PP(data), Z_STRLEN_PP(data), PHP_INI_USER, PHP_INI_STAGE_ACTIVATE);
- }
- break;
- }
- if (--path_len > 0) {
- while (path_len > 0 && path[path_len] != '/') {
- path_len--;
- }
- }
- path[path_len] = 0;
- }
- efree(orig_path);
- }
- #define PHPRC_REGISTRY_NAME "IniFilePath"
- char *GetIniPathFromRegistry()
- {
- char *reg_location = NULL;
- HKEY hKey;
-
- if (OpenPhpRegistryKey(NULL, &hKey)) {
- DWORD buflen = MAXPATHLEN;
- reg_location = emalloc(MAXPATHLEN+1);
- if(RegQueryValueEx(hKey, PHPRC_REGISTRY_NAME, 0, NULL, reg_location, &buflen) != ERROR_SUCCESS) {
- efree(reg_location);
- reg_location = NULL;
- return reg_location;
- }
- RegCloseKey(hKey);
- }
- return reg_location;
- }
|