Back to index

php5  5.3.10
Defines | Functions | Variables
registry.c File Reference
#include "php.h"
#include "php_ini.h"
#include "php_win32_globals.h"

Go to the source code of this file.

Defines

#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)
#define RegNotifyFlags   (REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_ATTRIBUTES | REG_NOTIFY_CHANGE_LAST_SET)
#define PHPRC_REGISTRY_NAME   "IniFilePath"

Functions

static int OpenPhpRegistryKey (char *sub_key, HKEY *hKey)
static int LoadDirectory (HashTable *directories, HKEY key, char *path, int path_len, HashTable *parent_ht)
static void delete_internal_hashtable (void *data)
void UpdateIniFromRegistry (char *path TSRMLS_DC)
char * GetIniPathFromRegistry ()

Variables

static const char * registry_keys []

Define Documentation

#define PHP_REGISTRY_KEY   "SOFTWARE\\PHP"

Definition at line 5 of file registry.c.

#define PHP_REGISTRY_KEY1 (   V1)    PHP_REGISTRY_KEY"\\"PHP_VER1(V1)

Definition at line 12 of file registry.c.

#define PHP_REGISTRY_KEY2 (   V1,
  V2 
)    PHP_REGISTRY_KEY"\\"PHP_VER2(V1,V2)

Definition at line 13 of file registry.c.

#define PHP_REGISTRY_KEY3 (   V1,
  V2,
  V3 
)    PHP_REGISTRY_KEY"\\"PHP_VER3(V1,V2,V3)

Definition at line 14 of file registry.c.

#define PHP_REGISTRY_KEYV (   VER)    PHP_REGISTRY_KEY"\\"VER

Definition at line 11 of file registry.c.

#define PHP_VER1 (   V1)    #V1

Definition at line 7 of file registry.c.

#define PHP_VER2 (   V1,
  V2 
)    #V1"."#V2

Definition at line 8 of file registry.c.

#define PHP_VER3 (   V1,
  V2,
  V3 
)    #V1"."#V2"."#V3

Definition at line 9 of file registry.c.

#define PHPRC_REGISTRY_NAME   "IniFilePath"

Definition at line 269 of file registry.c.

#define RegNotifyFlags   (REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_ATTRIBUTES | REG_NOTIFY_CHANGE_LAST_SET)

Definition at line 163 of file registry.c.


Function Documentation

static void delete_internal_hashtable ( void *  data) [static]

Definition at line 157 of file registry.c.

{
       zend_hash_destroy(*(HashTable**)data);
       free(*(HashTable**)data);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 271 of file registry.c.

{
       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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int LoadDirectory ( HashTable directories,
HKEY  key,
char *  path,
int  path_len,
HashTable parent_ht 
) [static]

Definition at line 60 of file registry.c.

{
       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));
                                                 zend_hash_init(ht, 0, NULL, ZVAL_INTERNAL_PTR_DTOR, 1);
                                          }
                                          data = (zval*)malloc(sizeof(zval));
                                          INIT_PZVAL(data);
                                          Z_STRVAL_P(data) = zend_strndup(value, value_len-1);
                                          Z_STRLEN_P(data) = value_len-1;
                                          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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int OpenPhpRegistryKey ( char *  sub_key,
HKEY *  hKey 
) [static]

Definition at line 25 of file registry.c.

{
       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;
}

Here is the caller graph for this function:

void UpdateIniFromRegistry ( char *path  TSRMLS_DC)

Definition at line 165 of file registry.c.

{
       char *p, *orig_path;
       int path_len;
       HashTable **pht;

       if(!path) {
              return;
       }

       if (!PW32G(registry_directories)) {
              PW32G(registry_directories) = (HashTable*)malloc(sizeof(HashTable));
              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_SYSTEM, 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);
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

const char* registry_keys[] [static]