RegQueryValueExA function (winreg.h)

注册表值查询与数据获取
该博客介绍了如何使用Windows API函数RegQueryValueEx来检索注册表键中指定值的类型和数据。函数参数详细解析,包括返回值、错误处理和注意事项。特别强调了对于字符串类型的值,需要确保其为null终止。示例代码展示了如何处理数据缓冲区大小不足的情况,以及如何循环获取足够的数据。

Retrieves the type and data for the specified value name associated with an open registry key.

To ensure that any string values (REG_SZ, REG_MULTI_SZ, and REG_EXPAND_SZ) returned are null-terminated, use the RegGetValue function.

Syntax

LSTATUS RegQueryValueExA(
  [in]                HKEY    hKey,
  [in, optional]      LPCSTR  lpValueName,
                      LPDWORD lpReserved,
  [out, optional]     LPDWORD lpType,
  [out, optional]     LPBYTE  lpData,
  [in, out, optional] LPDWORD lpcbData
);

Parameters

[in] hKey

A handle to an open registry key. The key must have been opened with the KEY_QUERY_VALUE access right. For more information, see Registry Key Security and Access Rights.

This handle is returned by the RegCreateKeyExRegCreateKeyTransactedRegOpenKeyEx, or RegOpenKeyTransacted function. It can also be one of the following predefined keys:

HKEY_CLASSES_ROOT

HKEY_CURRENT_CONFIG

HKEY_CURRENT_USER

HKEY_LOCAL_MACHINE

HKEY_PERFORMANCE_DATA

HKEY_PERFORMANCE_NLSTEXT

HKEY_PERFORMANCE_TEXT

HKEY_USERS

[in, optional] lpValueName

The name of the registry value.

If lpValueName is NULL or an empty string, "", the function retrieves the type and data for the key's unnamed or default value, if any.

If lpValueName specifies a value that is not in the registry, the function returns ERROR_FILE_NOT_FOUND.

Keys do not automatically have an unnamed or default value. Unnamed values can be of any type. For more information, see Registry Element Size Limits.

lpReserved

This parameter is reserved and must be NULL.

[out, optional] lpType

A pointer to a variable that receives a code indicating the type of data stored in the specified value. For a list of the possible type codes, see Registry Value Types. The lpType parameter can be NULL if the type code is not required.

[out, optional] lpData

A pointer to a buffer that receives the value's data. This parameter can be NULL if the data is not required.

[in, out, optional] lpcbData

A pointer to a variable that specifies the size of the buffer pointed to by the lpData parameter, in bytes. When the function returns, this variable contains the size of the data copied to lpData.

The lpcbData parameter can be NULL only if lpData is NULL.

If the data has the REG_SZ, REG_MULTI_SZ or REG_EXPAND_SZ type, this size includes any terminating null character or characters unless the data was stored without them. For more information, see Remarks.

If the buffer specified by lpData parameter is not large enough to hold the data, the function returns ERROR_MORE_DATA and stores the required buffer size in the variable pointed to by lpcbData. In this case, the contents of the lpData buffer are undefined.

If lpData is NULL, and lpcbData is non-NULL, the function returns ERROR_SUCCESS and stores the size of the data, in bytes, in the variable pointed to by lpcbData. This enables an application to determine the best way to allocate a buffer for the value's data.

If hKey specifies HKEY_PERFORMANCE_DATA and the lpData buffer is not large enough to contain all of the returned data, RegQueryValueEx returns ERROR_MORE_DATA and the value returned through the lpcbData parameter is undefined. This is because the size of the performance data can change from one call to the next. In this case, you must increase the buffer size and call RegQueryValueEx again passing the updated buffer size in the lpcbData parameter. Repeat this until the function succeeds. You need to maintain a separate variable to keep track of the buffer size, because the value returned by lpcbData is unpredictable.

If the lpValueName registry value does not exist, RegQueryValueEx returns ERROR_FILE_NOT_FOUND and the value returned through the lpcbData parameter is undefined.

