Convert Win32 Error Hresult
Contents |
Chen - MSFTNovember 3, 200632 0 0 0 Everybody knows that you can use the HRESULT_FROM_WIN32 macro to convert a Win32 error code to an HRESULT, but how do you do the reverse? Let's look at the convert hresult to string definition of HRESULT_FROM_WIN32: #define HRESULT_FROM_WIN32(x) \ ((HRESULT)(x) <= 0 ? ((HRESULT)(x)) \ :
Hresult_from_win32
((HRESULT) (((x) & 0x0000FFFF) | (FACILITY_WIN32 << 16) | 0x80000000))) If the value is less than or equal to zero, then
Hresult Values Win32 Error Codes
the macro returns the value unchanged. Otherwise, it takes the lower sixteen bits and combines them with FACILITY_WIN32 and SEVERITY_ERROR. How do you reverse this process? How do you write the function WIN32_FROM_HRESULT? It's
Make_hresult
impossible to write that function since the mapping provided by the HRESULT_FROM_WIN32 function is not one-to-one. I leave as an execise to draw the set-to-set mapping diagram from DWORD to HRESULT. (Original diagram removed since people hate VML so much, and I can't use SVG since it requies XHTML.) If you do it correctly, you'll have a single line which maps 0to S_OK, and a series of blocks ntstatus to hresult that map blocks of 65536 error codes into the same HRESULT space. Notice that the values in the range 1 through 0x7FFFFFFFF are impossible results from the HRESULT_FROM_WIN32 macro. Furthermore, values in the range 0x80070000 through 0x8007FFFF could have come from quite a few original Win32 codes; you can't pick just one. But let's try to write the reverse function anyway: BOOL WIN32_FROM_HRESULT(HRESULT hr, OUT DWORD *pdwWin32) { if ((hr & 0xFFFF0000) == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32)) { // Could have come from many values, but we choose this one *pdwWin32 = HRESULT_CODE(hr); return TRUE; } if (hr == S_OK) { *pdwWin32 = HRESULT_CODE(hr); return TRUE; } // otherwise, we got an impossible value return FALSE; } Of course, we could have been petulant and just written BOOL WIN32_FROM_HRESULT_alternate(HRESULT hr, OUT DWORD *pdwWin32) { if (hr < 0) { *pdwWin32 = (DWORD)hr; return TRUE; } // otherwise, we got an impossible value return FALSE; } because the HRESULT_FROM_WIN32 macro is idempotent: HRESULT_FROM_WIN32(HRESULT_FROM_WIN32(x)) == HRESULT_FROM_WIN32(x). Therefore you would be technically correct if you declared that the "inverse" function was trivial. But in practice, people want to try to get "x" back out, so that's what we give you. Now that you understand how the HR
here for a quick overview of the site Help Center Detailed answers to any questions you might have Meta Discuss the workings and policies of this site About Us convert hresult to hex Learn more about Stack Overflow the company Business Learn more about hiring developers _com_error or posting ads with us Stack Overflow Questions Jobs Documentation Tags Users Badges Ask Question x Dismiss Join the Stack Overflow print hresult Community Stack Overflow is a community of 4.7 million programmers, just like you, helping each other. Join them; it only takes a minute: Sign up How to convert specific NTSTATUS value to the https://blogs.msdn.microsoft.com/oldnewthing/20061103-07/?p=29133 Hresult? up vote 2 down vote favorite 2 I am know NTSTATUS that i will get in case of specific error, but i got hresult, not ntstatus from pinvoke. So how to convert specific NTSTATUS value to the Hresult. I tried with no success: class Program { private const int FacilityNtBit = 0x10000000; //#define STATUS_DUPLICATE_OBJECTID ((NTSTATUS)0xC000022AL) private const int STATUS_DUPLICATE_OBJECTID = unchecked((int) (0xC000022A)); // HResult that is http://stackoverflow.com/questions/25566234/how-to-convert-specific-ntstatus-value-to-the-hresult returned for the STATUS_DUPLICATE_OBJECTID private const int CorrectHrStatusDuplicateObjectid = -2147019886; static void Main(string[] args) { int res = HRESULT_FROM_NT(STATUS_DUPLICATE_OBJECTID); Debug.Assert(res == CorrectHrStatusDuplicateObjectid, "Must be the same"); } private static int HRESULT_FROM_NT(int ntStatus) { //#define HRESULT_FROM_NT(x) ((HRESULT) ((x) | FACILITY_NT_BIT)) return ntStatus | FacilityNtBit; } } c# winapi share|improve this question edited Aug 29 '14 at 10:35 asked Aug 29 '14 at 10:17 Brans Ds 1,421623 add a comment| 5 Answers 5 active oldest votes up vote 3 down vote The mapping of native OS error codes to the winapi layer error codes is non-trivial. There's just no correspondence whatsoever between 5010 and 0xc000022a. The mental image to use is a giant switch statement hidden inside ntdll.dll that translates from one to the other. Reluctantly exposed by Microsoft, you'd normally have to jump through hoops to use it. Actually easier from pinvoke code since it already uses GetProcAddress() to find exported functions. But as long as you are making a winapi call, you should only expect to get a winapi error code and make no attempt to translate it yourself. It can be wrapped in an HRESULT, simply 0x80070000 + error. The native OS error code does bleed through sometimes, part
Win32 1Comment There are three common error code formats used throughout Windows. In the kernel and native part, NTSTATUS is used exclusively. The Win32 API uses its own error codes (they do not really have a name, so I will refer to them as Win32 error codes) and COM uses HRESULTs -- though the separation https://jpassing.com/2007/08/20/error-codes-win32-vs-hresult-vs-ntstatus/ is not always so sharp, e.g. the safe string functions (StringCch* and friends) also return HRESULTs although they http://ntcoder.com/bab/2007/06/26/convert-win32-error-codes-to-hresult/ do not belong to COM. HRESULT (From winerror.h) // // HRESULTs are 32 bit values layed out as follows: // // 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 win32 error 3 2 1 0 // +-+-+-+-+-+---------------------+-------------------------------+ // |S|R|C|N|r| Facility | Code | // +-+-+-+-+-+---------------------+-------------------------------+ // // where // // S - Severity - indicates success/fail // // 0 - Success // 1 - Fail (COERROR) // // R - reserved portion of the facility code, corresponds to NT's // second severity bit. // // C - reserved portion of the facility code, corresponds to NT's // C field. // // N - reserved portion of the facility code. Used to indicate a // mapped NT status value. // // convert hresult to r - reserved portion of the facility code. Reserved for internal // use. Used to indicate HRESULT values that are not status // values, but are instead message ids for display strings. // // Facility - is the facility code // // Code - is the facility's status code // NTSTATUS and Win32 error codes (From Winerror.h or ntstatus.h) NTSTATUS* and Win32 error codes share the same definition: // // Values are 32 bit values layed out as follows: // // 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 // +---+-+-+-----------------------+-------------------------------+ // |Sev|C|R| Facility | Code | // +---+-+-+-----------------------+-------------------------------+ // // where // // Sev - is the severity code // // 00 - Success // 01 - Informational // 10 - Warning // 11 - Error // // C - is the Customer code flag // // R - is a reserved bit // // Facility - is the facility code // // Code - is the facility's status code // In user mode, these codes are primarily encountered as SEH exception codes (e.g. EXCEPTION_ACCESS_VIOLATION, 0xC0000005) or return values. However, due to compatibility reasons, all common error codes defined in winerror.h (such as ERROR_FILE_NOT_FOUND, 0x2) do not quite adhere to their definition. Neither have they set Severity to 0y11 nor have they set their facility code to FACILITY_WIN32). Unsurprisin
Share What You Found: Use HRESULT_FROM_WIN32. Related Share What You Found: Posted by Nibu Thomas at 8:21 am Tagged with: HRESULT, HRESULT From Win32 error code, WIN32 2 Responses to "Convert win32 error codes to HRESULT" mithun says: October 14, 2009 at 12:12 pm how to convert the hresult code to error description Reply Nibu Thomas says: October 14, 2009 at 2:08 pm Hi Mithun, You can type @err,hr into the debug watch window to see a description of last error. Also there is a API called FormatMessage, which helps in translating an error code to it's description. Reply Leave a Reply Cancel reply How to create SafeArray of BSTR's? Easy way to display Gif's, Ico's, JPEG's and BMP's on your window Follow Me Subscribe to this blogRSS - PostsRSS - Comments Donation shows Appreciation… Custom Search Me Me Visitors Ads Recent Posts How to set ServerRender property of a SharePoint WebPart via Powershell? How to restore deleted default farm and web application level SharePoint timer jobs? SharePoint 2013 August 2015 CU Bug How to manipulate strings using PowerShell? How to get rid of orphaned features in a SharePoint farm using PowerShell? Tags.net ActiveX ATL CComboBox CDialog Clipboard COM Console API Console Application cout CreateProcess CString Debug Debugger Debugging dumpbin Feature pack GDI Interview questions MVP MVP Summit MVP Summit 2008 Nibu Nibu babu thomas Nibu Thomas PowerShell Ray Ozzie Redmond SetBkMode SetWindowPos Sharepoint ShGetFileInfo Steve Ballmer stl Summit VC8 vector Visual studio Visual Studio 2013 VS2005 VS2008 VS2013 windbg Windows Windows Phone Articles About Nibu MFC Feature Pack Tutorial - Part 1 - Getting started MFC Feature Pack Tutorial - Part 2 - CMFCPropertySheet MFC Feature Pack Tutorial - Part 3 - CMFCPropertyGridCtrl What’s new in Visual Studio 2012 Solution Explorer © 2012 bits and bytes Suffusion theme by Sayontan Sinha