modified Resources/hresult.xml

Added S_OK and S_FALSE

modified   Resources/ntstatus.xml
    Added all possible STATUS_WAIT_XX codes as STATUS_WAIT_0 + XX

modified   TechBot.Console/App.config
    Don't use hard-coded paths, please!

modified   TechBot.Library/ErrorCommand.cs
    New and improved !error command, now performs heuristics to catch all possible or likely uses

modified   TechBot.Library/HresultCommand.cs
    Removed useless field

modified   TechBot.Library/NumberParser.cs
    Made a couple of methods static

modified   TechBot.Library/TechBotService.cs
    Disable !api until it fails gracefully

svn path=/trunk/; revision=23984
This commit is contained in:
KJK::Hyperion 2006-09-09 10:53:28 +00:00
parent 25c11e5f6e
commit dd77d1676b
7 changed files with 213 additions and 39 deletions

View file

@ -1,5 +1,7 @@
<?xml version="1.0" ?> <?xml version="1.0" ?>
<HresultList> <HresultList>
<Hresult text="S_OK" value="00000000" />
<Hresult text="S_FALSE" value="00000001" />
<Hresult text="STG_S_CONVERTED" value="00030200" /> <Hresult text="STG_S_CONVERTED" value="00030200" />
<Hresult text="STG_S_BLOCK" value="00030201" /> <Hresult text="STG_S_BLOCK" value="00030201" />
<Hresult text="STG_S_RETRYNOW" value="00030202" /> <Hresult text="STG_S_RETRYNOW" value="00030202" />

View file

@ -2,8 +2,69 @@
<NtstatusList> <NtstatusList>
<Ntstatus text="STATUS_SUCCESS" value="00000000"></Ntstatus> <Ntstatus text="STATUS_SUCCESS" value="00000000"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0" value="00000000"></Ntstatus> <Ntstatus text="STATUS_WAIT_0" value="00000000"></Ntstatus>
<Ntstatus text="STATUS_WAIT_1" value="00000001"></Ntstatus> <Ntstatus text="STATUS_WAIT_0 + 1" value="00000001"></Ntstatus>
<Ntstatus text="STATUS_WAIT_63" value="0000003F"></Ntstatus> <Ntstatus text="STATUS_WAIT_0 + 2" value="00000002"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 3" value="00000003"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 4" value="00000004"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 5" value="00000005"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 6" value="00000006"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 7" value="00000007"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 8" value="00000008"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 9" value="00000009"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 10" value="0000000A"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 11" value="0000000B"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 12" value="0000000C"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 13" value="0000000D"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 14" value="0000000E"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 15" value="0000000F"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 16" value="00000010"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 17" value="00000011"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 18" value="00000012"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 19" value="00000013"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 20" value="00000014"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 21" value="00000015"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 22" value="00000016"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 23" value="00000017"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 24" value="00000018"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 25" value="00000019"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 26" value="0000001A"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 27" value="0000001B"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 28" value="0000001C"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 29" value="0000001D"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 30" value="0000001E"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 31" value="0000001F"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 32" value="00000020"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 33" value="00000021"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 34" value="00000022"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 35" value="00000023"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 36" value="00000024"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 37" value="00000025"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 38" value="00000026"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 39" value="00000027"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 40" value="00000028"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 41" value="00000029"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 42" value="0000002A"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 43" value="0000002B"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 44" value="0000002C"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 45" value="0000002D"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 46" value="0000002E"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 47" value="0000002F"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 48" value="00000030"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 49" value="00000031"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 50" value="00000032"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 51" value="00000033"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 52" value="00000034"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 53" value="00000035"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 54" value="00000036"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 55" value="00000037"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 56" value="00000038"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 57" value="00000039"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 58" value="0000003A"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 59" value="0000003B"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 60" value="0000003C"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 61" value="0000003D"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 62" value="0000003E"></Ntstatus>
<Ntstatus text="STATUS_WAIT_0 + 63" value="0000003F"></Ntstatus>
<Ntstatus text="STATUS_ABANDONED" value="00000080"></Ntstatus> <Ntstatus text="STATUS_ABANDONED" value="00000080"></Ntstatus>
<Ntstatus text="STATUS_ABANDONED_WAIT_0" value="00000080"></Ntstatus> <Ntstatus text="STATUS_ABANDONED_WAIT_0" value="00000080"></Ntstatus>
<Ntstatus text="STATUS_ABANDONED_WAIT_63" value="000000BF"></Ntstatus> <Ntstatus text="STATUS_ABANDONED_WAIT_63" value="000000BF"></Ntstatus>

View file

