<?xml version="1.0" ?>\r
<HresultList>\r
+ <Hresult text="S_OK" value="00000000" />\r
+ <Hresult text="S_FALSE" value="00000001" />\r
<Hresult text="STG_S_CONVERTED" value="00030200" />\r
<Hresult text="STG_S_BLOCK" value="00030201" />\r
<Hresult text="STG_S_RETRYNOW" value="00030202" />\r
<NtstatusList>\r
<Ntstatus text="STATUS_SUCCESS" value="00000000"></Ntstatus>\r
<Ntstatus text="STATUS_WAIT_0" value="00000000"></Ntstatus>\r
- <Ntstatus text="STATUS_WAIT_1" value="00000001"></Ntstatus>\r
- <Ntstatus text="STATUS_WAIT_63" value="0000003F"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 1" value="00000001"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 2" value="00000002"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 3" value="00000003"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 4" value="00000004"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 5" value="00000005"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 6" value="00000006"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 7" value="00000007"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 8" value="00000008"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 9" value="00000009"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 10" value="0000000A"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 11" value="0000000B"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 12" value="0000000C"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 13" value="0000000D"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 14" value="0000000E"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 15" value="0000000F"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 16" value="00000010"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 17" value="00000011"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 18" value="00000012"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 19" value="00000013"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 20" value="00000014"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 21" value="00000015"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 22" value="00000016"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 23" value="00000017"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 24" value="00000018"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 25" value="00000019"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 26" value="0000001A"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 27" value="0000001B"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 28" value="0000001C"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 29" value="0000001D"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 30" value="0000001E"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 31" value="0000001F"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 32" value="00000020"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 33" value="00000021"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 34" value="00000022"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 35" value="00000023"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 36" value="00000024"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 37" value="00000025"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 38" value="00000026"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 39" value="00000027"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 40" value="00000028"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 41" value="00000029"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 42" value="0000002A"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 43" value="0000002B"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 44" value="0000002C"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 45" value="0000002D"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 46" value="0000002E"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 47" value="0000002F"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 48" value="00000030"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 49" value="00000031"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 50" value="00000032"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 51" value="00000033"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 52" value="00000034"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 53" value="00000035"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 54" value="00000036"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 55" value="00000037"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 56" value="00000038"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 57" value="00000039"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 58" value="0000003A"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 59" value="0000003B"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 60" value="0000003C"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 61" value="0000003D"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 62" value="0000003E"></Ntstatus>\r
+ <Ntstatus text="STATUS_WAIT_0 + 63" value="0000003F"></Ntstatus>\r
<Ntstatus text="STATUS_ABANDONED" value="00000080"></Ntstatus>\r
<Ntstatus text="STATUS_ABANDONED_WAIT_0" value="00000080"></Ntstatus>\r
<Ntstatus text="STATUS_ABANDONED_WAIT_63" value="000000BF"></Ntstatus>\r
<add key="IRCBotPassword" value="MyPassword" />\r
<add key="ChmPath" value="C:\IRC\TechBot\CHM" />\r
<add key="MainChm" value="kmarch.chm" />\r
- <add key="NtstatusXml" value="C:\IRC\TechBot\ntstatus.xml" />\r
- <add key="WinerrorXml" value="C:\IRC\TechBot\winerror.xml" />\r
- <add key="HresultXml" value="C:\IRC\TechBot\hresult.xml" />\r
- <add key="WmXml" value="C:\IRC\TechBot\wm.xml" />\r
+ <add key="NtstatusXml" value="ntstatus.xml" />\r
+ <add key="WinerrorXml" value="winerror.xml" />\r
+ <add key="HresultXml" value="hresult.xml" />\r
+ <add key="WmXml" value="wm.xml" />\r
<add key="SvnCommand" value="svn co svn://svn.reactos.org/trunk/reactos" />\r
<add key="BugUrl" value="http://www.reactos.org/bugzilla/show_bug.cgi?id={0}" />\r
<add key="WineBugUrl" value="http://bugs.winehq.org/show_bug.cgi?id={0}" />\r
using System;\r
using System.Xml;\r
+using System.Collections;\r
\r
namespace TechBot.Library\r
{\r
new string[] { "error" });\r
}\r
\r
+ private static int GetSeverity(long error)\r
+ {\r
+ return (int)((error >> 30) & 0x3);\r
+ }\r
+\r
+ private static bool IsCustomer(long error)\r
+ {\r
+ return (error & 0x20000000) != 0;\r
+ }\r
+ \r
+ private static bool IsReserved(long error)\r
+ {\r
+ return (error & 0x10000000) != 0;\r
+ }\r
+\r
+ private static int GetFacility(long error)\r
+ {\r
+ return (int)((error >> 16) & 0xFFF);\r
+ }\r
+ \r
+ private static short GetCode(long error)\r
+ {\r
+ return (short)((error >> 0) & 0xFFFF);\r
+ }\r
+\r
+ private static string FormatSeverity(long error)\r
+ {\r
+ int severity = GetSeverity(error);\r
+ switch (severity)\r
+ {\r
+ case 0: return "SUCCESS";\r
+ case 1: return "INFORMATIONAL";\r
+ case 2: return "WARNING";\r
+ case 3: return "ERROR";\r
+ }\r
+ return null;\r
+ }\r
+\r
+ private static string FormatFacility(long error)\r
+ {\r
+ int facility = GetFacility(error);\r
+ return facility.ToString();\r
+ }\r
+\r
+ private static string FormatCode(long error)\r
+ {\r
+ int code = GetCode(error);\r
+ return code.ToString();\r
+ }\r
+\r
public void Handle(MessageContext context,\r
string commandName,\r
string parameters)\r
{\r
- string errorText = parameters;\r
- if (errorText.Equals(String.Empty))\r
+ string originalErrorText = parameters.Trim();\r
+ if (originalErrorText.Equals(String.Empty))\r
{\r
serviceOutput.WriteLine(context,\r
"Please provide an Error Code.");\r
return;\r
}\r
+ \r
+ string errorText = originalErrorText;\r
\r
+ retry:\r
NumberParser np = new NumberParser();\r
long error = np.Parse(errorText);\r
if (np.Error)\r
{\r
serviceOutput.WriteLine(context,\r
String.Format("{0} is not a valid Error Code.",\r
- errorText));\r
+ originalErrorText));\r
return;\r
}\r
+ \r
+ ArrayList descriptions = new ArrayList();\r
\r
- string description = null;\r
- if (winerror.GetWinerrorDescription(error) != null)\r
+ // Error is out of bounds\r
+ if ((ulong)error > uint.MaxValue)\r
{\r
- description = winerror.GetWinerrorDescription(error);\r
- serviceOutput.WriteLine(context,\r
- String.Format("{0} is {1}.",\r
- error,\r
- description));\r
+ // Do nothing\r
}\r
- if (ntStatus.GetNtstatusDescription(error) != null)\r
+ // Error is outside of the range [0, 65535]: it cannot be a plain Win32 error code\r
+ else if ((ulong)error > ushort.MaxValue)\r
{\r
- description = ntStatus.GetNtstatusDescription(error);\r
+ // Customer bit is set: custom error code\r
+ if (IsCustomer(error))\r
+ {\r
+ string description = String.Format("[custom, severity {0}, facility {1}, code {2}]",\r
+ FormatSeverity(error),\r
+ FormatFacility(error),\r
+ FormatCode(error));\r
+ descriptions.Add(description);\r
+ }\r
+ // Reserved bit is set: HRESULT_FROM_NT(ntstatus)\r
+ else if (IsReserved(error))\r
+ {\r
+ int status = (int)(error & 0xCFFFFFFF);\r
+ string description = ntStatus.GetNtstatusDescription(status);\r
+ \r
+ if (description == null)\r
+ description = status.ToString("X");\r
+ \r
+ description = String.Format("HRESULT_FROM_NT({0})", description);\r
+ descriptions.Add(description);\r
+ }\r
+ // Win32 facility: HRESULT_FROM_WIN32(winerror)\r
+ else if (GetFacility(error) == 7)\r
+ {\r
+ // Must be an error code\r
+ if (GetSeverity(error) == 2)\r
+ {\r
+ short err = GetCode(error);\r
+ string description = winerror.GetWinerrorDescription(err);\r
+ \r
+ if (description == null)\r
+ description = err.ToString("D");\r
+ \r
+ description = String.Format("HRESULT_FROM_WIN32({0})", description);\r
+ descriptions.Add(description);\r
+ }\r
+ }\r
+ }\r
+\r
+ string winerrorDescription = winerror.GetWinerrorDescription(error);\r
+ string ntstatusDescription = ntStatus.GetNtstatusDescription(error);\r
+ string hresultDescription = hresult.GetHresultDescription(error);\r
+ \r
+ if (winerrorDescription != null)\r
+ descriptions.Add(winerrorDescription);\r
+ if (ntstatusDescription != null)\r
+ descriptions.Add(ntstatusDescription);\r
+ if (hresultDescription != null)\r
+ descriptions.Add(hresultDescription);\r
+\r
+ if (descriptions.Count == 0)\r
+ {\r
+ // Last chance heuristics: attempt to parse a 8-digit decimal as hexadecimal\r
+ if (errorText.Length == 8)\r
+ {\r
+ errorText = "0x" + errorText;\r
+ goto retry;\r
+ }\r
+\r
serviceOutput.WriteLine(context,\r
- String.Format("{0} is {1}.",\r
- errorText,\r
- description));\r
+ String.Format("I don't know about Error Code {0}.",\r
+ originalErrorText));\r
}\r
- if (hresult.GetHresultDescription(error) != null)\r
+ else if (descriptions.Count == 1)\r
{\r
- description = hresult.GetHresultDescription(error);\r
+ string description = (string)descriptions[0];\r
serviceOutput.WriteLine(context,\r
String.Format("{0} is {1}.",\r
- errorText,\r
+ originalErrorText,\r
description));\r
}\r
- if(description == null)\r
+ else\r
{\r
serviceOutput.WriteLine(context,\r
- String.Format("I don't know about Error Code {0}.",\r
- errorText));\r
+ String.Format("{0} could be:",\r
+ originalErrorText));\r
+ \r
+ foreach(string description in descriptions)\r
+ serviceOutput.WriteLine(context, String.Format("\t{0}", description));\r
}\r
}\r
\r
public class HresultCommand : BaseCommand, ICommand\r
{\r
private IServiceOutput serviceOutput;\r
- private string hresultXml;\r
private XmlDocument hresultXmlDocument;\r
\r
public HresultCommand(IServiceOutput serviceOutput,\r
string hresultXml)\r
{\r
this.serviceOutput = serviceOutput;\r
- this.hresultXml = hresultXml;\r
hresultXmlDocument = new XmlDocument();\r
hresultXmlDocument.Load(hresultXml);\r
}\r
\r
private const string SpecialHexCharacters = "ABCDEF";\r
\r
- private bool IsSpecialHexCharacter(char ch)\r
+ private static bool IsSpecialHexCharacter(char ch)\r
{\r
foreach (char specialChar in SpecialHexCharacters)\r
{\r
return false;\r
}\r
\r
- private bool HasSpecialHexCharacters(string s)\r
+ private static bool HasSpecialHexCharacters(string s)\r
{\r
foreach (char ch in s)\r
{\r
{\r
Error = false;\r
bool useHex = false;\r
- if (s.StartsWith("0x"))\r
+ if (s.StartsWith("0x", StringComparison.InvariantCultureIgnoreCase))\r
{\r
s = s.Substring(2);\r
useHex = true;\r
{\r
commands.Add(new HelpCommand(serviceOutput,\r
commands));\r
- commands.Add(new ApiCommand(serviceOutput,\r
+ /*commands.Add(new ApiCommand(serviceOutput,\r
chmPath,\r
- mainChm));\r
+ mainChm));*/\r
commands.Add(new NtStatusCommand(serviceOutput,\r
ntstatusXml));\r
commands.Add(new WinerrorCommand(serviceOutput,\r