News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

How to use CreateStream

Started by alonsomm, April 26, 2005, 03:16:45 PM

Previous topic - Next topic

alonsomm

Hi, to all

   Can some body help me please, I want to create an Stream in a IStorage object so I use the following code to create the IStorage object, but how to I call CreateStream function from IStorage object.

invoke MultiByteToWideChar,CP_OEMCP,MB_PRECOMPOSED,addr ArchivoThumbs,-1,addr NombreW,255
invoke StgCreateDocfile,addr NombreW,STGM_READWRITE or STGM_CREATE or STGM_SHARE_EXCLUSIVE,0,addr pIStorage
; If eax is = S_OK then Storage Object created succefully

; Convert stream object name to wide character
invoke MultiByteToWideChar,CP_OEMCP,MB_PRECOMPOSED,addr PrimerIcono,-1,addr NombreW,255

; THIS PART DOESN'T WORK CAN ANY BODY TELL ME HOW TO CALL THE CreateStrem function from  IStorage interface
    mov eax, pIStorage
    mov eax, [eax]
   call [eax].IStorage_Interface.CreateStream 
   coinvoke pIStorage,CreateStream,NombreW,STGM_READWRITE or STGM_SHARE_EXCLUSIVE,0,0,pIStream1

Sincerely,
            Alonso Murillo

AeroASM

When you say it doesn't work, do you mean that it doesn't compile, it makes a runtime error, or it doesn't do as it should?
What exactly is IStorage_Interface?
What is coinvoke?
I have a feeling that you do not need to deal with the interface; just use invoke CreateStream.

alonsomm

As far as I know IStorage_Interface is one of this OLE / COM things that you have to call an API function to fill out the address of the interface functions, the coinvoke it should call one of this interface functions I just don't know how to use it!.

.data?
IStorage_Interface struc
QueryInterface dd ?
AddRef dd ?
Release   dd ?
CreateStream dd   ?
OpenStream dd ?
CreateStorage dd ?
OpenStorage dd ?
CopyTo dd ?
MoveElementTo dd ?
Commit dd ?
Revert dd ?
EnumElements dd   ?
DestroyElement dd ?
RenameElement dd ?
SetElementTimes   dd ?
SetClass dd ?
SetStateBits dd   ?
Stat dd   ?
IStorage_Interface ends


AeroASM

EDIT: There are some glaring mistakes in this posrt. PLease ignore this post until later; I will PM you when I correct it

DO you know how to use CoCreateInstance? If you do, then it should be easy. REmove all definitions, prototypes etc relating to IStorage. Use CoCreateInstance. The value you get from CoCreateInstance is a pointer to a pointer to an array of pointers to the methods. Diagrammatically: (where > means "pointer to"):

Value from CoCreateInstance > a pointerto the function table > QueryInterfaceptr    >  The actual QueryInterface method
                                                                                      > AddRefptr               >  The actual AddRef method
                                                                                           ....                                 ....

Therefore:


;get value from CoCreateInstance
...
;get the pointer to the first entry in the function table
mov eax,[eax]
;now eax is a pointer to QueryInterfaceptr, so [eax] is the actual value of QueryInterfaceptr
;therefore call [eax] would call QueryInterfaceptr.
;however we want CreateStream, not QueryInterface, and if you look in the structure which you should have deleted
;you will see that it is the fourth dword and so at offset 12 within the function table
;therefore the pointer to CreateStream is at memory location eax+12
;therefore:
push whatever
push whatever
;and so on, I don't know how many arguments it takes
call [eax+12]


I hope you understand this well. I know this is tricky, and it is indeed much better to have a macro do this for you and have structures so MASM can lookup the offsets for you, but it is like push/call versus invoke: you need to know how to use push/call, before you can actually know what is happening when you use invoke. If you do not understand, please ask. I know this does not solve your problem but it looks like you have learnt how to use coinvoke without knowing what it actually Does. If I am mistaken please forgive me. once you know what coinvoke actually does, you may have a "flash of insight" and see and rectify you r problem.

Infro_X

Perhaps my COM program that i wrote a while can help you.
From what I understand, first you call CoInitialize to setup some variables in some "far off land" then you call CoCreateInstance with the data of which com object you want to create, CoCreateInstance returns with a pointer of a pointer to a table of functions. and the pointer of the pointer is one of the paramaters of the every function call. thats about all I know.

[attachment deleted by admin]

alonsomm

Thanks guys, i found an example program which compile fine but when i run it crash, do you have any idea why?

.data?

pIStream1 dd ?
pIStorage dd ?

IStorage_Interface struc
QueryInterface dd ?
AddRef dd ?
Release   dd ?
CreateStream dd   ?
OpenStream dd ?
CreateStorage dd ?
OpenStorage dd ?
CopyTo dd ?
MoveElementTo dd ?
Commit dd ?
Revert dd ?
EnumElements dd   ?
DestroyElement dd ?
RenameElement dd ?
SetElementTimes   dd ?
SetClass dd ?
SetStateBits dd   ?
Stat dd   ?
IStorage_Interface ends

.code

mov   edx, [ebp+pIStream1] ; lets use same variable for another stream    :-)
push   edx       ; &IStream1
push   0       ; zero (reserved)
push   0       ; zero (reserved)
push   1011h       ; STGM_CREATE + STGM_SHARE_EXCLUSIVE + STGM_WRITE
lea edi,NombreW
push   edi       ; name of stream to   create:   "WordDocument"
mov   ecx, [ebp+pIStorage]
push   ecx       ; &IStorage2 (heathen.vdo)
mov   eax, [ecx]
call   [eax+IStorage_Interface.CreateStream] ;   create stream

alonsomm

Thanks alot guys for your help, Another friend help with it, this is the correct way to do it!

mov   edx, offset pIStream1
push   edx       ; &IStream1
push   0       ; zero (reserved)
push   0       ; zero (reserved)
push   1011h       ; STGM_CREATE + STGM_SHARE_EXCLUSIVE + STGM_WRITE
lea edi,NombreW
push   edi       ; name of stream to   create:   "WordDocument"
mov   ecx, pIStorage
push   ecx       ; &IStorage2 (heathen.vdo)
mov   eax, [ecx]
call   [eax+IStorage_Interface.CreateStream] ;   create stream