Return value

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a system error code.

If the lpData buffer is too small to receive the data, the function returns ERROR_MORE_DATA.

If the lpValueName registry value does not exist, the function returns ERROR_FILE_NOT_FOUND.

Remarks

An application typically calls RegEnumValue to determine the value names and then RegQueryValueEx to retrieve the data for the names.

If the data has the REG_SZ, REG_MULTI_SZ or REG_EXPAND_SZ type, the string may not have been stored with the proper terminating null characters. Therefore, even if the function returns ERROR_SUCCESS, the application should ensure that the string is properly terminated before using it; otherwise, it may overwrite a buffer. (Note that REG_MULTI_SZ strings should have two terminating null characters.) One way an application can ensure that the string is properly terminated is to use RegGetValue, which adds terminating null characters if needed.

If the data has the REG_SZ, REG_MULTI_SZ or REG_EXPAND_SZ type, and the ANSI version of this function is used (either by explicitly calling RegQueryValueExA or by not defining UNICODE before including the Windows.h file), this function converts the stored Unicode string to an ANSI string before copying it to the buffer pointed to by lpData.

When calling the RegQueryValueEx function with hKey set to the HKEY_PERFORMANCE_DATA handle and a value string of a specified object, the returned data structure sometimes has unrequested objects. Do not be surprised; this is normal behavior. When calling the RegQueryValueEx function, you should always expect to walk the returned data structure to look for the requested object.

Note that operations that access certain registry keys are redirected. For more information, see Registry Virtualization and 32-bit and 64-bit Application Data in the Registry.

Examples

Ensure that you reinitialize the value pointed to by the lpcbData parameter each time you call this function. This is very important when you call this function in a loop, as in the following code example.

#include <windows.h>
#include <malloc.h>
#include <stdio.h>

#define TOTALBYTES    8192
#define BYTEINCREMENT 4096

void main()
{
    DWORD BufferSize = TOTALBYTES;
    DWORD cbData;
    DWORD dwRet;

    PPERF_DATA_BLOCK PerfData = (PPERF_DATA_BLOCK) malloc( BufferSize );
    cbData = BufferSize;

    printf("\nRetrieving the data...");

    dwRet = RegQueryValueEx( HKEY_PERFORMANCE_DATA,
                             TEXT("Global"),
                             NULL,
                             NULL,
                             (LPBYTE) PerfData,
                             &cbData );
    while( dwRet == ERROR_MORE_DATA )
    {
        // Get a buffer that is big enough.

        BufferSize += BYTEINCREMENT;
        PerfData = (PPERF_DATA_BLOCK) realloc( PerfData, BufferSize );
        cbData = BufferSize;

        printf(".");
        dwRet = RegQueryValueEx( HKEY_PERFORMANCE_DATA,
                         TEXT("Global"),
                         NULL,
                         NULL,
                         (LPBYTE) PerfData,
                         &cbData );
    }
    if( dwRet == ERROR_SUCCESS )
        printf("\n\nFinal buffer size is %d\n", BufferSize);
    else printf("\nRegQueryValueEx failed (%d)\n", dwRet);
}

 备注

The winreg.h header defines RegQueryValueEx as an alias which automatically selects the ANSI or Unicode version of this function based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that not encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions for Function Prototypes.

Requirements

REQUIREMENTS
  
