Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the rule on hijacking Windows error codes for return from my own code?

Tags:

winapi

Are the error codes defined in WinError.h free to be hijacked and returned my by own code?

There are some generic Win32 error codes defined:

  • ERROR_FILE_NOT_FOUND: "The system cannot find the file specified."

that of course i could use for my own purpose when a file is not found.

Then there are still some generic errors:

  • ERROR_ACCESS_DENIED: "Access is denied."

but it's generally understood that this error comes when trying to access a file. i might have an HttpGet() function that returns ERROR_ACCESS_DENIED if the server returns a 401.

But then there are codes that are defined as being for a particular purpose. Imagine my HttpGet() function throws an error if the https certificate is not a type we support:

  • ERROR_IPSEC_IKE_INVALID_CERT_TYPE: "Invalid certificate type"

except that code is defined quite clearly in WinError.h as belonging to IPSec:

///////////////////////////////////////////////////
//                                               //
//           Start of IPSec Error codes          //
//                                               //
//                 13000 to 13999                //
///////////////////////////////////////////////////

...

//
// MessageId: ERROR_IPSEC_IKE_INVALID_CERT_TYPE
//
// MessageText:
//
// Invalid certificate type
//
#define ERROR_IPSEC_IKE_INVALID_CERT_TYPE 13819L

But the error text is exactly what i want!

We have a financial system that requires a 2nd user to approve a transaction; this means that the entered credentials must be a different user than the first person:

  • MK_E_MUSTBOTHERUSER: "User input required for operation to succeed"

or perhaps:

  • ERROR_LOGON_TYPE_NOT_GRANTED: "Logon failure: the user has not been granted the requested logon type at this computer."

i get the sense that spelunking through WinError, cherry-picking error codes by the string they show and re-purposing them to indicate errors they were not designed for, is something Raymond would give me a slap for.

Are Windows error codes a freely available "pool" of error codes? Or are all Windows error codes only to be returned from Microsoft's code?

If i'm creating HRESULTS, i need to use some code. And it would be great if the user could call FormatMessage to turn my HRESULT into a string. (Especially since my return HRESULT could either me either my own code, or an HRESULT that was returned to me from Microsoft code).

like image 617
Ian Boyd Avatar asked Mar 16 '12 19:03

Ian Boyd


People also ask

What is computer error code?

In computer programming, a return code or an error code is a numeric or alphanumeric code that is used to determine the nature of an error and why it occurred.


2 Answers

When you define your own HRESULT codes, you are recommended to use FACILITY_ITF and define your codes in this range of application-defined codes. Yes the codes would overlap between applications, but you can also provide additional descriptive message through SetErrorInfo API and indicating support by implementing ISupportErrorInfo if you are implementing COM object/interface.

An excerpt from COM+ Programming book explains this in greater detail: COM+ programming: a practical guide using Visual C++ and ATL (page 67).

Simpler than that, you can use your custom facility code and this might be different in different modules, so you can easily identify which module is the source of the problem.

If you put MESSAGETABLE resource into your binary, FormatMessage API could resolve HRESULTs and extract description text for individual codes, just like it happens with regular Windows error codes (the app would still need to provide module handle to the API function).

See also: Creating your own HRESULT?


O.P. Edit:

From Microsoft's Open Protocol Specification of HRESULTs

2.1 HRESULT

The HRESULT numbering space is vendor-extensible. Vendors can supply their own values for this field, as long as the C bit (0x20000000) is set, indicating it is a customer code.

C (1 bit): Customer. This bit specifies if the value is customer-defined or Microsoft-defined. The bit is set for customer-defined values and clear for Microsoft-defined values. <1>

<1> Section 2.1: All HRESULT values used by Microsoft have the C bit clear.

This means that i can make up any HRESULT i like as long as i set the C bit. As a practical matter this means that i can any any code i like, e.g.:

E_LOGON_FAILURE = 0xA007052E;

Of course i didn't come up with this number at random.

First i set the high bit to 1, to indicate an error:

0x80000000

Then i "choose" an error code, e.g. 1326 (0x52E hex):

0x8000052E

Then i need to choose a facility. Let's chooooose, on i dunno, seven:

0x8007052E

Finally i set the Customer bit, to indicate it is not a Microsoft defined HRESULT:

0xA007052E

And coincidentally everything up until the last step is the guts of the Microsoft HRESULT_FROM_WIN32 macro:

Maps a system error code to an HRESULT value.

 HRESULT HRESULT_FROM_WIN32(DWORD x);
like image 171
Roman R. Avatar answered Sep 29 '22 23:09

Roman R.


Don't go down this road, and just define your own.

Reuse of the codes themselves is pointless, since having your own codes is just one #define away.

Reuse of the error strings is not such a good idea either:

  • These will be localized. So if your (English) application runs on a Chinese version of Windows, the user will see a mixture of the two languages.

  • Microsoft might change the text at their whim, with a new release of Windows or with an update. For example, if you used ERROR_IPSEC_IKE_INVALID_CERT_TYPE to indicate HTTPS certificate errors, and Microsoft decided to fix their vague message to say "Invalid IPSEC IKE certificate type" instead? (I don't know what IKE is at all, and have only a vague notion about IPSEC, but you get the point.)

  • You'll have no way of customizing the error messages to be clearer or more specific.

  • Once users of your API start using FormatMessage, you'll be forever tied to the set of error codes and messages that Microsoft provides.

If you already know that Raymond Chen would slap you, why are you even considering this? ;)

like image 45
Thomas Avatar answered Sep 29 '22 22:09

Thomas