You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
252 lines
6.0 KiB
252 lines
6.0 KiB
/*++
|
|
|
|
Copyright (c) 1985 - 1999, Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
registry.cpp
|
|
|
|
Abstract:
|
|
|
|
This file implements the Registry Class.
|
|
|
|
Author:
|
|
|
|
Revision History:
|
|
|
|
Notes:
|
|
|
|
--*/
|
|
|
|
#include "private.h"
|
|
|
|
#include "registry.h"
|
|
|
|
DWORD
|
|
CRegistry::CreateKey(
|
|
IN HKEY hKey,
|
|
IN LPCTSTR lpSubKey,
|
|
IN REGSAM access,
|
|
IN LPSECURITY_ATTRIBUTES lpSecAttr,
|
|
OUT LPDWORD pDisposition
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Create the registry key specified.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
if (_hKey != NULL) {
|
|
RegCloseKey(_hKey);
|
|
_hKey = NULL;
|
|
}
|
|
|
|
DWORD dwDisposition;
|
|
LONG lResult = RegCreateKeyEx(hKey, // handle of an open key.
|
|
lpSubKey, // address of subkey name.
|
|
0, // reserved.
|
|
NULL, // address of class string.
|
|
REG_OPTION_NON_VOLATILE, // special options flag.
|
|
access, // desired security access.
|
|
lpSecAttr, // address of key security structure.
|
|
&_hKey, // address of buffer for opened handle.
|
|
&dwDisposition); // address of disposition value buffer
|
|
if (lResult != ERROR_SUCCESS) {
|
|
_hKey = NULL;
|
|
}
|
|
|
|
if (pDisposition) {
|
|
*pDisposition = dwDisposition;
|
|
}
|
|
|
|
return lResult;
|
|
}
|
|
|
|
DWORD
|
|
CRegistry::OpenKey(
|
|
IN HKEY hKey,
|
|
IN LPCTSTR lpSubKey,
|
|
IN REGSAM access
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Open the registry key specified.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
if (_hKey != NULL) {
|
|
RegCloseKey(_hKey);
|
|
_hKey = NULL;
|
|
}
|
|
|
|
LONG lResult = RegOpenKeyEx(hKey, // handle of open key.
|
|
lpSubKey, // address of name of subkey to open
|
|
0, // reserved
|
|
access, // security access mask
|
|
&_hKey); // address of handle of open key
|
|
if (lResult != ERROR_SUCCESS) {
|
|
_hKey = NULL;
|
|
}
|
|
|
|
return lResult;
|
|
}
|
|
|
|
DWORD
|
|
CRegistry::QueryInfoKey(
|
|
IN REG_QUERY iType,
|
|
OUT LPBYTE lpData
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Retrieves information about a specified registry key.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
DWORD cSubKeys, cbMaxSubKeyLen;
|
|
|
|
LONG lResult = RegQueryInfoKey(_hKey, // handle to key to query
|
|
NULL, // address of buffer for class string
|
|
NULL, // address of size of class string buffer
|
|
NULL, // reserved
|
|
&cSubKeys, // address of buffer for number of subkeys
|
|
&cbMaxSubKeyLen, // address of buffer for longest subkey name length
|
|
NULL, // address of buffer for longest class string length
|
|
NULL, // address of buffer for number of value entries
|
|
NULL, // address of buffer for longest value name length
|
|
NULL, // address of buffer for longest value data length
|
|
NULL, // address of buffer for security descriptor length.
|
|
NULL); // address of buffer for last write time
|
|
|
|
switch (iType) {
|
|
case REG_QUERY_NUMBER_OF_SUBKEYS:
|
|
*((LPDWORD)lpData) = cSubKeys; break;
|
|
case REG_QUERY_MAX_SUBKEY_LEN:
|
|
*((LPDWORD)lpData) = cbMaxSubKeyLen; break;
|
|
}
|
|
|
|
return lResult;
|
|
}
|
|
|
|
DWORD
|
|
CRegistry::GetFirstSubKey(
|
|
OUT LPTSTR* lppStr,
|
|
OUT LPDWORD lpdwSize
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Reads a first subkey for the key.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
_iEnumKeyIndex = 0;
|
|
|
|
DWORD dwRet = QueryInfoKey(REG_QUERY_MAX_SUBKEY_LEN, (LPBYTE)&_dwMaxSubKeyLen);
|
|
if (dwRet != ERROR_SUCCESS) {
|
|
return dwRet;
|
|
}
|
|
|
|
return GetNextSubKey(lppStr, lpdwSize);
|
|
}
|
|
|
|
DWORD
|
|
CRegistry::GetNextSubKey(
|
|
OUT LPTSTR* lppStr,
|
|
OUT LPDWORD lpdwSize
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Reads the next subkey for the key.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
*lpdwSize = 0;
|
|
|
|
if (Allocate(*lpdwSize = (_dwMaxSubKeyLen+sizeof(TCHAR)) * sizeof(TCHAR)) == NULL) {
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
DWORD lResult = RegEnumKeyEx(_hKey, // handle of key to enumrate
|
|
_iEnumKeyIndex, // index of subkey to enumerate
|
|
(LPTSTR)_pMemBlock, // address of buffer for subkey name
|
|
lpdwSize, // address for size of subkey buffer
|
|
0, // reserved
|
|
NULL, // address of buffer for class string
|
|
NULL, // address for sieze of class buffer
|
|
NULL); // address for time key last written to
|
|
|
|
*lpdwSize += sizeof(TCHAR); // since null terminate is not included in the size.
|
|
|
|
if (lResult == ERROR_SUCCESS) {
|
|
*lppStr = (LPTSTR)_pMemBlock;
|
|
_iEnumKeyIndex++;
|
|
}
|
|
|
|
return lResult;
|
|
}
|
|
|
|
void*
|
|
CRegistry::Allocate(
|
|
IN DWORD dwSize
|
|
)
|
|
{
|
|
ASSERT(dwSize != 0);
|
|
|
|
if (_pMemBlock) {
|
|
Release();
|
|
}
|
|
|
|
_pMemBlock = new BYTE[dwSize];
|
|
|
|
return _pMemBlock;
|
|
}
|
|
|
|
void
|
|
CRegistry::Release(
|
|
)
|
|
{
|
|
if (_pMemBlock) {
|
|
delete [] _pMemBlock;
|
|
}
|
|
|
|
_pMemBlock = NULL;
|
|
}
|