2 * Windows regedit.exe registry editor implementation.
4 * Copyright 2002 Andriy Palamarchuk
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #include "wine/unicode.h"
26 #include "wine/debug.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(regedit
);
31 static void output_writeconsole(const WCHAR
*str
, DWORD wlen
)
35 ret
= WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE
), str
, wlen
, &count
, NULL
);
41 /* WriteConsole() fails on Windows if its output is redirected. If this occurs,
42 * we should call WriteFile() and assume the console encoding is still correct.
44 len
= WideCharToMultiByte(GetConsoleOutputCP(), 0, str
, wlen
, NULL
, 0, NULL
, NULL
);
45 msgA
= HeapAlloc(GetProcessHeap(), 0, len
);
48 WideCharToMultiByte(GetConsoleOutputCP(), 0, str
, wlen
, msgA
, len
, NULL
, NULL
);
49 WriteFile(GetStdHandle(STD_OUTPUT_HANDLE
), msgA
, len
, &count
, FALSE
);
50 HeapFree(GetProcessHeap(), 0, msgA
);
54 static void output_formatstring(const WCHAR
*fmt
, __ms_va_list va_args
)
59 SetLastError(NO_ERROR
);
60 len
= FormatMessageW(FORMAT_MESSAGE_FROM_STRING
|FORMAT_MESSAGE_ALLOCATE_BUFFER
,
61 fmt
, 0, 0, (WCHAR
*)&str
, 0, &va_args
);
62 if (len
== 0 && GetLastError() != NO_ERROR
)
64 WINE_FIXME("Could not format string: le=%u, fmt=%s\n", GetLastError(), wine_dbgstr_w(fmt
));
67 output_writeconsole(str
, len
);
71 void __cdecl
output_message(unsigned int id
, ...)
76 if (!LoadStringW(GetModuleHandleW(NULL
), id
, fmt
, sizeof(fmt
)/sizeof(*fmt
)))
78 WINE_FIXME("LoadString failed with %d\n", GetLastError());
81 __ms_va_start(va_args
, id
);
82 output_formatstring(fmt
, va_args
);
87 ACTION_ADD
, ACTION_EXPORT
, ACTION_DELETE
90 static void PerformRegAction(REGEDIT_ACTION action
, WCHAR
**argv
, int *i
)
94 WCHAR
*filename
= argv
[*i
];
95 WCHAR hyphen
[] = {'-',0};
96 WCHAR
*realname
= NULL
;
99 if (!strcmpW(filename
, hyphen
))
104 WCHAR rb_mode
[] = {'r','b',0};
106 size
= SearchPathW(NULL
, filename
, NULL
, 0, NULL
, NULL
);
109 realname
= HeapAlloc(GetProcessHeap(), 0, size
* sizeof(WCHAR
));
110 size
= SearchPathW(NULL
, filename
, NULL
, size
, realname
, NULL
);
114 output_message(STRING_FILE_NOT_FOUND
, filename
);
115 HeapFree(GetProcessHeap(), 0, realname
);
118 reg_file
= _wfopen(realname
, rb_mode
);
119 if (reg_file
== NULL
)
121 WCHAR regedit
[] = {'r','e','g','e','d','i','t',0};
123 output_message(STRING_CANNOT_OPEN_FILE
, filename
);
124 HeapFree(GetProcessHeap(), 0, realname
);
128 import_registry_file(reg_file
);
131 HeapFree(GetProcessHeap(), 0, realname
);
137 delete_registry_key(argv
[*i
]);
139 case ACTION_EXPORT
: {
140 WCHAR
*filename
= argv
[*i
];
141 WCHAR
*key_name
= argv
[++(*i
)];
143 if (key_name
&& *key_name
)
144 export_registry_key(filename
, key_name
, REG_FORMAT_4
);
146 export_registry_key(filename
, NULL
, REG_FORMAT_4
);
150 output_message(STRING_UNHANDLED_ACTION
);
156 BOOL
ProcessCmdLine(WCHAR
*cmdline
)
160 REGEDIT_ACTION action
= ACTION_ADD
;
162 argv
= CommandLineToArgvW(cmdline
, &argc
);
173 for (i
= 1; i
< argc
; i
++)
175 if (argv
[i
][0] != '/' && argv
[i
][0] != '-')
176 break; /* No flags specified. */
178 if (!argv
[i
][1] && argv
[i
][0] == '-')
179 break; /* '-' is a filename. It indicates we should use stdin. */
181 if (argv
[i
][1] && argv
[i
][2] && argv
[i
][2] != ':')
182 break; /* This is a file path beginning with '/'. */
184 switch (toupperW(argv
[i
][1]))
187 output_message(STRING_USAGE
);
191 action
= ACTION_DELETE
;
194 action
= ACTION_EXPORT
;
206 output_message(STRING_INVALID_SWITCH
, argv
[i
]);
207 output_message(STRING_HELP
);
218 output_message(STRING_NO_FILENAME
);
221 output_message(STRING_NO_REG_KEY
);
224 output_message(STRING_HELP
);
228 for (; i
< argc
; i
++)
229 PerformRegAction(action
, argv
, &i
);