Win32 APIの一部関数で実行結果を表す戻り値の型に使われるNTSTATUS
型の覚書です。
C++
C++で使用する場合の情報です。
定義
ntstatus.hで32ビット符号付き整数(int)のエイリアスとして定義されます1。Win32 Errorのint
型、HRESULT
もintなので相互に代入可能ですが、ビット単位の扱いは異なります。
typedef LONG NTSTATUS;
関連ヘッダーファイル
C++では次のヘッダーをインクルードして使用できます。
- ntdef.h
- ntstatus.h
状態判定
NTSTATUS
型にはビットマスクを用いたいくつかの状態が定義されており、次のマクロで確認できます。
- NT_SUCCESS(x)
- NT_INFORMATION(x)
- NT_WARNING(x)
- NT_ERROR(x)
Win32エラーコード、HRESULTとの変換
Win32エラーコードおよびHRESULT型とはマクロや関数を使用することで相互変換できます。
変換 | マクロ・関数 | ヘッダー |
---|---|---|
NTSTATUS → HRESULT | HRESULT_FROM_NT(x)1 | winerror.h |
NTSTATUS → Win32 Error | RtlNtStatusToDosError(Status)1 | winternl.h |
Win32 Error → NTSTATUS | NTSTATUS_FROM_WIN32(x) | ntstatus.h |
HRESULT
からNTSTATUS
を取得するにはHRESULT
をWin32 Errorに変換する必要があります。MAKE_HRESULT
やHRESULT_CODE
を組み合わせることで実装可能とのことです。
C#
状態判定
マクロを関数へ移植することで実装できます。
public static partial class NTStatusUtility { public static bool IsSuccess(int status) => status >= 0; public static bool IsInformation(int status) => (status >> 30) == 1; public static bool IsWarning(int status) => (status >> 30) == 2; public static bool IsError(int status) => (status >> 30) == 3; }
HRESULTへの変換
HRESULT_FROM_NTマクロを関数へ移植して実装できます。
public static partial class NTStatusUtility { public static int HResultFromNTStatus(int status) { const int FACILITY_NT_BIT = 0x10000000; return status | FACILITY_NT_BIT; } }
例外クラス
COMException
クラスを継承した例外クラスを作成します。NTStatusUtility
クラスを使用する場合はこのクラスでHResultFromNTStatus
を定義する必要はありません。
public sealed class NTStatusException : COMException { public NTStatusException() : base() { Status = 0; } public NTStatusException(int status) : base(null, HResultFromNTStatus(status)) { Status = status; } public NTStatusException(string message, int status) : base(message, HResultFromNTStatus(status)) { Status = status; } public NTStatusException(string message, Exception inner) : base(message, inner) { Status = 0; } public NTStatusException(string message) : base(message) { Status = 0; } public readonly int Status; private static int HResultFromNTStatus(int status) { const int FACILITY_NT_BIT = 0x10000000; return status | FACILITY_NT_BIT; } }