VirtualBox

source: vbox/trunk/src/VBox/Runtime/win/errmsgwin.cpp@ 96164

Last change on this file since 96164 was 96164, checked in by vboxsync, 3 years ago

IPRT/errmsgwin.cpp: Made IPRT_ERRMSG_DEFINES_ONLY only option next to IPRT_NO_ERROR_DATA.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 7.7 KB
Line 
1/* $Id: errmsgwin.cpp 96164 2022-08-12 11:40:11Z vboxsync $ */
2/** @file
3 * IPRT - Status code messages, Windows.
4 */
5
6/*
7 * Copyright (C) 2006-2022 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.215389.xyz. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#include <iprt/win/windows.h>
32
33#include <iprt/errcore.h>
34#include <iprt/asm.h>
35#include <iprt/string.h>
36
37#include <iprt/bldprog-strtab.h>
38
39
40/*********************************************************************************************************************************
41* Defined Constants And Macros *
42*********************************************************************************************************************************/
43#define ENTRY(a_pszMsg, a_pszDefine, a_iCode) \
44 { a_pszDefine, a_pszDefine, a_iCode }
45
46
47/*********************************************************************************************************************************
48* Global Variables *
49*********************************************************************************************************************************/
50#ifdef IPRT_NO_ERROR_DATA
51/* Cook data just for VINF_SUCCESS so that code below compiles fine. */
52static const char g_achWinStrTabData[] = { "ERROR_SUCCESS" };
53static const RTBLDPROGSTRTAB g_WinMsgStrTab = { g_achWinStrTabData, sizeof(g_achWinStrTabData) - 1, 0, NULL };
54static const struct
55{
56 int16_t iCode;
57 uint8_t offDefine;
58 uint8_t cchDefine;
59 uint8_t offMsgFull;
60 uint8_t cchMsgFull;
61} g_aWinMsgs[] =
62{
63 { 0, 0, 13, 0, 13, },
64};
65#else
66# include "errmsgwindata-only-defines.h"
67#endif
68
69
70/**
71 * Looks up the message table entry for @a rc.
72 *
73 * @returns index into g_aWinMsgs on success, ~(size_t)0 if not found.
74 * @param rc The status code to locate the entry for.
75 */
76static size_t rtErrWinLookup(long rc)
77{
78 /*
79 * Perform binary search (duplicate code in rtErrLookup).
80 */
81 size_t iStart = 0;
82 size_t iEnd = RT_ELEMENTS(g_aWinMsgs);
83 for (;;)
84 {
85 size_t i = iStart + (iEnd - iStart) / 2;
86 long const iCode = g_aWinMsgs[i].iCode;
87 if (rc < iCode)
88 {
89 if (iStart < i)
90 iEnd = i;
91 else
92 break;
93 }
94 else if (rc > iCode)
95 {
96 i++;
97 if (i < iEnd)
98 iStart = i;
99 else
100 break;
101 }
102 else
103 return i;
104 }
105
106#ifdef RT_STRICT
107 for (size_t i = 0; i < RT_ELEMENTS(g_aWinMsgs); i++)
108 Assert(g_aWinMsgs[i].iCode != rc);
109#endif
110
111 return ~(size_t)0;
112}
113
114
115RTDECL(bool) RTErrWinIsKnown(long rc)
116{
117 if (rtErrWinLookup(rc) != ~(size_t)0)
118 return true;
119 if (SCODE_FACILITY(rc) == FACILITY_WIN32)
120 {
121 if (rtErrWinLookup(HRESULT_CODE(rc)) != ~(size_t)0)
122 return true;
123 }
124 return false;
125}
126
127
128RTDECL(ssize_t) RTErrWinQueryDefine(long rc, char *pszBuf, size_t cbBuf, bool fFailIfUnknown)
129{
130 size_t idx = rtErrWinLookup(rc);
131 if (idx != ~(size_t)0)
132 return RTBldProgStrTabQueryString(&g_WinMsgStrTab,
133 g_aWinMsgs[idx].offDefine, g_aWinMsgs[idx].cchDefine,
134 pszBuf, cbBuf);
135
136 /*
137 * If FACILITY_WIN32 kind of status, look up the win32 code.
138 */
139 if ( SCODE_FACILITY(rc) == FACILITY_WIN32
140 && (idx = rtErrWinLookup(HRESULT_CODE(rc))) != ~(size_t)0)
141 {
142 /* Append the incoming rc, so we know it's not a regular WIN32 status: */
143 ssize_t cchRet = RTBldProgStrTabQueryString(&g_WinMsgStrTab,
144 g_aWinMsgs[idx].offDefine, g_aWinMsgs[idx].cchDefine,
145 pszBuf, cbBuf);
146 if (cchRet > 0)
147 {
148 pszBuf[cchRet++] = '/';
149 return RTStrFormatU32(pszBuf + cchRet, cbBuf - cchRet, rc, 16, 0, 0, RTSTR_F_SPECIAL);
150 }
151 return VERR_BUFFER_OVERFLOW;
152 }
153
154 if (fFailIfUnknown)
155 return VERR_NOT_FOUND;
156 return RTStrFormatU32(pszBuf, cbBuf, rc, 16, 0, 0, RTSTR_F_SPECIAL);
157}
158
159
160RTDECL(size_t) RTErrWinFormatDefine(long rc, PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, char *pszTmp, size_t cbTmp)
161{
162 RT_NOREF(pszTmp, cbTmp);
163 size_t idx = rtErrWinLookup(rc);
164 if (idx != ~(size_t)0)
165 return RTBldProgStrTabQueryOutput(&g_WinMsgStrTab,
166 g_aWinMsgs[idx].offDefine, g_aWinMsgs[idx].cchDefine,
167 pfnOutput, pvArgOutput);
168
169 /*
170 * If FACILITY_WIN32 kind of status, look up the win32 code.
171 */
172 size_t cchRet = 0;
173 if ( SCODE_FACILITY(rc) == FACILITY_WIN32
174 && (idx = rtErrWinLookup(HRESULT_CODE(rc))) != ~(size_t)0)
175 {
176 /* Append the incoming rc, so we know it's not a regular WIN32 status: */
177 cchRet = RTBldProgStrTabQueryOutput(&g_WinMsgStrTab,
178 g_aWinMsgs[idx].offDefine, g_aWinMsgs[idx].cchDefine,
179 pfnOutput, pvArgOutput);
180 cchRet += pfnOutput(pvArgOutput, RT_STR_TUPLE("/"));
181 }
182
183 ssize_t cchValue = RTStrFormatU32(pszTmp, cbTmp, rc, 16, 0, 0, RTSTR_F_SPECIAL);
184 Assert(cchValue > 0);
185 cchRet += pfnOutput(pvArgOutput, pszTmp, cchValue);
186 return cchRet;
187}
188
189
190RTDECL(size_t) RTErrWinFormatMsg(long rc, PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, char *pszTmp, size_t cbTmp)
191{
192 return RTErrWinFormatDefine(rc, pfnOutput, pvArgOutput, pszTmp, cbTmp);
193}
194
195
196RTDECL(size_t) RTErrWinFormatMsgAll(long rc, PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, char *pszTmp, size_t cbTmp)
197{
198 RT_NOREF(pszTmp, cbTmp);
199 size_t cchRet;
200 size_t idx = rtErrWinLookup(rc);
201 if ( idx != ~(size_t)0
202 || ( SCODE_FACILITY(rc) == FACILITY_WIN32
203 && (idx = rtErrWinLookup(HRESULT_CODE(rc))) != ~(size_t)0))
204 {
205 cchRet = RTBldProgStrTabQueryOutput(&g_WinMsgStrTab,
206 g_aWinMsgs[idx].offDefine, g_aWinMsgs[idx].cchDefine,
207 pfnOutput, pvArgOutput);
208 cchRet += pfnOutput(pvArgOutput, RT_STR_TUPLE(" ("));
209 }
210 else
211 cchRet = pfnOutput(pvArgOutput, RT_STR_TUPLE("Unknown Status "));
212
213 ssize_t cchValue = RTStrFormatU32(pszTmp, cbTmp, rc, 16, 0, 0, RTSTR_F_SPECIAL);
214 Assert(cchValue > 0);
215 cchRet += pfnOutput(pvArgOutput, pszTmp, cchValue);
216
217 return cchRet;
218}
219
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette