VirtualBox

Changeset 84067 in vbox for trunk/src/VBox/Runtime/win


Ignore:
Timestamp:
Apr 28, 2020 10:53:31 PM (5 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
137646
Message:

IPRT,++: Compress the windows status code info (errmsgwin.cpp) to save space and reduce load time a tiny bit. bugref:9726

Location:
trunk/src/VBox/Runtime/win
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/win/errmsgwin-sorter.cpp

    r84054 r84067  
    3939
    4040
    41 #define ERRMSG_WITH_STRTAB
    42 #ifdef ERRMSG_WITH_STRTAB
    4341/*
    4442 * Include the string table code.
    4543 */
    46 # define BLDPROG_STRTAB_MAX_STRLEN           512
    47 # define BLDPROG_STRTAB_WITH_COMPRESSION
    48 # define BLDPROG_STRTAB_PURE_ASCII
    49 # define BLDPROG_STRTAB_WITH_CAMEL_WORDS
    50 # include <iprt/bldprog-strtab-template.cpp.h>
    51 #endif
     44#define BLDPROG_STRTAB_MAX_STRLEN           512
     45#define BLDPROG_STRTAB_WITH_COMPRESSION
     46#define BLDPROG_STRTAB_PURE_ASCII
     47#define BLDPROG_STRTAB_WITH_CAMEL_WORDS
     48#include <iprt/bldprog-strtab-template.cpp.h>
    5249
    5350
     
    6259
    6360/*********************************************************************************************************************************
    64 *   Defined Constants And Macros                                                                                                 *
     61*   Structures and Typedefs                                                                                                      *
    6562*********************************************************************************************************************************/
    6663typedef long VBOXSTATUSTYPE; /* used by errmsgvboxcomdata.h */
    6764
     65/** Used for raw-input and sorting. */
     66typedef struct RTWINERRMSGINT1
     67{
     68    /** Pointer to the full message string. */
     69    const char     *pszMsgFull;
     70    /** Pointer to the define string. */
     71    const char     *pszDefine;
     72    /** Status code number. */
     73    long            iCode;
     74    /** Set if duplicate. */
     75    bool            fDuplicate;
     76} RTWINERRMSGINT1;
     77typedef RTWINERRMSGINT1 *PRTWINERRMSGINT1;
     78
     79
     80/** This is used when building the string table and printing it. */
     81typedef struct RTWINERRMSGINT2
     82{
     83    /** The full message string. */
     84    BLDPROGSTRING   MsgFull;
     85    /** The define string. */
     86    BLDPROGSTRING   Define;
     87    /** Pointer to the define string. */
     88    const char     *pszDefine;
     89    /** Status code number. */
     90    long            iCode;
     91} RTWINERRMSGINT2;
     92typedef RTWINERRMSGINT2 *PRTWINERRMSGINT2;
     93
    6894
    6995/*********************************************************************************************************************************
    7096*   Global Variables                                                                                                             *
    7197*********************************************************************************************************************************/
    72 static const char *g_pszProgName = "errmsgwin-sorter";
    73 static RTWINERRMSG  g_aStatusMsgs[] =
     98static const char     *g_pszProgName = "errmsgwin-sorter";
     99static RTWINERRMSGINT1 g_aStatusMsgs[] =
    74100{
    75101#if !defined(IPRT_NO_ERROR_DATA) && !defined(DOXYGEN_RUNNING)
     
    79105# endif
    80106#endif
    81     { "Success.", "ERROR_SUCCESS", 0 },
     107    { "Success.", "ERROR_SUCCESS", 0, false },
    82108};
    83109
     
    110136
    111137
    112 /**
    113  * Escapes @a pszString using @a pszBuf as needed.
    114  * @note Duplicated in errmsg-sorter.cpp.
    115  */
    116 static const char *EscapeString(const char *pszString, char *pszBuf, size_t cbBuf)
    117 {
    118     if (strpbrk(pszString, "\n\t\r\"\\") == NULL)
    119         return pszString;
    120 
    121     char *pszDst = pszBuf;
    122     char  ch;
    123     do
    124     {
    125         ch = *pszString++;
    126         switch (ch)
    127         {
    128             default:
    129                 *pszDst++ = ch;
    130                 break;
    131             case '\\':
    132             case '"':
    133                 *pszDst++ = '\\';
    134                 *pszDst++ = ch;
    135                 break;
    136             case '\n':
    137                 *pszDst++ = '\\';
    138                 *pszDst++ = 'n';
    139                 break;
    140             case '\t':
    141                 *pszDst++ = '\\';
    142                 *pszDst++ = 't';
    143                 break;
    144             case '\r':
    145                 break; /* drop it */
    146         }
    147     } while (ch);
    148 
    149     if ((uintptr_t)(pszDst - pszBuf) > cbBuf)
    150         fprintf(stderr, "Escape buffer overrun!\n");
    151 
    152     return pszBuf;
    153 }
    154 
    155 
    156138int main(int argc, char **argv)
    157139{
    158140    /*
    159      * Argument check.
    160      */
    161     if (argc != 1 && argc != 2)
     141     * Parse arguments.
     142     */
     143    enum { kMode_All, kMode_OnlyDefines } enmMode;
     144    if (argc == 3 && strcmp(argv[1], "--all") == 0)
     145        enmMode = kMode_All;
     146    else if (argc == 3 && strcmp(argv[1], "--only-defines") == 0)
     147        enmMode = kMode_OnlyDefines;
     148    else
    162149    {
    163150        fprintf(stderr,
    164151                "syntax error!\n"
    165                 "Usage: %s [outfile]\n", argv[0]);
     152                "Usage: %s <--all|--only-defines> <outfile>\n", argv[0]);
    166153        return RTEXITCODE_SYNTAX;
    167154    }
    168 
    169     /*
    170      * Sort the table.
     155    const char * const pszOutFile = argv[2];
     156
     157    /*
     158     * Sort the table and mark duplicates.
    171159     */
    172160    qsort(g_aStatusMsgs, RT_ELEMENTS(g_aStatusMsgs), sizeof(g_aStatusMsgs[0]), CompareWinErrMsg);
    173161
     162    int rcExit = RTEXITCODE_SUCCESS;
     163    long iPrev = (long)0x80000000;
     164    bool fHaveSuccess = false;
     165    for (size_t i = 0; i < RT_ELEMENTS(g_aStatusMsgs); i++)
     166    {
     167        PRTWINERRMSGINT1 pMsg = &g_aStatusMsgs[i];
     168        if (pMsg->iCode == iPrev && i != 0)
     169        {
     170            pMsg->fDuplicate = true;
     171
     172            if (iPrev == 0)
     173                continue;
     174
     175            PRTWINERRMSGINT1 pPrev = &g_aStatusMsgs[i - 1];
     176            if (strcmp(pMsg->pszDefine, pPrev->pszDefine) == 0)
     177                continue;
     178            rcExit = error("Duplicate value %#lx (%ld) - %s and %s\n",
     179                           (unsigned long)iPrev, iPrev, pMsg->pszDefine, pPrev->pszDefine);
     180        }
     181        else
     182        {
     183            pMsg->fDuplicate = false;
     184            iPrev = pMsg->iCode;
     185            if (iPrev == 0)
     186                fHaveSuccess = true;
     187        }
     188    }
     189    if (!fHaveSuccess)
     190        rcExit = error("No zero / success value in the table!\n");
     191
     192    /*
     193     * Create a string table for it all.
     194     */
     195    BLDPROGSTRTAB StrTab;
     196    if (!BldProgStrTab_Init(&StrTab, RT_ELEMENTS(g_aStatusMsgs) * 3))
     197        return error("Out of memory!\n");
     198
     199    static RTWINERRMSGINT2 s_aStatusMsgs2[RT_ELEMENTS(g_aStatusMsgs)];
     200    size_t                 cStatusMsgs = 0;
     201    for (size_t i = 0; i < RT_ELEMENTS(g_aStatusMsgs); i++)
     202    {
     203        if (!g_aStatusMsgs[i].fDuplicate)
     204        {
     205            s_aStatusMsgs2[cStatusMsgs].iCode     = g_aStatusMsgs[i].iCode;
     206            s_aStatusMsgs2[cStatusMsgs].pszDefine = g_aStatusMsgs[i].pszDefine;
     207            BldProgStrTab_AddStringDup(&StrTab, &s_aStatusMsgs2[cStatusMsgs].Define, g_aStatusMsgs[i].pszDefine);
     208            if (enmMode != kMode_OnlyDefines)
     209                BldProgStrTab_AddStringDup(&StrTab, &s_aStatusMsgs2[cStatusMsgs].MsgFull, g_aStatusMsgs[i].pszMsgFull);
     210            cStatusMsgs++;
     211        }
     212    }
     213
     214    if (!BldProgStrTab_CompileIt(&StrTab, true))
     215        return error("BldProgStrTab_CompileIt failed!\n");
     216
    174217    /*
    175218     * Prepare output file.
    176219     */
    177     int rcExit = RTEXITCODE_FAILURE;
    178     FILE *pOut = stdout;
    179     if (argc > 1)
    180         pOut = fopen(argv[1], "wt");
     220    FILE *pOut = fopen(pszOutFile, "wt");
    181221    if (pOut)
    182222    {
    183 #ifdef ERRMSG_WITH_STRTAB
    184         /*
    185          * String table fun.
    186          */
    187         static BLDPROGSTRING s_aStrings[RT_ELEMENTS(g_aStatusMsgs) * 2];
    188         size_t               iString = 0;
    189         BLDPROGSTRTAB        StrTab;
    190         if (!BldProgStrTab_Init(&StrTab, RT_ELEMENTS(s_aStrings)))
    191             return error("Out of memory!\n");
    192 #endif
    193 
    194223        /*
    195224         * Print the table.
    196225         */
    197         static char s_szMsgTmp[_256K];
    198         long iPrev = (long)0x80000000;
    199         rcExit = RTEXITCODE_SUCCESS;
    200         for (size_t i = 0; i < RT_ELEMENTS(g_aStatusMsgs); i++)
    201         {
    202             PCRTWINERRMSG pMsg = &g_aStatusMsgs[i];
    203 
    204             /* Paranoid ERROR_SUCCESS handling: */
    205             if (pMsg->iCode > 0 && iPrev < 0)
    206                 fprintf(pOut, "/*%#010lx:*/ { \"Success.\", \"ERROR_SUCCESS\", 0 }\n", (unsigned long)0);
    207             else if (pMsg->iCode == 0 && iPrev == 0)
    208                 continue;
    209 
    210             /* Deal with duplicates in a gentle manner: */
    211             if (pMsg->iCode == iPrev && i != 0)
    212             {
    213                 PCRTWINERRMSG pPrev = &g_aStatusMsgs[i - 1];
    214                 if (strcmp(pMsg->pszDefine, pPrev->pszDefine) == 0)
    215                     continue;
    216                 fprintf(stderr, "%s: error: Duplicate value %#lx (%ld) - %s and %s\n",
    217                         argv[0], (unsigned long)iPrev, iPrev, pMsg->pszDefine, pPrev->pszDefine);
    218                 rcExit = RTEXITCODE_FAILURE;
    219             }
    220             iPrev = pMsg->iCode;
    221 
    222 #ifdef ERRMSG_WITH_STRTAB
    223 # if 1
    224             s_aStrings[iString].pszString = strdup(pMsg->pszDefine);
    225             BldProgStrTab_AddString(&StrTab, &s_aStrings[iString]);
    226             iString++;
    227 # endif
    228 # if 0
    229             s_aStrings[iString].pszString = strdup(pMsg->pszMsgFull);
    230             BldProgStrTab_AddString(&StrTab, &s_aStrings[iString]);
    231             iString++;
    232 # endif
    233 #endif
    234 
    235             /* Produce the output: */
    236             fprintf(pOut, "/*%#010lx:*/ ENTRY(\"%s\", \"%s\", %ld),\n", (unsigned long)pMsg->iCode,
    237                     EscapeString(pMsg->pszMsgFull, s_szMsgTmp, sizeof(s_szMsgTmp)), pMsg->pszDefine, pMsg->iCode);
    238         }
     226        fprintf(pOut,
     227                "\n"
     228                "typedef struct RTMSGWINENTRYINT\n"
     229                "{\n"
     230                "    uint32_t offDefine : 20;\n"
     231                "    uint32_t cchDefine : 9;\n"
     232                "%s"
     233                "    int32_t  iCode;\n"
     234                "} RTMSGWINENTRYINT;\n"
     235                "typedef RTMSGWINENTRYINT *PCRTMSGWINENTRYINT;\n"
     236                "\n"
     237                "static const RTMSGWINENTRYINT g_aWinMsgs[] =\n"
     238                "{\n"
     239                ,
     240                enmMode == kMode_All
     241                ? "    uint32_t offMsgFull  : 23;\n"
     242                  "    uint32_t cchMsgFull  : 9;\n" : "");
     243
     244        if (enmMode == kMode_All)
     245            for (size_t i = 0; i < cStatusMsgs; i++)
     246                fprintf(pOut, "/*%#010lx:*/ { %#08x, %3u, %#08x, %3u, %ld },\n",
     247                        s_aStatusMsgs2[i].iCode,
     248                        s_aStatusMsgs2[i].Define.offStrTab,
     249                        (unsigned)s_aStatusMsgs2[i].Define.cchString,
     250                        s_aStatusMsgs2[i].MsgFull.offStrTab,
     251                        (unsigned)s_aStatusMsgs2[i].MsgFull.cchString,
     252                        s_aStatusMsgs2[i].iCode);
     253        else if (enmMode == kMode_OnlyDefines)
     254            for (size_t i = 0; i < cStatusMsgs; i++)
     255                fprintf(pOut, "/*%#010lx:*/ { %#08x, %3u, %ld },\n",
     256                        s_aStatusMsgs2[i].iCode,
     257                        s_aStatusMsgs2[i].Define.offStrTab,
     258                        (unsigned)s_aStatusMsgs2[i].Define.cchString,
     259                        s_aStatusMsgs2[i].iCode);
     260        else
     261            return error("Unsupported message selection (%d)!\n", enmMode);
     262        fprintf(pOut,
     263                "};\n"
     264                "\n");
     265
     266        BldProgStrTab_WriteStringTable(&StrTab, pOut, "static ", "g_", "WinMsgStrTab");
    239267
    240268        /*
    241269         * Close the output file and we're done.
    242270         */
     271        fflush(pOut);
     272        if (ferror(pOut))
     273            rcExit = error("Error writing '%s'!\n", pszOutFile);
    243274        if (fclose(pOut) != 0)
    244         {
    245             fprintf(stderr, "%s: Failed to flush/close '%s' after writing it!\n", argv[0], argv[1]);
    246             rcExit = RTEXITCODE_FAILURE;
    247         }
    248 
    249 #ifdef ERRMSG_WITH_STRTAB
    250         /*
    251          * More string table fun.
    252          */
    253         if (!BldProgStrTab_CompileIt(&StrTab, true))
    254             return error("BldProgStrTab_CompileIt failed!\n");
    255 #endif
     275            rcExit = error("Failed to close '%s' after writing it!\n", pszOutFile);
    256276    }
    257277    else
    258         fprintf(stderr, "%s: Failed to open '%s' for writing!\n", argv[0], argv[1]);
     278        rcExit = error("Failed to open '%s' for writing!\n", pszOutFile);
    259279    return rcExit;
    260280}
  • trunk/src/VBox/Runtime/win/errmsgwin.cpp

    r84063 r84067  
    3535#include <iprt/string.h>
    3636
     37#include <iprt/bldprog-strtab.h>
     38
    3739
    3840/*********************************************************************************************************************************
     
    5557*   Global Variables                                                                                                             *
    5658*********************************************************************************************************************************/
    57 /** Array of messages.
    58  * The data is generated by sed scripts and sorted by errmsgwin-sorter.cpp.
    59  */
    60 static const RTWINERRMSG    g_aStatusMsgs[] =
    61 {
    62 #if !defined(IPRT_NO_ERROR_DATA) && !defined(DOXYGEN_RUNNING)
    63 # include "errmsgwindata-sorted.h"
     59#ifdef IPRT_ERRMSG_DEFINES_ONLY
     60/* Cook data just for VINF_SUCCESS so that code below compiles fine. */
     61static const char            g_achWinStrTabData[] = { "ERROR_SUCCESS" };
     62static const RTBLDPROGSTRTAB g_WinMsgStrTab = { g_achWinStrTabData, sizeof(g_achWinStrTabData) - 1, 0, NULL };
     63static const struct
     64{
     65    int16_t     iCode;
     66    uint8_t     offDefine;
     67    uint8_t     cchDefine;
     68    uint8_t     offMsgFull;
     69    uint8_t     cchMsgFull;
     70} g_aWinMsgs[] =
     71{
     72    { 0, 0, 13, 0, 13, },
     73};
     74#elif defined(IPRT_ERRMSG_DEFINES_ONLY)
     75# include "errmsgwindata-only-defines.h"
    6476#else
    65     { "Success.", "ERROR_SUCCESS", 0 },
    66 #endif
    67 };
    68 
    69 
    70 /** Temporary buffers to format unknown messages in.
    71  * @{
    72  */
    73 static char                 g_aszUnknownStr[8][64];
    74 static RTWINERRMSG          g_aUnknownMsgs[8] =
    75 {
    76     { &g_aszUnknownStr[0][0], &g_aszUnknownStr[0][0], 0 },
    77     { &g_aszUnknownStr[1][0], &g_aszUnknownStr[1][0], 0 },
    78     { &g_aszUnknownStr[2][0], &g_aszUnknownStr[2][0], 0 },
    79     { &g_aszUnknownStr[3][0], &g_aszUnknownStr[3][0], 0 },
    80     { &g_aszUnknownStr[4][0], &g_aszUnknownStr[4][0], 0 },
    81     { &g_aszUnknownStr[5][0], &g_aszUnknownStr[5][0], 0 },
    82     { &g_aszUnknownStr[6][0], &g_aszUnknownStr[6][0], 0 },
    83     { &g_aszUnknownStr[7][0], &g_aszUnknownStr[7][0], 0 },
    84 };
    85 /** Last used index in g_aUnknownMsgs. */
    86 static volatile uint32_t    g_iUnknownMsgs;
    87 /** @} */
     77# include "errmsgwindata-all.h"
     78#endif
    8879
    8980
     
    9182 * Looks up the message table entry for @a rc.
    9283 *
    93  * @returns index into g_aStatusMsgs on success, ~(size_t)0 if not found.
     84 * @returns index into g_aWinMsgs on success, ~(size_t)0 if not found.
    9485 * @param   rc      The status code to locate the entry for.
    9586 */
     
    10091     */
    10192    size_t iStart = 0;
    102     size_t iEnd   = RT_ELEMENTS(g_aStatusMsgs);
     93    size_t iEnd   = RT_ELEMENTS(g_aWinMsgs);
    10394    for (;;)
    10495    {
    10596        size_t i = iStart + (iEnd - iStart) / 2;
    106         long const iCode = g_aStatusMsgs[i].iCode;
     97        long const iCode = g_aWinMsgs[i].iCode;
    10798        if (rc < iCode)
    10899        {
     
    125116
    126117#ifdef RT_STRICT
    127     for (size_t i = 0; i < RT_ELEMENTS(g_aStatusMsgs); i++)
    128         Assert(g_aStatusMsgs[i].iCode != rc);
     118    for (size_t i = 0; i < RT_ELEMENTS(g_aWinMsgs); i++)
     119        Assert(g_aWinMsgs[i].iCode != rc);
    129120#endif
    130121
     
    148139RTDECL(ssize_t) RTErrWinQueryDefine(long rc, char *pszBuf, size_t cbBuf, bool fFailIfUnknown)
    149140{
    150     size_t i = rtErrWinLookup(rc);
    151     if (i != ~(size_t)0)
    152     {
    153         size_t cch = strlen(g_aStatusMsgs[i].pszDefine);
    154         if (cch < cbBuf)
     141    size_t idx = rtErrWinLookup(rc);
     142    if (idx != ~(size_t)0)
     143        return RTBldProgStrTabQueryString(&g_WinMsgStrTab,
     144                                          g_aWinMsgs[idx].offDefine, g_aWinMsgs[idx].cchDefine,
     145                                          pszBuf, cbBuf);
     146
     147    /*
     148     * If FACILITY_WIN32 kind of status, look up the win32 code.
     149     */
     150    if (   SCODE_FACILITY(rc) == FACILITY_WIN32
     151        && (idx = rtErrWinLookup(HRESULT_CODE(rc))) != ~(size_t)0)
     152    {
     153        /* Append the incoming rc, so we know it's not a regular WIN32 status: */
     154        ssize_t cchRet = RTBldProgStrTabQueryString(&g_WinMsgStrTab,
     155                                                    g_aWinMsgs[idx].offDefine, g_aWinMsgs[idx].cchDefine,
     156                                                    pszBuf, cbBuf);
     157        if (cchRet > 0)
    155158        {
    156             memcpy(pszBuf, g_aStatusMsgs[i].pszDefine, cch + 1);
    157             return cch;
    158         }
    159         if (cbBuf)
    160         {
    161             memcpy(pszBuf, g_aStatusMsgs[i].pszDefine, cbBuf);
    162             pszBuf[cbBuf - 1] = '\0';
     159            pszBuf[cchRet++] = '/';
     160            return RTStrFormatU32(pszBuf + cchRet, cbBuf - cchRet, rc, 16, 0, 0, RTSTR_F_SPECIAL);
    163161        }
    164162        return VERR_BUFFER_OVERFLOW;
    165     }
    166 
    167     /*
    168      * If FACILITY_WIN32 kind of status, look up the win32 code.
    169      */
    170     if (   SCODE_FACILITY(rc) == FACILITY_WIN32
    171         && (i = rtErrWinLookup(HRESULT_CODE(rc))) != ~(size_t)0)
    172     {
    173         /* Append the incoming rc, so we know it's not a regular WIN32 status: */
    174         ssize_t cchRet = RTStrPrintf2(pszBuf, cbBuf, "%s/0x%x", g_aStatusMsgs[i].pszDefine, rc);
    175         return cchRet >= 0 ? cchRet : VERR_BUFFER_OVERFLOW;
    176163    }
    177164
     
    185172{
    186173    RT_NOREF(pszTmp, cbTmp);
    187     size_t i = rtErrWinLookup(rc);
    188     if (i != ~(size_t)0)
    189         return pfnOutput(pvArgOutput, g_aStatusMsgs[i].pszDefine, strlen(g_aStatusMsgs[i].pszDefine));
     174    size_t idx = rtErrWinLookup(rc);
     175    if (idx != ~(size_t)0)
     176        return RTBldProgStrTabQueryOutput(&g_WinMsgStrTab,
     177                                          g_aWinMsgs[idx].offDefine, g_aWinMsgs[idx].cchDefine,
     178                                          pfnOutput, pvArgOutput);
    190179
    191180    /*
    192181     * If FACILITY_WIN32 kind of status, look up the win32 code.
    193182     */
    194     if (SCODE_FACILITY(rc) == FACILITY_WIN32)
    195     {
    196         i = rtErrWinLookup(HRESULT_CODE(rc));
    197         if (i != ~(size_t)0)
    198             /* Append the incoming rc, so we know it's not a regular WIN32 status: */
    199             return RTStrFormat(pfnOutput, pvArgOutput, NULL, NULL, "%s/0x%x", g_aStatusMsgs[i].pszDefine, rc);
    200     }
    201 
    202     return RTStrFormat(pfnOutput, pvArgOutput, NULL, NULL, "0x%x", rc);
    203 }
    204 
    205 
    206 RTDECL(size_t)  RTErrWinFormatMsg(   long rc, PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, char *pszTmp, size_t cbTmp)
    207 {
    208     RT_NOREF(pszTmp, cbTmp);
     183    size_t cchRet = 0;
     184    if (   SCODE_FACILITY(rc) == FACILITY_WIN32
     185        && (idx = rtErrWinLookup(HRESULT_CODE(rc))) != ~(size_t)0)
     186    {
     187        /* Append the incoming rc, so we know it's not a regular WIN32 status: */
     188        cchRet  = RTBldProgStrTabQueryOutput(&g_WinMsgStrTab,
     189                                             g_aWinMsgs[idx].offDefine, g_aWinMsgs[idx].cchDefine,
     190                                             pfnOutput, pvArgOutput);
     191        cchRet += pfnOutput(pvArgOutput, RT_STR_TUPLE("/"));
     192    }
     193
     194    ssize_t cchValue = RTStrFormatU32(pszTmp, cbTmp, rc, 16, 0, 0, RTSTR_F_SPECIAL);
     195    Assert(cchValue > 0);
     196    cchRet += pfnOutput(pvArgOutput, pszTmp, cchValue);
     197    return cchRet;
     198}
     199
     200
     201RTDECL(size_t)  RTErrWinFormatMsg(long rc, PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, char *pszTmp, size_t cbTmp)
     202{
    209203#ifdef IPRT_ERRMSG_DEFINES_ONLY
    210204    return RTErrWinFormatDefine(rc, pfnOutput, pvArgOutput, pszTmp, cbTmp);
    211205#else
    212     size_t i = rtErrWinLookup(rc);
    213     if (i != ~(size_t)0)
    214         return pfnOutput(pvArgOutput, g_aStatusMsgs[i].pszMsgFull, strlen(g_aStatusMsgs[i].pszMsgFull));
     206    size_t idx = rtErrWinLookup(rc);
     207    if (idx != ~(size_t)0)
     208        return RTBldProgStrTabQueryOutput(&g_WinMsgStrTab,
     209                                          g_aWinMsgs[idx].offMsgFull, g_aWinMsgs[idx].cchMsgFull,
     210                                          pfnOutput, pvArgOutput);
    215211
    216212    /*
    217213     * If FACILITY_WIN32 kind of status, look up the win32 code.
    218214     */
    219     if (SCODE_FACILITY(rc) == FACILITY_WIN32)
    220     {
    221         i = rtErrWinLookup(HRESULT_CODE(rc));
    222         if (i != ~(size_t)0)
    223             /* Append the incoming rc, so we know it's not a regular WIN32 status: */
    224             return RTStrFormat(pfnOutput, pvArgOutput, NULL, NULL, "%s/0x%x", g_aStatusMsgs[i].pszDefine, rc);
    225     }
    226     return RTStrFormat(pfnOutput, pvArgOutput, NULL, NULL, "Unknown Status 0x%x", rc);
     215    const char *pszTail = NULL;
     216    size_t cchRet;
     217    if (   SCODE_FACILITY(rc) == FACILITY_WIN32
     218        && (idx = rtErrWinLookup(HRESULT_CODE(rc))) != ~(size_t)0)
     219    {
     220        /* Append the incoming rc, so we know it's not a regular WIN32 status: */
     221        cchRet  = RTBldProgStrTabQueryOutput(&g_WinMsgStrTab,
     222                                             g_aWinMsgs[idx].offMsgFull, g_aWinMsgs[idx].cchMsgFull,
     223                                             pfnOutput, pvArgOutput);
     224        cchRet += pfnOutput(pvArgOutput, RT_STR_TUPLE(" ("));
     225        pszTail = ")";
     226    }
     227    else
     228        cchRet  = pfnOutput(pvArgOutput, RT_STR_TUPLE("Unknown Status "));
     229
     230    ssize_t cchValue = RTStrFormatU32(pszTmp, cbTmp, rc, 16, 0, 0, RTSTR_F_SPECIAL);
     231    Assert(cchValue > 0);
     232    cchRet += pfnOutput(pvArgOutput, pszTmp, cchValue);
     233
     234    if (pszTail)
     235        cchRet += pfnOutput(pvArgOutput, pszTail, 1);
     236    return cchRet;
    227237#endif
    228238}
     
    232242{
    233243    RT_NOREF(pszTmp, cbTmp);
    234     size_t i = rtErrWinLookup(rc);
    235     if (i != ~(size_t)0)
    236 #ifdef IPRT_ERRMSG_DEFINES_ONLY
    237         return RTStrFormat(pfnOutput, pvArgOutput, NULL, NULL, "%s (0x%x)", g_aStatusMsgs[i].pszDefine, rc, g_aStatusMsgs[i].pszMsgFull);
    238 #else
    239         return RTStrFormat(pfnOutput, pvArgOutput, NULL, NULL, "%s (0x%x) - %s", g_aStatusMsgs[i].pszDefine, rc, g_aStatusMsgs[i].pszMsgFull);
    240 #endif
    241 
    242     /*
    243      * If FACILITY_WIN32 kind of status, look up the win32 code.
    244      */
    245     if (SCODE_FACILITY(rc) == FACILITY_WIN32)
    246     {
    247         i = rtErrWinLookup(HRESULT_CODE(rc));
    248         if (i != ~(size_t)0)
    249 #ifdef IPRT_ERRMSG_DEFINES_ONLY
    250             return RTStrFormat(pfnOutput, pvArgOutput, NULL, NULL, "%s (0x%x)", g_aStatusMsgs[i].pszDefine, rc, g_aStatusMsgs[i].pszMsgFull);
    251 #else
    252             return RTStrFormat(pfnOutput, pvArgOutput, NULL, NULL, "%s (0x%x) - %s", g_aStatusMsgs[i].pszDefine, rc, g_aStatusMsgs[i].pszMsgFull);
    253 #endif
    254     }
    255     return RTStrFormat(pfnOutput, pvArgOutput, NULL, NULL, "Unknown Status 0x%x", rc);
    256 }
    257 
     244    size_t cchRet;
     245    size_t idx = rtErrWinLookup(rc);
     246    if (   idx != ~(size_t)0
     247        || (   SCODE_FACILITY(rc) == FACILITY_WIN32
     248            && (idx = rtErrWinLookup(HRESULT_CODE(rc))) != ~(size_t)0))
     249    {
     250        cchRet  = RTBldProgStrTabQueryOutput(&g_WinMsgStrTab,
     251                                             g_aWinMsgs[idx].offDefine, g_aWinMsgs[idx].cchDefine,
     252                                             pfnOutput, pvArgOutput);
     253        cchRet += pfnOutput(pvArgOutput, RT_STR_TUPLE(" ("));
     254    }
     255    else
     256        cchRet  = pfnOutput(pvArgOutput, RT_STR_TUPLE("Unknown Status "));
     257
     258    ssize_t cchValue = RTStrFormatU32(pszTmp, cbTmp, rc, 16, 0, 0, RTSTR_F_SPECIAL);
     259    Assert(cchValue > 0);
     260    cchRet += pfnOutput(pvArgOutput, pszTmp, cchValue);
     261
     262#ifndef IPRT_ERRMSG_DEFINES_ONLY
     263    if (idx != ~(size_t)0)
     264    {
     265        cchRet += pfnOutput(pvArgOutput, RT_STR_TUPLE(" - "));
     266        cchRet += RTBldProgStrTabQueryOutput(&g_WinMsgStrTab,
     267                                             g_aWinMsgs[idx].offMsgFull, g_aWinMsgs[idx].cchMsgFull,
     268                                             pfnOutput, pvArgOutput);
     269    }
     270#endif
     271    return cchRet;
     272}
     273
Note: See TracChangeset for help on using the changeset viewer.

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