When using C ++ to develop a Windows program, we often see the following judgment:
Copy codeThe Code is as follows: HRESULT hr =: RegCreateKeyEx (hk, szKeyPath, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_QUERY_VALUE, NULL, & hk, NULL );
If (SUCCEEDED (hr ))
{
In the code, use the SUCCEEDED macro to determine the return value of the RegCreateKeyEx () function.
Some Programmers think that when RegCreateKeyEx returns 0, it is successful, and S_ OK is 0. Therefore, it is customary to use the SUCCEEDED macro for judgment.
Some people use the following method to make judgments, which looks more rigorous:Copy codeThe Code is 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 types are more rigorous, at least not causing big problems, while the 1st type is completely a big Bug, which is normal. However, once there is a problem, you cannot find it.
Where is the error? Let me introduce it below.
SUCCEEDED
Let's take a look at the definition of this macro (WinError. h ):Copy codeThe Code is as follows ://
// Generic test for success on any status value (non-negative numbers
// Indicate success ).
//
# Define SUCCEEDED (hr) (HRESULT) (hr)> = 0)
It can be seen from this that it is to convert hr to the HRESULT type, and then make a judgment on whether it is greater than 0. Note: If the value is not negative, the operation is successful.
That is to say, as long as the HRESULT is a value greater than or equal to 0, it is considered successful.
HRESULT
Let's take a look at the HRESULT definition (winnt. h ):Copy codeThe Code is as follows: // Component Object Model defines, and macros
# Ifndef _ HRESULT_DEFINED
# Define _ HRESULT_DEFINED
Typedef long hresult;
# Endif //! _ HRESULT_DEFINED
Well, the original HRESULT is a Long integer.
In MSDN, you can find more detailed information:
For example, HRESULT is a 4-byte Long type with a total of 32 bits. Where:
The 31st bits are the s bits, that is, the sign bits. Because the HRESUlT format specifies that all successes are positive integers, and the failed values are negative.
30th bits are r BITs, which are reserved bits, but n bits (28 BITs) are not set, it must be 0; If n bits are used, the value of NTSTATUS is identified together with the s bit.
The 29th bits are c bits, indicating Custom, that is, Custom bits. If it is a Microsoft-defined return value, this bits are 0. If it is a Custom bits, this bits are 1.
The 28th bits are n bits, indicating NTSTATUS. If the value is 0, the NTSTATUS value can be mapped to an HRESULT value.
The 27th bits are x bits. The reserved bits must be 0.
26th-16th bits are Facility, and 11 bits are used to indicate the error source, suchCopy codeThe Code is as follows: FACILITY_WINDOWS indicates that it is from the Windows Subsystem
The 15th-1st bits are Code bits used to save the error value.
It can be seen from this that only the last two bytes are used to indicate that the other returned values are auxiliary information, which is mainly used for the return values of the COM function.
Common HRESULT values
Name |
Description |
Value |
S_ OK |
Operation successful |
Zero x 00000000 |
S_FALSE |
Operation successful, but there is a problem |
0x00000001L |
E_ABORT |
Operation aborted |
Zero x 80004004 |
E_ACCESSDENIED |
Access denied |
Zero x 80070005 |
E_FAIL |
Unknown error |
Zero x 80004005 |
Note: In addition to S_ OK, there is also S_FALSE, which is also successful.
Therefore, Microsoft provides the SUCCEEDED macro and FAILED macro for your convenience.
The SUCCEEDED macro is used to determine whether the function execution in COM is successful. The failure value is a negative number, and the success value is 0 and a positive number.
Windows Error Code
In the preceding code, we call a Windows API:Copy codeThe Code is as follows: RegCreateKeyEx (hk, szKeyPath, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_QUERY_VALUE, NULL, & hk, NULL );
The declaration of this API is:Copy codeThe Code is 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
);
According to MSDN, if it succeeds, it returns ERROR_SUCCESS. If it is other values, it fails. Other values are error codes similar to GetLastError. These Error codes are Windows Error codes.
Windows Error Codes
Microsoft defined a large number of Windows Error Codes in WinError. h. The Error code range is 0x0000 ~ 0 xFFFF, that is, 2 bytes, but not limited to 2 bytes, can also be saved in 4 bytes. This error code is widely used in Windows APIs. For example, in the preceding registry API, the returned value is the error code.
Another feature of this error code is that Microsoft defines detailed and readable descriptions for these error codes, which can be obtained through the FormatMessage function. In the Chinese environment, displays the translated Chinese characters.
In addition to ERROR_SUCCESS, Windows Error Codes are all positive numbers, that is, they cannot be determined by the SUCCEEDED macro, because this macro only determines whether it is a non-negative number. For Windows Error Codes, all Windows Error Codes are successful.
Common Windows Error Codes
Win32 error codes |
Description |
Zero x 00000000 ERROR_SUCCESS |
The operation completed successfully. |
Zero x 00000000 NERR_Success |
The operation completed successfully. |
Zero x 00000001 ERROR_INVALID_FUNCTION |
Incorrect function. |
Zero x 00000002 ERROR_FILE_NOT_FOUND |
The system cannot find the file specified. |
Zero x 00000003 ERROR_PATH_NOT_FOUND |
The system cannot find the path specified. |
Zero x 00000004 ERROR_TOO_MANY_OPEN_FILES |
The system cannot open the file. |
Zero x 00000005 ERROR_ACCESS_DENIED |
Access is denied. |
So in the previous code, Obfuscated the HRESULT and Windows Error Code, especially the first type of Code, when the Registry fails, it will also be judged as successful, 2nd because both are 0, and it happens that no problem occurs, however, we recommend that you do not mix them like this.
Summary