📄 regproc.c
字号:
bTheKeyIsOpen = TRUE;
return hRes;
}
/******************************************************************************
* Extracts from [HKEY\some\key\path] or HKEY\some\key\path types of line
* the key name (what starts after the first '\')
*/
LPSTR getRegKeyName(LPSTR lpLine)
{
LPSTR keyNameBeg;
char lpLineCopy[KEY_MAX_LEN];
if (lpLine == NULL)
return NULL;
strcpy(lpLineCopy, lpLine);
keyNameBeg = strchr(lpLineCopy, '\\'); /* The key name start by '\' */
if (keyNameBeg) {
LPSTR keyNameEnd;
keyNameBeg++; /* is not part of the name */
keyNameEnd = strchr(lpLineCopy, ']');
if (keyNameEnd) {
*keyNameEnd = '\0'; /* remove ']' from the key name */
}
} else {
keyNameBeg = lpLineCopy + strlen(lpLineCopy); /* branch - empty string */
}
currentKeyName = HeapAlloc(GetProcessHeap(), 0, strlen(keyNameBeg) + 1);
CHECK_ENOUGH_MEMORY(currentKeyName);
strcpy(currentKeyName, keyNameBeg);
return currentKeyName;
}
/******************************************************************************
* Extracts from [HKEY\some\key\path] or HKEY\some\key\path types of line
* the key class (what ends before the first '\')
*/
HKEY getRegClass(LPSTR lpClass)
{
LPSTR classNameEnd;
LPSTR classNameBeg;
unsigned int i;
char lpClassCopy[KEY_MAX_LEN];
if (lpClass == NULL)
return (HKEY)ERROR_INVALID_PARAMETER;
lstrcpynA(lpClassCopy, lpClass, KEY_MAX_LEN);
classNameEnd = strchr(lpClassCopy, '\\'); /* The class name ends by '\' */
if (!classNameEnd) /* or the whole string */
{
classNameEnd = lpClassCopy + strlen(lpClassCopy);
if (classNameEnd[-1] == ']')
{
classNameEnd--;
}
}
*classNameEnd = '\0'; /* Isolate the class name */
if (lpClassCopy[0] == '[') {
classNameBeg = lpClassCopy + 1;
} else {
classNameBeg = lpClassCopy;
}
for (i = 0; i < REG_CLASS_NUMBER; i++) {
if (!strcmp(classNameBeg, reg_class_names[i])) {
return reg_class_keys[i];
}
}
return (HKEY)ERROR_INVALID_PARAMETER;
}
/******************************************************************************
* Close the currently opened key.
*/
void closeKey(void)
{
RegCloseKey(currentKeyHandle);
HeapFree(GetProcessHeap(), 0, currentKeyName); /* Allocated by getKeyName */
bTheKeyIsOpen = FALSE;
currentKeyName = NULL;
currentKeyClass = 0;
currentKeyHandle = 0;
}
/******************************************************************************
* This function is the main entry point to the setValue type of action. It
* receives the currently read line and dispatch the work depending on the
* context.
*/
void doSetValue(LPSTR stdInput)
{
/*
* We encountered the end of the file, make sure we
* close the opened key and exit
*/
if (stdInput == NULL) {
if (bTheKeyIsOpen != FALSE)
closeKey();
return;
}
if ( stdInput[0] == '[') /* We are reading a new key */
{
if ( bTheKeyIsOpen != FALSE )
closeKey(); /* Close the previous key before */
if ( openKey(stdInput) != ERROR_SUCCESS )
fprintf(stderr,"%s: setValue failed to open key %s\n",
getAppName(), stdInput);
} else if( ( bTheKeyIsOpen ) &&
(( stdInput[0] == '@') || /* reading a default @=data pair */
( stdInput[0] == '\"'))) /* reading a new value=data pair */
{
processSetValue(stdInput);
} else /* since we are assuming that the */
{ /* file format is valid we must */
if ( bTheKeyIsOpen ) /* be reading a blank line which */
closeKey(); /* indicate end of this key processing */
}
}
/******************************************************************************
* This function is the main entry point to the queryValue type of action. It
* receives the currently read line and dispatch the work depending on the
* context.
*/
void doQueryValue(LPSTR stdInput)
{
/*
* We encountered the end of the file, make sure we
* close the opened key and exit
*/
if (stdInput == NULL) {
if (bTheKeyIsOpen != FALSE)
closeKey();
return;
}
if ( stdInput[0] == '[') /* We are reading a new key */
{
if ( bTheKeyIsOpen != FALSE )
closeKey(); /* Close the previous key before */
if ( openKey(stdInput) != ERROR_SUCCESS )
fprintf(stderr,"%s: queryValue failed to open key %s\n",
getAppName(), stdInput);
} else if( ( bTheKeyIsOpen ) &&
(( stdInput[0] == '@') || /* reading a default @=data pair */
( stdInput[0] == '\"'))) /* reading a new value=data pair */
{
processQueryValue(stdInput);
} else /* since we are assuming that the */
{ /* file format is valid we must */
if ( bTheKeyIsOpen ) /* be reading a blank line which */
closeKey(); /* indicate end of this key processing */
}
}
/******************************************************************************
* This function is the main entry point to the deleteValue type of action. It
* receives the currently read line and dispatch the work depending on the
* context.
*/
void doDeleteValue(LPSTR line)
{
UNREFERENCED_PARAMETER(line);
fprintf(stderr,"%s: deleteValue not yet implemented\n", getAppName());
}
/******************************************************************************
* This function is the main entry point to the deleteKey type of action. It
* receives the currently read line and dispatch the work depending on the
* context.
*/
void doDeleteKey(LPSTR line)
{
UNREFERENCED_PARAMETER(line);
fprintf(stderr,"%s: deleteKey not yet implemented\n", getAppName());
}
/******************************************************************************
* This function is the main entry point to the createKey type of action. It
* receives the currently read line and dispatch the work depending on the
* context.
*/
void doCreateKey(LPSTR line)
{
UNREFERENCED_PARAMETER(line);
fprintf(stderr,"%s: createKey not yet implemented\n", getAppName());
}
/******************************************************************************
* This function is a wrapper for the setValue function. It prepares the
* land and clean the area once completed.
* Note: this function modifies the line parameter.
*
* line - registry file unwrapped line. Should have the registry value name and
* complete registry value data.
*/
void processSetValue(LPSTR line)
{
LPSTR val_name; /* registry value name */
LPSTR val_data; /* registry value data */
int line_idx = 0; /* current character under analysis */
HRESULT hRes = 0;
/* get value name */
if (line[line_idx] == '@' && line[line_idx + 1] == '=') {
line[line_idx] = '\0';
val_name = line;
line_idx++;
} else if (line[line_idx] == '\"') {
line_idx++;
val_name = line + line_idx;
while (TRUE) {
/* check if the line is unterminated (otherwise it may loop forever!) */
if (line[line_idx] == '\0') {
fprintf(stderr,"Warning! unrecognized line:\n%s\n", line);
return;
} else
if (line[line_idx] == '\\') /* skip escaped character */
{
line_idx += 2;
} else {
if (line[line_idx] == '\"') {
line[line_idx] = '\0';
line_idx++;
break;
} else {
line_idx++;
}
}
}
if (line[line_idx] != '=') {
line[line_idx] = '\"';
fprintf(stderr,"Warning! unrecognized line:\n%s\n", line);
return;
}
} else {
fprintf(stderr,"Warning! unrecognized line:\n%s\n", line);
return;
}
line_idx++; /* skip the '=' character */
val_data = line + line_idx;
REGPROC_unescape_string(val_name);
hRes = setValue(val_name, val_data);
if ( hRes != ERROR_SUCCESS )
fprintf(stderr,"%s: ERROR Key %s not created. Value: %s, Data: %s\n",
getAppName(),
currentKeyName,
val_name,
val_data);
}
/******************************************************************************
* This function is a wrapper for the queryValue function. It prepares the
* land and clean the area once completed.
*/
void processQueryValue(LPSTR cmdline)
{
UNREFERENCED_PARAMETER(cmdline);
fprintf(stderr,"ERROR!!! - temporary disabled");
exit(1);
#if 0
LPSTR argv[QUERY_VALUE_MAX_ARGS];/* args storage */
LPSTR token = NULL; /* current token analyzed */
ULONG argCounter = 0; /* counter of args */
INT counter;
HRESULT hRes = 0;
LPSTR keyValue = NULL;
LPSTR lpsRes = NULL;
/*
* Init storage and parse the line
*/
for (counter=0; counter<QUERY_VALUE_MAX_ARGS; counter++)
argv[counter]=NULL;
while( (token = getToken(&cmdline, queryValueDelim[argCounter])) != NULL ) {
argv[argCounter++] = getArg(token);
if (argCounter == QUERY_VALUE_MAX_ARGS)
break; /* Stop processing args no matter what */
}
/* The value we look for is the first token on the line */
if ( argv[0] == NULL )
return; /* SHOULD NOT HAPPEN */
else
keyValue = argv[0];
if( (keyValue[0] == '@') && (strlen(keyValue) == 1) ) {
LONG lLen = KEY_MAX_LEN;
CHAR* lpsData=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,KEY_MAX_LEN);
/*
* We need to query the key default value
*/
hRes = RegQueryValue(
currentKeyHandle,
currentKeyName,
(LPBYTE)lpsData,
&lLen);
if (hRes==ERROR_MORE_DATA) {
lpsData=HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,lpsData,lLen);
hRes = RegQueryValue(currentKeyHandle,currentKeyName,(LPBYTE)lpsData,&lLen);
}
if (hRes == ERROR_SUCCESS) {
lpsRes = HeapAlloc( GetProcessHeap(), 0, lLen);
lstrcpynA(lpsRes, lpsData, lLen);
}
} else {
DWORD dwLen = KEY_MAX_LEN;
BYTE* lpbData=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,KEY_MAX_LEN);
DWORD dwType;
/*
* We need to query a specific value for the key
*/
hRes = RegQueryValueEx(
currentKeyHandle,
keyValue,
0,
&dwType,
(LPBYTE)lpbData,
&dwLen);
if (hRes==ERROR_MORE_DATA) {
lpbData=HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,lpbData,dwLen);
hRes = RegQueryValueEx(currentKeyHandle,keyValue,NULL,&dwType,(LPBYTE)lpbData,&dwLen);
}
if (hRes == ERROR_SUCCESS) {
/*
* Convert the returned data to a displayable format
*/
switch ( dwType ) {
case REG_SZ:
case REG_EXPAND_SZ: {
lpsRes = HeapAlloc( GetProcessHeap(), 0, dwLen);
lstrcpynA(lpsRes, lpbData, dwLen);
break;
}
case REG_DWORD: {
lpsRes = convertHexToDWORDStr(lpbData, dwLen);
break;
}
default: {
lpsRes = convertHexToHexCSV(lpbData, dwLen);
break;
}
}
}
HeapFree(GetProcessHeap(), 0, lpbData);
}
if ( hRes == ERROR_SUCCESS )
fprintf(stderr,
"%s: Value \"%s\" = \"%s\" in key [%s]\n",
getAppName(),
keyValue,
lpsRes,
currentKeyName);
else
fprintf(stderr,"%s: ERROR Value \"%s\" not found for key \"%s\".\n",
getAppName(),
keyValue,
currentKeyName);
/*
* Do some cleanup
*/
for (counter=0; counter<argCounter; counter++)
if (argv[counter] != NULL)
HeapFree(GetProcessHeap(), 0, argv[counter]);
if (lpsRes != NULL)
HeapFree(GetProcessHeap(), 0, lpsRes);
#endif
}
/******************************************************************************
* Calls command for each line of a registry file.
* Correctly processes comments (in # form), line continuation.
*
* Parameters:
* in - input stream to read from
* command - command to be called for each line
*/
void processRegLines(FILE *in, CommandAPI command)
{
LPSTR line = NULL; /* line read from input stream */
size_t lineSize = REG_VAL_BUF_SIZE;
line = HeapAlloc(GetProcessHeap(), 0, lineSize);
CHECK_ENOUGH_MEMORY(line);
while (!feof(in)) {
LPSTR s; /* The pointer into line for where the current fgets should read */
s = line;
for (;;) {
size_t size_remaining;
int size_to_get;
char *s_eol; /* various local uses */
/* Do we need to expand the buffer ? */
assert (s >= line && s <= line + lineSize);
size_remaining = lineSize - (s-line);
if (size_remaining < 2) /* room for 1 character and the \0 */
{
char *new_buffer;
size_t new_size = lineSize + REG_VAL_BUF_SIZE;
if (new_size > lineSize) /* no arithmetic overflow */
new_buffer = HeapReAlloc (GetProcessHeap(), 0, line, new_size);
else
new_buffer = NULL;
CHECK_ENOUGH_MEMORY(new_buffer);
line = new_buffer;
s = line + lineSize - size_remaining;
lineSize = new_size;
size_remaining = lineSize - (s-line);
}
/* Get as much as possible into the buffer, terminated either by
* eof, error, eol or getting the maximum amount. Abort on error.
*/
size_to_get = (int) (size_remaining > INT_MAX ? INT_MAX : size_remaining);
if (NULL == fgets (s, size_to_get, in)) {
if (ferror(in)) {
perror ("While reading input");
exit (IO_ERROR);
} else {
assert (feof(in));
*s = '\0';
/* It is not clear to me from the definition that the
* contents of the buffer are well defined on detecting
* an eof without managing to read anything.
*/
}
}
/* If we didn't read the eol nor the eof go around for the rest */
s_eol = strchr (s, '\n');
if (!feof (in) && !s_eol) {
s = strchr (s, '\0');
/* It should be s + size_to_get - 1 but this is safer */
continue;
}
/* If it is a comment line then discard it and go around again */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -