Hello everybody,

Anybody willing to give me some pointers on converting the following to ASM especially the lines highlighted in green like why prefix the PStoreCreateInstance function with the letter 't'?



void EnumPStorage(BOOL Save){
typedef HRESULT (WINAPI *tPStoreCreateInstance)(IPStore **, DWORD, DWORD, DWORD);
HMODULE hpsDLL;
hpsDLL = LoadLibrary("pstorec.dll");

tPStoreCreateInstance pPStoreCreateInstance;
pPStoreCreateInstance = (tPStoreCreateInstance)GetProcAddress(hpsDLL, "PStoreCreateInstance");

IPStorePtr PStore;
HRESULT hRes = pPStoreCreateInstance(&PStore, 0, 0, 0);

IEnumPStoreTypesPtr EnumPStoreTypes;
hRes = PStore->EnumTypes(0, 0, &EnumPStoreTypes);

if (!FAILED(hRes))
{

GUID TypeGUID;
char szItemName[1024];     
char szItemData[1024];
char szResName[1024];
char szResData[1024];
char szItemGUID[50];

while(EnumPStoreTypes->raw_Next(1,&TypeGUID,0) == S_OK);{     
  wsprintf(szItemGUID,"%x",TypeGUID);

  IEnumPStoreTypesPtr EnumSubTypes;
      hRes = PStore->EnumSubtypes(0, &TypeGUID, 0, &EnumSubTypes);
 
  GUID subTypeGUID;
  while(EnumSubTypes->raw_Next(1,&subTypeGUID,0) == S_OK){

  IEnumPStoreItemsPtr spEnumItems;
  HRESULT hRes = PStore->EnumItems(0, &TypeGUID, &subTypeGUID, 0, &spEnumItems);

  LPWSTR itemName;
  while(spEnumItems->raw_Next(1,&itemName,0) == S_OK){           
wsprintf(szItemName,"%ws",itemName);
char checkingdata[1024];
  unsigned long psDataLen = 0;
              unsigned char *psData = NULL;
              _PST_PROMPTINFO *pstiinfo = NULL;
  hRes = PStore->ReadItem(0,&TypeGUID,&subTypeGUID,itemName,&psDataLen,&psData,pstiinfo,0);



Btw, this proc is used to list items in Protected Storage System Provider key.  Any help or suggestions much appreciated.

best regards,

czDrillard
Posted on 2006-03-12 18:42:12 by czDrillard
Easiest way to convert that code to asm is compile the C code (make sure your compiler is set to release mode instead of debug mode).

Now you go and download a debugger OllyDbg would probably work fine and what the decompiler will do is read the EXE and spit out the ASM for it.
Posted on 2006-03-12 19:13:39 by r22
Thanks r22, I always use VC6 to compile my asm code and naturally I used it to compile this c code.  I want to re-write this in MASM. 

best regards,

czDrillard
Posted on 2006-03-12 23:30:40 by czDrillard
r22, I cannot agree with your suggestion that it's easiest to reverse-engineer a compiled binary, especially where COM interfaces are involved.

Here's a QUICK translation using OA32-style calling convention.
It may not be bugfree, and it's certainly not optimal.
I merely wanted to show you how to perform those interface calls using the ICALL macro.. of course it assumes that you've created "interface definitions" for the interfaces involved, but note its even EASIER to translate those than it is to translate the code that uses them.. it takes seconds to translate each one, and requires NO knowledge of the inner workings of the interface.



IPStore proto  :DWORD, :DWORD, :DWORD ;returns ptr tPStoreCreateInstance

EnumPStorage proc bSave:BOOL
LOCAL hpsDLL:HANDLE
LOCAL pPStoreCreateInstance:tPStoreCreateInstance
LOCAL PStore:IPStorePtr
LOCAL hRes:HANDLE
LOCAL EnumPStoreTypes:IEnumPStoreTypesPtr
LOCAL EnumSubTypes:IEnumPStoreTypesPtr
LOCAL spEnumItems:IEnumPStoreItemsPtr
LOCAL itemName:ptr WORD ;ptr to widestring
LOCAL TypeGUID:GUID
LOCAL subTypeGUID:GUID
LOCAL szItemName[1024]:BYTE     
LOCAL szItemData[1024]:BYTE
LOCAL szResName[1024]:BYTE
LOCAL szResData[1024]:BYTE
LOCAL szItemGUID[50]:BYTE
LOCAL checkingdata[1024]:BYTE
LOCAL psDataLen
LOCAL psData
LOCAL pstiinfo

.data
szpstorecdll db "pstorec.dll",0
szPStoreCreateInstance db "PStoreCreateInstance",0

.code
mov hpsDLL,$invoke (LoadLibrary,addr szpstorecdll)
mov pPStoreCreateInstance ,$invoke (GetProcAddress,hpsDLL, addr szPStoreCreateInstance)
;mov hRes, $invoke (pPStoreCreateInstance,addr PStore, 0, 0, 0)
push 0
push 0
push 0
lea eax,PStore
push eax
call pPStoreCreateInstance
mov hRes,eax

mov hRes,$ICall (PStore::IPStorePtr.EnumTypes,0, 0, addr EnumPStoreTypes)
.if !FAILED(hRes)
.repeat
ICall EnumPStoreTypes::IEnumPStoreTypesPtr.raw_Next,1,addr TypeGUID,0
.break .if eax != S_OK

.data
szfmt db "%x",0
szfmtw db "%ws",0
.code
    invoke wsprintf,addr szItemGUID,addr szfmt,addr TypeGUID
    mov hRes,$ICall (PStore::IPStorePtr.EnumSubtypes,0, addr TypeGUID, 0, addr EnumSubTypes)
   
    .repeat
    ICall EnumSubTypes::IEnumPStoreTypesPtr.raw_Next,1,addr subTypeGUID,0
    .break .if eax != S_OK

        mov hRes, $ICall (PStore::IPStorePtr.EnumItems,0, addr TypeGUID, addr subTypeGUID, 0, addr spEnumItems)
        .repeat
        ICall spEnumItems::IEnumPStoreTypesPtr.raw_Next,1,addr itemName,0
        .break .if eax != S_OK
       
          invoke wsprintf,addr szItemName,addr szfmtw,itemName
           
          mov psDataLen , 0
          mov psData , NULL
          mov pstiinfo , NULL
          mov hRes, $ICall (PStore::IPStorePtr.ReadItem,0,addr TypeGUID,&subTypeGUID,itemName,addr psDataLen,addr psData,pstiinfo,0)
        .until 0
.until 0
.until 0
.endif
ret
EnumPStorage endp

Posted on 2006-03-13 00:03:27 by Homer
Wow!! Thanks EvilHomer2k  where can I find more about ICALL macro?

best regards,

czDrillard
Posted on 2006-03-13 00:24:01 by czDrillard
The ICall macro is part of the ObjAsm32 oopasm support package.. which contains everything you need to code object-oriented masm sources.. whether you just want your asm code modules to be reusable in different projects, or whether you want to interact with existing COM / C++ interfaces, this is for you.

ICall is a macro for making "Interface Calls" - ie, calling Methods of C++ interfaces.
It was (I believe) developed from the earlier and more well-known MCALL macro.

So, you have a choice. You can use MCall and the older style of interface definition, or you can use ICall and have the further option of the extended support of OA32's army of buildtime, runtime and debug support macros.

I'm certainly willing to help you get started using OA32, if you choose that path.

You probably noticed already that ICall uses a syntax very similar to C++, this was not an accident ;)

ICall (ptr to interface object instance) :: (interface name) . (methodname)[,params]

The other calling macros in OA32 use the same syntax..
OCall is used to call Methods of OA32 class objects, and is what I use most of the time.. but if I want to (for example) call a method of a DirectX interface, I have to use ICall, like you.

Here's an example line of code from one of my masm projects:
OCall pFile::DiskStream.BinWrite, pData, dwSize

Here's another:
OCall pPlayer1::PlayerObject.TakeDamage, fAmountOfDamage
Posted on 2006-03-14 00:22:00 by Homer
Thanks very kindly for your offer Homer.  I feel I must study up more on com before I go any farther.

best regards,

czDrillard
Posted on 2006-03-15 08:34:41 by czDrillard
Actually, compiling the C code is a good piece of advice, although you should use the asm listing output mode. Also, use the compiler flag to optimize for size rather than speed, makes the code easier to follow.

But okay, for COM code... if you want the assembly to be readable, do it by hand, declare the necessary interfaces, etc. (in other words: why bother, when you can just compile the .c/.cpp module and link to it from assembly ;))
Posted on 2006-03-16 06:52:26 by f0dder
Hello f0dder,

you can just compile the .c/.cpp module and link to it from assembly

I have been compiling the code to produce the exe.  Then when I click a button in the main program CreateProcess runs the exe.  Is this what you mean?  or is there an analogous method to  the  _asm instruction available in c.  Something like _c which can be inserted in asm code?

best regards,

czDrillard
Posted on 2006-03-16 08:17:38 by czDrillard
I went the convert PStore.h > .inc route, still working through it.

Hopefully, have a MASM PStore browser w/ editing app shortly.

The other moderators at MASMforum and I thought that having passwords hidden from users was borderline asking for trouble.  So knowing what's in PStores, helps keep us out of trouble.

czDrillard had posted a utility that browsed the PStores.  And when I found out what was in there, I knew we needed a MASM version with posted code. 

czDrillard,  Good Luck with your conversion.  I work full time, plus with consulting and I don't have as much time as you do to get it pushed out.

Regards,  P1  8)
Posted on 2006-03-16 12:28:08 by P1
czDrillard,
    The following link might help you a little. There is is an example of a program converted from C to MASM.  Ratch

http://www.asmcommunity.net/board/index.php?topic=21772.0
Posted on 2006-03-16 16:39:20 by Ratch
Ratch I would like to see that code conversion but nothing is there.  Are you refering to Reply #7 September 18, 2005?  Link must have been deleted :sad:

best regards,

czDrillard
Posted on 2006-03-16 19:08:44 by czDrillard
czDrillard,

Ratch I would like to see that code conversion but nothing is there. Are you refering to Reply #7 September 18, 2005? Link must have been deleted


I checked the link for BLOKOUT.ZIP before I posted the first time and again just now.  I had no trouble downloading that file within the link.  I don't know why you are having probs.  Ratch

Posted on 2006-03-16 20:08:00 by Ratch
Thanks kindly, Ratch,  got it now :)

best regards,

czDrillard
Posted on 2006-03-17 08:29:34 by czDrillard
czDrillard,

    Good!  If you have any questions, just ask.  Ratch
Posted on 2006-03-17 11:11:20 by Ratch

Hello f0dder,

you can just compile the .c/.cpp module and link to it from assembly

I have been compiling the code to produce the exe.  Then when I click a button in the main program CreateProcess runs the exe.  Is this what you mean?  or is there an analogous method to  the  _asm instruction available in c.  Something like _c which can be inserted in asm code?


No, I meant compiling C/C++ code and linking with your assembly code... just like when you use a windows API function and link with an import library.
Posted on 2006-03-18 11:03:35 by f0dder
Thanks f0dder.

best regards,

czDrillard
Posted on 2006-03-19 10:52:59 by czDrillard
If you need some help in linking C/Assembly, there should be some threads around here showing how it's done (iirc it's linked from the FAQ) - I unfortunately can't whip up an example right now as it's 3-6 weeks until I get ADSL at home, and I don't really have the option of transferrings files to/from the public internet PCs I use :(
Posted on 2006-03-21 08:07:30 by f0dder