1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
|
/** @file
* IPRT - Runtime Init/Term.
*/
/*
* Copyright (C) 2006-2022 Oracle and/or its affiliates.
*
* This file is part of VirtualBox base platform packages, as
* available from https://www.virtualbox.org.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation, in version 3 of the
* License.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <https://www.gnu.org/licenses>.
*
* The contents of this file may alternatively be used under the terms
* of the Common Development and Distribution License Version 1.0
* (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
* in the VirtualBox distribution, in which case the provisions of the
* CDDL are applicable instead of those of the GPL.
*
* You may elect to license modified versions of this file under the
* terms and conditions of either the GPL or the CDDL or both.
*
* SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
*/
#ifndef IPRT_INCLUDED_initterm_h
#define IPRT_INCLUDED_initterm_h
#ifndef RT_WITHOUT_PRAGMA_ONCE
# pragma once
#endif
#include <iprt/cdefs.h>
#include <iprt/types.h>
RT_C_DECLS_BEGIN
/** @defgroup grp_rt IPRT C/C++ APIs
* @{
*/
/** @defgroup grp_rt_initterm RTInit/RTTerm - Initialization and Termination
*
* APIs for initializing and terminating the IPRT, optionally it can also
* convert input arguments to UTF-8 (in ring-3).
*
* @sa RTOnce, RTOnceEx.
*
* @{
*/
#ifdef IN_RING3
/** @name RTR3INIT_FLAGS_XXX - RTR3Init* flags.
* @see RTR3InitExeNoArguments, RTR3InitExe, RTR3InitDll, RTR3InitEx
* @{ */
/** Initializing IPRT from a DLL. */
# define RTR3INIT_FLAGS_DLL RT_BIT(0)
/** The caller ensures that the argument vector is UTF-8. */
# define RTR3INIT_FLAGS_UTF8_ARGV RT_BIT(1)
/** Indicates that this is a standalone application without any additional
* shared libraries in the application directory. Mainly windows loader mess. */
# define RTR3INIT_FLAGS_STANDALONE_APP RT_BIT(2)
/** We are sharing a process space, so we need to behave. */
# define RTR3INIT_FLAGS_UNOBTRUSIVE RT_BIT(3)
/** Initialize SUPLib (must not fail). */
# define RTR3INIT_FLAGS_SUPLIB RT_BIT(16)
/** Try initialize SUPLib and ignore failures. */
# define RTR3INIT_FLAGS_TRY_SUPLIB RT_BIT(17)
/** Shift count for passing thru SUPR3INIT_F_XXX flags. */
# define RTR3INIT_FLAGS_SUPLIB_SHIFT 18
/** The mask covering the passthru SUPR3INIT_F_XXX flags. */
# define RTR3INIT_FLAGS_SUPLIB_MASK UINT32_C(0xfffc0000)
/** Valid flag mask. */
# define RTR3INIT_FLAGS_VALID_MASK UINT32_C(0xffff000f)
/** @} */
/** @name RTR3InitEx version
* @{ */
/** Version 1. */
# define RTR3INIT_VER_1 UINT32_C(1)
/** Version 2 - new flags, rearranged a bit. */
# define RTR3INIT_VER_2 UINT32_C(2)
/** The current version. */
# define RTR3INIT_VER_CUR RTR3INIT_VER_2
/** @} */
/**
* Initializes the runtime library.
*
* @returns iprt status code.
* @param fFlags Flags, see RTR3INIT_FLAGS_XXX.
*/
RTR3DECL(int) RTR3InitExeNoArguments(uint32_t fFlags);
/**
* Initializes the runtime library.
*
* @returns iprt status code.
* @param cArgs Pointer to the argument count.
* @param ppapszArgs Pointer to the argument vector pointer.
* @param fFlags Flags, see RTR3INIT_FLAGS_XXX.
*/
RTR3DECL(int) RTR3InitExe(int cArgs, char ***ppapszArgs, uint32_t fFlags);
/**
* Initializes the runtime library.
*
* @returns iprt status code.
* @param fFlags Flags, see RTR3INIT_FLAGS_XXX.
*/
RTR3DECL(int) RTR3InitDll(uint32_t fFlags);
/**
* Initializes the runtime library and possibly also SUPLib too.
*
* Avoid this interface, it's not considered stable.
*
* @returns IPRT status code.
* @param iVersion The interface version. Must be 0 atm.
* @param fFlags Flags, see RTR3INIT_FLAGS_XXX.
* @param cArgs Pointer to the argument count.
* @param ppapszArgs Pointer to the argument vector pointer. NULL
* allowed if @a cArgs is 0.
* @param pszProgramPath The program path. Pass NULL if we're to figure it
* out ourselves.
*/
RTR3DECL(int) RTR3InitEx(uint32_t iVersion, uint32_t fFlags, int cArgs, char ***ppapszArgs, const char *pszProgramPath);
/**
* Terminates the runtime library.
*/
RTR3DECL(void) RTR3Term(void);
/**
* Is IPRT succesfully initialized?
*
* @returns true/false.
*/
RTR3DECL(bool) RTR3InitIsInitialized(void);
/**
* Are we running in unobtrusive mode?
* @returns true/false.
*/
RTR3DECL(bool) RTR3InitIsUnobtrusive(void);
#endif /* IN_RING3 */
#ifdef IN_RING0
/**
* Initializes the ring-0 driver runtime library.
*
* @returns iprt status code.
* @param fReserved Flags reserved for the future.
*/
RTR0DECL(int) RTR0Init(unsigned fReserved);
/**
* Terminates the ring-0 driver runtime library.
*/
RTR0DECL(void) RTR0Term(void);
/**
* Forcibily terminates the ring-0 driver runtime library.
*
* This should be used when statically linking the IPRT. Module using dynamic
* linking shall use RTR0Term. If you're not sure, use RTR0Term!
*/
RTR0DECL(void) RTR0TermForced(void);
#endif
#ifdef IN_RC
/**
* Initializes the raw-mode context runtime library.
*
* @returns iprt status code.
*
* @param u64ProgramStartNanoTS The startup timestamp.
*/
RTRCDECL(int) RTRCInit(uint64_t u64ProgramStartNanoTS);
/**
* Terminates the raw-mode context runtime library.
*/
RTRCDECL(void) RTRCTerm(void);
#endif
/**
* Termination reason.
*/
typedef enum RTTERMREASON
{
/** Normal exit. iStatus contains the exit code. */
RTTERMREASON_EXIT = 1,
/** Any abnormal exit. iStatus is 0 and has no meaning. */
RTTERMREASON_ABEND,
/** Killed by a signal. The iStatus contains the signal number. */
RTTERMREASON_SIGNAL,
/** The IPRT module is being unloaded. iStatus is 0 and has no meaning. */
RTTERMREASON_UNLOAD
} RTTERMREASON;
/** Whether lazy clean up is Okay or not.
* When the process is exiting, it is a waste of time to for instance free heap
* memory or close open files. OTOH, when the runtime is unloaded from the
* process, it is important to release absolutely all resources to prevent
* resource leaks. */
#define RTTERMREASON_IS_LAZY_CLEANUP_OK(enmReason) ((enmReason) != RTTERMREASON_UNLOAD)
/**
* IPRT termination callback function.
*
* @param enmReason The cause of the termination.
* @param iStatus The meaning of this depends on enmReason.
* @param pvUser User argument passed to RTTermRegisterCallback.
*/
typedef DECLCALLBACKTYPE(void, FNRTTERMCALLBACK,(RTTERMREASON enmReason, int32_t iStatus, void *pvUser));
/** Pointer to an IPRT termination callback function. */
typedef FNRTTERMCALLBACK *PFNRTTERMCALLBACK;
/**
* Registers a termination callback.
*
* This is intended for performing clean up during IPRT termination. Frequently
* paired with lazy initialization thru RTOnce.
*
* The callbacks are called in LIFO order.
*
* @returns IPRT status code.
*
* @param pfnCallback The callback function.
* @param pvUser The user argument for the callback.
*
* @remarks May need to acquire a fast mutex or critical section, so use with
* some care in ring-0 context.
*
* @remarks Be very careful using this from code that may be unloaded before
* IPRT terminates. Unlike some atexit and on_exit implementations,
* IPRT will not automatically unregister callbacks when a module gets
* unloaded.
*/
RTDECL(int) RTTermRegisterCallback(PFNRTTERMCALLBACK pfnCallback, void *pvUser);
/**
* Deregister a termination callback.
*
* @returns VINF_SUCCESS if found, VERR_NOT_FOUND if the callback/pvUser pair
* wasn't found.
*
* @param pfnCallback The callback function.
* @param pvUser The user argument for the callback.
*/
RTDECL(int) RTTermDeregisterCallback(PFNRTTERMCALLBACK pfnCallback, void *pvUser);
/**
* Runs the termination callback queue.
*
* Normally called by an internal IPRT termination function, but may also be
* called by external code immediately prior to terminating IPRT if it is in a
* better position to state the termination reason and/or status.
*
* @param enmReason The reason why it's called.
* @param iStatus The associated exit status or signal number.
*/
RTDECL(void) RTTermRunCallbacks(RTTERMREASON enmReason, int32_t iStatus);
/** @} */
/** @} */
RT_C_DECLS_END
#endif /* !IPRT_INCLUDED_initterm_h */
|