Hello guys,


How masm handle the typedef enums ?

I'm trying to figure it out how it handles things like

typedef enum _D3DRMMATERIALMODE{
D3DRMMATERIAL_FROMMESH,
D3DRMMATERIAL_FROMPARENT,
D3DRMMATERIAL_FROMFRAME
} D3DRMMATERIALMODE;

The enumerations works like the TypeDef Structures ? I mean
D3DRMMATERIAL_FROMMESH = 01 ; D3DRMMATERIAL_FROMPARENT =02 ?

I saw that on the file GUIDS.lib on masm folder, it contains the D3DRMMATERIALMODE, bbut how to use this library to analyse the result ? I mean how to fully insert this .lib file on a .asm file on a way that the executable (or the object file) contains all the information ?

Other thing...On win32.hlp we have things like:

IClientSecurity::QueryBlanket
Retrieves authentication information.

HRESULT QueryBlanket(

void* pProxy , //Location for the proxy to query

DWORD* pAuthnSvc , //Location for the current authentication service

DWORD* pAuthzSvc , //Location for the current authorization service

OLECHAR ** pServerPrincName , //Location for the current principal name

DWORD * pAuthnLevel , //Location for the current authentication level

DWORD * pImpLevel , //Location for the current impersonation level

RPC_AUTH_IDENTITY_HANDLE ** ppAuthInfo , //Location for the value passed to IClientSecurity::SetBlanket

DWORD ** pCapabilities //Location for flags indicating further capabilities of the proxy

);

And

IDirectDrawSurface::BltBatch

Performs a sequence of IDirectDrawSurface::Blt operations from several
sources to a single destination. At present this method is only a stub; it
has not yet been implemented.

HRESULT BltBatch(
LPDDBLTBATCH lpDDBltBatch,
DWORD dwCount,
DWORD dwFlags
)


What are those things ? They are functions ? If they are, how to use them on masm ? I mean we have to rename them ?
From IDirectDrawSurface::BltBatch to IDirectDrawSurface_BltBatch ?


Last thing:
There is a way to convert that lib file to an obj file ?


Best Regards,

Beyond2000!
Posted on 2002-11-03 13:17:04 by Beyond2000!
Regarding your questions about IClientSecurity::QueryBlanket and IDirectDrawSurface::BltBatch: they are functions which are accessed via an interface, IClientSecurity and IDirectDrawSurface are the interfaces. Probably the simplest (but not the most technically accurate) explanation i can come up with to describe an interface is this: think of it as each interface is a separate dll, but you don't handle it in the normal way. To find out how to handle them, check out the COM section of the forum.

As for your enums, i personally would declare them all individually. There may be a way to do enums in MASM, but i don't know it, although if the enums are in a lib file then you should be able to just link to it. If they are in a typelib then there may be a way to use them, but i don't know how :)
Posted on 2002-11-03 15:11:42 by sluggy
I read them.


But one thing it was not clear.

These functions are called on a differenmt way. That means that they can't be retrieved with an API importer ?

I mean, if they belongs to a specifc dll., we can't retrieve their names on the import section ?

If not, they are inside functions, like _malloc etc....?


Regards,

beyond2000!
Posted on 2002-11-03 19:07:36 by Beyond2000!
These functions are called on a differenmt way. That means that they can't be retrieved with an API importer ?


Thats right. Any dll that acts as a COM object server will export a CoCreateInstance API. You can try your importer on that, but its well documented so that you don't have to bother.

I mean, if they belongs to a specifc dll., we can't retrieve their names on the import section ?


COM dll's 'publish' what they export in a type library, a resource usually attatched to the dll (occasionally seperate in older dll's). This may seem very strange, but these exports are actually closer to C++ objects then simple dll exports.

COM is a whole subject unto itself, its use in ASM is fairly well documented.

How masm handle the typedef enums ?


Unfirtunately, MASM doesn't handle typed enumerations. One work-around is to use the type name -underscore- the enum name as a constant definition:


D3DRMMATERIAL_FROMMESH, EQU 1
D3DRMMATERIAL_FROMPARENT, EQU 2
D3DRMMATERIAL_FROMFRAME EQU 3
Posted on 2002-11-03 23:18:30 by Ernie
Hi Ernie, tks.

I found some examples on the COM section (DX8withMacro.asm), that displayed exactly those kind of things.

Like:


; Get the current desktop display mode
g_pD3D GetAdapterDisplayMode, D3DADAPTER_DEFAULT, ADDR d3ddm

That is

IDirect3D8::GetAdapterDisplayMode

After some analysis, i saw that this code is nothing but a call inside the address 416230 on d3d8.dll, that is exactly an "inside"functin called GetAdapterDisplayMode.

On masm example the way to go to that adress is:

lea eax, ; Coding for
push eax ; ADDR d3ddm
push 0 ; here means D3DADAPTER_DEFAULT

mov edx, edx ; -----here we calculate to go inside the dll
mov eax, _g_pD3D ----> similar to the object stuff (interface)
push eax
mov eax,
call dword ptr ; call to 416230 that is GetAdapterDisplayMode


In other hands, since these functions are not exported, masm need to calculate where the call need to go inside the dll.


That is really weird, because if the dll had the function GetAdapterDisplayMode as an export, all we have to do should be:

invoke GetAdapterDisplayMode, D3DADAPTER_DEFAULT, ADDR d3ddm

Instead using all that coding routines.


The masm way to calculate the offset inside the dll, is the same as VC or in Borland C or other compilers ?

Best Regards,

Beyond2000!
Posted on 2002-11-04 01:38:01 by Beyond2000!
Assessing COM Methods
--------------------------------------------------------------------------------------------------------------------
To use COM methods you need to know before hand what the interface looks like. Even if you "late bind" through an IDispatch interface, you still need to know what IDispatch looks like. A COM interface is just table of pointers to functions. Let's start with the IUnknown interface. If you were to create a component that simply exports the IUnknown interface, you have a fully functional COM object (albeit on the level of "Hello World"). IUnknown has the 3 basic methods of every interface, since all interfaces inherit from IUnknown. Keep in mind all an interface consists of is a structure of function pointers. For IUnknown, it looks like this:



IUnknown STRUCT DWORD
; IUnknown methods
IUnknown_QueryInterface QueryInterface_Pointer ?
IUnknown_AddRef AddRef_Pointer ?
IUnknown_Release Release_Pointer ?
IUnknown ENDS


That's it, just 12 bytes long. It holds 3 DWORD pointers to the procedures that actually implement the methods. It is the infamous "vtable" you may have heard of. The pointers are defined as such so we can have MASM do some type checking for us when compiling our calls. Since the vtable holds the addresses of functions, or pointers, these pointers are typedefed in our interface definition as such:



QueryInterface_Pointer typedef ptr QueryInterface_Proto
AddRef_Pointer typedef ptr AddRef_Proto
Release_Pointer typedef ptr Release_Proto


Finally, we define the function prototypes as follows:



QueryInterface_Proto typedef PROTO :DWORD, :DWORD, :DWORD
AddRef_Pointer typedef PROTO :DWORD
Release_Pointer typedef PROTO :DWORD


In keeping with the MASM32 practice of "loose" type checking, function parameters are just defined as DWORDs. Lots of work to set things up, but it does keeps lots of errors confined to compile time, not run time. In practice, we will wrap up these interface definitions in include files and keep them from cluttering up the source code.

One rather big compilation on defining an interface: MASM cannot resolve forward references like this, so we have to define them backwards, by defining the function prototype typedefs first, and the interface table last. The include files for the example program later on defines the interfaces this way.

To actually use an interface, you need a pointer to it.

The CoCreateInstance API can be used to return us this indirect pointer to an interface structure. It is one level removed from the vtable itself, and actually points to the "object" that holds the interface. The final structure looks like this:




There is a lot of indirection using this structure, it can drive you batty trying to write code to properly reference and de-reference these elements. Macros to simplify this task will be defined.

When the client makes a call to the COM library to create a COM object, it passes in the address where it wants the object pointer to be placed. This initial pointer is generically referred to as "ppv," from the C++ speak "pointer to pointer to (void)," where (void) means an unspecified type. It holds the address of another pointer ("pv"), and this pointer refers to a whole table of pointers, one table entry for each function of the interface.

For example, say we used CoCreateInstance and successfully got an interface pointer ppv, and wanted to see if it supports some other interface. We can call its QueryInterface method and request a new ppv (ppv2, pointer to an Interface) to the other interface (pIID, pointer to a Interface Identifying GUID) we are interested in. In C, QueryInterface has a prototype that would look like so:



(HRESULT) SomeObject::QueryInterface (this:pObject, IID:pGUID, ppv2:pInterface)


Such a call would look like this:



; get pointer to the object
mov eax, ppv
; and use it to find the interface structure
mov edx, [eax]

; push the function parameters onto the stack
push OFFSET ppv2
push OFFSET IID_ISomeOtherInterface
push dword ppv

; and then call that method
call dword ptr [edx + 0]


Note we must pass in the pointer we used, this lets the interface know which object (literally "this" object) we are using.

Note the register must be type cast (IUnknown PTR ). This lets the compiler know what structure to use to get the correct offset in the vtable for the .QueryInterface function (in this case it means an offset of zero from ). Actually, the information contained by the interface name and function name called disappear at compile time, all that is left is a numeric offset from an as of yet value unspecified pointer.
Posted on 2002-11-06 20:47:07 by Ernie