1/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
2/* If you are missing that file, acquire a complete release at teeworlds.com. */
3
4#ifndef BASE_WINDOWS_H
5#define BASE_WINDOWS_H
6
7#include "detect.h"
8
9#if defined(CONF_FAMILY_WINDOWS)
10
11#include <cstdint>
12#include <optional>
13#include <string>
14
15/**
16 * Windows-specific functionality.
17 *
18 * @defgroup Windows Windows
19 */
20
21/**
22 * Formats a Windows error code as a human-readable string.
23 *
24 * @ingroup Windows
25 *
26 * @param error The Windows error code.
27 *
28 * @return A new std::string representing the error code.
29 */
30std::string windows_format_system_message(unsigned long error);
31
32/**
33 * Converts an array of arguments into a wide string with proper escaping for Windows command-line usage.
34 *
35 * @ingroup Windows
36 *
37 * @param arguments Array of arguments.
38 * @param num_arguments The number of arguments.
39 *
40 * @return Wide string of arguments with escaped quotes.
41 */
42std::wstring windows_args_to_wide(const char **arguments, size_t num_arguments);
43
44/**
45 * Converts a UTF-8 encoded string to a wide character string
46 * for use with the Windows API.
47 *
48 * @ingroup Windows
49 *
50 * @param str The UTF-8 encoded string to convert.
51 *
52 * @return The argument as a wide character string.
53 *
54 * @remark The strings are treated as null-terminated strings.
55 * @remark Fails with assertion error if passed UTF-8 is invalid.
56 */
57std::wstring windows_utf8_to_wide(const char *str);
58
59/**
60 * Converts a wide character string obtained from the Windows API
61 * to a UTF-8 encoded string.
62 *
63 * @ingroup Windows
64 *
65 * @param wide_str The wide character string to convert.
66 *
67 * @return The argument as a UTF-8 encoded string, wrapped in an optional.
68 * The optional is empty, if the wide string contains invalid codepoints.
69 *
70 * @remark The strings are treated as null-terminated strings.
71 */
72std::optional<std::string> windows_wide_to_utf8(const wchar_t *wide_str);
73
74/**
75 * This is a RAII wrapper to initialize/uninitialize the Windows COM library,
76 * which may be necessary for using the @link open_file @endlink and
77 * @link open_link @endlink functions.
78 * Must be used on every thread. It's automatically used on threads created
79 * with @link thread_init @endlink. Pass `true` to the constructor on threads
80 * that own a window (i.e. pump a message queue).
81 *
82 * @ingroup Windows
83 */
84class CWindowsComLifecycle
85{
86public:
87 CWindowsComLifecycle(bool HasWindow);
88 ~CWindowsComLifecycle();
89 CWindowsComLifecycle(const CWindowsComLifecycle &) = delete;
90};
91
92/**
93 * Registers a protocol handler.
94 *
95 * @ingroup Windows
96 *
97 * @param protocol_name The name of the protocol.
98 * @param executable The absolute path of the executable that will be associated with the protocol.
99 * @param updated Pointer to a variable that will be set to `true`, iff the shell needs to be updated.
100 *
101 * @return `true` on success, `false` on failure.
102 *
103 * @remark The caller must later call @link shell_update @endlink, iff the shell needs to be updated.
104 */
105bool windows_shell_register_protocol(const char *protocol_name, const char *executable, bool *updated);
106
107/**
108 * Registers a file extension.
109 *
110 * @ingroup Windows
111 *
112 * @param extension The file extension, including the leading dot.
113 * @param description A readable description for the file extension.
114 * @param executable_name A unique name that will used to describe the application.
115 * @param executable The absolute path of the executable that will be associated with the file extension.
116 * @param updated Pointer to a variable that will be set to `true`, iff the shell needs to be updated.
117 *
118 * @return `true` on success, `false` on failure.
119 *
120 * @remark The caller must later call @link shell_update @endlink, iff the shell needs to be updated.
121 */
122bool windows_shell_register_extension(const char *extension, const char *description, const char *executable_name, const char *executable, bool *updated);
123
124/**
125 * Registers an application.
126 *
127 * @ingroup Windows
128 *
129 * @param name Readable name of the application.
130 * @param executable The absolute path of the executable being registered.
131 * @param updated Pointer to a variable that will be set to `true`, iff the shell needs to be updated.
132 *
133 * @return `true` on success, `false` on failure.
134 *
135 * @remark The caller must later call @link shell_update @endlink, iff the shell needs to be updated.
136 */
137bool windows_shell_register_application(const char *name, const char *executable, bool *updated);
138
139/**
140 * Unregisters a protocol or file extension handler.
141 *
142 * @ingroup Windows
143 *
144 * @param shell_class The shell class to delete.
145 * For protocols this is the name of the protocol.
146 * For file extensions this is the program ID associated with the file extension.
147 * @param updated Pointer to a variable that will be set to `true`, iff the shell needs to be updated.
148 *
149 * @return `true` on success, `false` on failure.
150 *
151 * @remark The caller must later call @link shell_update @endlink, iff the shell needs to be updated.
152 */
153bool windows_shell_unregister_class(const char *shell_class, bool *updated);
154
155/**
156 * Unregisters an application.
157 *
158 * @ingroup Windows
159 *
160 * @param executable The absolute path of the executable being unregistered.
161 * @param updated Pointer to a variable that will be set to `true`, iff the shell needs to be updated.
162 *
163 * @return `true` on success, `false` on failure.
164 *
165 * @remark The caller must later call @link shell_update @endlink, iff the shell needs to be updated.
166 */
167bool windows_shell_unregister_application(const char *executable, bool *updated);
168
169/**
170 * Notifies the system that a protocol or file extension has been changed and the shell needs to be updated.
171 *
172 * @ingroup Windows
173 *
174 * @remark This is a potentially expensive operation, so it should only be called when necessary.
175 */
176void windows_shell_update();
177
178#endif
179
180#endif
181