[REG] Sync with Wine Staging 4.18. CORE-16441
[reactos.git] / base / applications / cmdutils / reg / reg.c
index 5e65aee..21a0861 100644 (file)
@@ -18,8 +18,8 @@
 
 #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"
@@ -144,23 +144,6 @@ static void output_formatstring(const WCHAR *fmt, __ms_va_list va_args)
     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];
@@ -208,7 +191,7 @@ BOOL ask_confirm(unsigned int msgid, WCHAR *reg_info)
         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])
@@ -218,9 +201,9 @@ BOOL ask_confirm(unsigned int msgid, WCHAR *reg_info)
 
 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] == '\\'));
 }
 
@@ -247,7 +230,7 @@ static DWORD wchar_get_type(const WCHAR *type_name)
 
     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;
     }
 
@@ -292,7 +275,7 @@ static LPBYTE get_regdata(const WCHAR *data, DWORD reg_type, WCHAR separator, DW
         {
             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;
@@ -333,7 +316,7 @@ static LPBYTE get_regdata(const WCHAR *data, DWORD reg_type, WCHAR separator, DW
         }
         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++)
@@ -370,7 +353,7 @@ static LPBYTE get_regdata(const WCHAR *data, DWORD reg_type, WCHAR separator, DW
 
 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] == '\\'))
     {
@@ -545,7 +528,7 @@ static WCHAR *reg_data_to_wchar(DWORD type, const BYTE *src, DWORD size_bytes)
         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:
@@ -556,7 +539,7 @@ static WCHAR *reg_data_to_wchar(DWORD type, const BYTE *src, DWORD size_bytes)
             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:
@@ -567,7 +550,7 @@ static WCHAR *reg_data_to_wchar(DWORD type, const BYTE *src, DWORD size_bytes)
             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:
@@ -652,7 +635,7 @@ WCHAR *build_subkey_path(WCHAR *path, DWORD path_len, WCHAR *subkey_name, DWORD
     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;
 }
@@ -711,7 +694,7 @@ static int query_value(HKEY key, WCHAR *value_name, WCHAR *path, BOOL recurse)
 
     subkey_name = heap_xalloc(MAX_SUBKEY_LEN * sizeof(WCHAR));
 
-    path_len = strlenW(path);
+    path_len = lstrlenW(path);
 
     i = 0;
     for (;;)
@@ -789,7 +772,7 @@ static int query_all(HKEY key, WCHAR *path, BOOL recurse)
 
     subkey_name = heap_xalloc(MAX_SUBKEY_LEN * sizeof(WCHAR));
 
-    path_len = strlenW(path);
+    path_len = lstrlenW(path);
 
     i = 0;
     for (;;)
@@ -862,18 +845,18 @@ static WCHAR *get_long_key(HKEY root, WCHAR *path)
             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;
 }
 
@@ -882,7 +865,7 @@ BOOL parse_registry_key(const WCHAR *key, HKEY *root, WCHAR **path, WCHAR **long
     if (!sane_path(key))
         return FALSE;
 
-    *path = strchrW(key, '\\');
+    *path = wcschr(key, '\\');
     if (*path) (*path)++;
 
     *root = path_get_rootkey(key);
@@ -900,150 +883,15 @@ BOOL parse_registry_key(const WCHAR *key, HKEY *root, WCHAR **path, WCHAR **long
 
 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'))
@@ -1058,8 +906,6 @@ enum operations {
     REG_IMPORT,
     REG_EXPORT,
     REG_QUERY,
-    REG_SAVE,
-    REG_RESTORE,
     REG_INVALID
 };
 
@@ -1072,8 +918,6 @@ static enum operations get_operation(const WCHAR *str, int *op_help)
     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[] =
     {
@@ -1082,8 +926,6 @@ static enum operations get_operation(const WCHAR *str, int *op_help)
         { 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 }
     };
 
@@ -1101,7 +943,7 @@ static enum operations get_operation(const WCHAR *str, int *op_help)
     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;
@@ -1139,7 +981,7 @@ int wmain(int argc, WCHAR *argvW[])
     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)
@@ -1154,12 +996,6 @@ int wmain(int argc, WCHAR *argvW[])
     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;
 
@@ -1185,7 +1021,7 @@ int wmain(int argc, WCHAR *argvW[])
                 return 1;
             }
 
-            switch(tolowerW(argvW[i][1]))
+            switch(towlower(argvW[i][1]))
             {
             case 'v':
                 if (value_name || !(value_name = argvW[++i]))
@@ -1216,7 +1052,7 @@ int wmain(int argc, WCHAR *argvW[])
                 }
 
                 ptr = argvW[++i];
-                if (!ptr || strlenW(ptr) != 1)
+                if (!ptr || lstrlenW(ptr) != 1)
                 {
                     output_message(STRING_INVALID_CMDLINE);
                     return 1;