📄 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.
*/
/*
*
* @author Mladen Turk
* @version $Revision: 466609 $, $Date: 2006-10-22 01:30:39 +0200 (dim., 22 oct. 2006) $
*/
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0500
#endif
#include <winsock2.h>
#include <mswsock.h>
#include <ws2tcpip.h>
#include <shlwapi.h>
#include "apr.h"
#include "apr_pools.h"
#include "apr_arch_misc.h" /* for apr_os_level */
#include "apr_arch_atime.h" /* for FileTimeToAprTime */
#include "tcn.h"
#define SAFE_CLOSE_KEY(k) \
if ((k) != NULL && (k) != INVALID_HANDLE_VALUE) { \
RegCloseKey((k)); \
(k) = NULL; \
}
typedef struct {
apr_pool_t *pool;
HKEY root;
HKEY key;
} tcn_nt_registry_t;
#define TCN_HKEY_CLASSES_ROOT 1
#define TCN_HKEY_CURRENT_CONFIG 2
#define TCN_HKEY_CURRENT_USER 3
#define TCN_HKEY_LOCAL_MACHINE 4
#define TCN_HKEY_USERS 5
static const struct {
HKEY k;
} TCN_KEYS[] = {
INVALID_HANDLE_VALUE,
HKEY_CLASSES_ROOT,
HKEY_CURRENT_CONFIG,
HKEY_CURRENT_USER,
HKEY_LOCAL_MACHINE,
HKEY_USERS,
INVALID_HANDLE_VALUE
};
#define TCN_KEY_ALL_ACCESS 0x0001
#define TCN_KEY_CREATE_LINK 0x0002
#define TCN_KEY_CREATE_SUB_KEY 0x0004
#define TCN_KEY_ENUMERATE_SUB_KEYS 0x0008
#define TCN_KEY_EXECUTE 0x0010
#define TCN_KEY_NOTIFY 0x0020
#define TCN_KEY_QUERY_VALUE 0x0040
#define TCN_KEY_READ 0x0080
#define TCN_KEY_SET_VALUE 0x0100
#define TCN_KEY_WOW64_64KEY 0x0200
#define TCN_KEY_WOW64_32KEY 0x0400
#define TCN_KEY_WRITE 0x0800
#define TCN_REGSAM(s, x) \
s = 0; \
if (x & TCN_KEY_ALL_ACCESS) \
s |= KEY_ALL_ACCESS; \
if (x & TCN_KEY_CREATE_LINK) \
s |= KEY_CREATE_LINK; \
if (x & TCN_KEY_CREATE_SUB_KEY) \
s |= KEY_CREATE_SUB_KEY; \
if (x & TCN_KEY_ENUMERATE_SUB_KEYS) \
s |= KEY_ENUMERATE_SUB_KEYS; \
if (x & TCN_KEY_EXECUTE) \
s |= KEY_EXECUTE; \
if (x & TCN_KEY_NOTIFY) \
s |= KEY_NOTIFY; \
if (x & TCN_KEY_READ) \
s |= KEY_READ; \
if (x & TCN_KEY_SET_VALUE) \
s |= KEY_SET_VALUE; \
if (x & TCN_KEY_WOW64_64KEY) \
s |= KEY_WOW64_64KEY; \
if (x & TCN_KEY_WOW64_32KEY) \
s |= KEY_WOW64_32KEY; \
if (x & TCN_KEY_WRITE) \
s |= KEY_WRITE
#define TCN_REG_BINARY 1
#define TCN_REG_DWORD 2
#define TCN_REG_EXPAND_SZ 3
#define TCN_REG_MULTI_SZ 4
#define TCN_REG_QWORD 5
#define TCN_REG_SZ 6
static const struct {
DWORD t;
} TCN_REGTYPES[] = {
REG_NONE,
REG_BINARY,
REG_DWORD,
REG_EXPAND_SZ,
REG_MULTI_SZ,
REG_QWORD,
REG_SZ,
REG_NONE
};
static apr_status_t registry_cleanup(void *data)
{
tcn_nt_registry_t *reg = (tcn_nt_registry_t *)data;
if (reg) {
SAFE_CLOSE_KEY(reg->key);
}
return APR_SUCCESS;
}
TCN_IMPLEMENT_CALL(jlong, Registry, create)(TCN_STDARGS, jint root, jstring name,
jint sam, jlong pool)
{
apr_pool_t *p = J2P(pool, apr_pool_t *);
tcn_nt_registry_t *reg = NULL;
TCN_ALLOC_WSTRING(name);
HKEY key;
LONG rc;
REGSAM s;
UNREFERENCED(o);
TCN_ASSERT(pool != 0);
if (root < TCN_HKEY_CLASSES_ROOT || root > TCN_HKEY_USERS) {
tcn_ThrowException(e, "Invalid Registry Root Key");
goto cleanup;
}
if (sam < TCN_KEY_ALL_ACCESS || root > TCN_KEY_WRITE) {
tcn_ThrowException(e, "Invalid Registry Key Security");
goto cleanup;
}
reg = (tcn_nt_registry_t *)apr_palloc(p, sizeof(tcn_nt_registry_t));
reg->pool = p;
reg->root = TCN_KEYS[root].k;
reg->key = NULL;
TCN_INIT_WSTRING(name);
TCN_REGSAM(s, sam);
rc = RegCreateKeyExW(reg->root, J2W(name), 0, NULL, REG_OPTION_NON_VOLATILE,
s, NULL, &key, NULL);
if (rc != ERROR_SUCCESS) {
tcn_ThrowAPRException(e, APR_FROM_OS_ERROR(rc));
goto cleanup;
}
reg->key = key;
apr_pool_cleanup_register(p, (const void *)reg,
registry_cleanup,
apr_pool_cleanup_null);
cleanup:
TCN_FREE_WSTRING(name);
return P2J(reg);
}
TCN_IMPLEMENT_CALL(jlong, Registry, open)(TCN_STDARGS, jint root, jstring name,
jint sam, jlong pool)
{
apr_pool_t *p = J2P(pool, apr_pool_t *);
tcn_nt_registry_t *reg = NULL;
TCN_ALLOC_WSTRING(name);
HKEY key;
LONG rc;
REGSAM s;
UNREFERENCED(o);
TCN_ASSERT(pool != 0);
if (root < TCN_HKEY_CLASSES_ROOT || root > TCN_HKEY_USERS) {
tcn_ThrowException(e, "Invalid Registry Root Key");
goto cleanup;
}
if (sam < TCN_KEY_ALL_ACCESS || root > TCN_KEY_WRITE) {
tcn_ThrowException(e, "Invalid Registry Key Security");
goto cleanup;
}
reg = (tcn_nt_registry_t *)apr_palloc(p, sizeof(tcn_nt_registry_t));
reg->pool = p;
reg->root = TCN_KEYS[root].k;
reg->key = NULL;
TCN_INIT_WSTRING(name);
TCN_REGSAM(s, sam);
rc = RegOpenKeyExW(reg->root, J2W(name), 0, s, &key);
if (rc != ERROR_SUCCESS) {
tcn_ThrowAPRException(e, APR_FROM_OS_ERROR(rc));
goto cleanup;
}
reg->key = key;
apr_pool_cleanup_register(p, (const void *)reg,
registry_cleanup,
apr_pool_cleanup_null);
cleanup:
TCN_FREE_WSTRING(name);
return P2J(reg);
}
TCN_IMPLEMENT_CALL(jint, Registry, close)(TCN_STDARGS, jlong reg)
{
tcn_nt_registry_t *r = J2P(reg, tcn_nt_registry_t *);
UNREFERENCED_STDARGS;
TCN_ASSERT(reg != 0);
registry_cleanup(r);
apr_pool_cleanup_kill(r->pool, r, registry_cleanup);
return APR_SUCCESS;
}
TCN_IMPLEMENT_CALL(jint, Registry, getType)(TCN_STDARGS, jlong key,
jstring name)
{
tcn_nt_registry_t *k = J2P(key, tcn_nt_registry_t *);
TCN_ALLOC_WSTRING(name);
LONG rc;
DWORD v;
UNREFERENCED(o);
TCN_ASSERT(key != 0);
TCN_INIT_WSTRING(name);
rc = RegQueryValueExW(k->key, J2W(name), NULL, &v, NULL, NULL);
if (rc != ERROR_SUCCESS)
v = -rc;
TCN_FREE_WSTRING(name);
switch (v) {
case REG_BINARY:
v = TCN_REG_BINARY;
break;
case REG_DWORD:
v = TCN_REG_DWORD;
break;
case REG_EXPAND_SZ:
v = TCN_REG_EXPAND_SZ;
break;
case REG_MULTI_SZ:
v = TCN_REG_MULTI_SZ;
break;
case REG_QWORD:
v = TCN_REG_QWORD;
break;
case REG_SZ:
v = TCN_REG_SZ;
break;
case REG_DWORD_BIG_ENDIAN:
v = 0;
break;
}
return v;
}
TCN_IMPLEMENT_CALL(jint, Registry, getSize)(TCN_STDARGS, jlong key,
jstring name)
{
tcn_nt_registry_t *k = J2P(key, tcn_nt_registry_t *);
TCN_ALLOC_WSTRING(name);
LONG rc;
DWORD v;
UNREFERENCED(o);
TCN_ASSERT(key != 0);
TCN_INIT_WSTRING(name);
rc = RegQueryValueExW(k->key, J2W(name), NULL, NULL, NULL, &v);
if (rc != ERROR_SUCCESS)
v = -rc;
TCN_FREE_WSTRING(name);
return v;
}
TCN_IMPLEMENT_CALL(jint, Registry, getValueI)(TCN_STDARGS, jlong key,
jstring name)
{
tcn_nt_registry_t *k = J2P(key, tcn_nt_registry_t *);
TCN_ALLOC_WSTRING(name);
LONG rc;
DWORD t, l;
DWORD v = 0;
UNREFERENCED(o);
TCN_ASSERT(key != 0);
TCN_INIT_WSTRING(name);
rc = RegQueryValueExW(k->key, J2W(name), NULL, &t, NULL, &l);
if (rc != ERROR_SUCCESS) {
tcn_ThrowAPRException(e, APR_FROM_OS_ERROR(rc));
goto cleanup;
}
if (t == REG_DWORD) {
l = sizeof(DWORD);
rc = RegQueryValueExW(k->key, J2W(name), NULL, NULL, (LPBYTE)&v, &l);
if (rc != ERROR_SUCCESS) {
tcn_ThrowAPRException(e, APR_FROM_OS_ERROR(rc));
goto cleanup;
}
}
else if (t == REG_SZ || t == REG_BINARY ||
t == REG_MULTI_SZ || t == REG_EXPAND_SZ)
v = l;
else {
v = 0;
tcn_ThrowException(e, "Unable to convert the value to integer");
}
cleanup:
TCN_FREE_WSTRING(name);
return v;
}
TCN_IMPLEMENT_CALL(jlong, Registry, getValueJ)(TCN_STDARGS, jlong key,
jstring name)
{
tcn_nt_registry_t *k = J2P(key, tcn_nt_registry_t *);
TCN_ALLOC_WSTRING(name);
LONG rc;
DWORD t, l;
UINT64 v = 0;
UNREFERENCED(o);
TCN_ASSERT(key != 0);
TCN_INIT_WSTRING(name);
rc = RegQueryValueExW(k->key, J2W(name), NULL, &t, NULL, &l);
if (rc != ERROR_SUCCESS) {
tcn_ThrowAPRException(e, APR_FROM_OS_ERROR(rc));
goto cleanup;
}
if (t == REG_DWORD) {
DWORD tv;
l = sizeof(DWORD);
rc = RegQueryValueExW(k->key, J2W(name), NULL, NULL, (LPBYTE)&tv, &l);
if (rc != ERROR_SUCCESS) {
tcn_ThrowAPRException(e, APR_FROM_OS_ERROR(rc));
goto cleanup;
}
v = tv;
}
else if (t == REG_QWORD) {
l = sizeof(UINT64);
rc = RegQueryValueExW(k->key, J2W(name), NULL, NULL, (LPBYTE)&v, &l);
if (rc != ERROR_SUCCESS) {
tcn_ThrowAPRException(e, APR_FROM_OS_ERROR(rc));
goto cleanup;
}
}
else if (t == REG_SZ || t == REG_BINARY ||
t == REG_MULTI_SZ || t == REG_EXPAND_SZ)
v = l;
else {
v = 0;
tcn_ThrowException(e, "Unable to convert the value to long");
}
cleanup:
TCN_FREE_WSTRING(name);
return v;
}
TCN_IMPLEMENT_CALL(jstring, Registry, getValueS)(TCN_STDARGS, jlong key,
jstring name)
{
tcn_nt_registry_t *k = J2P(key, tcn_nt_registry_t *);
TCN_ALLOC_WSTRING(name);
LONG rc;
DWORD t, l;
jstring v = NULL;
UNREFERENCED(o);
TCN_ASSERT(key != 0);
TCN_INIT_WSTRING(name);
rc = RegQueryValueExW(k->key, J2W(name), NULL, &t, NULL, &l);
if (rc != ERROR_SUCCESS) {
tcn_ThrowAPRException(e, APR_FROM_OS_ERROR(rc));
goto cleanup;
}
if (t == REG_SZ || t == REG_EXPAND_SZ) {
jchar *vw = (jchar *)malloc(l);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -