When you use C + + to develop a Windows program, you often see the following judgments:
Copy Code code as follows:
HRESULT hr =:: RegCreateKeyEx (HK, szkeypath, 0, NULL, reg_option_non_volatile, key_query_value, NULL, &HK, NULL);
if (SUCCEEDED (HR))
{
In your code, use the succeeded macro to determine the return value of the function RegCreateKeyEx () function.
Some programmers think that RegCreateKeyEx return 0 is a success, and S_OK is 0, so the habitual use of succeeded macro to make judgments.
Some people use the following method to judge, look more rigorous:
Copy Code code as follows:
HRESULT hr =:: RegCreateKeyEx (HK, szkeypath, 0, NULL, reg_option_non_volatile, key_query_value, NULL, &HK, NULL);
if (S_OK = hr)
{
Indeed, the 2nd is more rigorous, at least not a big problem, and the 1th is a completely large bug, the bug in normal circumstances is not a problem. But once you have a problem, you can't find it.
Where is the mistake? Let me introduce you to the following.
Succeeded
First look at the definition of the macro (WINERROR.H):
Copy Code code as follows:
//
Generic test for success on any status value (non-negative numbers
Indicate success).
//
#define SUCCEEDED (HR) (HRESULT) (HR) >= 0)
As you can see from here, it is the conversion of HR into an HRESULT type, and then the judgment of whether it is greater than 0. Note also indicates that success is indicated when the value is non-negative.
That is, as long as the HRESULT is a value greater than or equal to 0, it is considered successful.
HRESULT
Let's look at the definition of HRESULT (WINNT.H):
Copy Code code as follows:
Component Object Model defines, and macros
#ifndef _hresult_defined
#define _hresult_defined
typedef LONG HRESULT;
#endif//!_hresult_defined
Oh, the original HRESULT is a long integer.
More detailed information can be found in MSDN:
As shown above, the HRESULT is a 4-byte long with a total of 32 bits. which
The 31st digit is the s bit, the sign bit, because the HRESULT format stipulates that all successes are positive integers and that the failed values are negative
The 30th bit is R bit, is reserved bit, but n bit (28 bit) is not set, it must be 0, if n bit used, and s bit together to identify ntstatus value.
The 29th bit is the C bit, which means custom bit, and if it is a Microsoft-defined return value, the bit is 0, and if it is customized, the bit is 1.
The 28th bit is n bit, which means ntstatus, and a value of 0 can map the Ntstatus value to an HRESULT value.
The 27th digit is the x bit, the reserved bit, must be 0.
The 26th to 16th place is facility, using 11 digits to indicate the source of the error, such as
Copy Code code as follows:
Facility_windows representation from the WINDOWS subsystem
The 15th to 1th bit is the code bit, which is used to save the error value.
As you can see from here, only the last 2 bytes are used to represent the return value of the other is auxiliary information, it is mainly used for the return value of the COM function.
Common HRESULT Values
Name |
Description |
Value |
S_ok |
Operation successful |
0x00000000 |
S_false |
The operation was successful, but there was a problem |
0x00000001l |
E_abort |
Operation Abort |
0x80004004 |
E_accessdenied |
Access Denied |
0x80070005 |
E_fail |
Unknown error |
0x80004005 |
Note: In addition to S_OK, there is a s_false, it also belongs to success.
Therefore, Microsoft for the convenience of everyone to use, specifically provides succeeded macros and failed macros to facilitate everyone to make judgments.
Here, you see: The succeeded macro is used to determine whether the function execution in COM was successful and failed with a negative number, with a success of 0 and a positive number.
Windows Error Code
In the previous code we called a Windows API:
Copy Code code as follows:
: RegCreateKeyEx (HK, szkeypath, 0, NULL, reg_option_non_volatile, key_query_value, NULL, &HK, NULL);
The Declaration of this API is:
Copy Code code as follows:
LONG WINAPI RegCreateKeyEx (
__in hkey HKEY,
__in LPCTSTR Lpsubkey,
__reserved DWORD reserved,
__in_opt LPTSTR Lpclass,
__in DWORD dwoptions,
__in Regsam samdesired,
__in_opt Lpsecurity_attributes lpSecurityAttributes,
__out Phkey Phkresult,
__out_opt Lpdword lpdwdisposition
);
As you know from MSDN, it returns ERROR_SUCCESS when it succeeds, other values fail, and other values are similar to GetLastError error codes. These error codes are Windows error code.
Windows Error Codes
Microsoft has defined a large number of Windows error codes in WinError.h, a range of 0x0000~0xffff, 2 bytes, but not 2 bytes, or 4 bytes to save. In the Windows API, this error code is used in large numbers. For example, the registry API above, its return value is this error code.
Another feature of this error code is that Microsoft defines more detailed, readable descriptive information for these error codes, which can be obtained through the FormatMessage function, which in the Chinese context shows the translated Chinese.
Windows error codes, in addition to Error_success, is a positive number, that is, can not be judged by the succeeded macro, because the macro only judge is not a negative, for it, all Windows error codes is successful.
Common Windows Error codes
0x00000000
error_success 0x00000000
nerr_success 0x00000001
error_invalid_function 0x00000002
error_file_not_found 0x00000003
error_path_not_found 0x00000004
error_too_many_open_files
wi N32 error   codes |
Description |
the operation   Completed successfully. |
the operation   Completed successfully. |
incorrect function. |
the   system cannot find   the file specified. |
the   system cannot find   the path specified. |
the   system cannot open   the file. |
0x00000005 Error_access_denied |
Access is denied . |
So in the previous code, the HRESULT and Windows Error code were confused, especially the first code, which, when the registry failed, was judged to be a success, and the 2nd was not a problem because two were 0, but the suggestion was not to be mixed.
Summarize