WinApiErrの概要 - inoueshinichi/Wiki_Windows GitHub Wiki

参考

Windows API Error (システムエラー)

範囲 URL
0-499 https://learn.microsoft.com/ja-jp/windows/win32/debug/system-error-codes--0-499-
500-999 https://learn.microsoft.com/ja-jp/windows/win32/debug/system-error-codes--500-999-
1000-1299 https://learn.microsoft.com/ja-jp/windows/win32/debug/system-error-codes--1000-1299-
1300-1699 https://learn.microsoft.com/ja-jp/windows/win32/debug/system-error-codes--1300-1699-
1700-3999 https://learn.microsoft.com/ja-jp/windows/win32/debug/system-error-codes--1700-3999-
4000-5999 https://learn.microsoft.com/ja-jp/windows/win32/debug/system-error-codes--4000-5999-
6000-8199 https://learn.microsoft.com/ja-jp/windows/win32/debug/system-error-codes--6000-8199-
8200-8999 https://learn.microsoft.com/ja-jp/windows/win32/debug/system-error-codes--8200-8999-
9000-11999 https://learn.microsoft.com/ja-jp/windows/win32/debug/system-error-codes--9000-11999-
12000-15999 https://learn.microsoft.com/ja-jp/windows/win32/debug/system-error-codes--12000-15999-

プログラム例

#pragma once
#include <framework.hpp>
#include <defs.hpp>
#include <format_string.hpp>

#include <cstdio>  // std::snprintf
#include <cstdlib> // std::abort
#include <vector>
#include <exception>
#include <iostream>
#include <sstream>
#include <string>

namespace is
{
    /* Windows-APIに関する例外スロー */
#define IS_WIN_API_ERROR(winErrorCode, msg, ...)                                      \
    throw WinApiException(winErrorCode, is::FormatString(msg, ##__VA_ARGS__), \
                          __func__, __FILE__, __LINE__);

#define IS_WIN_API_CHECK(winErrorCode, msg, ...)                                                        \
    if (winErrorCode != NO_ERROR)                                                                       \
    {                                                                                                   \
        IS_COM_HR_ERROR(winErrorCode, std::string("Failed `" #winErrorCode "`: ") + msg, ##__VA_ARGS__) \
    }

#define IS_WIN_API_FORCE_ASSERT(winErrorCode, msg, ...)                           \
    if (winErrorCode != NO_ERROR)                                                 \
    {                                                                             \
        std::cerr << "Aborting: " << is::FormatString(msg, ##__VA_ARGS__)         \
                  << " at " << __func__                                           \
                  << " in " << __FILE__                                           \
                  << ":" << __LINE__                                              \
                  << std::endl;                                                   \
        std::abort();                                                             \
    }

    /**
     * @brief Win32API Error を取得する
     * http://yamatyuu.net/computer/program/sdk/base/errmsg1/index.html
     * @return CString
     * errorCode returned from ::GetLastError()
     */
    inline CString GetWinApiErrorString(DWORD errorCode)
    {
        LPVOID lpMsgBuf;
        DWORD dwChars; // Number of chars returns;

        /**
         * DWORD FormatMessage(
         *  DWORD dwFlags,      // 入力元と処理方法のオプション
         *  LPCVOID lpSource,   // メッセージの入力元
         *  DWORD dwMessageId,  // メッセージ識別子
         *  DWORD dwLanguageId, // 言語識別子
         *  LPTSTR lpBuffer,    // メッセージバッファ
         *  DOWRD nSize,        // メッセージバッファの最大サイズ
         *  va_list* Arguments  // 複数のメッセージ挿入シーケンスからなる配列
         * )
         */
        dwChars = ::FormatMessage(
            FORMAT_MESSAGE_ALLOCATE_BUFFER |   // テキストのメモリ割り当てを要求
            FORMAT_MESSAGE_FROM_SYSTEM |       // エラーメッセージはWindowsが用意しているものを使用
            FORMAT_MESSAGE_IGNORE_INSERTS,     // 次の引数を無視してエラーコードに対するエラーメッセージを作成する
            NULL,
            errorCode,
            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // 言語(日本語)を設定
            (LPTSTR)&lpMsgBuf,                         // メッセージテキストが保存されるバッファへのポインタ
            0,
            NULL);

        if (dwChars == 0)
        {
            // The error code did not exist in the system errors.
            // Try Ntdsbmsg.dll for the error code.
            HINSTANCE hInstance;

            // Load the library.
            hInstance = LoadLibrary(_T("Ntdsbmsg.dll"));
            if (hInstance == NULL)
            {
                _tprintf(_T("Can not load Ntdsbmsg.dll\n"));
                std::abort();
            }

            dwChars = ::FormatMessage(
                FORMAT_MESSAGE_ALLOCATE_BUFFER |
                    FORMAT_MESSAGE_FROM_SYSTEM |
                    FORMAT_MESSAGE_IGNORE_INSERTS,
                NULL,
                errorCode,
                MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // 言語(日本語)を設定
                (LPTSTR)&lpMsgBuf,
                0,
                NULL);
        }

        // コピー
        CString errorMsg((LPTSTR)&lpMsgBuf);

        // ヒープメモリ解放
        LocalFree(lpMsgBuf);

        return errorMsg;
    }

    class IS_WIN_API WinApiException : public std::exception
    {
    protected:
        ATL::CString mFullMsg; // 表示されるFullメッセージ
        std::string mMsg;      // エラーメッセージ
        std::string mFunc;     // エラーが発生した関数名
        std::string mFile;     // エラーが発生したファイル名
        int mLine;             // エラーが発生した行番号

        DWORD mWinApiErrorCode;

    public:
        WinApiException(DWORD winApiErrorCode, const std::string &msg, const std::string &func, const std::string &file, int line)
            : mWinApiErrorCode(winApiErrorCode), mMsg(msg), mFunc(func), mFile(file), mLine(line)
        {
#if (defined(UNICODE) || defined(_UNICODE)) && !defined(_MBCS)
            std::wostringstream woss;
            woss << GetWinApiErrorString(mWinApiErrorCode).GetString() << L" in "
                 << is::CvtShiftJisToUtf16(mFunc) << L":" << mLine << std::endl;
            woss << is::CvtShiftJisToUtf16(mMsg) << std::endl;
            mFullMsg = woss.str().c_str();
#else
            std::ostringstream oss;
            oss << GetWinApiErrorString(mWinApiErrorCode).GetString() << " in "
                << mFunc << ":" << mLine << std::endl;
            oss << mMsg << std::endl;
            mFullMsg = oss.str().c_str();
#endif
        }

        virtual ~WinApiException() noexcept {}
        virtual const TCHAR *What() const noexcept { return mFullMsg.GetString(); }
        DWORD GetWinError() const { return mWinApiErrorCode; }
    };
}
⚠️ **GitHub.com Fallback** ⚠️