News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Masm32Ref

Started by mabdelouahab, January 14, 2016, 09:56:41 AM

Previous topic - Next topic

mabdelouahab

Zen
Did you include any file before DotNetHelper.inc, or what is the IDE editor that you use it, what version of ML.exe, I don't know may be anything

Zen

MABDELOUAHAB,
If the BSTR$ Macro works for everyone else, then the error is on my part (and, it probably is,...I make plenty of mistakes).
I'm using HUTCH's Quick Editor to write and assemble the executable. And, yes, I have a number of include files that are listed in the includes section before DotNetHelper.inc.
I'll do more source reading and experimenting with the way I have arranged the MASM project. There are still many possibilities that I can check for potential errors. Don't worry about it. :bgrin:

mabdelouahab

Quote from: Zen on June 11, 2016, 03:42:41 AM
If the BSTR$ Macro works for everyone else, then the error is on my part ...

Zen, I'm working to make it work with everyone, even with you you  :biggrin:

Zen

MABDELOUAHAB,
Like I said before, I don't understand what the macro does. And, I think the error I'm getting when compiling is probably spurious (one of those errors that you get in MASM so often that's close to the real error, but somewhat misleading).
Anyway, I'm thinking, that I could just write a long procedure that would create all those BSTRs in memory (the long way), and then just modify DotNetHelper.inc so that all those functions that call the BSTR$ macro, would just have an address to the BSTR in the .data section. It wouldn't be as elegant as your code, but, it would probably work.
But, there's certainly no rush. I've got an enormous amount of time on my hands,...and, with a project like this (which I find really interesting) I can modify the code in numerous ways,...many of which will fail,...but, I might be able to improve things somewhat. :bgrin:
If I come up with anything interesting, I'll post the source code, so you can see what I'm talking about ,...

mabdelouahab

Quote from: Zen on June 11, 2016, 04:00:06 AM
MABDELOUAHAB,
Like I said before, I don't understand what the macro does.

It is just shorthand

Quote
BSTR$("mscorlib,")

        =

invoke SysAllocString,chr$("mscorlib,")
mov bstrValue,eax
...
invoke SysFreeString,bstrValue

Quote
BSTR$("v2.0.50727")

        =
.data
             dd   10*2
    clrV2   dw "v","2",".","0",".","5","0","7","2","7",0
.code


Zen

MABDELOUAHAB,
I assumed that the macro was just creating BSTRs (and concatenating BSTRs). Frankly, I don't see any obvious error. I'm assuming that you have used this macro many times without a problem. The only possibility that I can see is that maybe because there are so many embedded IF/ELSE type blocks that the compiler didn't translate it correctly into an executable instruction sequence.
At any rate, I'll test it and DotNetHelper.inc in a new uncluttered MASM project to find out what is going on 'beneath the hood' as they say.

jj2007

Quote from: mabdelouahab on June 11, 2016, 04:22:31 AM
It is just shorthand

BSTR$("mscorlib,")

        =

invoke SysAllocString,chr$("mscorlib,")
mov bstrValue,eax
...
invoke SysFreeString,bstrValue

Sure?

BSTR Data Type
Length prefix    Consists of a four-byte integer.
Data string       On Microsoft Windows, consists of a string of Unicode characters (wide or double-byte characters).

Zen

JOCHEN and MABDELOUAHAB,
I'm reading through the MASM Programmer's Guide, Version 6.1, 1992, Chapter 9 Using Macros, starts on page 176. I'm a COMPLETE IMBECILE when it comes to understanding macros. :bgrin: ...But, I'm making progress,...I have a much better concept of what the BSTR$ Macro is actually supposed to be doing,...although I'm still kinda hazy on the specifics,...:dazzled: I also set up a new MASM project that just contains the simplest possible configuration for creating a Windows program. Then, I included the two MASMRef include files: ComHelper.inc and DotNetHelper.inc. I tried to compile this project, and got many errors,...all of the same type (error A2085: instruction or register not accepted in current CPU mode.). By reading the error descriptions carefully, I discovered that I could comment out only three lines of the BSTR$ macro (in ComHelper.inc), and the whole project compiled without any errors. I haven't tried to invoke any of the methods, yet,...to test if the BSTR$ macro will actually work (I'm assuming that it won't work correctly).
Here is the BSTR$ Macro with the three lines that I commented out (this is the original version, by the way):

BSTR$ MACRO qstr:vararg
LOCAL arg,qot,q,bstrLbl,bstr_Seg,FrstL,tmpLen,cur_Pos,tmpStr,cur_tPos
cs_Seg catstr @CurSeg
    ifidn cs_Seg, <CONST>
bstr_Seg TEXTEQU <.const>        
    elseifidn cs_Seg, <_BSS>
bstr_Seg TEXTEQU <.data?>
    elseifidn cs_Seg, <_DATA>
bstr_Seg TEXTEQU <.data> 
    elseifidn cs_Seg, <_TEXT>
bstr_Seg TEXTEQU <.code>         
    endif
; .data
; dd _LenBSTR(qstr)
FrstL = 0
FOR arg,<qstr>
tmpStr equ <>
qot SubStr <arg>,1,1
IFIDNI qot,<!'> 
tmpLen = @SizeStr(<arg>)
tmpLen = tmpLen - 2
cur_Pos = 1
cur_tPos = 0
repeat tmpLen
cur_Pos=cur_Pos+1
cur_tPos=cur_tPos+1
ch_unq SubStr <arg>,cur_Pos,1
IF cur_Pos eq 2
tmpStr CATSTR tmpStr,<!">,ch_unq,<!">
ELSE
IF cur_tPos eq 1
tmpStr CATSTR tmpStr,<!">,ch_unq,<!">
ELSE
tmpStr CATSTR tmpStr,<!,">,ch_unq,<!">
ENDIF
ENDIF
IF cur_tPos eq 15
IF FrstL eq 0
bstrLbl dw tmpStr
FrstL = 1
ELSE
dw tmpStr
ENDIF
cur_tPos = 0
tmpStr CATSTR <>
ENDIF
endm
IF tmpLen ne 0
IF cur_tPos ne 0
IF FrstL eq 0
bstrLbl dw tmpStr
FrstL = 1
ELSE
dw tmpStr
ENDIF
ENDIF
ENDIF
ELSEIFIDNI qot,<!">
tmpLen = @SizeStr(<arg>)
tmpLen = tmpLen - 2
cur_Pos = 1
cur_tPos = 0
repeat tmpLen
cur_Pos=cur_Pos+1
cur_tPos=cur_tPos+1
ch_unq SubStr <arg>,cur_Pos,1
IF (cur_Pos eq 2)
tmpStr CATSTR tmpStr,<!">,ch_unq,<!">
ELSE
IF (cur_tPos eq 1)
tmpStr CATSTR tmpStr,<!">,ch_unq,<!">
ELSE
tmpStr CATSTR tmpStr,<!,">,ch_unq,<!">
ENDIF
ENDIF
IF cur_tPos eq 15
IF FrstL eq 0
bstrLbl dw tmpStr
FrstL = 1
ELSE
dw tmpStr
ENDIF
cur_tPos = 0
tmpStr CATSTR <>
ENDIF
endm
IF tmpLen ne 0
IF cur_tPos ne 0
IF FrstL eq 0
bstrLbl dw tmpStr
FrstL = 1
ELSE
dw tmpStr
ENDIF
ENDIF
ENDIF
ELSE
IF FrstL eq 0
bstrLbl dw arg
FrstL = 1
ELSE
dw arg
ENDIF
ENDIF
ENDM
IF FrstL eq 0
bstrLbl dw 0
ELSE
dw 0
ENDIF
; bstr_Seg
EXITM <OFFSET bstrLbl>
ENDM


So, the lines 13 and 14, which look like this:
;         .data
;            dd   _LenBSTR(qstr)


...And, the next to last line of the macro:   
;      bstr_Seg

...I have no idea what that .data line is doing, and, I have no idea what the bstr_Seg line is doing,...:dazzled:

mabdelouahab

Quote from: jj2007 on June 11, 2016, 07:58:39 AM
Sure?

BSTR Data Type
Length prefix    Consists of a four-byte integer.
Data string       On Microsoft Windows, consists of a string of Unicode characters (wide or double-byte characters).

of course JOCHEN

Quote
.data                                ; Must be in DATA section
   dd   _LenBSTR(qstr)
       ; < ----------- Length prefix   

            . Consists of a four-byte integer.
            . Occurs immediately before the first character of the data string.
            . Contains the number of bytes in the following data string.
            . Does not include the terminator.


   bstrLbl   dw   tmpStr          ; < ----------- Data string

            . On Microsoft Windows, consists of a string of Unicode characters (wide or double-byte characters).
            . On Apple Power Macintosh, consists of a single-byte string.
            . May contain multiple embedded null characters.

   DW 0             ;< ----------- Terminator

            . Consists of two null characters (0x00).

    bstr_Seg; return to the last section



ZEN
I've put some of the possibilities, just to make sure try this:
_LenBSTR MACRO qstr:VARARG
LOCAL arg,qot,szT,n,Len__
Len__ = 0
FOR arg,<qstr>
qot SubStr <arg>,1,1
IFIDNI qot,<!'> 
n=__checkNDQot(arg)
Len__ = Len__ +@SizeStr(<arg>)-2-n
ELSEIFIDNI qot,<!">
n=__checkN2Qot(arg)
Len__ = Len__ +@SizeStr(<arg>)-2-n
ELSE
Len__ = Len__ +1
ENDIF
ENDM
Len__= Len__ + Len__ ;*2
szT TEXTEQU %Len__;<@CatStr(%co__)>
EXITM< szT >
ENDM



BSTR$ MACRO qstr:vararg
LOCAL arg,qot,q,bstrLbl,FrstL,tmpLen,cur_Pos,tmpStr,cur_tPos,cs_Seg
cs_Seg catstr @CurSeg
;     ifidn cs_Seg, <CONST>
; bstr_Seg TEXTEQU <.const>        
;     elseifidn cs_Seg, <_BSS>
; bstr_Seg TEXTEQU <.data?>
;     elseifidn cs_Seg, <_DATA>
; bstr_Seg TEXTEQU <.data> 
;     elseifidn cs_Seg, <_TEXT>
; bstr_Seg TEXTEQU <.code>         
;     endif
.data
dd _LenBSTR(qstr)
FrstL = 0
tmpStr equ <>
cur_tPos = 0
FOR arg,<qstr>
qot SubStr <arg>,1,1
IsQot = 0
IFIDNI qot,<!'>
IsQot = 1
ELSEIFIDNI qot,<!">
IsQot = 1
ENDIF
IF IsQot eq 1
tmpLen = @SizeStr(<arg>)
tmpLen = tmpLen - 2
cur_Pos = 1
QuotF = 0
repeat tmpLen
cur_Pos=cur_Pos+1
ch_unq SubStr <arg>,cur_Pos,1
tmpStr2 CATSTR <>
IFIDNI ch_unq,<!">
IF QuotF eq 0
QuotF = 1
ELSE
QuotF = 0
tmpStr2 CATSTR <!022h>
ENDIF
ELSE
tmpStr2 CATSTR <!">,ch_unq,<!">
ENDIF
IF QuotF eq 0
cur_tPos=cur_tPos+1
IF (cur_tPos eq 1)
tmpStr CATSTR tmpStr,tmpStr2
ELSE
tmpStr CATSTR tmpStr,<!,>,tmpStr2
ENDIF
ENDIF
IF cur_tPos eq 15
IF FrstL eq 0
bstrLbl dw tmpStr
FrstL = 1
ELSE
dw tmpStr
ENDIF
cur_tPos = 0
tmpStr CATSTR <>
ENDIF
endm
ELSE
cur_tPos=cur_tPos+1
ch_unq SubStr <arg>,1
IF (cur_tPos eq 1)
tmpStr CATSTR tmpStr,ch_unq
ELSE
tmpStr CATSTR tmpStr,<!,>,ch_unq
ENDIF

IF cur_tPos eq 15
IF FrstL eq 0
bstrLbl dw tmpStr
FrstL = 1
ELSE
   dw tmpStr
ENDIF
cur_tPos = 0
tmpStr CATSTR <>
ENDIF

ENDIF
ENDM
IF FrstL eq 0
IF cur_tPos eq 0
bstrLbl dw 0
else
bstrLbl dw tmpStr,0
ENDIF
ELSE
IF cur_tPos eq 0
dw 0
ELSE
dw tmpStr,0
ENDIF
ENDIF
;bstr_Seg
    ifidn cs_Seg, <CONST>
.const        
    elseifidn cs_Seg, <_BSS>
.data?
    elseifidn cs_Seg, <_TEXT>
.code   
    endif

EXITM <OFFSET bstrLbl>
ENDM

jj2007

Quote from: mabdelouahab on June 11, 2016, 05:25:12 PM
Quote from: jj2007 on June 11, 2016, 07:58:39 AM
Sure?

BSTR Data Type
Length prefix    Consists of a four-byte integer.
Data string       On Microsoft Windows, consists of a string of Unicode characters (wide or double-byte characters).

of course JOCHEN

Quote
.data                                ; Must be in DATA section
   dd   _LenBSTR(qstr)
       ; < ----------- Length prefix   

            . Consists of a four-byte integer.
            . Occurs immediately before the first character of the data string.
            . Contains the number of bytes in the following data string.
            . Does not include the terminator.


   bstrLbl   dw   tmpStr          ; < ----------- Data string

            . On Microsoft Windows, consists of a string of Unicode characters (wide or double-byte characters).



Yep, dw tmpStr makes sense. But SysAllocString,chr$("mscorlib,") (see "shorthand" above) will not give you what you want. Btw in MB it's called Ole$() for a reason ;-)

mabdelouahab

Quote from: jj2007 on June 11, 2016, 05:52:21 PM
Yep, dw tmpStr makes sense. But SysAllocString,chr$("mscorlib,") (see "shorthand" above) will not give you what you want
jj2007  why not:SysAllocString

Quote
Return value

If successful, returns the string. If psz is a zero-length string, returns a zero-length BSTR. If psz is NULL or insufficient memory exists, returns NULL.
Remarks

You can free strings created with SysAllocString using SysFreeString.

jj2007

Quote from: mabdelouahab on June 11, 2016, 07:56:59 PMjj2007  why not:SysAllocString

Because SysAllocString,chr$("mscorlib,") will not give you a Unicode string. And BSTR is explicitly defined as UNICODE.

mabdelouahab

JOCHEN

QuoteBSTR SysAllocString(
  OLECHAR FAR* sz
);

From SysAllocString

jj2007

Quote from: mabdelouahab on June 11, 2016, 04:22:31 AM
It is just shorthand

BSTR$("mscorlib,")

        =

invoke SysAllocString,chr$("mscorlib,")

Launch Olly and see what you get. I see eax pointing to an ANSI string 8)

include \masm32\include\masm32rt.inc

.code
start:
  invoke SysAllocString,chr$("mscorlib,")
  int 3
  exit

end start

mabdelouahab

Jochen, Don't forget that the third line in ComHelper.inc is
Quote__UNICODE__    equ   1
because:
QuoteA BSTR (Basic string or binary string) is a string data type that is used by COM, Automation, and Interop functions. Use the BSTR data type in all interfaces that will be accessed from script.
relaunch Olly and see what you get 8)
Quote
__UNICODE__    equ   1
include \masm32\include\masm32rt.inc

.code
start:
  invoke SysAllocString,chr$("mscorlib,")
  int 3
  exit

end start