This is from the psdk and don't know what to do with 0x80000000 or if this is even correct so far:
HRESULT_FROM_WIN32 proc x:DWORD
;#define FACILITY_WIN32 7
;
;#define HRESULT_FROM_WIN32(x) ((HRESULT)(x) <= 0 ? ((HRESULT)(x)) \
;
;: ((HRESULT) (((x) & 0x0000FFFF) | (FACILITY_WIN32 << 16) | 0x80000000)))
mov eax, x
test eax, eax
jz Done
and eax, 0FFFFh
mov ecx, 7
shl ecx, 16
or eax, ecx
; what is next?
Done:
ret
HRESULT_FROM_WIN32 endp
EDIT: Ok I added add eax, 080000000h
after or eax, ecx and it seems to give me something that formatmessage understands... still is it correct?
Macro and procedure versions:
;==============================================================================
include \masm32\include\masm32rt.inc
;==============================================================================
; #define __HRESULT_FROM_WIN32(x) ((HRESULT)(x) <= 0 ?
; ((HRESULT)(x)) :
; ((HRESULT) (((x) & 0x0000FFFF) | (FACILITY_WIN32 << 16) | 0x80000000)))
FACILITY_WIN32 equ 7
_HRESULT_FROM_WIN32 MACRO x
LOCAL result
IF opattr x AND 4 ;; if x is an immediate expression
IF x LE 0
result = x
ELSE
result = (((x) AND 0ffffh) OR (FACILITY_WIN32 SHL 16) OR 80000000h)
ENDIF
EXITM <result>
ELSE
mov eax, x
test eax, eax
jle @F
and eax, 0ffffh
or eax, FACILITY_WIN32 SHL 16 OR 80000000h
@@:
EXITM <eax>
ENDIF
ENDM
;==============================================================================
.data
.code
;==============================================================================
HRESULT_FROM_WIN32 proc x:DWORD
mov eax, x
test eax, eax
jle @F
and eax, 0ffffh
or eax, FACILITY_WIN32 SHL 16 OR 80000000h
@@:
ret
HRESULT_FROM_WIN32 endp
;==============================================================================
start:
;==============================================================================
mov eax, _HRESULT_FROM_WIN32(0)
print str$(eax),13,10
mov eax, _HRESULT_FROM_WIN32(1)
print str$(eax),13,10
mov eax, _HRESULT_FROM_WIN32(-1)
print str$(eax),13,10
mov eax, _HRESULT_FROM_WIN32(123)
print str$(eax),13,10
mov eax, _HRESULT_FROM_WIN32(32767)
print str$(eax),13,10
mov eax, _HRESULT_FROM_WIN32(-32768)
print str$(eax),13,10,13,10
mov eax, 0
mov eax, _HRESULT_FROM_WIN32(eax)
print str$(eax),13,10
mov eax, 1
mov eax, _HRESULT_FROM_WIN32(eax)
print str$(eax),13,10
mov eax, -1
mov eax, _HRESULT_FROM_WIN32(eax)
print str$(eax),13,10
mov eax, 123
mov eax, _HRESULT_FROM_WIN32(eax)
print str$(eax),13,10
mov eax, 32767
mov eax, _HRESULT_FROM_WIN32(eax)
print str$(eax),13,10
mov eax, -32768
mov eax, _HRESULT_FROM_WIN32(eax)
print str$(eax),13,10,13,10
invoke HRESULT_FROM_WIN32, 0
print str$(eax),13,10
invoke HRESULT_FROM_WIN32, 1
print str$(eax),13,10
invoke HRESULT_FROM_WIN32, -1
print str$(eax),13,10
invoke HRESULT_FROM_WIN32, 123
print str$(eax),13,10
invoke HRESULT_FROM_WIN32, 32767
print str$(eax),13,10
invoke HRESULT_FROM_WIN32, -32768
print str$(eax),13,10,13,10
inkey "Press any key to exit..."
exit
;==============================================================================
end start
Results:
0
-2147024895
-1
-2147024773
-2146992129
-32768
0
-2147024895
-1
-2147024773
-2146992129
-32768
0
-2147024895
-1
-2147024773
-2146992129
-32768
And the results for the C code below:
0
-2147024895
-1
-2147024773
-2146992129
-32768
#include <windows.h>
#include <stdio.h>
#include <conio.h>
int main(void)
{
int e;
e = HRESULT_FROM_WIN32(0);
printf( "%d\n",e );
e = HRESULT_FROM_WIN32(1);
printf( "%d\n",e );
e = HRESULT_FROM_WIN32(-1);
printf( "%d\n",e );
e = HRESULT_FROM_WIN32(123);
printf( "%d\n",e );
e = HRESULT_FROM_WIN32(32767);
printf( "%d\n",e );
e = HRESULT_FROM_WIN32(-32768);
printf( "%d\n",e );
getch();
return 0;
}
http://msdn.microsoft.com/en-us/library/ms690088(VS.85).aspx
Thanks....
Can't you simply write:
((HRESULT) (((x) & 0x0000FFFF) | (FACILITY_WIN32 << 16) | 0x80000000)))
as:
.data
FACILITY_WIN32 equ 7
.code
GET_MESSAGE proc x:DWORD
mov eax,x
test eax,eax
jz @F
and eax, 0FFFFh
mov ecx,FACILITY_WIN32
shl ecx,16
or eax,ecx
or eax,800000000h
@@:
ret 4
GET_MESSAGE endp
?
Best regards,
Robin.
Quote from: Astro on February 17, 2010, 04:14:49 AM
Can't you simply write...
Yes, and with a few corrections your code will assemble and produce the correct result:
GET_MESSAGE proc x:DWORD
mov eax,x
test eax,eax
;jz @F
jle @F
and eax, 0FFFFh
mov ecx,FACILITY_WIN32
shl ecx,16
or eax,ecx
;or eax,800000000h
or eax,80000000h
@@:
ret 4
GET_MESSAGE endp
But why do the (FACILITY_WIN32 << 16) | 0x80000000 in pieces at run time when the assembler can do it at assembly time and encode the result as a constant.
Or, 33% shorter:
GetMsg proc ; x:DWORD
pop edx
pop eax
test eax, eax
jng @F
movzx eax, ax
or eax, 80070000h
@@:
jmp edx
GetMsg endp
:8)