@ -8,10 +8,10 @@
<add key="IRCBotPassword" value="MyPassword" /> <add key="IRCBotPassword" value="MyPassword" />
<add key="ChmPath" value="C:\IRC\TechBot\CHM" /> <add key="ChmPath" value="C:\IRC\TechBot\CHM" />
<add key="MainChm" value="kmarch.chm" /> <add key="MainChm" value="kmarch.chm" />
<add key="NtstatusXml" value="C:\IRC\TechBot\ntstatus.xml" /> <add key="NtstatusXml" value="ntstatus.xml" />
<add key="WinerrorXml" value="C:\IRC\TechBot\winerror.xml" /> <add key="WinerrorXml" value="winerror.xml" />
<add key="HresultXml" value="C:\IRC\TechBot\hresult.xml" /> <add key="HresultXml" value="hresult.xml" />
<add key="WmXml" value="C:\IRC\TechBot\wm.xml" /> <add key="WmXml" value="wm.xml" />
<add key="SvnCommand" value="svn co svn://svn.reactos.org/trunk/reactos" /> <add key="SvnCommand" value="svn co svn://svn.reactos.org/trunk/reactos" />
<add key="BugUrl" value="http://www.reactos.org/bugzilla/show_bug.cgi?id={0}" /> <add key="BugUrl" value="http://www.reactos.org/bugzilla/show_bug.cgi?id={0}" />
<add key="WineBugUrl" value="http://bugs.winehq.org/show_bug.cgi?id={0}" /> <add key="WineBugUrl" value="http://bugs.winehq.org/show_bug.cgi?id={0}" />

View file

@ -1,5 +1,6 @@
using System; using System;
using System.Xml; using System.Xml;
using System.Collections;
namespace TechBot.Library namespace TechBot.Library
{ {
@ -28,58 +29,170 @@ namespace TechBot.Library
new string[] { "error" }); new string[] { "error" });
} }
private static int GetSeverity(long error)
{
return (int)((error >> 30) & 0x3);
}
private static bool IsCustomer(long error)
{
return (error & 0x20000000) != 0;
}
private static bool IsReserved(long error)
{
return (error & 0x10000000) != 0;
}
private static int GetFacility(long error)
{
return (int)((error >> 16) & 0xFFF);
}
private static short GetCode(long error)
{
return (short)((error >> 0) & 0xFFFF);
}
private static string FormatSeverity(long error)
{
int severity = GetSeverity(error);
switch (severity)
{
case 0: return "SUCCESS";
case 1: return "INFORMATIONAL";
case 2: return "WARNING";
case 3: return "ERROR";
}
return null;
}
private static string FormatFacility(long error)
{
int facility = GetFacility(error);
return facility.ToString();
}
private static string FormatCode(long error)
{
int code = GetCode(error);
return code.ToString();
}
public void Handle(MessageContext context, public void Handle(MessageContext context,
string commandName, string commandName,
string parameters) string parameters)
{ {
string errorText = parameters; string originalErrorText = parameters.Trim();
if (errorText.Equals(String.Empty)) if (originalErrorText.Equals(String.Empty))
{ {
serviceOutput.WriteLine(context, serviceOutput.WriteLine(context,
"Please provide an Error Code."); "Please provide an Error Code.");
return; return;
} }
string errorText = originalErrorText;
retry:
NumberParser np = new NumberParser(); NumberParser np = new NumberParser();
long error = np.Parse(errorText); long error = np.Parse(errorText);
if (np.Error) if (np.Error)
{ {
serviceOutput.WriteLine(context, serviceOutput.WriteLine(context,
String.Format("{0} is not a valid Error Code.", String.Format("{0} is not a valid Error Code.",
errorText)); originalErrorText));
return; return;
} }
string description = null; ArrayList descriptions = new ArrayList();
if (winerror.GetWinerrorDescription(error) != null)
// Error is out of bounds
if ((ulong)error > uint.MaxValue)
{ {
description = winerror.GetWinerrorDescription(error); // Do nothing
serviceOutput.WriteLine(context,
String.Format("{0} is {1}.",
error,
description));
} }
if (ntStatus.GetNtstatusDescription(error) != null) // Error is outside of the range [0, 65535]: it cannot be a plain Win32 error code
else if ((ulong)error > ushort.MaxValue)
{ {
description = ntStatus.GetNtstatusDescription(error); // Customer bit is set: custom error code
serviceOutput.WriteLine(context, if (IsCustomer(error))
String.Format("{0} is {1}.", {
errorText, string description = String.Format("[custom, severity {0}, facility {1}, code {2}]",
description)); FormatSeverity(error),
FormatFacility(error),
FormatCode(error));
descriptions.Add(description);
}
// Reserved bit is set: HRESULT_FROM_NT(ntstatus)
else if (IsReserved(error))
{
int status = (int)(error & 0xCFFFFFFF);
string description = ntStatus.GetNtstatusDescription(status);
if (description == null)
description = status.ToString("X");
description = String.Format("HRESULT_FROM_NT({0})", description);
descriptions.Add(description);
}
// Win32 facility: HRESULT_FROM_WIN32(winerror)
else if (GetFacility(error) == 7)
{
// Must be an error code
if (GetSeverity(error) == 2)
{
short err = GetCode(error);
string description = winerror.GetWinerrorDescription(err);
if (description == null)
description = err.ToString("D");
description = String.Format("HRESULT_FROM_WIN32({0})", description);
descriptions.Add(description);
}
}
} }
if (hresult.GetHresultDescription(error) != null)
{ string winerrorDescription = winerror.GetWinerrorDescription(error);
description = hresult.GetHresultDescription(error); string ntstatusDescription = ntStatus.GetNtstatusDescription(error);
serviceOutput.WriteLine(context, string hresultDescription = hresult.GetHresultDescription(error);
String.Format("{0} is {1}.",
errorText, if (winerrorDescription != null)
description)); descriptions.Add(winerrorDescription);
} if (ntstatusDescription != null)
if(description == null) descriptions.Add(ntstatusDescription);
if (hresultDescription != null)
descriptions.Add(hresultDescription);
if (descriptions.Count == 0)
{ {
// Last chance heuristics: attempt to parse a 8-digit decimal as hexadecimal
if (errorText.Length == 8)
{
errorText = "0x" + errorText;
goto retry;
}
serviceOutput.WriteLine(context, serviceOutput.WriteLine(context,
String.Format("I don't know about Error Code {0}.", String.Format("I don't know about Error Code {0}.",
errorText)); originalErrorText));
}
else if (descriptions.Count == 1)
{
string description = (string)descriptions[0];
serviceOutput.WriteLine(context,
String.Format("{0} is {1}.",
originalErrorText,
description));
}
else
{
serviceOutput.WriteLine(context,
String.Format("{0} could be:",
originalErrorText));
foreach(string description in descriptions)
serviceOutput.WriteLine(context, String.Format("\t{0}", description));
} }
} }

