📄 registry.c
字号:
/* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */#ifdef WIN32/* * Functions to handle interacting with the Win32 registry *//* * Apache registry key structure * * Apache's registry information is stored in the HKEY_LOCAL_MACHINE * key, under * * HKLM\SOFTWARE\Apache Group\Apache\version * * These keys are defined in this file. The definition of the "version" part * will need updating each time Apache moves from beta to non-beta or from a * release to a development or beta version. *//* To allow for multiple services, store the configuration file's full path * under each service entry: * * HKLM\System\CurrentControlSet\Services\[service name]\Parameters\ConfPath * * The default configuration path (for console apache) is still stored: * * HKLM\Software\[Vendor]\[Software]\[Version]\ServerRoot */#include <windows.h>#include <stdio.h>#include "httpd.h"#include "http_log.h"#include "service.h"/* Define where the Apache values are stored in the registry. In general * VERSION will be the same across all beta releases for a particular * major release, but will change when the final release is made. *//* Define where the Apache values are stored in the registry. * * If you are looking here to roll the tarball, you didn't need to visit. * registry.c now picks up the version from include/httpd.h */#define REGKEY "SOFTWARE\\" SERVER_BASEVENDOR "\\" SERVER_BASEPRODUCT "\\" SERVER_BASEREVISION#define SERVICEKEYPRE "System\\CurrentControlSet\\Services\\"#define SERVICEKEYPOST "\\Parameters"/* * The Windows API registry key functions don't set the last error * value (the windows equivalent of errno). So we need to set it * with SetLastError() before calling the aplog_error() function. * Because this is common, let's have a macro. */#define do_error(rv,fmt,arg) do { \ SetLastError(rv); \ ap_log_error(APLOG_MARK, APLOG_WIN32ERROR|APLOG_ERR, NULL, fmt,arg); \ } while (0);/* * Get the data for registry key value. This is a generic function that * can either get a value into a caller-supplied buffer, or it can * allocate space for the value from the pass-in pool. It will normally * be used by other functions within this file to get specific key values * (e.g. registry_get_server_root()). This function returns a number of * different error statuses, allowing the caller to differentiate * between a key or value not existing and other kinds of errors. Depending * on the type of data being obtained the caller can then either ignore * the key-not-existing error, or treat it as a real error. * * If ppValue is NULL, allocate space for the value and return it in * *pValue. The return value is the number of bytes in the value. * The first argument is the pool to use to allocate space for the value. * * If pValue is not NULL, assume it is a buffer of nSizeValue bytes, * and write the value into the buffer. The return value is the number * of bytes in the value (so if the return value is greater than * the supplied nSizeValue, the caller knows that *pValue is truncated). * The pool argument is ignored. * * The return value is the number of bytes in the successfully retreived * key if everything worked, or: * * -1 the key does not exists * -2 if out of memory during the function * -3 if the buffer specified by *pValue/nSizeValue was not large enough * for the value. * -4 if an error occurred * * If the return value is negative a message will be logged to the error * log (aplog_error) function. If the return value is -2, -3 or -4 the message * will be logged at priority "error", while if the return value is -1 the * message will be logged at priority "warning". */static int ap_registry_get_key_int(pool *p, char *key, char *name, char *pBuffer, int nSizeBuffer, char **ppValue){ long rv; HKEY hKey; char *pValue; int nSize; int retval; rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, KEY_READ, &hKey); if (rv == ERROR_FILE_NOT_FOUND) { ap_log_error(APLOG_MARK,APLOG_WARNING|APLOG_NOERRNO,NULL, "Registry does not contain key %s",key); return -1; } if (rv != ERROR_SUCCESS) { do_error(rv, "RegOpenKeyEx HKLM\\%s",key); return -4; } if (pBuffer == NULL) { /* Find the size required for the data by passing NULL as the buffer * pointer. On return nSize will contain the size required for the * buffer if the return value is ERROR_SUCCESS. */ rv = RegQueryValueEx(hKey, name, /* key name */ NULL, /* reserved */ NULL, /* type */ NULL, /* for value */ &nSize); /* for size of "value" */ if (rv != ERROR_SUCCESS) { do_error(rv, "RegQueryValueEx(key %s)", key); return -1; } pValue = ap_palloc(p, nSize); *ppValue = pValue; if (!pValue) { /* Eek, out of memory, probably not worth trying to carry on, * but let's give it a go */ ap_log_error(APLOG_MARK,APLOG_ERR|APLOG_NOERRNO,NULL, "Error getting registry key: out of memory"); return -2; } } else { /* Get the value into the existing buffer of length nSizeBuffer */ pValue = pBuffer; nSize = nSizeBuffer; } rv = RegQueryValueEx(hKey, name, /* key name */ NULL, /* reserved */ NULL, /* type */ pValue, /* for value */ &nSize); /* for size of "value" */ retval = 0; /* Return value */ if (rv == ERROR_FILE_NOT_FOUND) { ap_log_error(APLOG_MARK,APLOG_WARNING|APLOG_NOERRNO,NULL, "Registry does not contain value %s\\%s", key, name); retval = -1; } else if (rv == ERROR_MORE_DATA) { /* This should only happen if we got passed a pre-existing buffer * (pBuffer, nSizeBuffer). But I suppose it could also happen if we * allocate a buffer if another process changed the length of the * value since we found out its length above. Umm. */ ap_log_error(APLOG_MARK,APLOG_ERR|APLOG_NOERRNO,NULL, "Error getting registry value %s: buffer not big enough", key); retval = -3; } else if (rv != ERROR_SUCCESS) { do_error(rv, "RegQueryValueEx(key %s)", key); retval = -4; } rv = RegCloseKey(hKey); if (rv != ERROR_SUCCESS) { do_error(rv, "RegCloseKey HKLM\\%s", key); if (retval == 0) { /* Keep error status from RegQueryValueEx, if any */ retval = -4; } } return retval < 0 ? retval : nSize;}/* * Get the server root from the registry into 'dir' which is * size bytes long. Returns 0 if the server root was found * or if the serverroot key does not exist (in which case * dir will contain an empty string), or -1 if there was * an error getting the key. */API_EXPORT(int) ap_registry_get_server_root(pool *p, char *dir, int size){ int rv; rv = ap_registry_get_key_int(p, REGKEY, "ServerRoot", dir, size, NULL); if (rv < 0) { dir[0] = '\0'; } return (rv < 0) ? -1 : 0;}API_EXPORT(char *) ap_get_service_key(char *display_name){ char *key, *service_name; if (display_name == NULL) return strdup(""); service_name = get_service_name(display_name); key = malloc(strlen(SERVICEKEYPRE) + strlen(service_name) + strlen(SERVICEKEYPOST) + 1); sprintf(key,"%s%s%s", SERVICEKEYPRE, service_name, SERVICEKEYPOST); return(key);}/********************************************************************** * The rest of this file deals with storing keys or values in the registry */char *ap_registry_parse_key(int index, char *key){ char *head = key, *skey; int i; if(!key) return(NULL); for(i = 0; i <= index; i++) { if(key && key[0] == '\\') key++; if (!key) return(NULL); head = key; key = strchr(head, '\\'); } if(!key) return(strdup(head)); *key = '\0'; skey = strdup(head); *key = '\\'; return(skey);}/* * ap_registry_create_apache_key() creates the Apache registry key * (HLKM\SOFTWARE\Apache Group\Apache\version, as defined at the start * of this file), if it does not already exist. It will be called by
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -