📄 registry_db.cpp
字号:
// Registry_DB.cpp: implementation of the CRegistry_DB class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Registry_DB.h"
#include "eBackup2002Dialog.h"
#include "File.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#define PROGRESSRANGE 20
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CRegistry_DB::CRegistry_DB()
{
if (m_DBItemList.GetCount() >0 )
m_DBItemList.RemoveAll();
m_StorageType.Empty();
m_pProgressWnd = NULL;
}
CRegistry_DB::CRegistry_DB(CString Str)
{
CRegistry_DB();
m_StorageType = Str;
}
CRegistry_DB::~CRegistry_DB()
{
}
//////////////////////////////////////////////////////////////////
// Make Backup for Database
// PARAMETER:
// dbname ---- database's name
// pceguid ---- PCEGUID for Mount Volume
// RETURN VALUE:
// TRUE if backup successfully,otherwise FALSE
// AUTOTHOR: sunyh
// VERSION: 1.0
//////////////////////////////////////////////////////////////////
BOOL CRegistry_DB::BackupDB(LPWSTR dbname,PCEGUID &pceguid)
{
HANDLE hStorageDB,hCurrentDB;
CEOID openoid=0;
CEGUID dbguid;
CREATE_SYSTEMGUID(&dbguid);
//open the database in the object store
hCurrentDB=CeOpenDatabaseEx(&dbguid,&openoid,dbname,0,0,NULL);
if(hCurrentDB==INVALID_HANDLE_VALUE||openoid==0)
{
CloseHandle(hCurrentDB);
return FALSE;
}
//get the backup database information
CEDBASEINFO CEDBInfo;
CEOIDINFO oidinfo;
CeOidGetInfo(openoid,&oidinfo);
//create the database info in the mounted volume
CEDBInfo=oidinfo.infDatabase;
CEOID dbceoid=0;//the database oid in the mounted volume
wcscpy(CEDBInfo.szDbaseName,dbname);
CEOID exitOid=0;
//if the database have been in the volume ,delete it first
HANDLE hHandle = CeOpenDatabaseEx(pceguid,&exitOid,dbname,0,0,NULL);
if(hHandle != INVALID_HANDLE_VALUE)
{
if(!CeDeleteDatabaseEx(pceguid,exitOid))
{
CloseHandle(hHandle);
CloseHandle(hCurrentDB);
return FALSE;
}
}
CloseHandle(hHandle);
//create the database in the mounted volume
dbceoid=CeCreateDatabaseEx(pceguid,&CEDBInfo);
if(dbceoid==NULL)
{
CloseHandle(hCurrentDB);
return FALSE;
}
//open the database in the mounted volume
hStorageDB=CeOpenDatabaseEx(pceguid,&dbceoid,NULL,0,0,NULL);
CEOID oidRecord,recOid;
LPBYTE pBuff=NULL;
DWORD dwRecSize,dwIndex;
WORD wProps=0;
PCEPROPVAL pRecord =0;
recOid=CeSeekDatabase(hCurrentDB,CEDB_SEEK_BEGINNING,0,&dwIndex);
//if there is no records in the database ,do nothing!
if(recOid!=0)
{
do
{
//read records form the database in the object store
oidRecord=CeReadRecordProps(hCurrentDB,CEDB_ALLOWREALLOC
,&wProps,NULL,&pBuff,&dwRecSize);
recOid=CeSeekDatabase(hCurrentDB,CEDB_SEEK_CURRENT,1,&dwIndex);
//write the records to the database in the cfcards
pRecord=(PCEPROPVAL)pBuff;
if(oidRecord)
{
CEOID woid;
woid=CeWriteRecordProps(hStorageDB,0,wProps,pRecord);
}
LocalFree ((LPBYTE)pRecord);
pBuff=NULL;
}while(recOid);
}
//close the two database,in volume and object store
CloseHandle(hStorageDB);
CloseHandle(hCurrentDB);
return TRUE;
}
//////////////////////////////////////////////////////////////////
// restore Database
// PARAMETER:
// dbname ---- database's name
// pceguid ---- PCEGUID for Backup Volume
// RETURN VALUE:
// TRUE if restore successfully,otherwise FALSE
// AUTOTHOR: sunyh
// VERSION: 1.0
//////////////////////////////////////////////////////////////////
BOOL CRegistry_DB::RestoreDB(LPWSTR dbname,PCEGUID &pceguid)
{
//read the data form cfcards,write the data into the database in the object store
CEOID dbceoid=0;
HANDLE hContactsbk,hContacts;
hContactsbk=CeOpenDatabaseEx(pceguid,&dbceoid,dbname,0,0,NULL);
if(dbceoid==0 || hContactsbk==INVALID_HANDLE_VALUE)
return FALSE;
//delete the records in the database,use mfc function
CEOID deleteoid=0;
HANDLE DBHandle = CeOpenDatabase(&deleteoid,dbname,0,0,NULL);
DWORD lpdwIndex;
if (DBHandle != INVALID_HANDLE_VALUE)
{
CEOID oidRecord = CeSeekDatabase(DBHandle,CEDB_SEEK_BEGINNING,0,&lpdwIndex);
while (CeDeleteRecord(DBHandle,oidRecord))
{
oidRecord = CeSeekDatabase(DBHandle,CEDB_SEEK_CURRENT,1,&lpdwIndex);
if (oidRecord == 0)
break;
}
CloseHandle(DBHandle);
}
/* CCeDBDatabase db;
if (db.Open((LPCWSTR)dbname,NULL,NULL))
{
db.SeekFirst();
while(db.DeleteCurrRecord())
{
db.SeekNext();
}
db.Close();
}
*/ //deleting records is ok
//if the mounted database no records return true;
CEOIDINFO CeObjectInfo;
CEDBASEINFO infDatabase;
CeOidGetInfoEx(pceguid,dbceoid,&CeObjectInfo);
infDatabase=CeObjectInfo.infDatabase;
//ASSERT(infDatabase.wNumRecords);
//TCHAR tmp[3];
//wsprintf(tmp,TEXT("%ld"),(DWORD)infDatabase.wNumRecords);
// if(infDatabase.wNumRecords==0)
// {
// CloseHandle(hContactsbk);
// return TRUE;
// }
CEGUID dbreguid;
CEOID openoid=0;
CREATE_SYSTEMGUID(&dbreguid);
hContacts=CeOpenDatabaseEx(&dbreguid,&openoid,dbname,0,0,NULL);
DWORD IfDBExist=GetLastError();
//when the restored database not in object store ,create it!
if(IfDBExist==ERROR_FILE_NOT_FOUND)
{
//get the backup database infomation in cf card
CEDBASEINFO CEDBInfo;
CEOIDINFO oidinfo;
CeOidGetInfoEx(pceguid,dbceoid,&oidinfo);
//create the database in the object store
CEDBInfo=oidinfo.infDatabase;
CEOID dbceoid=0;
wcscpy(CEDBInfo.szDbaseName,dbname);
CREATE_SYSTEMGUID(&dbreguid);
CeCreateDatabaseEx(&dbreguid,&CEDBInfo);
hContacts=CeOpenDatabaseEx(&dbreguid,&openoid,dbname,0,0,NULL);
}
if(hContacts==INVALID_HANDLE_VALUE)
{
CloseHandle(hContactsbk);
CloseHandle(hContacts);
return FALSE;
}
CEOID oidRecord;
CEOID recOid;
DWORD dwIndex;
recOid=CeSeekDatabase(hContactsbk,CEDB_SEEK_BEGINNING,0,&dwIndex);
if(recOid==0)
{
CloseHandle(hContacts);
CloseHandle(hContactsbk);
return TRUE;
}
PBYTE pBuff=NULL;
DWORD dwRecSize;
WORD wProps;
PCEPROPVAL pRecord=NULL;
do
{
//read records form the database in the cfcard
oidRecord=CeReadRecordProps(hContactsbk,CEDB_ALLOWREALLOC
,&wProps,NULL,&(LPBYTE)pBuff,&dwRecSize);
recOid=CeSeekDatabase(hContactsbk,CEDB_SEEK_CURRENT,1,&dwIndex);
//write the records to the database on the object store
pRecord=(PCEPROPVAL)pBuff;
if(oidRecord)
CeWriteRecordProps(hContacts,0,wProps,pRecord);
pRecord=NULL;
}while(recOid);
CloseHandle(hContacts);
CloseHandle(hContactsbk);
return TRUE;
}
//////////////////////////////////////////////////////////////////
// Make Backup for registry
// RETURN VALUE:
// TRUE if backup successfully,otherwise FALSE
// AUTOTHOR: sunyh
// VERSION: 1.0
//////////////////////////////////////////////////////////////////
BOOL CRegistry_DB::BackupRegistry()
{
CFile savedFile;
if (!savedFile.Open(m_StorageType+REGDIR,CFile::modeCreate|CFile::modeReadWrite))
{
CString Msg;
// Msg.LoadString(MSG_NO_BKFILE);
Msg.LoadString(MSG_WRITE_ERROR);
::MessageBox(NULL,Msg,BACKUPTITLE,MB_OK|MB_ICONEXCLAMATION|MB_ICONERROR);
return FALSE;
}
SAVEREGISTRY sr;
HKEY hKeyRoot[]={HKEY_LOCAL_MACHINE,HKEY_CLASSES_ROOT,HKEY_CURRENT_USER,HKEY_USERS,0};
WCHAR *keyRootName[]={L"HKEY_LOCAL_MACHINE",L"HKEY_CLASSES_ROOT",L"HKEY_CURRENT_USER",L"HKEY_USERS",0};
CArray<KEYNODE, KEYNODE> keyNode;
HKEY *hkRoot;
WCHAR **krName;
hkRoot=hKeyRoot;
krName=keyRootName;
WCHAR* keyName=new WCHAR[MAX_PATH];
UCHAR* valueData=new UCHAR[MAX_DATA_SIZE];
if (!keyName || !valueData)
{
CString Msg;
Msg.LoadString(MSG_NO_MEMO);
::MessageBox(NULL,Msg,BACKUPTITLE,MB_OK|MB_ICONEXCLAMATION|MB_ICONERROR);
savedFile.Close();
return FALSE;
}
while (*hkRoot)
{
HKEY hKey=*hkRoot;
sr.isValue=0;
sr.depath=0;
sr.keyNameLength=wcslen(*krName)*sizeof(WCHAR);
// TRY {
if ((savedFile.Write(&sr,REGVALUESIZE) == -1) ||
(savedFile.Write(*krName,sr.keyNameLength) == -1))
// }
// CATCH( CFileException, e )
{
CString Msg;
Msg.LoadString(MSG_WRITE_ERROR);
::MessageBox(NULL,Msg,BACKUPTITLE,MB_OK|MB_ICONEXCLAMATION|MB_ICONERROR);
savedFile.Close();
return FALSE;
}
// END_CATCH
m_pProgressWnd->SetProgressPos(REGVALUESIZE+sr.keyNameLength);
KEYNODE kNode;
kNode.hKey=hKey;
kNode.nodeIndex=0;
kNode.depath=0;
keyNode.Add(kNode);
while (1) {
DWORD keyNameLen=MAX_PATH;
long rt=RegEnumKeyEx(kNode.hKey, kNode.nodeIndex, keyName, &keyNameLen, NULL, NULL, NULL, NULL);
if (rt==ERROR_SUCCESS) {
RegOpenKeyEx(kNode.hKey,keyName,NULL,NULL,&hKey);
kNode.hKey=hKey;
kNode.nodeIndex=0;
kNode.depath++;
keyNode.Add(kNode);
sr.isValue=0;
sr.depath=kNode.depath;
sr.keyNameLength=(WORD)keyNameLen*sizeof(WCHAR);
// TRY {
// savedFile.Write(&sr,REGVALUESIZE);
// savedFile.Write(keyName,sr.keyNameLength);
// }
// CATCH( CFileException, e )
if ((savedFile.Write(&sr,REGVALUESIZE) == -1) ||
(savedFile.Write(keyName,sr.keyNameLength) == -1))
{
CString Msg;
Msg.LoadString(MSG_WRITE_ERROR);
::MessageBox(NULL,Msg,BACKUPTITLE,MB_OK|MB_ICONEXCLAMATION|MB_ICONERROR);
savedFile.Close();
return FALSE;
}
// END_CATCH
m_pProgressWnd->SetProgressPos(REGVALUESIZE+sr.keyNameLength);
continue;
}
int vIndex=0;
DWORD valueDataLen=MAX_DATA_SIZE;
DWORD valueType;
keyNameLen=MAX_PATH;
while (RegEnumValue(kNode.hKey, vIndex++, keyName, &keyNameLen, NULL, &valueType, valueData, &valueDataLen)==ERROR_SUCCESS)
{
sr.isValue=1;
sr.depath=kNode.depath;
sr.keyNameLength=(WORD)keyNameLen*sizeof(WCHAR);
sr.keyValueType=valueType;
sr.keyValueSize=(WORD)valueDataLen;
// TRY {
// savedFile.Write(&sr,REGVALUESIZE);
// savedFile.Write(keyName,sr.keyNameLength);
// savedFile.Write(valueData,valueDataLen);
// }
// CATCH( CFileException, e )
if ((savedFile.Write(&sr,REGVALUESIZE) == -1) ||
(savedFile.Write(keyName,sr.keyNameLength) == -1) ||
(savedFile.Write(valueData,valueDataLen) == -1))
{
CString Msg;
Msg.LoadString(MSG_WRITE_ERROR);
::MessageBox(NULL,Msg,BACKUPTITLE,MB_OK|MB_ICONEXCLAMATION|MB_ICONERROR);
savedFile.Close();
return FALSE;
}
// END_CATCH
// ProgressBarStepUP(REGVALUESIZE+sr.keyNameLength+valueDataLen);
m_pProgressWnd->SetProgressPos(REGVALUESIZE+sr.keyNameLength+valueDataLen);
keyNameLen=MAX_PATH;
valueDataLen=MAX_DATA_SIZE;
}
int keyNodeEnd=keyNode.GetSize()-1;
if (keyNodeEnd) RegCloseKey(kNode.hKey);
keyNode.RemoveAt(keyNodeEnd);
if (!keyNodeEnd) break;
kNode=keyNode.GetAt(--keyNodeEnd);
kNode.nodeIndex++;
keyNode.RemoveAt(keyNodeEnd);
keyNode.Add(kNode);
}
hkRoot++;
krName++;
}
delete[] keyName;
delete[] valueData;
// set "ok" at the end of file, this means "backup success"
char buf[] = {"OK"};
savedFile.Write(buf,2);
savedFile.Close();
return TRUE;
}
//////////////////////////////////////////////////////////////////
// restore registry
// RETURN VALUE:
// TRUE if restore successfully,otherwise FALSE
// AUTOTHOR: sunyh
// VERSION: 1.0
//////////////////////////////////////////////////////////////////
BOOL CRegistry_DB::RestoreRegistry()
{
enum {REGHEAD=1,REGKEYNAME,REGVALUE};
UCHAR* headBuf; // save head properties temporarily when exceed buffers
UCHAR* buffers; // read from savedfilelist
UCHAR* valueData;
WCHAR* keyName; // used for avoid datatype misalignment;
SAVEREGISTRY sr; // save head properties temporarily
UINT rn; // record the bytes read from file
int readStatus=REGHEAD;
int savedSize=0;
HKEY hKeyRoot[]={HKEY_LOCAL_MACHINE,HKEY_CLASSES_ROOT,HKEY_CURRENT_USER,HKEY_USERS,0};
WCHAR* keyRootName[]={L"HKEY_LOCAL_MACHINE",L"HKEY_CLASSES_ROOT",L"HKEY_CURRENT_USER",L"HKEY_USERS",0};
HKEY* hkRoot;
WCHAR **krName;
hkRoot=hKeyRoot;
krName=keyRootName;
CArray<KEYNODE, KEYNODE> keyNode;
CStringList keyNameList; // used for delete key;
bool isKeyLast=true; // true: is read key last time false: read value last
if (!SetKeyFlag()) {
// SetKeyFlag(false);
return false;
}
buffers=new UCHAR[READ_NUMBER+4];
keyName=new WCHAR[MAX_PATH];
valueData=new UCHAR[MAX_DATA_SIZE];
if (!keyName || !valueData || !valueData)
{
CString Msg;
Msg.LoadString(MSG_NO_MEMO);
::MessageBox(NULL,Msg,BACKUPTITLE,MB_OK|MB_ICONEXCLAMATION|MB_ICONERROR);
return false;
}
KEYNODE kNode;
kNode.nodeIndex=0;
CFile savedFile;
if (!savedFile.Open(m_StorageType+REGDIR,CFile::modeRead))
{
CString Msg,War;
Msg.LoadString(MSG_NO_BKFILE);
War.LoadString(WARNING_TXT);
MessageBox(NULL,Msg,War,MB_OK|MB_ICONEXCLAMATION|MB_ICONERROR);
return FALSE;
}
while (rn=savedFile.Read(buffers, READ_NUMBER)) {
UCHAR* buf=buffers;
UCHAR* bufEnd=buffers+rn;
LOOPHERE:
switch (readStatus) {
case REGHEAD:
{int nSize=REGVALUESIZE-savedSize;
int remainBuf=bufEnd-buf;
headBuf=(UCHAR*)&sr+savedSize;
if (nSize>remainBuf) {
memcpy(headBuf,buf,remainBuf);
savedSize+=remainBuf;
continue;
} else {
memcpy(headBuf,buf,nSize);
if (sr.isValue!=1 && sr.isValue)
{
CString Msg;
Msg.LoadString(MSG_BKFILE_ERROR);
::MessageBox(NULL,Msg,BACKUPTITLE,MB_OK|MB_ICONEXCLAMATION|MB_ICONERROR);
savedFile.Close();
return false;
}
// ProgressBarStepUP(savedSize+nSize);
m_pProgressWnd->SetProgressPos(savedSize+nSize);
buf+=nSize;
savedSize=0;
readStatus=REGKEYNAME;
}}
break;
case REGKEYNAME:
{int nSize=sr.keyNameLength-savedSize;
int remainBuf=bufEnd-buf;
UCHAR* pTmp;
pTmp=(UCHAR*)keyName;
pTmp+=savedSize;
if (nSize>remainBuf) {
memcpy(pTmp,buf,remainBuf);
savedSize+=remainBuf;
continue;
} else {
memcpy(pTmp,buf,nSize);
// ProgressBarStepUP(savedSize+nSize);
m_pProgressWnd->SetProgressPos(savedSize+nSize);
pTmp+=nSize;
buf+=nSize;
nSize=sizeof(WCHAR);
while(nSize--) *pTmp++='\0';
sr.keyName=keyName;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -