-
레지스트리 - Win32Platform/File(장치 IO) 2009. 2. 4. 21:46RegOpenKeyEx()
RegCreateKeyEx()
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
KEY_WRITE
KEY_READ
RegCloseKey()
RegDeleteKey()
RegQueryInfoKey()
RegEnumKeyEx()
RegEnumValue()
ERROR_NO_MORE_ITEMS
RegEnumValueEx()
RegSetValueEx()
REG_SZRegDeleteValue()
RegQueryValueEx()
SHDeleteKey()
#define MAX_KEY_LENGTH 255
#define MAX_VALUE_NAME 16383
static void QueryKey(HKEY hKey)
{
TCHAR achKey[MAX_KEY_LENGTH]; // buffer for subkey name
DWORD cbName; // size of name string
TCHAR achClass[MAX_PATH] = TEXT("" ); // buffer for class name
DWORD cchClassName = MAX_PATH; // size of class string
DWORD cSubKeys=0; // number of subkeys
DWORD cbMaxSubKey; // longest subkey size
DWORD cchMaxClass; // longest class string
DWORD cValues; // number of values for key
DWORD cchMaxValue; // longest value name
DWORD cbMaxValueData; // longest value data
DWORD cbSecurityDescriptor; // size of security descriptor
FILETIME ftLastWriteTime; // last write time
DWORD i, retCode;
TCHAR achValue[MAX_VALUE_NAME];
DWORD cchValue = MAX_VALUE_NAME;
// Get the class name and the value count.
retCode = RegQueryInfoKey(
hKey, // key handle
achClass, // buffer for class name
&cchClassName, // size of class string
NULL, // reserved
&cSubKeys, // number of subkeys
&cbMaxSubKey, // longest subkey size
&cchMaxClass, // longest class string
&cValues, // number of values for this key
&cchMaxValue, // longest value name
&cbMaxValueData, // longest value data
&cbSecurityDescriptor, // security descriptor
&ftLastWriteTime); // last write time
// Enumerate the subkeys, until RegEnumKeyEx fails.
if (cSubKeys)
{
TRACE( "\nNumber of subkeys: %d\n" , cSubKeys);
for (i=0; i<cSubKeys; i++)
{
cbName = MAX_KEY_LENGTH;
retCode = RegEnumKeyEx(hKey, i,
achKey,
&cbName,
NULL,
NULL,
NULL,
&ftLastWriteTime);
if (retCode == ERROR_SUCCESS)
{
TRACE(TEXT("(%d) %s\n" ), i+1, achKey);
}
}
}
// Enumerate the key values.
if (cValues)
{
TRACE( "\nNumber of values: %d\n" , cValues);
for (i=0, retCode=ERROR_SUCCESS; i<cValues; i++)
{
cchValue = MAX_VALUE_NAME;
achValue[0] = '\0';
retCode = RegEnumValue(hKey, i,
achValue,
&cchValue,
NULL,
NULL,
NULL,
NULL);
if (retCode == ERROR_SUCCESS )
{
TRACE(TEXT("(%d) %s\n" ), i+1, achValue);
}
}
}
}
BOOL CTry02Dlg::OnInitDialog()
{
...
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
// {
HKEY hTestKey;
if( RegOpenKeyEx( HKEY_LOCAL_MACHINE,
TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run" ),
0,
KEY_READ,
&hTestKey) == ERROR_SUCCESS
)
{
QueryKey(hTestKey);
}
// }
return TRUE; // return TRUE unless you set the focus to a control
}
void CTry01Dlg::OnButton1()
{
// TODO: Add your control notification handler code here
HKEY newKey;
LONG ret = 0;
ret = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
"Software\\Test\\test",
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_WRITE,
NULL,
&newKey,
NULL);
if (ret == ERROR_SUCCESS)
{
const char *data_buffer = "/cygdrive";
RegSetValueEx(
newKey,
"cygdrive prefix", // 키 안에 값 이름
0, // 옵션 항상 0
REG_SZ, // 데이터 타입
(BYTE*) data_buffer, // 써 넣을 데이터
strlen( data_buffer ) + 1 // 데이터 크기
);
RegCloseKey( newKey );
}
}
void CTry01Dlg::OnButton2()
{
// TODO: Add your control notification handler code here
HKEY key;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Adobe", 0, KEY_READ, &key)
== ERROR_SUCCESS)
{
...
RegCloseKey( key );
}
}
// The sample code makes no attempt to check or recover from partial
// deletions.
//
// A registry key that is opened by an application can be deleted
// without error by another application in both Windows 95 and
// Windows NT. This is by design.
#define MAX_KEY_LENGTH 256
static DWORD RegDeleteKeyNT(HKEY hStartKey , LPTSTR pKeyName )
{
DWORD dwRtn, dwSubKeyLength;
LPTSTR pSubKey = NULL;
TCHAR szSubKey[MAX_KEY_LENGTH]; // (256) this should be dynamic.
HKEY hKey;
// Do not allow NULL or empty key name
if ( pKeyName && lstrlen(pKeyName))
{
if( (dwRtn=RegOpenKeyEx(hStartKey,pKeyName,
0, KEY_ENUMERATE_SUB_KEYS | DELETE, &hKey )) == ERROR_SUCCESS)
{
while (dwRtn == ERROR_SUCCESS )
{
dwSubKeyLength = MAX_KEY_LENGTH;
dwRtn=RegEnumKeyEx(
hKey,
0, // always index zero
szSubKey,
&dwSubKeyLength,
NULL,
NULL,
NULL,
NULL
);
if(dwRtn == ERROR_NO_MORE_ITEMS)
{
dwRtn = RegDeleteKey(hStartKey, pKeyName);
break;
}
else if(dwRtn == ERROR_SUCCESS)
dwRtn=RegDeleteKeyNT(hKey, szSubKey);
}
RegCloseKey(hKey);
// Do not save return code because error
// has already occurred
}
}
else
dwRtn = ERROR_BADKEY;
return dwRtn;
}
/*
// 레지스트리 하위키 포함 몽땅 삭제하는 함수
LONG RegMyDeleteKey(HKEY hKey, LPCTSTR lpSubKey)
{
// RegDeleteKey() 함수는 NT이후 서브키가 있으면 삭제가 안된다.
// 그래서 서브키까지 모두 삭제해주는 함수를 만들었다.
// 코드 작성 : boy0
HKEY newKey;
char newSubKey[MAX_PATH];
LONG Result;
DWORD Size;
FILETIME FileTime;
RegOpenKeyEx(hKey, lpSubKey, 0, KEY_ALL_ACCESS, &newKey);
Result = ERROR_SUCCESS;
while(TRUE) {
Size = MAX_PATH;
// 계속 키가 삭제 되므로 dwIndex는 항상 0을 넣어주어야 한다.
// 만약 for문으로 i를 증가시며 사용하면 하나지우고 하나 뛰어넘어 반이 남는다.
Result = RegEnumKeyEx(newKey, 0, newSubKey, &Size, NULL, NULL, NULL, &FileTime);
if (Result != ERROR_SUCCESS) break;
Result = RegMyDeleteKey(newKey, newSubKey);
if (Result != ERROR_SUCCESS) break;
}
RegCloseKey(newKey);
return RegDeleteKey(hKey, lpSubKey);
}
*/
void CTry03Dlg::OnButton1()
{
// TODO: Add your control notification handler code here
DWORD dwRtn;
dwRtn = RegDeleteKeyNT(HKEY_CURRENT_USER , "Software\\Microsoft\\Protected Storage System Provider\\S-1-5-21-1960408961-2000478354-725345543-500\\Data\\e161255a-37c3-11d2-bcaa-00c04fd929db\\e161255a-37c3-11d2-bcaa-00c04fd929db" );
/* or
dwRtn = SHDeleteKey(HKEY_CURRENT_USER, "Software\\Microsoft\\Protected Storage System Provider\\S-1-5-21-1960408961-2000478354-725345543-500\\Data\\e161255a-37c3-11d2-bcaa-00c04fd929db\\e161255a-37c3-11d2-bcaa-00c04fd929db");
*/
if (ERROR_SUCCESS != dwRtn) {
AfxMessageBox("fail");
}
}
BOOL TraverseRegistry (HKEY, LPTSTR, LPTSTR, LPBOOL);
BOOL DisplayPair (LPTSTR, DWORD, LPBYTE, DWORD, LPBOOL);
BOOL DisplaySubKey (LPTSTR, LPTSTR, PFILETIME, LPBOOL);
int _tmain (int argc, LPTSTR argv [])
{
BOOL Flags[2], ok = TRUE;
TCHAR KeyName [MAX_PATH+1];
LPTSTR pScan;
DWORD i, KeyIndex;
HKEY hKey, hNextKey;
/* Tables of predefined key names and keys */
LPTSTR PreDefKeyNames [] = {
_T("HKEY_LOCAL_MACHINE"),
_T("HKEY_CLASSES_ROOT"),
_T("HKEY_CURRENT_USER"),
_T("HKEY_CURRENT_CONFIG"),
NULL };
HKEY PreDefKeys [] = {
HKEY_LOCAL_MACHINE,
HKEY_CLASSES_ROOT,
HKEY_CURRENT_USER,
HKEY_CURRENT_CONFIG };
if (argc < 2) {
_tprintf (_T("Usage: lsREG [options] SubKey\n"));
return 1;
}
KeyIndex = Options (argc, argv, _T ("Rl"), &Flags[0], &Flags[1], NULL);
/* "Parse" the search pattern into two parts: the "key"
and the "subkey". The key is the first back-slash terminated
string and must be one of HKEY_LOCAL_MACHINE, HKEY_CLASSES_ROOT,
or HKEY_CURRENT_USER. The subkey is everything else.
The key and subkey names will be copied from argv[KeyIndex]. */
/* Build the Key */
pScan = argv[KeyIndex];
for (i = 0; *pScan != _T('\\') && *pScan != _T('\0'); pScan++, i++)
KeyName[i] = *pScan;
KeyName[i] = _T('\0'); if (*pScan == _T('\\')) pScan++;
/* Translate predefined key name to an HKEY */
for ( i = 0;
PreDefKeyNames[i] != NULL && _tcscmp (PreDefKeyNames[i], KeyName) != 0;
i++) ;
if (PreDefKeyNames[i] == NULL) ReportError (_T("Use a Predefined Key"), 1, FALSE);
hKey = PreDefKeys[i];
/* pScan points to the start of the subkey string. It is not directly
documented that \ is the separator, but it works fine */
if (RegOpenKeyEx (hKey, pScan, 0, KEY_READ, &hNextKey) != ERROR_SUCCESS)
ReportError (_T("Cannot open subkey properly"), 2, TRUE);
hKey = hNextKey;
ok = TraverseRegistry (hKey, argv[KeyIndex], NULL, Flags);
return ok ? 0 : 1;
}
BOOL TraverseRegistry (HKEY hKey, LPTSTR FullKeyName, LPTSTR SubKey, LPBOOL Flags)
/* Traverse a registry key, listing the name-value pairs and
traversing subkeys if the -R option is set.
FullKeyName is a "full key name" starting with one of the open key
names, such as "HKEY_LOCAL_MACHINE".
SubKey, which can be null, is the rest of the path to be traversed. */
{
HKEY hSubKey;
BOOL Recursive = Flags [0];
LONG Result;
DWORD ValueType, Index;
DWORD NumSubKeys, MaxSubKeyLen, NumValues, MaxValueNameLen, MaxValueLen;
DWORD SubKeyNameLen, ValueNameLen, ValueLen;
FILETIME LastWriteTime;
LPTSTR SubKeyName, ValueName;
LPBYTE Value;
TCHAR FullSubKeyName [MAX_PATH+1];
/* Open up the key handle. */
if (RegOpenKeyEx (hKey, SubKey, 0, KEY_READ, &hSubKey) != ERROR_SUCCESS)
ReportError (_T("\nCannot open subkey"), 2, TRUE);
/* Find max size info regarding the key and allocate storage */
if (RegQueryInfoKey (hSubKey, NULL, NULL, NULL,
&NumSubKeys, &MaxSubKeyLen, NULL,
&NumValues, &MaxValueNameLen, &MaxValueLen,
NULL, &LastWriteTime) != ERROR_SUCCESS)
ReportError (_T("Cannot query subkey information"), 3, TRUE);
SubKeyName = malloc (MaxSubKeyLen+1); /* size in characters w/o null */
ValueName = malloc (MaxValueNameLen+1);/* so add one to allow for null */
Value = malloc (MaxValueLen); /* size in bytes */
/* First pass for name-value pairs. */
for ( Index = 0; Index < NumValues; Index++) {
ValueNameLen = MaxValueNameLen + 1; /* A very common bug is to forget to set */
ValueLen = MaxValueLen + 1; /* these values, both function input and output */
Result = RegEnumValue (hSubKey, Index, ValueName, &ValueNameLen, NULL,
&ValueType, Value, &ValueLen);
if (Result == ERROR_SUCCESS && GetLastError() == 0)
DisplayPair (ValueName, ValueType, Value, ValueLen, Flags);
/* If you wanted to change a value, this would be the place to do it.
RegSetValueEx (hSubKey, ValueName, 0, ValueType, pNewValue, NewValueSize); */
}
/* Second pass for subkeys */
for (Index = 0; Index < NumSubKeys; Index++) {
SubKeyNameLen = MaxSubKeyLen + 1;
Result = RegEnumKeyEx (hSubKey, Index, SubKeyName, &SubKeyNameLen, NULL,
NULL, NULL, &LastWriteTime);
if (GetLastError() == 0) {
DisplaySubKey (FullKeyName, SubKeyName, &LastWriteTime, Flags);
/* Display subkey components if -R is specified */
if (Recursive) {
_stprintf (FullSubKeyName, _T("%s\\%s"), FullKeyName, SubKeyName);
TraverseRegistry (hSubKey, FullSubKeyName, SubKeyName, Flags);
}
}
}
_tprintf (_T("\n"));
free (SubKeyName);
free (ValueName);
free (Value);
RegCloseKey (hSubKey);
return TRUE;
}
BOOL DisplayPair (LPTSTR ValueName, DWORD ValueType,
LPBYTE Value, DWORD ValueLen,
LPBOOL Flags)
/* Function to display name-value pairs. */
{
LPBYTE pV = Value;
DWORD i;
_tprintf (_T ("\nValue: %s = "), ValueName);
switch (ValueType) {
case REG_FULL_RESOURCE_DESCRIPTOR: /* 9: Resource list in the hardware description */
case REG_BINARY: /* 3: Binary data in any form. */
for (i = 0; i < ValueLen; i++, pV++)
_tprintf (_T(" %x"), *pV);
break;
case REG_DWORD: /* 4: A 32-bit number. */
_tprintf (_T("%x"), (DWORD)*Value);
break;
case REG_EXPAND_SZ: /* 2: null-terminated string with unexpanded references to environment variables (for example, ?PATH%?. */
case REG_MULTI_SZ: /* 7: An array of null-terminated strings, terminated by two null characters. */
case REG_SZ: /* 1: A null-terminated string. */
_tprintf (_T("%s"), (LPTSTR)Value);
break;
case REG_DWORD_BIG_ENDIAN: /* 5: A 32-bit number in big-endian format. */
case REG_LINK: /* 6: A Unicode symbolic link. */
case REG_NONE: /* 0: No defined value type. */
case REG_RESOURCE_LIST: /* 8: A device-driver resource list. */
default: _tprintf (_T(" ** Cannot display value of type: %d. Exercise for reader\n"), ValueType);
break;
}
return TRUE;
}
BOOL DisplaySubKey (LPTSTR KeyName, LPTSTR SubKeyName, PFILETIME pLastWrite, LPBOOL Flags)
{
BOOL Long = Flags [1];
SYSTEMTIME SysLastWrite;
_tprintf (_T("\nSubkey: %s"), KeyName);
if (_tcslen(SubKeyName) > 0) _tprintf (_T("\\%s "), SubKeyName);
if (Long) {
FileTimeToSystemTime (pLastWrite, &SysLastWrite);
_tprintf (_T (" %02d/%02d/%04d %02d:%02d:%02d"),
SysLastWrite.wMonth, SysLastWrite.wDay,
SysLastWrite.wYear, SysLastWrite.wHour,
SysLastWrite.wMinute, SysLastWrite.wSecond);
}
return TRUE;
}
참조 사이트:
http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=51&MAEULNo=20&no=6701&ref=6701
http://jjjryu.tistory.com/entry/%EC%9E%90%EB%8F%99-%EC%8B%9C%EC%9E%91
http://support.microsoft.com/kb/201431/en-us/
http://support.microsoft.com/kb/142491/en-us/