⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 regproc.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 4 页
字号:
            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(&reg_key_name_buf, &reg_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,
                        &reg_key_name_buf, &reg_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,
                        &reg_key_name_buf, &reg_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],
                            &reg_key_name_buf, &reg_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 + -