📄 regproc.c
字号:
if (line [0] == '#') {
s = line;
continue;
}
/* Remove any line feed. Leave s_eol on the \0 */
if (s_eol) {
*s_eol = '\0';
if (s_eol > line && *(s_eol-1) == '\r')
*--s_eol = '\0';
} else
s_eol = strchr (s, '\0');
/* If there is a concatenating \\ then go around again */
if (s_eol > line && *(s_eol-1) == '\\') {
int c;
s = s_eol-1;
/* The following error protection could be made more self-
* correcting but I thought it not worth trying.
*/
if ((c = fgetc (in)) == EOF || c != ' ' ||
(c = fgetc (in)) == EOF || c != ' ')
fprintf(stderr,"%s: ERROR - invalid continuation.\n",
getAppName());
continue;
}
break; /* That is the full virtual line */
}
command(line);
}
command(NULL);
HeapFree(GetProcessHeap(), 0, line);
}
/******************************************************************************
* This function is the main entry point to the registerDLL action. It
* receives the currently read line, then loads and registers the requested DLLs
*/
void doRegisterDLL(LPSTR stdInput)
{
HMODULE theLib = 0;
UINT retVal = 0;
/* Check for valid input */
if (stdInput == NULL)
return;
/* Load and register the library, then free it */
theLib = LoadLibraryA(stdInput);
if (theLib) {
FARPROC lpfnDLLRegProc = GetProcAddress(theLib, "DllRegisterServer");
if (lpfnDLLRegProc)
retVal = (*lpfnDLLRegProc)();
else
fprintf(stderr,"%s: Couldn't find DllRegisterServer proc in '%s'.\n",
getAppName(), stdInput);
if (retVal != S_OK)
fprintf(stderr,"%s: DLLRegisterServer error 0x%x in '%s'.\n",
getAppName(), retVal, stdInput);
FreeLibrary(theLib);
} else {
fprintf(stderr,"%s: Could not load DLL '%s'.\n", getAppName(), stdInput);
}
}
/******************************************************************************
* This function is the main entry point to the unregisterDLL action. It
* receives the currently read line, then loads and unregisters the requested DLLs
*/
void doUnregisterDLL(LPSTR stdInput)
{
HMODULE theLib = 0;
UINT retVal = 0;
/* Check for valid input */
if (stdInput == NULL)
return;
/* Load and unregister the library, then free it */
theLib = LoadLibraryA(stdInput);
if (theLib) {
FARPROC lpfnDLLRegProc = GetProcAddress(theLib, "DllUnregisterServer");
if (lpfnDLLRegProc)
retVal = (*lpfnDLLRegProc)();
else
fprintf(stderr,"%s: Couldn't find DllUnregisterServer proc in '%s'.\n",
getAppName(), stdInput);
if (retVal != S_OK)
fprintf(stderr,"%s: DLLUnregisterServer error 0x%x in '%s'.\n",
getAppName(), retVal, stdInput);
FreeLibrary(theLib);
} else {
fprintf(stderr,"%s: Could not load DLL '%s'.\n", getAppName(), stdInput);
}
}
/****************************************************************************
* REGPROC_print_error
*
* Print the message for GetLastError
*/
static void REGPROC_print_error(void)
{
LPVOID lpMsgBuf;
DWORD error_code;
int status;
error_code = GetLastError ();
status = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, error_code, 0, (LPTSTR) &lpMsgBuf, 0, NULL);
if (!status) {
fprintf(stderr,"%s: Cannot display message for error %ld, status %ld\n",
getAppName(), error_code, GetLastError());
exit(1);
}
puts(lpMsgBuf);
LocalFree((HLOCAL)lpMsgBuf);
exit(1);
}
/******************************************************************************
* Checks whether the buffer has enough room for the string or required size.
* Resizes the buffer if necessary.
*
* Parameters:
* buffer - pointer to a buffer for string
* len - current length of the buffer in characters.
* required_len - length of the string to place to the buffer in characters.
* The length does not include the terminating null character.
*/
static void REGPROC_resize_char_buffer(CHAR **buffer, DWORD *len, DWORD required_len)
{
required_len++;
if (required_len > *len) {
*len = required_len;
if (!*buffer)
*buffer = HeapAlloc(GetProcessHeap(), 0, *len * sizeof(**buffer));
else
*buffer = HeapReAlloc(GetProcessHeap(), 0, *buffer, *len * sizeof(**buffer));
CHECK_ENOUGH_MEMORY(*buffer);
}
}
/******************************************************************************
* Prints string str to file
*/
static void REGPROC_export_string(FILE *file, CHAR *str)
{
size_t len = strlen(str);
size_t i;
/* escaping characters */
for (i = 0; i < len; i++) {
CHAR c = str[i];
switch (c) {
case '\\':
fputs("\\\\", file);
break;
case '\"':
fputs("\\\"", file);
break;
case '\n':
fputs("\\\n", file);
break;
default:
fputc(c, file);
break;
}
}
}
/******************************************************************************
* Writes contents of the registry key to the specified file stream.
*
* Parameters:
* file - writable file stream to export registry branch to.
* key - registry branch to export.
* reg_key_name_buf - name of the key with registry class.
* Is resized if necessary.
* reg_key_name_len - length of the buffer for the registry class in characters.
* val_name_buf - buffer for storing value name.
* Is resized if necessary.
* val_name_len - length of the buffer for storing value names in characters.
* val_buf - buffer for storing values while extracting.
* Is resized if necessary.
* val_size - size of the buffer for storing values in bytes.
*/
static void export_hkey(FILE *file, HKEY key,
CHAR **reg_key_name_buf, DWORD *reg_key_name_len,
CHAR **val_name_buf, DWORD *val_name_len,
BYTE **val_buf, DWORD *val_size)
{
DWORD max_sub_key_len;
DWORD max_val_name_len;
DWORD max_val_size;
DWORD curr_len;
DWORD i;
BOOL more_data;
LONG ret;
/* get size information and resize the buffers if necessary */
if (RegQueryInfoKey(key, NULL, NULL, NULL, NULL,
&max_sub_key_len, NULL,
NULL, &max_val_name_len, &max_val_size, NULL, NULL
) != ERROR_SUCCESS) {
REGPROC_print_error();
}
curr_len = (DWORD) strlen(*reg_key_name_buf);
REGPROC_resize_char_buffer(reg_key_name_buf, reg_key_name_len,
max_sub_key_len + curr_len + 1);
REGPROC_resize_char_buffer(val_name_buf, val_name_len,
max_val_name_len);
if (max_val_size > *val_size) {
*val_size = max_val_size;
if (!*val_buf) *val_buf = HeapAlloc(GetProcessHeap(), 0, *val_size);
else *val_buf = HeapReAlloc(GetProcessHeap(), 0, *val_buf, *val_size);
CHECK_ENOUGH_MEMORY(val_buf);
}
/* output data for the current key */
fputs("\n[", file);
fputs(*reg_key_name_buf, file);
fputs("]\n", file);
/* print all the values */
i = 0;
more_data = TRUE;
while(more_data) {
DWORD value_type;
DWORD val_name_len1 = *val_name_len;
DWORD val_size1 = *val_size;
ret = RegEnumValueA(key, i, *val_name_buf, &val_name_len1, NULL,
&value_type, *val_buf, &val_size1);
if (ret != ERROR_SUCCESS) {
more_data = FALSE;
if (ret != ERROR_NO_MORE_ITEMS) {
REGPROC_print_error();
}
} else {
i++;
if ((*val_name_buf)[0]) {
fputs("\"", file);
REGPROC_export_string(file, *val_name_buf);
fputs("\"=", file);
} else {
fputs("@=", file);
}
switch (value_type) {
case REG_SZ:
case REG_EXPAND_SZ:
fputs("\"", file);
REGPROC_export_string(file, (char*) *val_buf);
fputs("\"\n", file);
break;
case REG_DWORD:
fprintf(file, "dword:%08lx\n", *((DWORD *)*val_buf));
break;
default:
fprintf(stderr,"%s: warning - unsupported registry format '%ld', "
"treat as binary\n",
getAppName(), value_type);
fprintf(stderr,"key name: \"%s\"\n", *reg_key_name_buf);
fprintf(stderr,"value name:\"%s\"\n\n", *val_name_buf);
/* falls through */
case REG_MULTI_SZ:
/* falls through */
case REG_BINARY: {
DWORD i1;
const CHAR *hex_prefix;
CHAR buf[20];
int cur_pos;
if (value_type == REG_BINARY) {
hex_prefix = "hex:";
} else {
hex_prefix = buf;
sprintf(buf, "hex(%ld):", value_type);
}
/* position of where the next character will be printed */
/* NOTE: yes, strlen("hex:") is used even for hex(x): */
cur_pos = (int) (strlen("\"\"=") + strlen("hex:") +
strlen(*val_name_buf));
fputs(hex_prefix, file);
for (i1 = 0; i1 < val_size1; i1++) {
fprintf(file, "%02x", (unsigned int)(*val_buf)[i1]);
if (i1 + 1 < val_size1) {
fputs(",", file);
}
cur_pos += 3;
/* wrap the line */
if (cur_pos > REG_FILE_HEX_LINE_LEN) {
fputs("\\\n ", file);
cur_pos = 2;
}
}
fputs("\n", file);
break;
}
}
}
}
i = 0;
more_data = TRUE;
(*reg_key_name_buf)[curr_len] = '\\';
while(more_data) {
DWORD buf_len = *reg_key_name_len - curr_len;
ret = RegEnumKeyExA(key, i, *reg_key_name_buf + curr_len + 1, &buf_len,
NULL, NULL, NULL, NULL);
if (ret != ERROR_SUCCESS && ret != ERROR_MORE_DATA) {
more_data = FALSE;
if (ret != ERROR_NO_MORE_ITEMS) {
REGPROC_print_error();
}
} else {
HKEY subkey;
i++;
if (RegOpenKeyA(key, *reg_key_name_buf + curr_len + 1,
&subkey) == ERROR_SUCCESS) {
export_hkey(file, subkey, reg_key_name_buf, reg_key_name_len,
val_name_buf, val_name_len, val_buf, val_size);
RegCloseKey(subkey);
} else {
REGPROC_print_error();
}
}
}
(*reg_key_name_buf)[curr_len] = '\0';
}
/******************************************************************************
* Open file for export.
*/
static FILE *REGPROC_open_export_file(const TCHAR *file_name)
{
FILE *file = _tfopen(file_name, _T("w"));
if (!file) {
perror("");
/* fprintf(stderr,"%s: Can't open file \"%s\"\n", getAppName(), file_name);*/
exit(1);
}
fputs("REGEDIT4\n", file);
return file;
}
/******************************************************************************
* Writes contents of the registry key to the specified file stream.
*
* Parameters:
* file_name - name of a file to export registry branch to.
* reg_key_name - registry branch to export. The whole registry is exported if
* reg_key_name is NULL or contains an empty string.
*/
BOOL export_registry_key(const TCHAR *file_name, CHAR *reg_key_name)
{
HKEY reg_key_class;
CHAR *reg_key_name_buf;
CHAR *val_name_buf;
BYTE *val_buf;
DWORD reg_key_name_len = KEY_MAX_LEN;
DWORD val_name_len = KEY_MAX_LEN;
DWORD val_size = REG_VAL_BUF_SIZE;
FILE *file = NULL;
reg_key_name_buf = HeapAlloc(GetProcessHeap(), 0,
reg_key_name_len * sizeof(*reg_key_name_buf));
val_name_buf = HeapAlloc(GetProcessHeap(), 0,
val_name_len * sizeof(*val_name_buf));
val_buf = HeapAlloc(GetProcessHeap(), 0, val_size);
CHECK_ENOUGH_MEMORY(reg_key_name_buf && val_name_buf && val_buf);
if (reg_key_name && reg_key_name[0]) {
CHAR *branch_name;
HKEY key;
REGPROC_resize_char_buffer(®_key_name_buf, ®_key_name_len,
(DWORD) strlen(reg_key_name));
strcpy(reg_key_name_buf, reg_key_name);
/* open the specified key */
reg_key_class = getRegClass(reg_key_name);
if (reg_key_class == (HKEY)ERROR_INVALID_PARAMETER) {
fprintf(stderr,"%s: Incorrect registry class specification in '%s'\n",
getAppName(), reg_key_name);
exit(1);
}
branch_name = getRegKeyName(reg_key_name);
CHECK_ENOUGH_MEMORY(branch_name);
if (!branch_name[0]) {
/* no branch - registry class is specified */
file = REGPROC_open_export_file(file_name);
export_hkey(file, reg_key_class,
®_key_name_buf, ®_key_name_len,
&val_name_buf, &val_name_len,
&val_buf, &val_size);
} else if (RegOpenKeyA(reg_key_class, branch_name, &key) == ERROR_SUCCESS) {
file = REGPROC_open_export_file(file_name);
export_hkey(file, key,
®_key_name_buf, ®_key_name_len,
&val_name_buf, &val_name_len,
&val_buf, &val_size);
RegCloseKey(key);
} else {
fprintf(stderr,"%s: Can't export. Registry key '%s' does not exist!\n",
getAppName(), reg_key_name);
REGPROC_print_error();
}
HeapFree(GetProcessHeap(), 0, branch_name);
} else {
unsigned int i;
/* export all registry classes */
file = REGPROC_open_export_file(file_name);
for (i = 0; i < REG_CLASS_NUMBER; i++) {
/* do not export HKEY_CLASSES_ROOT */
if (reg_class_keys[i] != HKEY_CLASSES_ROOT &&
reg_class_keys[i] != HKEY_CURRENT_USER &&
reg_class_keys[i] != HKEY_CURRENT_CONFIG &&
reg_class_keys[i] != HKEY_DYN_DATA) {
strcpy(reg_key_name_buf, reg_class_names[i]);
export_hkey(file, reg_class_keys[i],
®_key_name_buf, ®_key_name_len,
&val_name_buf, &val_name_len,
&val_buf, &val_size);
}
}
}
if (file) {
fclose(file);
}
HeapFree(GetProcessHeap(), 0, val_buf);
return TRUE;
}
/******************************************************************************
* Reads contents of the specified file into the registry.
*/
BOOL import_registry_file(LPTSTR filename)
{
FILE* reg_file = _tfopen(filename, _T("r"));
if (reg_file) {
unsigned char ch1 = fgetc(reg_file);
unsigned char ch2 = fgetc(reg_file);
/* detect UTF-16.LE or UTF-16.BE format */
if ((ch1 == 0xff && ch2 == 0xfe) ||
(ch1 == 0xfe && ch2 == 0xff)) {
/* TODO: implement support for UNICODE files! */
} else {
/* restore read point to the first line */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -