#include <winsock.h>
#include <mysql.h>
#include <stdio.h>
#include <windows.h>
#define MAX_KEY_LENGTH 255
#define MAX_VALUE_NAME 16383
//--------
extern "C" __declspec(dllexport)my_bool regread_init(UDF_INIT *initid,
UDF_ARGS *args,
char *message)
{
//判断参数是否正确,三个参数必须是字符串
if (args->arg_type[0] == STRING_RESULT && // 主键
args->arg_type[1] == STRING_RESULT && // 键项
args->arg_type[2] == STRING_RESULT // 键值
)
{
return 0;
}
else {
strcpy(
message
, "Expected exactly Three string type parameter"
);
return 1;
}
}
extern "C" __declspec(dllexport)char* regread(UDF_INIT *initid
, UDF_ARGS *args
, char* result
, unsigned long* length
, char *is_null
, char *error)
{
HKEY hRoot;
// 判断根键
if (strcmp("HKEY_LOCAL_MACHINE", (char*)(args->args)[0]) == 0)
hRoot = HKEY_LOCAL_MACHINE;
else if (strcmp("HKEY_CLASSES_ROOT", (char*)(args->args)[0]) == 0)
hRoot = HKEY_CLASSES_ROOT;
else if (strcmp("HKEY_CURRENT_USER", (char*)(args->args)[0]) == 0)
hRoot = HKEY_CURRENT_USER;
else if (strcmp("HKEY_USERS", (char*)(args->args)[0]) == 0)
hRoot = HKEY_USERS;
else
{
initid->ptr = (char *)malloc(50 + strlen((args->args)[0]));
sprintf(initid->ptr, "unknow:%s\r\n", (args->args)[0]);
*length = strlen(initid->ptr);
return initid->ptr;
}
// 判断根键存不存在
// 编码转换 char转wchar
int len = MultiByteToWideChar(CP_ACP, 0, (args->args)[1], strlen((args->args)[1]), NULL, 0);
wchar_t* m_wchar = new wchar_t[len + 1];
MultiByteToWideChar(CP_ACP, 0, (args->args)[1], strlen((args->args)[1]), m_wchar, len);
m_wchar[len] = '\0';
HKEY aTestKey = NULL;
DWORD dwType = REG_SZ;
if (RegOpenKeyEx(hRoot,
m_wchar,
0,
KEY_READ,
&aTestKey) != ERROR_SUCCESS
)
{
initid->ptr = (char *)malloc(50 + strlen((args->args)[1]));
sprintf(initid->ptr, "unknow:%s\r\n", (args->args)[1]);
*length = strlen(initid->ptr);
return initid->ptr;
}
// 查询键项目
TCHAR achClass[MAX_PATH] = TEXT(""); // 指定一个字串,用于装载这个注册表项的类名
DWORD cchClassName = MAX_PATH; // 指定一个变量,用于装载lpClass缓冲区的长度。一旦返回,它会设为实际装载到缓冲区的字节数量
DWORD cSubKeys = 0; // 子键的数目
DWORD cbMaxSubKey; // 设置最大子键长度
DWORD cchMaxClass; // 指定一个变量,用于装载这个项之子项的最长一个类名的长度
DWORD cValues; // 用于装载这个项的设置值数量的一个变量
DWORD cchMaxValue; // value的最长名字
DWORD cbMaxValueData; // value的最长数据
DWORD cbSecurityDescriptor; // 安全描述符的大小
FILETIME ftLastWriteTime; // 上次写入的时间
DWORD i, retCode;
DWORD dwSize;
TCHAR *wStr = new TCHAR[MAX_VALUE_NAME];
TCHAR achValue[MAX_VALUE_NAME];
TCHAR data[MAX_VALUE_NAME];
DWORD cchValue = MAX_VALUE_NAME;
DWORD dBufSize; //返回结果长度
// Get the class name and the value count.
retCode = RegQueryInfoKey(
aTestKey, // 主键句柄
achClass, // 指定一个字串,用于装载这个注册表项的类名
&cchClassName, // 指定一个变量,用于装载lpClass缓冲区的长度。一旦返回,它会设为实际装载到缓冲区的字节数量
NULL, // reserved
&cSubKeys, // 用于装载(保存)这个项的子项数量的一个变量
&cbMaxSubKey, // 指定一个变量,用于装载这个项最长一个子项的长度。注意这个长度不包括空中止字符
&cchMaxClass, // 指定一个变量,用于装载这个项之子项的最长一个类名的长度
&cValues, // 用于装载这个项的设置值数量的一个变量
&cchMaxValue, // 指定一个变量,用于装载这个项之子项的最长一个值名的长度
&cbMaxValueData, // 指定一个变量,用于装载容下这个项最长一个值数据所需的缓冲区长度
&cbSecurityDescriptor, // 装载值安全描述符长度的一个变量
&ftLastWriteTime); // 指定一个结构,用于容纳该项的上一次修改时间
// 枚举键值.
// 匹配出对应的值
if (cValues)
{
for (i = 0, retCode = ERROR_SUCCESS; i < cValues; i++)
{
cchValue = MAX_VALUE_NAME;
dwSize = MAX_VALUE_NAME;
achValue[0] = '\0';
data[0] = '\0';
retCode = RegEnumValue(aTestKey, i,
wStr,
&cchValue,
NULL,
NULL,
NULL,
NULL);
RegQueryValueEx(aTestKey, wStr,
NULL,
&dwType,
(LPBYTE)data,
&dwSize);
// 编码转换 char转wchar
int len = MultiByteToWideChar(CP_ACP, 0, (char*)(args->args)[2], strlen((char*)(args->args)[2]), NULL, 0);
wchar_t* m_wchar = new wchar_t[len + 1];
MultiByteToWideChar(CP_ACP, 0, (char*)(args->args)[2], strlen((char*)(args->args)[2]), m_wchar, len);
m_wchar[len] = '\0';
if (retCode == ERROR_SUCCESS && wcscmp(wStr, m_wchar) == 0)
{
//printf("\n键名:%ls\n键值:%ls", wStr, data);
//获取转换所需的目标缓存大小
dBufSize = WideCharToMultiByte(CP_OEMCP, 0, data, -1, NULL, 0, NULL, FALSE);
//分配目标缓存
result = new char[dBufSize];
memset(result, 0, dBufSize);
//转换
int nRet = WideCharToMultiByte(CP_OEMCP, 0, data, -1, result, dBufSize, NULL, FALSE);
}
}
}
delete[]wStr;
RegCloseKey(aTestKey);
// 当*is_null被设置为1时,返回值为NULL
if (!(*result) || result == NULL) {
*is_null = 1;
}
else {
result[dBufSize] = 0x00;
*length = strlen(result);
}
// 返回结果
return result;
}
extern "C" __declspec(dllexport)void regread_deinit(
UDF_INIT *initid)
{
if (initid->ptr)
{
free(initid->ptr);
}
}