文章目录
Header file
/**
* @file xRegistry.h
* @date 2012 5.18/周六 14:20:32
* @author lei email:[email protected]
* @copyright GNU Public License.
* @remark 注册表编辑
*/
#ifndef AFX_XREGISTRY_H__98332335_740E_4E47_8F08_0689B508E55B__INCLUDED_
#define AFX_XREGISTRY_H__98332335_740E_4E47_8F08_0689B508E55B__INCLUDED_
#include <tchar.h>
#include <vector>
#ifdef __AFXWIN_H__
#include <afxtempl.h> //方便使用CStringArray
#endif
class Registry
{
typedef struct _RegItem {
TCHAR szItemName[256];
unsigned char* pValueBuf;
unsigned long dwValBufLen;
} RegItem;
public:
// defroot: HKEY_CURRENT_USER(0x80000001)
Registry(const TCHAR* lpDefKeyName=_T("Software\\leizi"), void* hDefRootKey=(void*)0x80000001);
virtual ~Registry();
bool SetRootKey(void* hRootKey=(void*)0x80000001);
bool OpenKey(const TCHAR* lpRegKey,bool bCreateIfNoExist=false);
void GetKey(TCHAR* lpszRegKey/*OUT*/, void* *phRootKey/*OUT*/);
bool SetValue(const TCHAR* lpItem,void *pValue,unsigned long dwLen=sizeof(unsigned long),unsigned long dwType=4); //REG_DWORD
bool GetValue(const TCHAR* lpItem,void *pValue,unsigned long *pdwLen=NULL,unsigned long *pdwType=NULL) ;
bool DelValue(const TCHAR* lpItem) ;
// exepath为空时表当前程序的全路径
void SetAutoRunOnBoot(TCHAR* pStartName,bool bRunFlag,TCHAR* pExeFullPath=NULL);
// RegItems由使用者释放(free)
bool EnumKeyValues(std::vector<RegItem*>& arrValues,const TCHAR* lpRegKey=NULL);
#ifdef UNICODE
bool EnumSubkeys(std::vector<std::wstring>& arrSubkeys,const TCHAR* lpRegKey=NULL);
#else
bool EnumSubkeys(std::vector<std::string>& arrSubkeys,const TCHAR* lpRegKey=NULL);
#endif
#ifdef __AFXWIN_H__
bool EnumKeyValues(CArray<RegItem*,RegItem*> &arrValues,const TCHAR* lpRegKey=NULL);
bool EnumSubkeys(CStringArray &arrSubkeys,const TCHAR* lpRegKey=NULL);
#endif
void FreeRegItem(void *pItem);
//////////////////////////////////////////////////////////////////////////
private:
void* m_hKeyOpened ;
void* m_hRootKey ;
TCHAR m_szOpenedKey[1024];
};
#endif
source file
#include "stdafx.h"
#include "xRegistry.h"
#include <string>
#include <windows.h>
#include <winreg.h> //using windows.h
#pragma warning (disable: 4996)
Registry::Registry(const TCHAR* lpDefKeyName/*Software/leizi*/, void* hDefRootKey/*HKEY_CURRENT_USER*/)
{
m_hKeyOpened = NULL;
SetRootKey(hDefRootKey);
OpenKey(lpDefKeyName,true);
}
Registry::~Registry()
{
if (m_hKeyOpened != NULL) {
RegCloseKey((HKEY)m_hKeyOpened);
m_hKeyOpened = NULL;
}
}
bool Registry::SetRootKey(void* hRootKey/*HKEY_CURRENT_USER*/)
{
if (hRootKey != HKEY_CLASSES_ROOT &&
hRootKey != HKEY_CURRENT_USER &&
hRootKey != HKEY_LOCAL_MACHINE &&
hRootKey != HKEY_USERS)
return false;
m_hRootKey = hRootKey;
return true;
}
int trimleft(TCHAR* s)
{
if (!s) return -1;
TCHAR* p = s;
while (*p && ((_T(' ') == *p) || (_T('\t') == *p) || (_T('\\') == *p))) p++;
if (*p) _tcscpy(s, p);
else *s = 0;
return 0;
}
int trimright(TCHAR* s)
{
if (!s) return -1;
TCHAR* p = s + _tcslen(s) - 1;
while (*p && (p - s) && ((_T(' ') == *p) || (_T('\t') == *p) || (_T('\\') == *p))) p --;
*(p + 1) = 0;
if ((_T(' ') == *p) || (_T('\t') == *p) || (_T('\\') == *p)) *p = 0;
return 0;
}
// if the subkey already exist,this function just like RegOpenKeyEx().
// if the subkey does not exist,we will call RegCreateKey() recursively
bool Registry::OpenKey(const TCHAR* lpRegKey,bool bCreateIfNoExist/*=TRUE*/)
{
if (!lpRegKey) return false;
if (m_hKeyOpened != NULL) {
RegCloseKey((HKEY)m_hKeyOpened);
m_hKeyOpened = NULL;
}
// here,save the opened key handle
if (ERROR_SUCCESS == RegOpenKeyEx((HKEY)m_hRootKey,lpRegKey,0,KEY_ALL_ACCESS, (HKEY*)&m_hKeyOpened)) {
_tcscpy(m_szOpenedKey,lpRegKey);
return true;
} else { // this subkey does'nt exist in registry
if (bCreateIfNoExist) {
TCHAR szPath[MAX_PATH];
_tcscpy(szPath,lpRegKey);
trimright(szPath);
#ifdef UNICODE
std::wstring sReg(szPath);
sReg.append(_T("\\"));
std::wstring sTmp;
#else
std::string sReg(szPath);
sReg.append(_T("\\"));
std::string sTmp;
#endif
int nFind = 0;
while (1) {
nFind = sReg.find(_T('\\'),nFind);
if (nFind < 0) break;
if (m_hKeyOpened) RegCloseKey((HKEY)m_hKeyOpened);
sTmp = sReg.substr(0,nFind);
if (ERROR_SUCCESS == RegOpenKey((HKEY)m_hRootKey,sTmp.c_str(), (HKEY*)&m_hKeyOpened)) {
RegCloseKey((HKEY)m_hKeyOpened);
m_hKeyOpened = NULL;
} else {
RegCreateKey((HKEY)m_hRootKey,sTmp.c_str(),(HKEY*)&m_hKeyOpened);
}
nFind++;
}
}
if (m_hKeyOpened != NULL)
return true;
}
m_hRootKey = HKEY_CURRENT_USER;
m_hKeyOpened = NULL;
return false;
}
void Registry::GetKey(TCHAR* lpszRegKey, void**phRootKey)
{
if (!lpszRegKey || !phRootKey) return;
*phRootKey = m_hRootKey;
_tcscpy(lpszRegKey,m_szOpenedKey);
}
// if the value(wait be setted) is a string,the third param is 0 & last param is ignored
bool Registry::SetValue(const TCHAR* lpItem,void* pValue,unsigned long dwLen/*sizeof(DWORD)*/,unsigned long dwType/*=REG_DWORD*/)
{
unsigned long dwSetType = dwType;
unsigned long dwSetSize = dwLen;
if (dwLen == 0) {
dwSetType = REG_SZ;
dwSetSize = _tcslen((TCHAR*)pValue);
}
if (m_hKeyOpened==NULL || pValue==NULL ||
ERROR_SUCCESS!=RegSetValueEx((HKEY)m_hKeyOpened,lpItem,0,dwSetType,(CONST BYTE *)pValue,dwSetSize))
return false;
return true;
}
bool Registry::GetValue(const TCHAR* lpItem,void *pValue,unsigned long *pdwLen/*=NULL*/,unsigned long *pdwType/*NULL*/)
{
if (m_hKeyOpened==NULL || pValue==NULL)
return false;
unsigned long dwLen=0,dwType=0;
// first check the item to see if it exist. if it does exist,get the value, type and length
bool bGetOK = (ERROR_SUCCESS == RegQueryValueEx((HKEY)m_hKeyOpened,lpItem,NULL,&dwType,NULL,&dwLen) &&
ERROR_SUCCESS == RegQueryValueEx((HKEY)m_hKeyOpened,lpItem,NULL,&dwType,(BYTE*)pValue,&dwLen));
if (pdwType != NULL)
*pdwType = dwType;
if (pdwLen != NULL)
*pdwLen = dwLen;
if (dwType == REG_SZ)
((TCHAR *)pValue)[dwLen] = 0;
return bGetOK;
}
void Registry::FreeRegItem(void *pItem)
{
if (pItem != NULL) {
if (((RegItem*)pItem)->pValueBuf != NULL)
free(((RegItem*)pItem)->pValueBuf);
free(pItem);
pItem = NULL;
}
}
bool Registry::DelValue(const TCHAR* lpItem)
{
if (m_hKeyOpened==NULL || ERROR_SUCCESS!=RegDeleteValue((HKEY)m_hKeyOpened,lpItem))
return false;
return true;
}
#ifdef __AFXWIN_H__
// you are be responsable for freeing the mem which is associate with the first arg
bool Registry::EnumKeyValues(CArray<RegItem*,RegItem*> &arrValues,const TCHAR* lpRegKey/*NULL*/)
{
if (!lpRegKey)
return false;
// 先保存之前打开的键
TCHAR szOldKeyName[1024] = {0};
_tcscpy(szOldKeyName,m_szOpenedKey);
arrValues.RemoveAll();
// 会改变 m_sOpenedKey
if (!OpenKey(lpRegKey,false))
return false;
TCHAR szItemName[256] ={0};
BYTE szItemValue[4096] ={0};
for (unsigned long i=0; ; i++)
{
unsigned long dwType = 0;
unsigned long dwNameLen = sizeof(szItemName);
unsigned long dwValueLen = sizeof(szItemValue);
memset(szItemName ,0,sizeof(szItemName));
memset(szItemValue,0,sizeof(szItemValue));
if (ERROR_NO_MORE_ITEMS == RegEnumValue((HKEY)m_hKeyOpened,i,szItemName,&dwNameLen,0,&dwType,szItemValue,&dwValueLen))
break;
RegItem* lpItem = (RegItem*)calloc(1,sizeof(RegItem));
_tcscpy(lpItem->szItemName,szItemName);
lpItem->pValueBuf = (BYTE *)calloc(dwValueLen+1,sizeof(BYTE));
memcpy(lpItem->pValueBuf,szItemValue,dwValueLen);
arrValues.Add(lpItem);
}
OpenKey(szOldKeyName,false); // 恢复之间打开的key
return true;
}
#endif
bool Registry::EnumKeyValues( std::vector<RegItem*>& arrValues,const TCHAR* lpRegKey/*=NULL*/)
{
if (!lpRegKey) return false;
TCHAR szOldKeyName[1024] = {0};
_tcscpy(szOldKeyName,m_szOpenedKey);
arrValues.clear();
if (!OpenKey(lpRegKey,false))
return false;
TCHAR szItemName[256] ={0};
BYTE szItemValue[4096] ={0};
for (unsigned long i=0; ; i++)
{
unsigned long dwType = 0;
unsigned long dwNameLen = sizeof(szItemName);
unsigned long dwValueLen = sizeof(szItemValue);
memset(szItemName ,0,sizeof(szItemName));
memset(szItemValue,0,sizeof(szItemValue));
if (ERROR_NO_MORE_ITEMS == RegEnumValue((HKEY)m_hKeyOpened,i,szItemName,&dwNameLen,0,&dwType,szItemValue,&dwValueLen))
break;
RegItem* lpItem = (RegItem*)calloc(1,sizeof(RegItem));
_tcscpy(lpItem->szItemName,szItemName);
lpItem->pValueBuf = (BYTE *)calloc(dwValueLen+1,sizeof(BYTE));
memcpy(lpItem->pValueBuf,szItemValue,dwValueLen);
arrValues.push_back(lpItem);
}
OpenKey(szOldKeyName,false); // rollback
return true;
}
#ifdef __AFXWIN_H__
bool Registry::EnumSubkeys(CStringArray &arrSubkeys,const TCHAR* lpRegKey/*NULL*/)
{
if (!lpRegKey) return false;
if (!OpenKey(lpRegKey,false)) return false;
TCHAR szKeyName[1024] = {0};
arrSubkeys.RemoveAll();
for (unsigned long i=0; ; i++) {
if (ERROR_NO_MORE_ITEMS == RegEnumKey((HKEY)m_hKeyOpened,i,szKeyName,1024))
break;
arrSubkeys.Add(szKeyName);
}
OpenKey(m_szOpenedKey,false);
return true;
}
#endif
#ifdef UNICODE
bool Registry::EnumSubkeys(std::vector<std::wstring>& arrSubkeys,const TCHAR* lpRegKey/*=NULL*/)
#else
bool Registry::EnumSubkeys(std::vector<std::string>& arrSubkeys,const TCHAR* lpRegKey/*=NULL*/)
#endif
{
if (!lpRegKey) return false;
// 打开注册表
if (!OpenKey(lpRegKey,false)) return false;
TCHAR szKeyName[1024] = {0};
arrSubkeys.clear();
for (unsigned long i=0; ; i++) {
if (ERROR_NO_MORE_ITEMS == RegEnumKey((HKEY)m_hKeyOpened,i,szKeyName,1024))
break;
arrSubkeys.push_back(szKeyName);
}
OpenKey(m_szOpenedKey,false);
return true;
}
void Registry::SetAutoRunOnBoot(TCHAR *pStartName,bool bEnable,TCHAR *pExeFullPath/*=NULL*/)
{
HKEY hKey;
RegOpenKey(HKEY_CURRENT_USER, _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"), &hKey);
if (!bEnable) {
RegDeleteValue(hKey, pStartName);
RegCloseKey(hKey);
return;
}
#ifdef UNICODE
std::wstring sRunPath(pExeFullPath);
#else
std::string sRunPath(pExeFullPath);
#endif
TCHAR szAppPathName[MAX_PATH];
GetModuleFileName(NULL,szAppPathName,MAX_PATH);
if (sRunPath.empty()) sRunPath = szAppPathName;
sRunPath.append(_T(" /OnSysStart"));
const BYTE *pData = (BYTE *)sRunPath.c_str();
RegSetValueEx(hKey, pStartName, 0, REG_SZ, pData, sRunPath.length());
RegCloseKey(hKey);
}