Annotation of embedaddon/php/win32/registry.c, revision 1.1

1.1     ! misho       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 **tmpdata;
        !            99: 
        !           100:                                        for (zend_hash_internal_pointer_reset_ex(parent_ht, &pos);
        !           101:                                             zend_hash_get_current_data_ex(parent_ht, (void**)&tmpdata, &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, tmpdata, sizeof(zval*), NULL) == SUCCESS) {
        !           105:                                                    Z_ADDREF_PP(tmpdata);
        !           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(!path) {
        !           172:                return;
        !           173:        }
        !           174: 
        !           175:        if (!PW32G(registry_directories)) {
        !           176:                PW32G(registry_directories) = (HashTable*)malloc(sizeof(HashTable));
        !           177:                zend_hash_init(PW32G(registry_directories), 0, NULL, delete_internal_hashtable, 1);
        !           178:                if (!OpenPhpRegistryKey("\\Per Directory Values", &PW32G(registry_key))) {
        !           179:                        PW32G(registry_key) = NULL;
        !           180:                        return;
        !           181:                }
        !           182:                PW32G(registry_event) = CreateEvent(NULL, TRUE, FALSE, NULL);
        !           183:                if (PW32G(registry_event)) {
        !           184:                        RegNotifyChangeKeyValue(PW32G(registry_key), TRUE, RegNotifyFlags, PW32G(registry_event), TRUE);
        !           185:                }
        !           186:                if (!LoadDirectory(PW32G(registry_directories), PW32G(registry_key), "", 0, NULL)) {
        !           187:                        return;
        !           188:                }
        !           189:        } else if (PW32G(registry_event) && WaitForSingleObject(PW32G(registry_event), 0) == WAIT_OBJECT_0) {
        !           190:                RegNotifyChangeKeyValue(PW32G(registry_key), TRUE, RegNotifyFlags, PW32G(registry_event), TRUE);
        !           191:                zend_hash_clean(PW32G(registry_directories));
        !           192:                if (!LoadDirectory(PW32G(registry_directories), PW32G(registry_key), "", 0, NULL)) {
        !           193:                        return;
        !           194:                }
        !           195:        } else if (zend_hash_num_elements(PW32G(registry_directories)) == 0) {
        !           196:                return;
        !           197:        }
        !           198: 
        !           199:        orig_path = path = estrdup(path);
        !           200: 
        !           201:        /* Get rid of C:, if exists */
        !           202:        p = strchr(path, ':');
        !           203:        if (p) {
        !           204:                *p = path[0];   /* replace the colon with the drive letter */
        !           205:                path = p;               /* make path point to the drive letter */
        !           206:        } else {
        !           207:                if (path[0] != '\\' && path[0] != '/') {
        !           208:                        char tmp_buf[MAXPATHLEN], *cwd;
        !           209:                        char drive_letter;
        !           210: 
        !           211:                        /* get current working directory and prepend it to the path */
        !           212:                        if (!VCWD_GETCWD(tmp_buf, MAXPATHLEN)) {
        !           213:                                efree(orig_path);
        !           214:                                return;
        !           215:                        }
        !           216:                        cwd = strchr(tmp_buf, ':');
        !           217:                        if (!cwd) {
        !           218:                                drive_letter = 'C';
        !           219:                                cwd = tmp_buf;
        !           220:                        } else {
        !           221:                                drive_letter = tmp_buf[0];
        !           222:                                cwd++;
        !           223:                        }
        !           224:                        while (*cwd == '\\' || *cwd == '/') {
        !           225:                                cwd++;
        !           226:                        }
        !           227:                        spprintf(&path, 0, "%c\\%s\\%s", drive_letter, cwd, orig_path);
        !           228:                        efree(orig_path);
        !           229:                        orig_path = path;
        !           230:                }
        !           231:        }
        !           232: 
        !           233:        path_len = 0;
        !           234:        while (path[path_len] != 0) {
        !           235:                if (path[path_len] == '\\') {
        !           236:                        path[path_len] = '/';
        !           237:                }
        !           238:                path_len++;
        !           239:        }
        !           240:        zend_str_tolower(path, path_len);
        !           241:        while (path_len >= 0) {
        !           242:                if (zend_hash_find(PW32G(registry_directories), path, path_len+1, (void**)&pht) == SUCCESS) {
        !           243:                        HashTable *ht = *pht;
        !           244:                        HashPosition pos;
        !           245:                        char *index;
        !           246:                        uint index_len;
        !           247:                        ulong num;
        !           248:                        zval **data;
        !           249: 
        !           250:                        for (zend_hash_internal_pointer_reset_ex(ht, &pos);
        !           251:                             zend_hash_get_current_data_ex(ht, (void**)&data, &pos) == SUCCESS &&
        !           252:                             zend_hash_get_current_key_ex(ht, &index, &index_len, &num, 0, &pos) == HASH_KEY_IS_STRING;
        !           253:                             zend_hash_move_forward_ex(ht, &pos)) {
        !           254:                                zend_alter_ini_entry(index, index_len, Z_STRVAL_PP(data), Z_STRLEN_PP(data), PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE);
        !           255:                        }
        !           256:                        break;
        !           257:                }
        !           258:                if (--path_len > 0) {
        !           259:                        while (path_len > 0 && path[path_len] != '/') {
        !           260:                                path_len--;
        !           261:                        }
        !           262:                }
        !           263:                path[path_len] = 0;
        !           264:        }
        !           265: 
        !           266:        efree(orig_path);
        !           267: }
        !           268: 
        !           269: #define PHPRC_REGISTRY_NAME "IniFilePath"
        !           270: 
        !           271: char *GetIniPathFromRegistry()
        !           272: {
        !           273:        char *reg_location = NULL;
        !           274:        HKEY hKey;
        !           275:        
        !           276:        if (OpenPhpRegistryKey(NULL, &hKey)) {
        !           277:                DWORD buflen = MAXPATHLEN;
        !           278:                reg_location = emalloc(MAXPATHLEN+1);
        !           279:                if(RegQueryValueEx(hKey, PHPRC_REGISTRY_NAME, 0, NULL, reg_location, &buflen) != ERROR_SUCCESS) {
        !           280:                        efree(reg_location);
        !           281:                        reg_location = NULL;
        !           282:                        return reg_location;
        !           283:                }
        !           284:                RegCloseKey(hKey);
        !           285:        }
        !           286:        return reg_location;
        !           287: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>