Skip to content

Commit 6fc7f87

Browse files
committed
[MSGTRANS]
- Add support for NTSTATUS to Win32 error code conversion - Allow codes to be looked up via #define value as well as numeric
1 parent 8a9417b commit 6fc7f87

File tree

6 files changed

+193
-34
lines changed

6 files changed

+193
-34
lines changed

MsgTrans.Library/Command.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,10 @@ public Command(MessageTranslator msgTrans)
5252
}
5353

5454
protected void AddMessage(MessageType msgType,
55-
long dec,
56-
string hex,
57-
string code,
58-
string msg)
55+
long dec,
56+
string hex,
57+
string code,
58+
string msg)
5959
{
6060
MsgType = msgType;
6161
Number = dec;

MsgTrans.Library/MsgTrans.Library.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
<Compile Include="bugcheck.cs" />
6666
<Compile Include="BugCommand.cs" />
6767
<Compile Include="CustomCommand.cs" />
68+
<Compile Include="NtStatusToWin32.cs" />
6869
<Compile Include="XmlCommand.cs" />
6970
<Compile Include="ErrorCommand.cs" />
7071
<Compile Include="HresultCommand.cs" />

MsgTrans.Library/MsgTrans.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ public enum MessageType
3636
BugUrl = 5,
3737
//
3838
// Summary:
39+
// NTSTATUS to Win32 code conversion
40+
NtStatusToDos = 5,
41+
//
42+
// Summary:
3943
// a custom Check code
4044
Custom = 6
4145
}
@@ -81,6 +85,7 @@ public MessageTranslator(IMsgOutput msgOutput,
8185
bugcheckXml));
8286
commands.Add(new WMCommand(this, wmXml));
8387
commands.Add(new BugCommand(this, bugUrl));
88+
commands.Add(new NtStatusToWin32(this, ntstatusXml, winerrorXml));
8489
}
8590

8691
public bool ParseCommandMessage(MessageContext context,

MsgTrans.Library/NtStatusCommand.cs

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,31 +26,35 @@ public override bool Handle(MessageContext context,
2626
return false;
2727
}
2828

29+
long dec;
30+
string hex;
2931
NumberParser np = new NumberParser();
30-
if (!np.Parse(ntstatusText))
32+
if (np.Parse(ntstatusText))
3133
{
32-
return false;
34+
dec = np.Decimal;
35+
hex = np.Hex;
3336
}
34-
35-
string description = GetNtstatusDescription(np.Decimal);
37+
else
38+
{
39+
dec = GetNtStatusNumber(ntstatusText);
40+
if (dec == -1)
41+
{
42+
return false;
43+
}
44+
hex = dec.ToString("X");
45+
}
46+
47+
string description = GetNtstatusDescription(dec);
3648
if (description != null)
3749
{
3850
AddMessage(MessageType.NTSTATUS,
39-
np.Decimal,
40-
np.Hex,
51+
dec,
52+
hex,
4153
description,
4254
null);
4355

4456
return true;
45-
}/*
46-
else
47-
{
48-
MsgTrans.MsgOutput.MsgOut(context,
49-
String.Format("I don't know about NTSTATUS {0}.",
50-
ntstatusText));
51-
52-
return false;
53-
}*/
57+
}
5458

