in x64
ISequentialStream struct
;public:
IUnknown <>
;public:
Read typedef proto WINSTDCALLCONV :ptr ,:DWORD,:ptr DWORD
Write typedef proto WINSTDCALLCONV :ptr ,:DWORD,:ptr DWORD
ISequentialStream ends
IStream struct
;public:
ISequentialStream <>
;public:
Seek typedef proto WINSTDCALLCONV :LARGE_INTEGER,:DWORD,:ptr ULARGE_INTEGER
SetSize typedef proto WINSTDCALLCONV :ULARGE_INTEGER
CopyTo typedef proto WINSTDCALLCONV :ptr IStream,:ULARGE_INTEGER,:ptr ULARGE_INTEGER,:ptr ULARGE_INTEGER
Commit typedef proto WINSTDCALLCONV :DWORD
Revert typedef proto WINSTDCALLCONV
LockRegion typedef proto WINSTDCALLCONV :ULARGE_INTEGER,:ULARGE_INTEGER,:DWORD
UnlockRegion typedef proto WINSTDCALLCONV :ULARGE_INTEGER,:ULARGE_INTEGER,:DWORD
Stat typedef proto WINSTDCALLCONV :ptr STATSTG,:DWORD
Clone typedef proto WINSTDCALLCONV :ptr ptr IStream
IStream ends
Hi six_L
The file containig the original definition is objidl.h
typedef struct IStreamVtbl
{
BEGIN_INTERFACE
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
__RPC__in IStream * This,
/* [in] */ __RPC__in REFIID riid,
/* [annotation][iid_is][out] */
_COM_Outptr_ void **ppvObject);
ULONG ( STDMETHODCALLTYPE *AddRef )(
__RPC__in IStream * This);
ULONG ( STDMETHODCALLTYPE *Release )(
__RPC__in IStream * This);
/* [local] */ HRESULT ( STDMETHODCALLTYPE *Read )(
IStream * This,
/* [annotation] */
_Out_writes_bytes_to_(cb, *pcbRead) void *pv,
/* [annotation][in] */
_In_ ULONG cb,
/* [annotation] */
_Out_opt_ ULONG *pcbRead);
/* [local] */ HRESULT ( STDMETHODCALLTYPE *Write )(
IStream * This,
/* [annotation] */
_In_reads_bytes_(cb) const void *pv,
/* [annotation][in] */
_In_ ULONG cb,
/* [annotation] */
_Out_opt_ ULONG *pcbWritten);
/* [local] */ HRESULT ( STDMETHODCALLTYPE *Seek )(
IStream * This,
/* [in] */ LARGE_INTEGER dlibMove,
/* [in] */ DWORD dwOrigin,
/* [annotation] */
_Out_opt_ ULARGE_INTEGER *plibNewPosition);
HRESULT ( STDMETHODCALLTYPE *SetSize )(
__RPC__in IStream * This,
/* [in] */ ULARGE_INTEGER libNewSize);
/* [local] */ HRESULT ( STDMETHODCALLTYPE *CopyTo )(
IStream * This,
/* [annotation][unique][in] */
_In_ IStream *pstm,
/* [in] */ ULARGE_INTEGER cb,
/* [annotation] */
_Out_opt_ ULARGE_INTEGER *pcbRead,
/* [annotation] */
_Out_opt_ ULARGE_INTEGER *pcbWritten);
HRESULT ( STDMETHODCALLTYPE *Commit )(
__RPC__in IStream * This,
/* [in] */ DWORD grfCommitFlags);
HRESULT ( STDMETHODCALLTYPE *Revert )(
__RPC__in IStream * This);
HRESULT ( STDMETHODCALLTYPE *LockRegion )(
__RPC__in IStream * This,
/* [in] */ ULARGE_INTEGER libOffset,
/* [in] */ ULARGE_INTEGER cb,
/* [in] */ DWORD dwLockType);
HRESULT ( STDMETHODCALLTYPE *UnlockRegion )(
__RPC__in IStream * This,
/* [in] */ ULARGE_INTEGER libOffset,
/* [in] */ ULARGE_INTEGER cb,
/* [in] */ DWORD dwLockType);
HRESULT ( STDMETHODCALLTYPE *Stat )(
__RPC__in IStream * This,
/* [out] */ __RPC__out STATSTG *pstatstg,
/* [in] */ DWORD grfStatFlag);
HRESULT ( STDMETHODCALLTYPE *Clone )(
__RPC__in IStream * This,
/* [out] */ __RPC__deref_out_opt IStream **ppstm);
END_INTERFACE
} IStreamVtbl;
h2incX translated it as:
IStreamVtbl struct
BEGIN_INTERFACE
??Interface equ <IStreamVtbl>
STD_METHOD QueryInterface, :ptr IStream, :REFIID, :ptr ptr
STD_METHOD AddRef, :ptr IStream
STD_METHOD Release, :ptr IStream
STD_METHOD Read, :ptr IStream, :ptr, :ULONG, :ptr ULONG
STD_METHOD Write, :ptr IStream, :ptr, :ULONG, :ptr ULONG
STD_METHOD Seek, :ptr IStream, :LARGE_INTEGER, :DWORD, :ptr ULARGE_INTEGER
STD_METHOD SetSize, :ptr IStream, :ULARGE_INTEGER
STD_METHOD CopyTo, :ptr IStream, :ptr IStream, :ULARGE_INTEGER, :ptr ULARGE_INTEGER, :ptr ULARGE_INTEGER
STD_METHOD Commit, :ptr IStream, :DWORD
STD_METHOD Revert, :ptr IStream
STD_METHOD LockRegion, :ptr IStream, :ULARGE_INTEGER, :ULARGE_INTEGER, :DWORD
STD_METHOD UnlockRegion, :ptr IStream, :ULARGE_INTEGER, :ULARGE_INTEGER, :DWORD
STD_METHOD Stat, :ptr IStream, :ptr STATSTG, :DWORD
STD_METHOD Clone, :ptr IStream, :ptr ptr IStream
??Interface equ <>
END_INTERFACE
IStreamVtbl ends
It matches with your code
ISequentialStream struct
;public:
IUnknown <>
;public:
Read typedef proto WINSTDCALLCONV :ptr ,:DWORD,:ptr DWORD
Write typedef proto WINSTDCALLCONV :ptr ,:DWORD,:ptr DWORD
ISequentialStream ends
IStream struct
;public:
ISequentialStream <>
;public:
Seek typedef proto WINSTDCALLCONV :LARGE_INTEGER,:DWORD,:ptr ULARGE_INTEGER
SetSize typedef proto WINSTDCALLCONV :ULARGE_INTEGER
CopyTo typedef proto WINSTDCALLCONV :ptr IStream,:ULARGE_INTEGER,:ptr ULARGE_INTEGER,:ptr ULARGE_INTEGER
Commit typedef proto WINSTDCALLCONV :DWORD
Revert typedef proto WINSTDCALLCONV
LockRegion typedef proto WINSTDCALLCONV :ULARGE_INTEGER,:ULARGE_INTEGER,:DWORD
UnlockRegion typedef proto WINSTDCALLCONV :ULARGE_INTEGER,:ULARGE_INTEGER,:DWORD
Stat typedef proto WINSTDCALLCONV :ptr STATSTG,:DWORD
Clone typedef proto WINSTDCALLCONV :ptr ptr IStream
IStream ends
Biterider
Hey,Biterider
thanks you for the answer.
memcpy proc uses rdi rsi pDest:qword, pSource:qword, SizeByte:qword
cld
mov rcx, SizeByte
mov rsi, pSource
mov rdi, pDest
mov rax, rcx
shr rcx, 3
rep movsq
mov rcx, rax
and rcx, 7
rep movsb
ret
memcpy endp
ResImageLoad proc ResID:QWORD
LOCAL hRes:QWORD
LOCAL pRes:QWORD
LOCAL lRes:QWORD
LOCAL x_IStream:IStream
invoke FindResource,0,ResID,RT_RCDATA
mov hRes, rax
invoke LoadResource,0,hRes
mov pRes, rax ; load the resource
invoke SizeofResource,0,hRes ; get its size
inc rax
mov lRes, rax
;int 3
;invoke HeapAlloc,hHeap, HEAP_ZERO_MEMORY, lRes ;as load gdi, the function is defeated
;invoke GlobalAlloc,GMEM_MOVEABLE,lRes ;as load gdi, the function is defeated
invoke VirtualAlloc,0,lRes,MEM_COMMIT,PAGE_READWRITE ; allocate memory
.if rax != 0
mov pGlobal,rax
.else
invoke ErrorMessage,CStr("VirtualAlloc")
mov rax,0
ret
.endif
invoke memcpy,pGlobal,pRes,lRes
invoke CreateStreamOnHGlobal,pGlobal,FALSE,addr x_IStream
invoke GdipLoadImageFromStream,x_IStream,addr pImg
invoke VirtualFree,pGlobal,0,MEM_RELEASE ; release the allocated memory
mov rax, pImg ; return the IMAGE handle in RAX
ret
ResImageLoad endp
those Api in ResImageLoad is worked ok, but no image is created.
QuoteIDC_IMGID RCDATA "b2.jpg"