View file

@ -6,14 +6,12 @@ namespace TechBot.Library
public class HresultCommand : BaseCommand, ICommand public class HresultCommand : BaseCommand, ICommand
{ {
private IServiceOutput serviceOutput; private IServiceOutput serviceOutput;
private string hresultXml;
private XmlDocument hresultXmlDocument; private XmlDocument hresultXmlDocument;
public HresultCommand(IServiceOutput serviceOutput, public HresultCommand(IServiceOutput serviceOutput,
string hresultXml) string hresultXml)
{ {
this.serviceOutput = serviceOutput; this.serviceOutput = serviceOutput;
this.hresultXml = hresultXml;
hresultXmlDocument = new XmlDocument(); hresultXmlDocument = new XmlDocument();
hresultXmlDocument.Load(hresultXml); hresultXmlDocument.Load(hresultXml);
} }

View file

@ -9,7 +9,7 @@ namespace TechBot.Library
private const string SpecialHexCharacters = "ABCDEF"; private const string SpecialHexCharacters = "ABCDEF";
private bool IsSpecialHexCharacter(char ch) private static bool IsSpecialHexCharacter(char ch)
{ {
foreach (char specialChar in SpecialHexCharacters) foreach (char specialChar in SpecialHexCharacters)
{ {
@ -19,7 +19,7 @@ namespace TechBot.Library
return false; return false;
} }
private bool HasSpecialHexCharacters(string s) private static bool HasSpecialHexCharacters(string s)
{ {
foreach (char ch in s) foreach (char ch in s)
{ {
@ -35,7 +35,7 @@ namespace TechBot.Library
{ {
Error = false; Error = false;
bool useHex = false; bool useHex = false;
if (s.StartsWith("0x")) if (s.StartsWith("0x", StringComparison.InvariantCultureIgnoreCase))
{ {
s = s.Substring(2); s = s.Substring(2);
useHex = true; useHex = true;

View file

@ -49,9 +49,9 @@ namespace TechBot.Library
{ {
commands.Add(new HelpCommand(serviceOutput, commands.Add(new HelpCommand(serviceOutput,
commands)); commands));
commands.Add(new ApiCommand(serviceOutput, /*commands.Add(new ApiCommand(serviceOutput,
chmPath, chmPath,
mainChm)); mainChm));*/
commands.Add(new NtStatusCommand(serviceOutput, commands.Add(new NtStatusCommand(serviceOutput,
ntstatusXml)); ntstatusXml));
commands.Add(new WinerrorCommand(serviceOutput, commands.Add(new WinerrorCommand(serviceOutput,