Minimum supported clientWindows 2000 Professional [desktop apps only]
Minimum supported serverWindows 2000 Server [desktop apps only]
Target PlatformWindows
Headerwinreg.h (include Windows.h)
LibraryAdvapi32.lib
DLLAdvapi32.dll
// autostart_registry_manager.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <windows.h> #include <iostream> #include <string> #include <vector> #include <map> #include <winreg.h> #include <tlhelp32.h> #include <psapi.h> class AutostartRegistryManager { private: std::map<std::string, std::string> startupLocations; std::string serviceName; std::string executablePath; void InitializeStartupLocations() { startupLocations["HKCU_Run"] = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"; startupLocations["HKCU_RunOnce"] = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce"; startupLocations["HKLM_Run"] = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"; startupLocations["HKLM_RunOnce"] = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce"; startupLocations["Startup_Folder"] = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"; } bool CreateServiceName() { // 生成合法的服务名称 char computerName[MAX_COMPUTERNAME_LENGTH + 1]; DWORD size = sizeof(computerName); if (GetComputerNameA(computerName, &size)) { serviceName = "SystemUpdateTask_" + std::string(computerName); } else { serviceName = "SystemUpdateTask_Default"; } return true; } bool GetExecutablePath() { char buffer[MAX_PATH]; if (GetModuleFileNameA(NULL, buffer, MAX_PATH)) { executablePath = std::string(buffer); return true; } return false; } bool AddToRegistry(HKEY hKey, const std::string& subKey, const std::string& valueName, const std::string& valueData) { HKEY hSubKey; LONG result = RegCreateKeyExA(hKey, subKey.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hSubKey, NULL); if (result != ERROR_SUCCESS) { std::cout << "创建注册表项失败: " << subKey << std::endl; return false; } result = RegSetValueExA(hSubKey, valueName.c_str(), 0, REG_SZ, (const BYTE*)valueData.c_str(), valueData.length() + 1); RegCloseKey(hSubKey); if (result != ERROR_SUCCESS) { std::cout << "设置注册表值失败: " << valueName << std::endl; return false; } return true; } bool RemoveFromRegistry(HKEY hKey, const std::string& subKey, const std::string& valueName) { HKEY hSubKey; LONG result = RegOpenKeyExA(hKey, subKey.c_str(), 0, KEY_WRITE, &hSubKey); if (result != ERROR_SUCCESS) { std::cout << "打开注册表项失败: " << subKey << std::endl; return false; } result = RegDeleteValueA(hSubKey, valueName.c_str()); RegCloseKey(hSubKey); if (result != ERROR_SUCCESS) { std::cout << "删除注册表值失败: " << valueName << std::endl; return false; } return true; } bool CheckRegistryValue(HKEY hKey, const std::string& subKey, const std::string& valueName) { HKEY hSubKey; LONG result = RegOpenKeyExA(hKey, subKey.c_str(), 0, KEY_READ, &hSubKey); if (result != ERROR_SUCCESS) { return false; } char buffer[1024]; DWORD bufferSize = sizeof(buffer); DWORD dataType; result = RegQueryValueExA(hSubKey, valueName.c_str(), NULL, &dataType, (LPBYTE)buffer, &bufferSize); RegCloseKey(hSubKey); return (result == ERROR_SUCCESS); } std::string GetStartupFolderPath() { char buffer[MAX_PATH]; HKEY hKey; if (RegOpenKeyExA(HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", 0, KEY_READ, &hKey) == ERROR_SUCCESS) { DWORD bufferSize = sizeof(buffer); if (RegQueryValueExA(hKey, "Startup", NULL, NULL, (LPBYTE)buffer, &bufferSize) == ERROR_SUCCESS) { RegCloseKey(hKey); return std::string(buffer); } RegCloseKey(hKey); } return ""; } bool CreateShortcutInStartupFolder() { std::string startupFolder = GetStartupFolderPath(); if (startupFolder.empty()) { std::cout << "无法获取启动文件夹路径" << std::endl; return false; } std::string shortcutPath = startupFolder + "\\" + serviceName + ".lnk"; // 创建快捷方式文件 std::ofstream shortcut(shortcutPath); if (!shortcut.is_open()) { std::cout << "无法创建快捷方式文件" << std::endl; return false; } // 写入快捷方式内容 shortcut << "[InternetShortcut]" << std::endl; shortcut << "URL=file://" << executablePath << std::endl; shortcut.close(); return true; } bool RemoveShortcutFromStartupFolder() { std::string startupFolder = GetStartupFolderPath(); if (startupFolder.empty()) { return false; } std::string shortcutPath = startupFolder + "\\" + serviceName + ".lnk"; return DeleteFileA(shortcutPath.c_str()) != 0; } bool CreateScheduledTask() { std::string command = "schtasks /create /tn \"" + serviceName + "\" /tr \"" + executablePath + "\" /sc onlogon /ru \"SYSTEM\" /f"; STARTUPINFOA si = { 0 }; PROCESS_INFORMATION pi = { 0 }; si.cb = sizeof(si); if (CreateProcessA(NULL, (LPSTR)command.c_str(), NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) { WaitForSingleObject(pi.hProcess, 5000); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); return true; } return false; } bool RemoveScheduledTask() { std::string command = "schtasks /delete /tn \"" + serviceName + "\" /f"; STARTUPINFOA si = { 0 }; PROCESS_INFORMATION pi = { 0 }; si.cb = sizeof(si); if (CreateProcessA(NULL, (LPSTR)command.c_str(), NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) { WaitForSingleObject(pi.hProcess, 5000); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); return true; } return false; } public: AutostartRegistryManager() { InitializeStartupLocations(); CreateServiceName(); GetExecutablePath(); } bool RegisterAutostart() { std::cout << "正在注册自启动项..." << std::endl; // 添加到HKCU\Run if (!AddToRegistry(HKEY_CURRENT_USER, startupLocations["HKCU_Run"], serviceName, executablePath)) { std::cout << "添加到HKCU\\Run失败" << std::endl; return false; } // 添加到HKLM\Run (需要管理员权限) if (!AddToRegistry(HKEY_LOCAL_MACHINE, startupLocations["HKLM_Run"], serviceName, executablePath)) { std::cout << "添加到HKLM\\Run失败 (可能需要管理员权限)" << std::endl; } // 创建启动文件夹快捷方式 if (!CreateShortcutInStartupFolder()) { std::cout << "创建启动文件夹快捷方式失败" << std::endl; } // 创建计划任务 if (!CreateScheduledTask()) { std::cout << "创建计划任务失败" << std::endl; } std::cout << "自启动项注册完成" << std::endl; return true; } bool UnregisterAutostart() { std::cout << "正在移除自启动项..." << std::endl; // 从HKCU\Run移除 RemoveFromRegistry(HKEY_CURRENT_USER, startupLocations["HKCU_Run"], serviceName); // 从HKLM\Run移除 RemoveFromRegistry(HKEY_LOCAL_MACHINE, startupLocations["HKLM_Run"], serviceName); // 移除启动文件夹快捷方式 RemoveShortcutFromStartupFolder(); // 移除计划任务 RemoveScheduledTask(); std::cout << "自启动项移除完成" << std::endl; return true; } bool IsRegistered() { // 检查HKCU\Run if (CheckRegistryValue(HKEY_CURRENT_USER, startupLocations["HKCU_Run"], serviceName)) { return true; } // 检查HKLM\Run if (CheckRegistryValue(HKEY_LOCAL_MACHINE, startupLocations["HKLM_Run"], serviceName)) { return true; } // 检查启动文件夹 std::string startupFolder = GetStartupFolderPath(); if (!startupFolder.empty()) { std::string shortcutPath = startupFolder + "\\" + serviceName + ".lnk"; if (GetFileAttributesA(shortcutPath.c_str()) != INVALID_FILE_ATTRIBUTES) { return true; } } return false; } void ListAutostartItems() { std::cout << "=== 当前自启动项 ===" << std::endl; // 列出HKCU\Run项 HKEY hKey; if (RegOpenKeyExA(HKEY_CURRENT_USER, startupLocations["HKCU_Run"].c_str(), 0, KEY_READ, &hKey) == ERROR_SUCCESS) { char valueName[256]; char valueData[1024]; DWORD valueNameSize = sizeof(valueName); DWORD valueDataSize = sizeof(valueData); DWORD index = 0; while (RegEnumValueA(hKey, index, valueName, &valueNameSize, NULL, NULL, (LPBYTE)valueData, &valueDataSize) == ERROR_SUCCESS) { std::cout << "HKCU\\Run: " << valueName << " = " << valueData << std::endl; valueNameSize = sizeof(valueName); valueDataSize = sizeof(valueData); index++; } RegCloseKey(hKey); } // 列出HKLM\Run项 if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, startupLocations["HKLM_Run"].c_str(), 0, KEY_READ, &hKey) == ERROR_SUCCESS) { char valueName[256]; char valueData[1024]; DWORD valueNameSize = sizeof(valueName); DWORD valueDataSize = sizeof(valueData); DWORD index = 0; while (RegEnumValueA(hKey, index, valueName, &valueNameSize, NULL, NULL, (LPBYTE)valueData, &valueDataSize) == ERROR_SUCCESS) { std::cout << "HKLM\\Run: " << valueName << " = " << valueData << std::endl; valueNameSize = sizeof(valueName); valueDataSize = sizeof(valueData); index++; } RegCloseKey(hKey); } } std::string GetServiceName() const { return serviceName; } std::string GetExecutablePath() const { return executablePath; } }; int main() { SetConsoleOutputCP(CP_UTF8); AutostartRegistryManager manager; std::cout << "自启动注册管理器" << std::endl; std::cout << "服务名称: " << manager.GetServiceName() << std::endl; std::cout << "可执行文件路径: " << manager.GetExecutablePath() << std::endl; // 检查当前状态 if (manager.IsRegistered()) { std::cout << "当前已注册自启动" << std::endl; } else { std::cout << "当前未注册自启动" << std::endl; } // 列出当前自启动项 std::cout << "\n当前系统自启动项:" << std::endl; manager.ListAutostartItems(); // 注册自启动 std::cout << "\n正在注册自启动..." << std::endl; if (manager.RegisterAutostart()) { std::cout << "自启动注册成功" << std::endl; } else { std::cout << "自启动注册失败" << std::endl; } // 再次检查状态 if (manager.IsRegistered()) { std::cout << "注册后状态: 已注册" << std::endl; } else { std::cout << "注册后状态: 未注册" << std::endl; } // 移除自启动 std::cout << "\n正在移除自启动..." << std::endl; if (manager.UnregisterAutostart()) { std::cout << "自启动移除成功" << std::endl; } else { std::cout << "自启动移除失败" << std::endl; } std::cout << "\n自启动注册管理测试完成" << std::endl; system("pause"); return 0; } 用vs2015编译的时候报错了,修改代码并给出完整的C++代码
07-11
#include <Windows.h> #include <Wbemidl.h> #include <comdef.h> #include <WinCrypt.h> #include <string> #include <algorithm> #include <sstream> #include <vector> #pragma comment(lib, "wbemuuid.lib") #pragma comment(lib, "Advapi32.lib") #pragma comment(lib, "Crypt32.lib") // 导出函数声明 extern "C" __declspec(dllexport) const char* GetMachineCode(); extern "C" __declspec(dllexport) const char* ComputeRegistration(const char* machineCode, int daysChoice); extern "C" __declspec(dllexport) BOOL SaveRegistration(const char* machineCode, const char* regCode, int daysChoice); extern "C" __declspec(dllexport) int ValidateLicense(); // 全局缓冲区用于返回字符串 thread_local static char g_buffer[256] = { 0 }; // 获取机器码函数 const char* GetMachineCode() { HRESULT hres; std::string serials; // 初始化COM hres = CoInitializeEx(0, COINIT_MULTITHREADED); if (FAILED(hres)) { strcpy_s(g_buffer, "COM Init Failed"); return g_buffer; } // 设置安全级别 hres = CoInitializeSecurity( NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL ); if (FAILED(hres)) { CoUninitialize(); strcpy_s(g_buffer, "Security Init Failed"); return g_buffer; } // 创建WMI实例 IWbemLocator* pLoc = NULL; hres = CoCreateInstance( CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pLoc ); if (FAILED(hres)) { CoUninitialize(); strcpy_s(g_buffer, "WMI Locator Failed"); return g_buffer; } // 连接WMI IWbemServices* pSvc = NULL; hres = pLoc->ConnectServer( _bstr_t(L"ROOT\\CIMV2"), NULL, NULL, 0, NULL, 0, 0, &pSvc ); if (FAILED(hres)) { pLoc->Release(); CoUninitialize(); strcpy_s(g_buffer, "WMI Connect Failed"); return g_buffer; } // 设置代理安全 hres = CoSetProxyBlanket( pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE ); if (FAILED(hres)) { pSvc->Release(); pLoc->Release(); CoUninitialize(); strcpy_s(g_buffer, "Proxy Setup Failed"); return g_buffer; } // 执行查询 IEnumWbemClassObject* pEnumerator = NULL; hres = pSvc->ExecQuery( bstr_t("WQL"), bstr_t("SELECT SerialNumber FROM Win32_DiskDrive"), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator ); if (FAILED(hres)) { pSvc->Release(); pLoc->Release(); CoUninitialize(); strcpy_s(g_buffer, "Query Failed"); return g_buffer; } // 处理查询结果 IWbemClassObject* pclsObj = NULL; ULONG uReturn = 0; while (pEnumerator) { HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); if (uReturn == 0) break; VARIANT vtProp; VariantInit(&vtProp); // 获取序列号 hr = pclsObj->Get(L"SerialNumber", 0, &vtProp, 0, 0); if (SUCCEEDED(hr) && vtProp.vt == VT_BSTR) { _bstr_t bstr(vtProp.bstrVal); serials += (const char*)bstr; } VariantClear(&vtProp); pclsObj->Release(); } // 清理资源 pEnumerator->Release(); pSvc->Release(); pLoc->Release(); CoUninitialize(); // 计算MD5哈希 HCRYPTPROV hProv = 0; HCRYPTHASH hHash = 0; BYTE rgbHash[16]; DWORD cbHash = 16; CHAR rgbDigits[] = "0123456789abcdef"; if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { strcpy_s(g_buffer, "Crypto Context Failed"); return g_buffer; } if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) { CryptReleaseContext(hProv, 0); strcpy_s(g_buffer, "Hash Creation Failed"); return g_buffer; } if (!CryptHashData(hHash, (BYTE*)serials.c_str(), (DWORD)serials.length(), 0)) { CryptDestroyHash(hHash); CryptReleaseContext(hProv, 0); strcpy_s(g_buffer, "Hashing Failed"); return g_buffer; } if (CryptGetHashParam(hHash, HP_HASHVAL, rgbHash, &cbHash, 0)) { std::string hashStr; for (DWORD i = 0; i < cbHash; i++) { char hex[3]; sprintf_s(hex, "%02x", rgbHash[i]); hashStr += hex; } strcpy_s(g_buffer, hashStr.c_str()); } else { strcpy_s(g_buffer, "Hash Retrieval Failed"); } CryptDestroyHash(hHash); CryptReleaseContext(hProv, 0); return g_buffer; } // 计算注册码 const char* ComputeRegistration(const char* machineCode, int daysChoice) { int days; switch (daysChoice) { case 0: days = 7; break; case 1: days = 15; break; case 2: days = 30; break; default: days = 9999; // 永久 } std::string mc(machineCode); if (mc.length() < 5) { strcpy_s(g_buffer, "Invalid Machine Code"); return g_buffer; } // 算法:前4字符 + (第5字符ASCII+天数) + 反转字符前4 + 天数*100 std::string part1 = mc.substr(0, 4); char c = mc[4]; std::string part2 = std::to_string(static_cast<int>(c) + days); std::string reversed = mc; std::reverse(reversed.begin(), reversed.end()); std::string part3 = reversed.substr(0, 4); std::string part4 = std::to_string(days * 100); std::string regCode = part1 + part2 + part3 + part4; strcpy_s(g_buffer, regCode.c_str()); return g_buffer; } // 保存注册信息 BOOL SaveRegistration(const char* machineCode, const char* regCode, int daysChoice) { HKEY hKey; std::string subkey = "Software\\MyPlugin\\"; subkey += machineCode; // 创建注册表项 if (RegCreateKeyExA( HKEY_CURRENT_USER, subkey.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL) != ERROR_SUCCESS) { return FALSE; } // 写入注册码 if (RegSetValueExA( hKey, "Registration", 0, REG_SZ, (const BYTE*)regCode, (DWORD)strlen(regCode) + 1) != ERROR_SUCCESS) { RegCloseKey(hKey); return FALSE; } // 写入天数选项 std::string daysStr = std::to_string(daysChoice); if (RegSetValueExA( hKey, "ExpireDays", 0, REG_SZ, (const BYTE*)daysStr.c_str(), (DWORD)daysStr.length() + 1) != ERROR_SUCCESS) { RegCloseKey(hKey); return FALSE; } // 写入注册日期 (使用系统时间) SYSTEMTIME st; GetLocalTime(&st); char dateStr[32]; sprintf_s(dateStr, "%04d%02d%02d%02d%02d%02d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); if (RegSetValueExA( hKey, "RegisterDate", 0, REG_SZ, (const BYTE*)dateStr, (DWORD)strlen(dateStr) + 1) != ERROR_SUCCESS) { RegCloseKey(hKey); return FALSE; } RegCloseKey(hKey); return TRUE; } // 验证授权 int ValidateLicense() { const char* machineCode = GetMachineCode(); if (!machineCode || strlen(machineCode) == 0) { return 0; // 获取机器码失败 } std::string subkey = "Software\\MyPlugin\\"; subkey += machineCode; HKEY hKey; if (RegOpenKeyExA( HKEY_CURRENT_USER, subkey.c_str(), 0, KEY_READ, &hKey) != ERROR_SUCCESS) { return -1; // 未注册 } // 读取注册信息 char regDate[32] = { 0 }; DWORD size = sizeof(regDate); if (RegQueryValueExA( hKey, "RegisterDate", NULL, NULL, (LPBYTE)regDate, &size) != ERROR_SUCCESS) { RegCloseKey(hKey); return -1; } char daysChoice[10] = { 0 }; size = sizeof(daysChoice); if (RegQueryValueExA( hKey, "ExpireDays", NULL, NULL, (LPBYTE)daysChoice, &size) != ERROR_SUCCESS) { RegCloseKey(hKey); return -1; } RegCloseKey(hKey); // 解析注册日期 int year, month, day, hour, min, sec; if (sscanf_s(regDate, "%4d%2d%2d%2d%2d%2d", &year, &month, &day, &hour, &min, &sec) != 6) { return -1; } // 计算已过天数 SYSTEMTIME regTime = { 0 }; regTime.wYear = year; regTime.wMonth = month; regTime.wDay = day; FILETIME ftReg, ftNow; SystemTimeToFileTime(&regTime, &ftReg); GetSystemTimeAsFileTime(&ftNow); ULARGE_INTEGER ulReg, ulNow; ulReg.LowPart = ftReg.dwLowDateTime; ulReg.HighPart = ftReg.dwHighDateTime; ulNow.LowPart = ftNow.dwLowDateTime; ulNow.HighPart = ftNow.dwHighDateTime; ULONGLONG diff = ulNow.QuadPart - ulReg.QuadPart; int daysPassed = static_cast<int>(diff / (10000000ULL * 60 * 60 * 24)); // 检查授权状态 int choice = atoi(daysChoice); if (choice == 3) return 1; // 永久授权 int maxDays = 0; switch (choice) { case 0: maxDays = 7; break; case 1: maxDays = 15; break; case 2: maxDays = 30; break; default: return 0; } return (daysPassed <= maxDays) ? 1 : 0; } C1010 在查找预编译头时遇到意外的文件结尾。是否忘记了向源中添加“#include"pch.h""? 修改一套完整版代码
最新发布
07-18
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值