5559
return false;
5660
}
@@ -75,5 +79,24 @@ public string GetNtstatusDescription(long ntstatus)
7579
else
7680
return null;
7781
}
82+
83+
private long GetNtStatusNumber(string ntstatus)
84+
{
85+
XmlElement root = base.m_XmlDocument.DocumentElement;
86+
XmlNode node = root.SelectSingleNode(String.Format("Ntstatus[@text='{0}']",
87+
ntstatus));
88+
if (node != null)
89+
{
90+
XmlAttribute value = node.Attributes["value"];
91+
if (value == null)
92+
throw new Exception("Node has no value attribute.");
93+
94+
string hex = value.Value;
95+
96+
return Convert.ToInt64(hex, 16);
97+
}
98+
else
99+
return -1;
100+
}
78101
}
79102
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
using System;
2+
using System.Xml;
3+
using System.Runtime.InteropServices;
4+
5+
namespace MsgTrans.Library
6+
{
7+
public class NtStatusToWin32 : Command
8+
{
9+
NtStatusCommand NtstatusCodes = null;
10+
WinerrorCommand WinerrorCodes = null;
11+
12+
[DllImport("kernel32.dll")]
13+
public static extern IntPtr LoadLibrary(string FileName);
14+
15+
[DllImport("kernel32.dll")]
16+
public static extern IntPtr GetProcAddress(IntPtr hModule, string ProcName);
17+
18+
[DllImport("kernel32.dll")]
19+
public static extern bool FreeLibrary(IntPtr hModule);
20+
21+
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
22+
private delegate ulong fRtlNtStatusToDosError(ulong NtStatusCode);
23+
24+
25+
public NtStatusToWin32(MessageTranslator msgTrans,
26+
string ntstatusXml,
27+
string winerrorXml) :
28+
base(msgTrans)
29+
{
30+
NtstatusCodes = new NtStatusCommand(msgTrans, ntstatusXml);
31+
WinerrorCodes = new WinerrorCommand(msgTrans, winerrorXml);
32+
}
33+
34+
public override string[] AvailableCommands
35+
{
36+
get { return new string[] { "ntstat2dos" }; }
37+
}
38+
39+
public override bool Handle(MessageContext context,
40+
string commandName,
41+
string parameters)
42+
{
43+
string ntstatusText = parameters;
44+
if (ntstatusText.Equals(String.Empty))
45+
{
46+
return false;
47+
}
48+
49+
if (!NtstatusCodes.Handle(context, commandName, parameters))
50+
{
51+
return false;
52+
}
53+
54+
long DosCode = GetDosCodeFromNtstatus(NtstatusCodes.Number);
55+
if (DosCode == 0xFFFFFFFF)
56+
{
57+
return false;
58+
}
59+
60+
if (!WinerrorCodes.Handle(context, commandName, DosCode.ToString()))
61+
{
62+
return false;
63+
}
64+
65+
return true;
66+
}
67+
68+
public override string Help()
69+
{
70+
return "blurgh <value>";
71+
}
72+
73+
private long GetDosCodeFromNtstatus(long ntstatus)
74+
{
75+
ulong DosCode = 0xFFFFFFFF;
76+
IntPtr hModule = LoadLibrary(@"ntdll.dll");
77+
if (hModule != null)
78+
{
79+
IntPtr Address = GetProcAddress(hModule, "RtlNtStatusToDosError");
80+
81+
fRtlNtStatusToDosError RtlNtStatusToDosError =
82+
(fRtlNtStatusToDosError)Marshal.GetDelegateForFunctionPointer(Address,
83+
typeof(fRtlNtStatusToDosError));
84+
85+
DosCode = RtlNtStatusToDosError((ulong)ntstatus);
86+
87+
FreeLibrary(hModule);
88+
89+
}
90+
return (long)DosCode;
91+
}
92+
}
93+
}
94+
95+
96+
/*
97+
DWORD Status;
98+
RTL_NTSTATUS_TO_DOS_ERROR pRtlNtStatusToDosError;
99+
HMODULE hModule = LoadLibraryW(L"ntdll.dll");
100+
if (hModule)
101+
{
102+
pRtlNtStatusToDosError = (RTL_NTSTATUS_TO_DOS_ERROR)GetProcAddress(hModule, "RtlNtStatusToDosError");
103+
104+
#define STATUS_PROCESS_IS_PROTECTED ((NTSTATUS)0xC0000712L)
105+
Status = pRtlNtStatusToDosError(STATUS_PROCESS_IS_PROTECTED);
106+
}
107+
108+
*/

MsgTrans.Library/WinerrorCommand.cs

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -27,32 +27,37 @@ public override bool Handle(MessageContext context,
2727
return false;
2828
}
2929

30+
long dec;
31+
string hex;
3032
NumberParser np = new NumberParser();
31-
if (!np.Parse(winerrorText))
33+
if (np.Parse(winerrorText))
3234
{
33-
return false;
35+
dec = np.Decimal;
36+
hex = np.Hex;
3437
}
35-
36-
string description = GetWinerrorDescription(np.Decimal);
38+
else
39+
{
40+
dec = GetNtStatusNumber(winerrorText);
41+
if (dec == -1)
42+
{
43+
return false;
44+
}
45+
hex = dec.ToString("X");
46+
}
47+
48+
string description = GetWinerrorDescription(dec);
3749
if (description != null)
3850
{
39-
string message = new System.ComponentModel.Win32Exception(Convert.ToInt32(np.Decimal)).Message;
51+
string message = new System.ComponentModel.Win32Exception(Convert.ToInt32(dec)).Message;
4052

4153
AddMessage(MessageType.WinError,
42-
np.Decimal,
43-
np.Hex,
54+
dec,
55+
hex,
4456
description,
4557
message);
4658

4759
return true;
48-
}/*
49-
else
50-
{
51-
MsgTrans.MsgOutput.MsgOut(context,
52-
String.Format("I don't know about System Error Code {0}.",
53-
winerrorText));
54-
return false;
55-
}*/
60+
}
5661

5762
return false;
5863
}
@@ -77,5 +82,22 @@ public string GetWinerrorDescription(long winerror)
7782
else
7883
return null;
7984
}
85+
86+
private long GetNtStatusNumber(string winerrorName)
87+
{
88+
XmlElement root = base.m_XmlDocument.DocumentElement;
89+
XmlNode node = root.SelectSingleNode(String.Format("Winerror[@text='{0}']",
90+
winerrorName));
91+
if (node != null)
92+
{
93+
XmlAttribute value = node.Attributes["value"];
94+
if (value == null)
95+
throw new Exception("Node has no value attribute.");
96+
97+
return Convert.ToInt64(value.Value);
98+
}
99+
else
100+
return -1;
101+
}
80102
}
81103
}

0 commit comments

Comments
 (0)