#include <windows.h>
#include <errno.h>
+#include <stdio.h>
#include <stdlib.h>
-#include <wine/unicode.h>
#include <wine/debug.h>
#include <wine/heap.h>
#include "reg.h"
LocalFree(str);
}
-static void output_error(LSTATUS status)
-{
- WCHAR* str;
- DWORD len;
-
- SetLastError(NO_ERROR);
- len = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, status, 0, (WCHAR*)&str, 0, NULL);
- if (len == 0 && GetLastError() != NO_ERROR)
- {
- WINE_FIXME("Could not format error code: le=%u, error=%u", GetLastError(), status);
- return;
- }
-
- output_writeconsole(str, len);
- LocalFree(str);
-}
-
void WINAPIV output_message(unsigned int id, ...)
{
WCHAR fmt[1024];
output_message(msgid, str);
output_message(STRING_YESNO);
ReadConsoleW(GetStdHandle(STD_INPUT_HANDLE), answer, ARRAY_SIZE(answer), &count, NULL);
- answer[0] = toupperW(answer[0]);
+ answer[0] = towupper(answer[0]);
if (answer[0] == Ybuffer[0])
return TRUE;
if (answer[0] == Nbuffer[0])
static inline BOOL path_rootname_cmp(const WCHAR *input_path, const WCHAR *rootkey_name)
{
- DWORD length = strlenW(rootkey_name);
+ DWORD length = lstrlenW(rootkey_name);
- return (!strncmpiW(input_path, rootkey_name, length) &&
+ return (!_wcsnicmp(input_path, rootkey_name, length) &&
(input_path[length] == 0 || input_path[length] == '\\'));
}
for (i = 0; i < ARRAY_SIZE(type_rels); i++)
{
- if (!strcmpiW(type_rels[i].name, type_name))
+ if (!wcsicmp(type_rels[i].name, type_name))
return type_rels[i].type;
}
{
LPWSTR rest;
unsigned long val;
- val = wcstoul(data, &rest, (tolowerW(data[1]) == 'x') ? 16 : 10);
+ val = wcstoul(data, &rest, (towlower(data[1]) == 'x') ? 16 : 10);
if (*rest || data[0] == '-' || (val == ~0u && errno == ERANGE)) {
output_message(STRING_MISSING_INTEGER);
break;
}
case REG_MULTI_SZ:
{
- int i, destindex, len = strlenW(data);
+ int i, destindex, len = lstrlenW(data);
WCHAR *buffer = heap_xalloc((len + 2) * sizeof(WCHAR));
for (i = 0, destindex = 0; i < len; i++, destindex++)
static BOOL sane_path(const WCHAR *key)
{
- unsigned int i = strlenW(key);
+ unsigned int i = lstrlenW(key);
if (i < 3 || (key[i - 1] == '\\' && key[i - 2] == '\\'))
{
case REG_SZ:
case REG_EXPAND_SZ:
buffer = heap_xalloc(size_bytes);
- strcpyW(buffer, (WCHAR *)src);
+ lstrcpyW(buffer, (WCHAR *)src);
break;
case REG_NONE:
case REG_BINARY:
buffer = heap_xalloc((size_bytes * 2 + 1) * sizeof(WCHAR));
ptr = buffer;
for (i = 0; i < size_bytes; i++)
- ptr += sprintfW(ptr, fmt, src[i]);
+ ptr += swprintf(ptr, fmt, src[i]);
break;
}
case REG_DWORD:
static const WCHAR fmt[] = {'0','x','%','x',0};
buffer = heap_xalloc((zero_x_dword + 1) * sizeof(WCHAR));
- sprintfW(buffer, fmt, *(DWORD *)src);
+ swprintf(buffer, fmt, *(DWORD *)src);
break;
}
case REG_MULTI_SZ:
static const WCHAR fmt[] = {'%','s','\\','%','s',0};
subkey_path = heap_xalloc((path_len + subkey_len + 2) * sizeof(WCHAR));
- sprintfW(subkey_path, fmt, path, subkey_name);
+ swprintf(subkey_path, fmt, path, subkey_name);
return subkey_path;
}
subkey_name = heap_xalloc(MAX_SUBKEY_LEN * sizeof(WCHAR));
- path_len = strlenW(path);
+ path_len = lstrlenW(path);
i = 0;
for (;;)
subkey_name = heap_xalloc(MAX_SUBKEY_LEN * sizeof(WCHAR));
- path_len = strlenW(path);
+ path_len = lstrlenW(path);
i = 0;
for (;;)
break;
}
- len = strlenW(root_rels[i].long_name);
+ len = lstrlenW(root_rels[i].long_name);
if (!path)
{
long_key = heap_xalloc((len + 1) * sizeof(WCHAR));
- strcpyW(long_key, root_rels[i].long_name);
+ lstrcpyW(long_key, root_rels[i].long_name);
return long_key;
}
- len += strlenW(path) + 1; /* add one for the backslash */
+ len += lstrlenW(path) + 1; /* add one for the backslash */
long_key = heap_xalloc((len + 1) * sizeof(WCHAR));
- sprintfW(long_key, fmt, root_rels[i].long_name, path);
+ swprintf(long_key, fmt, root_rels[i].long_name, path);
return long_key;
}
if (!sane_path(key))
return FALSE;
- *path = strchrW(key, '\\');
+ *path = wcschr(key, '\\');
if (*path) (*path)++;
*root = path_get_rootkey(key);
static BOOL is_switch(const WCHAR *s, const WCHAR c)
{
- if (strlenW(s) > 2)
+ if (lstrlenW(s) > 2)
return FALSE;
- if ((s[0] == '/' || s[0] == '-') && (s[1] == c || s[1] == toupperW(c)))
+ if ((s[0] == '/' || s[0] == '-') && (s[1] == c || s[1] == towupper(c)))
return TRUE;
return FALSE;
}
-static BOOL set_privilege(LPCWSTR privilegeName, BOOL enabled)
-{
- HANDLE hToken = INVALID_HANDLE_VALUE;
- TOKEN_PRIVILEGES tp;
- DWORD error = ERROR_SUCCESS;
-
- if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
- {
- tp.PrivilegeCount = 1;
- tp.Privileges[0].Attributes = (enabled ? SE_PRIVILEGE_ENABLED : 0);
-
- if (LookupPrivilegeValueW(NULL, privilegeName, &tp.Privileges[0].Luid))
- {
- if (AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL))
- {
- if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
- {
- error = ERROR_NOT_ALL_ASSIGNED;
- goto fail;
- }
- }
- else
- {
- error = GetLastError();
- goto fail;
- }
- }
- else
- {
- error = GetLastError();
- goto fail;
- }
- }
- else
- {
- error = GetLastError();
- goto fail;
- }
-
- CloseHandle(hToken);
- return TRUE;
-
-fail:
- // Don't allow a success error to be printed, as that would confuse the user.
- // "Access denied" seems like a reasonable default.
- if (error == ERROR_SUCCESS) error = ERROR_ACCESS_DENIED;
- if (hToken != INVALID_HANDLE_VALUE) CloseHandle(hToken);
-
- output_error(error);
- return FALSE;
-}
-
-static int reg_save(int argc, WCHAR* argv[]) {
- HKEY root, hkey;
- LSTATUS status;
- WCHAR* path, *long_key;
-
- if (argc < 4 || argc > 5) goto error;
-
- if (!parse_registry_key(argv[2], &root, &path, &long_key))
- return 1;
-
- if (GetFileAttributes(argv[3]) != INVALID_FILE_ATTRIBUTES)
- {
- if (argc == 5 && !strcmpiW(argv[4], L"/y"))
- {
- DeleteFile(argv[3]);
- }
- else
- {
- if (ask_confirm(STRING_OVERWRITE_FILE, argv[3]))
- DeleteFile(argv[3]);
- }
- }
-
- if (RegOpenKeyExW(root, path, 0, KEY_READ, &hkey))
- {
- output_message(STRING_INVALID_KEY);
- return 1;
- }
-
- if (!set_privilege(SE_BACKUP_NAME, TRUE)) return 1;
-
- status = RegSaveKeyExW(hkey, argv[3], NULL, REG_LATEST_FORMAT);
- RegCloseKey(hkey);
-
- if (status != ERROR_SUCCESS) {
- output_error(status);
- return 1;
- }
-
- return 0;
-
-error:
- output_message(STRING_INVALID_SYNTAX);
- output_message(STRING_FUNC_HELP, struprW(argv[1]));
- return 1;
-}
-
-static int reg_restore(int argc, WCHAR* argv[])
-{
- HKEY root, hkey;
- LSTATUS status;
- WCHAR* path, * long_key;
-
- if (argc != 4) goto error;
-
- if (!parse_registry_key(argv[2], &root, &path, &long_key))
- return 1;
-
- if (RegOpenKeyExW(root, path, 0, KEY_READ, &hkey))
- {
- output_message(STRING_INVALID_KEY);
- return 1;
- }
-
- if (!set_privilege(SE_BACKUP_NAME, TRUE)) return 1;
- if (!set_privilege(SE_RESTORE_NAME, TRUE)) return 1;
-
- status = RegRestoreKeyW(hkey, argv[3], 0);
- RegCloseKey(hkey);
-
- if (status != ERROR_SUCCESS) {
- output_error(status);
- return 1;
- }
-
- return 0;
-
-error:
- output_message(STRING_INVALID_SYNTAX);
- output_message(STRING_FUNC_HELP, struprW(argv[1]));
- return 1;
-}
-
static BOOL is_help_switch(const WCHAR *s)
{
if (is_switch(s, '?') || is_switch(s, 'h'))
REG_IMPORT,
REG_EXPORT,
REG_QUERY,
- REG_SAVE,
- REG_RESTORE,
REG_INVALID
};
static const WCHAR import[] = {'i','m','p','o','r','t',0};
static const WCHAR export[] = {'e','x','p','o','r','t',0};
static const WCHAR query[] = {'q','u','e','r','y',0};
- static const WCHAR save[] = L"save";
- static const WCHAR restore[] = L"restore";
static const struct op_info op_array[] =
{
{ import, REG_IMPORT, STRING_IMPORT_USAGE },
{ export, REG_EXPORT, STRING_EXPORT_USAGE },
{ query, REG_QUERY, STRING_QUERY_USAGE },
- { save, REG_SAVE, STRING_SAVE_USAGE },
- { restore, REG_RESTORE, STRING_RESTORE_USAGE },
{ NULL, -1, 0 }
};
return REG_INVALID;
}
-int wmain(int argc, WCHAR *argvW[])
+int __cdecl wmain(int argc, WCHAR *argvW[])
{
int i, op, op_help, ret;
BOOL show_op_help = FALSE;
if (argc == 2 || ((show_op_help || op == REG_IMPORT) && argc > 3))
{
output_message(STRING_INVALID_SYNTAX);
- output_message(STRING_FUNC_HELP, struprW(argvW[1]));
+ output_message(STRING_FUNC_HELP, _wcsupr(argvW[1]));
return 1;
}
else if (show_op_help)
if (op == REG_EXPORT)
return reg_export(argc, argvW);
- if (op == REG_SAVE)
- return reg_save(argc, argvW);
-
- if (op == REG_RESTORE)
- return reg_restore(argc, argvW);
-
if (!parse_registry_key(argvW[2], &root, &path, &key_name))
return 1;
return 1;
}
- switch(tolowerW(argvW[i][1]))
+ switch(towlower(argvW[i][1]))
{
case 'v':
if (value_name || !(value_name = argvW[++i]))
}
ptr = argvW[++i];
- if (!ptr || strlenW(ptr) != 1)
+ if (!ptr || lstrlenW(ptr) != 1)
{
output_message(STRING_INVALID_CMDLINE);
return 1;