The MASM Forum

General => The Workshop => Topic started by: mabdelouahab on January 14, 2016, 09:56:41 AM

Title: Masm32Ref
Post by: mabdelouahab on January 14, 2016, 09:56:41 AM
Masm32Ref idea adapted from advanced programming languages, you can add a reference to your project and use it directly, such as Visual Studio, on the Project menu choose Add reference, I wanted to make the same thing for Assembly programmers

Masm32Ref is a free Software, is intended for Assembly programmers, to extract the .INC file to direct access to COM objects and .net object, contains everything a programmer, for use directly without adding or modifying,
This work is primary, improvement, development and auditing, but this depends on the participation of everyone, because it's free and for everyone

Masm32Ref contains open source helper files plus tools to extract reference files; it also contains a utility to inject .net code within your program
The tool contains three axes:
   •   Extract COM object
   •   Extract dot net object
   •   Injector


Extract COM object
I will explain how to use by examples, and I propose to this example, https://msdn.microsoft.com/en-us/library/office/ff838565.aspx
If the object name is "Word.Application", we will replace the point "." by "_" will become the name of the object '' Word_Application"
To get an new instance add "New_" to the name of the object with the addition of a variable either defined or not defined
   New_Word_Application   _WordApplication

Then you can call any Method or Property by adding the name of the function to the name of the object
For example:
Method "Open": Word_Documents_Open
Property " Visible " : Word_Application_Visible_Set
to set up an event proc receiver add "_On_" after the name of the object and add Event name
Event "Quit"    : Word_Application_On_Quit
Application:
First, download the tool,and the helper (copy COMHelper.inc to \Masm32\Include)
Second, after execution Choose List Registred COM TypeLibrary
(http://gdurl.com/1XYY)

Go to : Microsoft Word ?? Object Library , I have Microsoft Word 15.0 Object Library
Double Click then Choose OutPut Folder, You will get a file Word.INC
Open a new empty project , and write the following code
Quoteinclude word.inc
.data
   _WordDocuments   dd   0
   _WordDocument   dd   0
.code
   ON_Application_Quit    PROC __Inst_Obj:DWORD
      invoke MessageBox,0, chr$("ON_Application_Quit"),0,0
       RET   
   ON_Application_Quit    ENDP
Start:
   New_Word_Application         _WordApplication
   Word_Application_Visible_Set   _WordApplication,TRUE
   ;Event   :   Quit
   Word_Application_On_Quit      _WordApplication,offset ON_Application_Quit
   
   Word_Application_Documents_Get    _WordApplication,addr _WordDocuments
   Word_Documents_Open         _WordDocuments,__String("d:\01.doc"),,,,,,,,,,,,,,,,addr _WordDocument
   inkey
   __Release _WordApplication
   exit
end Start

Try it

Second example:   https://msdn.microsoft.com/en-us/library/windows/desktop/aa393960%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396
Microsoft WMI Scripting V1.2 Library (WbemScripting.SWbemLocator)
Quote
include WbemScripting.INC
   .data
      _ISWbemServices      dd   0
      _SWbemObjectSet      dd   0
      _ISWbemObject      dd   0
      _ISWbemPropertySet   dd   0
      _ISWbemProperty      dd   0
      _varValue            VARIANT   <>
   .code
Start:

   New_WbemScripting_SWbemLocator _SWbemLocator
   WbemScripting_SWbemLocator_ConnectServer    _SWbemLocator,BSTR$("."),BSTR$("root\cimv2"),0,0,0,0,0,0,addr _ISWbemServices
   WbemScripting_SWbemServices_ExecQuery      _ISWbemServices,BSTR$("Select * From Win32_ComputerSystem"),BSTR$("WQL"),0,0,   addr _SWbemObjectSet
   WbemScripting_SWbemObjectSet_ItemIndex       _SWbemObjectSet,0,addr _ISWbemObject
   WbemScripting_SWbemObject_Properties__Get    _ISWbemObject,addr _ISWbemPropertySet

      ;===========================================   Name
      WbemScripting_SWbemPropertySet_Item      _ISWbemPropertySet,BSTR$("Name"),0,addr _ISWbemProperty
      WbemScripting_SWbemProperty_Value_Get   _ISWbemProperty,addr _varValue
      invoke crt_wprintf,cfm$("\n Computer name   :%s"),_varValue.bstrVal
      ;===========================================   NumberOfProcessors
      WbemScripting_SWbemPropertySet_Item      _ISWbemPropertySet,BSTR$("NumberOfProcessors"),0,addr _ISWbemProperty
      WbemScripting_SWbemProperty_Value_Get   _ISWbemProperty,addr _varValue
      invoke crt_wprintf,cfm$("\n Nb Processors   :%d    "),_varValue.lVal
      ;===========================================   Workgroup
      WbemScripting_SWbemPropertySet_Item      _ISWbemPropertySet,BSTR$("Workgroup"),0,addr _ISWbemProperty
      WbemScripting_SWbemProperty_Value_Get   _ISWbemProperty,addr _varValue
      invoke crt_wprintf,cfm$("\n Workgroup   :%s   "),_varValue.bstrVal
      ;===========================================   BootupState
      WbemScripting_SWbemPropertySet_Item      _ISWbemPropertySet,BSTR$("BootupState"),0,addr _ISWbemProperty
      WbemScripting_SWbemProperty_Value_Get   _ISWbemProperty,addr _varValue
      invoke crt_wprintf,cfm$("\n BootupState   :%s   "),_varValue.bstrVal
      ;===========================================   DNSHostName
      WbemScripting_SWbemPropertySet_Item      _ISWbemPropertySet,BSTR$("DNSHostName"),0,addr _ISWbemProperty
      WbemScripting_SWbemProperty_Value_Get   _ISWbemProperty,addr _varValue
      invoke crt_wprintf,cfm$("\n DNSHostName   :%s    "),_varValue.bstrVal
   
      invoke crt_wprintf,cfm$("\n \n ")
   inkey
   exit
end Start

I am looking for everyone's participation to improve the tool
I will complete with .net later

To get the latest update Visit https://sourceforge.net/projects/masm32ref/files/ (https://sourceforge.net/projects/masm32ref/files/)
Title: Re: Masm32Ref
Post by: qWord on January 14, 2016, 11:49:49 AM
The Word-example directly worked  :t

The file COMHelper.inc does include code/data and also references masm32rt.inc.
I would at least move the code and data into separate asm files, or better supply them via a static library.  The reference to masm32rt.inc should be completely removed IMO.
There is some redundant macro code (__New_float/double/short,....) that could be removed by using macros that define other macros (afaics).

regards
Title: Re: Masm32Ref
Post by: guga on January 14, 2016, 01:41:32 PM
Not working on XP
Title: Re: Masm32Ref
Post by: jj2007 on January 14, 2016, 04:09:41 PM
Works great on Win7-64 :t

Here is my version :P

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  SendWordCommands      ; prepare a DDE session; Word must be running
  .if eax
      void FileRead$("http://masm32.com/board/index.php?topic=5028.0")
      Let esi=CurDir$()+"Masm32Ref.htm"
      Rename "~FrLocal.tmp", esi
      SendWordCommands Cat$('[FileOpen "'+esi+'"]')
      SendWordCommands '[MsgBox "Cute"]'
  .else
      MsgBox 0, "MS Word doesn't answer", "Sorry", MB_OK
  .endif
  SendWordCommands exit      ; finish DDE session
EndOfCode
Title: Re: Masm32Ref
Post by: guga on January 14, 2016, 04:22:41 PM
I managed to make it work after manual patching the file. The PE Section IMAGE_OPTIONAL_HEADER on the members MajorOperatingSystemVersion and MajorSubsystemVersion are marked as 6 that does not work on earlier versions of windows :(

After changing them to 4, the app runned. Btw,...i liked it a lot ! I wonder if you could make it also export RosAsm version of this macros too ;)
Title: Re: Masm32Ref
Post by: mabdelouahab on January 14, 2016, 04:24:59 PM
Hello qWord,guga,jj2007
We will discuss a lot
But let me complete the examples and then I will come back
Extract dot net object
after execution Choose List Registred .net Assembly
for example just, select System.Windows.Forms
Double Click then Choose OutPut Folder, You will get a file "System.Windows.Forms.INC"
Open a new empty project , and write the following code
Quote
include System.Windows.Forms.inc
.code
   On_Click   PROC _sender:VARIANT, _e:DWORD
      LOCAL vt_e:VARIANT
      mov vt_e.vt,VT_DISPATCH;  VT_UNKNOWN
      m2m vt_e.punkVal,_e
         invoke MessageBox,0,BSTR$("On_Click"),0,0
      RET
   On_Click   ENDP

start:

   invoke __InitCLR
   .if eax
      New_System_Windows_Forms_Form             Form1
         System_Windows_Forms_Form_Text_Set      Form1,__String("My First Form")
         System_Windows_Forms_Button_SetBounds    Form1,__Integer(640),__Integer(480),__Integer(640),__Integer(480)
      
      New_System_Windows_Forms_Button            Button1
         System_Windows_Forms_Button_Text_Set    Button1,__String("My First Button")
         System_Windows_Forms_Button_SetBounds    Button1,__Integer(100),__Integer(100),__Integer(160),__Integer(60)

         System_Windows_Forms_Button_On_Click       Button1,offset On_Click
   
      __New_Null Controls
      System_Windows_Forms_Control_Controls_Get   Form1,Controls
      System_Windows_Forms_Control_ControlCollection_Add Controls, Button1
   
      System_Windows_Forms_Form_ShowDialog       Form1,0
      invoke __ReleaseClr
   .endif
   exit
end start
Title: Re: Masm32Ref
Post by: mabdelouahab on January 14, 2016, 04:29:56 PM
Copy DotNetHelper.inc to \Masm32\include
Title: Re: Masm32Ref
Post by: TouEnMasm on January 14, 2016, 06:34:13 PM

Help possible with the source code of Masm32Ref.exe
Title: Re: Masm32Ref
Post by: mabdelouahab on January 14, 2016, 07:17:58 PM
Injector
Injector is a tool to help you insert the .net code within your program directly
after execut masm32Ref Choose Injector
Copy this Code example:
Public Class MyClass1
    Public Function MyFirstFunc(s As String) As System.Windows.Forms.DialogResult
        Return System.Windows.Forms.MessageBox.Show("Masm32 Injector:"+s, "Masm32Ref")
    End Function
    Public Shared Function MySecFunc(s As String) As System.Windows.Forms.DialogResult
        Return System.Windows.Forms.MessageBox.Show("Masm32 Injector:"+s, "Masm32Ref")
    End Function
End Class

click "Add Ref" and select System.Windows.Forms.dll
click "Generat Inc File" ,type the assembly name "MyAssembly",Choose OutPut Folder, You will get a file "MyAssembly.INC"
Open a new empty project , and write the following code
Quote
include MyAssembly.inc

start:

   invoke __InitCLR
   .if eax
      __New_Empty   _msgRet
      ;Static function
      MyClass1_MySecFunc __String("Hello"),_msgRet

      New_MyClass1    _cls1
      MyClass1_MyFirstFunc _cls1,__String("Hello"),_msgRet
      invoke __ReleaseClr
   .endif

   inkey
   exit
end start
Title: Re: Masm32Ref
Post by: TWell on January 14, 2016, 07:38:13 PM
Statusline is too narrow in Windows 10
Title: Re: Masm32Ref
Post by: mabdelouahab on January 14, 2016, 10:59:12 PM
Quote from: qWord on January 14, 2016, 11:49:49 AM
The Word-example directly worked  :t

The file COMHelper.inc does include code/data and also references masm32rt.inc.
I would at least move the code and data into separate asm files, or better supply them via a static library.  The reference to masm32rt.inc should be completely removed IMO.
There is some redundant macro code (__New_float/double/short,....) that could be removed by using macros that define other macros (afaics).

regards

Thank you qWord Good observation, I've removed  masm32rt.inc. I've added what I need only
Title: Re: Masm32Ref
Post by: mabdelouahab on January 14, 2016, 11:21:26 PM
Quote from: TWell on January 14, 2016, 07:38:13 PM
Statusline is too narrow in Windows 10

Thank you TWell   I reset to default font, If you have experience in colors and fonts please suggest us

(http://gdurl.com/kO3u)
Title: Re: Masm32Ref
Post by: HSE on February 23, 2016, 06:50:37 AM
Apparently it's posible download only one com object by session, second time nothing happen.
Title: Re: Masm32Ref
Post by: mabdelouahab on February 25, 2016, 08:07:01 AM
Thank you HSE  :t, You can download the latest update,You must download the files: Masm32Ref.lib and Masm32Ref.inc, Also you can download Masm32RefMacro.INC, I took the tip of qWord (http://masm32.com/board/index.php?topic=5028.msg54006#msg54006)to make the tool work well with Masm ,jwasm,hjwasm,and rosasm, I've put COMHelper.INC and DotNetHelper.INC inside static lib and dynamic link lib

All that is >>> here <<< (https://sourceforge.net/projects/masm32ref/files/)

You can enjoy with .net object and COM object
Title: Re: Masm32Ref
Post by: HSE on February 25, 2016, 10:46:32 AM
Perfect now :t
Title: Re: Masm32Ref
Post by: Zen on May 13, 2016, 06:59:49 AM
Hi, MABDELOUAHAB,
:bgrin: I think you just conquered the COM/NET Galaxy single-handedly. :bgrin:
:bgrin: MASM assembly language programming will never be the same. :bgrin:
Title: Re: Masm32Ref
Post by: mabdelouahab on May 13, 2016, 08:39:49 PM
Quote from: Zen on May 13, 2016, 06:59:49 AM
Hi, MABDELOUAHAB,
:bgrin: I think you just conquered the COM/NET Galaxy single-handedly. :bgrin:
:bgrin: MASM assembly language programming will never be the same. :bgrin:

Hi Zen,We are at your service.
Title: Re: Masm32Ref
Post by: Zen on May 14, 2016, 05:26:18 AM
Hi, Again, MABDELOUAHAB,
Well, I've been making a preliminary scan of some of the Include files that you provided in your Sql Server & Masm32 example (http://masm32.com/board/index.php?topic=5299.0), (System.Data), and quickly reading through some of the source code that is downloadable from your SourceForge Masm32Ref (https://sourceforge.net/projects/masm32ref/files/) site,...

DotNetHelper.INC, in particular, is immense,...:dazzled:,...I mean, mind-boggling immense,...and loaded with PROCS,... :dazzled:
:dazzled:...Which makes me wonder, how you conceived of everything that goes into the process of creating Masm32Ref,...:dazzled:

I don't want you to give away all your secrets,...but, I've got a million questions,...:icon_eek:

...Anyway, I tried using the Masm32 Ref utility on something I thought  I knew something about,...the .NET Framework assembly, System.Xml Version 4.0.0.0. Well, I'm happy to report that in addition to the System.Xml.INC file (18 Kb), that lists all the other include files in the package, MASM32Ref produced 266 files, comprising 2.33 MB (size on disk). Again,...immensely mind-boggling,...:dazzled:   And, it appears, just on the initial inspection, that these include files and their type definitions would work perfectly with MASM32,...:dazzled:

The MSDN .NET Framework Version 4.5, Class Library, System.Xml Namespace documentation is here: System.Xml Namespace (https://msdn.microsoft.com/en-us/library/system.xml(v=vs.110).aspx)

...So, I'm wondering,...let's say, for example, I wanted to create a MASM32 application that uses the System.Xml classes, interfaces, and methods,...
I would include the appropriate Xml include files (created by Masm32Ref) at the beginning of my main assembly file,...and,...:dazzled:
How do I link my program's assembly language files to a .NET Framework assembly ??? I'm guessing that the MASM compiler (ml.exe) cannot read .NET Framework assemblies, even though they are in essence, normal DLLs with an extra section that describes the .NET metadata.

Is it necessary to compile this MASM32 project with Visual Studio ???
What about the possibility of using the .NET Framework Tool, Tlbexp.exe (Type Library Exporter) (https://msdn.microsoft.com/en-us/library/hfzzah2c(v=vs.110).aspx) to generate a Type Library ???

...I had to go back and re-read: Really Bizarre Question, July 2013  (http://masm32.com/board/index.php?topic=2106.msg21988), because I'd forgotten all that stuff. The article: Injecting .Net Assemblies Into Unmanaged Processes, CodeProject (http://www.codeproject.com/Articles/607352/Injecting-Net-Assemblies-Into-Unmanaged-Processes) was useful.

MSDN documentation: Hosting the Common Language Runtime (https://msdn.microsoft.com/en-us/library/9x0wh2z3(v=vs.90).aspx)

...You know,...I've completely forgotten all the .NET/COM interop techniques that I learned from: ".NET and COM: The Complete Interoperability Guide", by Adam Nathan.
Title: Re: Masm32Ref
Post by: mabdelouahab on May 14, 2016, 05:23:48 PM
Hi Zen
First I'm sorry I no better English, I just use the translator
Quote from: Zen on May 14, 2016, 05:26:18 AM
I don't want you to give away all your secrets,...but, I've got a million questions,...:icon_eek:
I don't have secrets, "It's science", and I'll answer to 2 million question

MASM32Ref  is not magic, Is just a translation of what exists in "Hosting the Common Language Runtime (https://msdn.microsoft.com/en-us/library/9x0wh2z3(v=vs.90).aspx)" to Assembly language, it cost me two years,and it is not necessary to compile your project with Visual Studio, I personally use the RadAsm IDE.

MASM32Ref make for you a MACROs ready for direct use, and it initialise the last CLR automatically for you if you have not done so
You can use the full namespace include file , also you can use one type include file
I will give you the simplest example "Hello world"
Quoteinclude System.Windows.Forms.MessageBox.inc
include masm32rt.inc
.data
   msg__   = BSTR$("Hello World")
   
    vString   dw VT_BSTR,0,0,0
                    dd msg__,0
.code
Start:
   System_Windows_Forms_MessageBox_Show_14 addr vString,0
   inkey
   exit
end Star
t

You may notice that I used a single include file of the class: System.Windows.Forms.MessageBox (https://msdn.microsoft.com/en-us/library/system.windows.forms.messagebox(v=vs.110).aspx)

You may notice that I used System_Windows_Forms_MessageBox_Show_14 method, Why 14, because there are 21 method Show (https://msdn.microsoft.com/en-us/library/system.windows.forms.messagebox.show(v=vs.110).aspx), and when you return to the include file "System.Windows.Forms.MessageBox.inc" you will find that before each macro find a comment to the method  to be used
Quote
   
...
   ;[Static];System.Windows.Forms.DialogResult Show(System.String, System.String)
      System_Windows_Forms_MessageBox_Show_13 MACRO  _text ,_caption ,lpvtRetValue
         ??DEF_System_Windows_Forms_MessageBox
         invoke __NetFWHelper_Method,addr __Type_System_Windows_Forms_MessageBox,13,0,lpvtRetValue,2, _text ,_caption
      ENDM
      ;[Static];System.Windows.Forms.DialogResult Show(System.String)
      System_Windows_Forms_MessageBox_Show_14 MACRO  _text ,lpvtRetValue
         ??DEF_System_Windows_Forms_MessageBox
         invoke __NetFWHelper_Method,addr __Type_System_Windows_Forms_MessageBox,14,0,lpvtRetValue,1, _text
      ENDM
...

You may notice that I used vString as VARIANT, because any argument passed  (or return) must be in the form of VARIANT, and 0 means null variant

Zen if you wanted to create a MASM32 application that uses the System.Xml namespace, just include "System.Xml.INC" before any other inc file then use what you want from him, 

I think it is better to define me in .net example to show you how you can turn it into an example of masm32
Title: Re: Masm32Ref
Post by: Zen on May 15, 2016, 03:27:45 AM
Thanks, MABDELOUAHAB,
The explanation is clear and simple,...thank you. I'll try it,...and then, I'll post some code. :bgrin:
I know I'm repeating myself,...but, Masm32Ref is a great tool. :bgrin:
I've read a number of the include files created by Masm32Ref,...and, at first, the macros confused me (just because I don't really understand how macros work). But, after, studying them for awhile, they seem clear and actually easy to understand. I think that you probably used the simplest and most reliable method to design the .NET to MASM object conversion macro. Again, an incredibly useful utility. :bgrin:
Title: Re: Masm32Ref
Post by: mabdelouahab on May 15, 2016, 07:10:37 AM
Thanks Zen, Again, We are at your service. :biggrin:
Title: Re: Masm32Ref
Post by: habran on May 15, 2016, 08:09:02 AM
Good job mabdelouahab :t
What about MASM64Ref or even better: HJWASM64Ref ;)
Title: Re: Masm32Ref
Post by: mabdelouahab on May 15, 2016, 10:49:11 PM
Hello habran
Quote from: habran on May 15, 2016, 08:09:02 AM
What about MASM64Ref or even better: HJWASM64Ref ;)
It's summer project  :lol:
Title: Re: Masm32Ref
Post by: habran on May 15, 2016, 11:24:35 PM
When is a summer in your country ;)
Title: Re: Masm32Ref
Post by: Zen on June 08, 2016, 07:02:44 AM
:bgrin: MABDELOUAHAB !!! :bgrin:
Hi. I've been working on a MASM project to write an XML file (using the .NET Framework, System.Xml assembly), like I mentioned above.
At this point, I've become semi-crazy (well,...probably, seriously demented),...it's not difficult, but, it's tedious coding. Anyway, I've read an enormous amount of MSDN .NET Framework documentation, and, I've written routines to enumerate installed CLRs and then to load a version of the CLR (version 4). And,...I thought I was doing OK,...everything was working just fine,...:bgrin:

Then, I got to the part where I would be creating an actual XmlWriter (to create an XML Document),...and, I started seriously reading a number of those System.Xml include files that were created by MASMRef,...and, naturally,...I started reading DotNetHelper.inc in depth,...and, I realized, to my horror,...that you have already done all the COM interface instantiation, CLR enumerating, loading and initializing that I've spent several weeks doing on my own.
In fact, DotNetHelper.inc is the key to the entire .NET Framework CLR hosting process. If you are going to write an unmanaged MASM process to host the .NET Framework Common Language Runtime, it's the first file you should read.
And, you did it so well !!! I'm REALLY impressed. I'm learning alot of cool assembly programming techniques just from reading that file.

...I wondered what you meant when you said,
Quote from: MABDELOUAHABMASM32Ref make for you a MACROs ready for direct use, and it initialise the last CLR automatically for you if you have not done so.

:bgrin:...It's just WAY TOO EASY,...almost FUN,...:bgrin:  It's quite possible that you've thought of everything,...:bgrin:
Title: Re: Masm32Ref
Post by: Zen on June 09, 2016, 09:35:50 AM
Well, OK,...I have run into a problem. There is a MACRO defined in ComHelper.inc, (BSTR$) the code is like this:   

   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


To be perfectly honest, I don't understand what it does, except that I'm guessing that it creates a BSTR. It's called numerous times in DotNetHelper.inc, with syntax like this:
invoke CompareString, LOCALE_USER_DEFAULT, NORM_IGNORECASE, __lpstrname,9,BSTR$("mscorlib,"),9

And, everywhere this macro is called, I'm getting the following error when compiling:
error A2085: instruction or register not accepted in current CPU mode. No clue as to why,...:icon_eek:

What I really don't understand is: when I was including the ComHelper.inc and DotNetHelper.inc into my project, I knew I was going to get compiler errors, so I included the ComHelper.inc file first, but, NOT, the DotNetHelper.inc file, just to see what kind of errors I was going to get,...and the project compiled without any errors at all. Apparently, the MACRO syntax will compile, but, is not expanded until it is actually invoked in the source, is this correct ?

...And, by the way,...what does ELSEIFIDN mean ??? I've looked everywhere, and could not find a definition for it,...
Title: Re: Masm32Ref
Post by: hutch-- on June 09, 2016, 02:00:02 PM
Zen,

What processor model are you using ?

Quote
And, everywhere this macro is called, I'm getting the following error when compiling:
error A2085: instruction or register not accepted in current CPU mode. No clue as to why

Try 686p, MMX, XMM

From masm32.chm

[ELSE]IFDIF


Syntax: [ELSE]IFDIF textitem1, textitem2

[ELSE]IFIDN textitem1, textitem2


Description

Causes assembly of a block of statements depending on whether two textitems are different or identical. IFDIF assembles the block if <textitem1> and <textitem2> are different. IFIDN assembles the block if they are the same. IFDIFI and IFIDNI do the same actions but are not case sensitive.

The <textitem1> and <textitem2> parameters are text items.


NOTE: The MASM macro notation messes up the formatting of the BBC tags.
Title: Re: Masm32Ref
Post by: mabdelouahab on June 09, 2016, 07:02:27 PM
ZEN
I did not update "ComHelper.inc", but there is a new update for file "Masm32Ref.Inc", it contains BSTR$  macro differs from existing in the first file
Title: Re: Masm32Ref
Post by: mabdelouahab on June 09, 2016, 09:04:03 PM
Last update:

1. BSTR$ Macro: Corrected in the correct size while you insert 2 Quot ; ex:BSTR$("my name is ""MA"".")

2. __ForEach Macro: To get a loop for each value in a array
Syntax:
Quote__ForEach MyVariable in MyArray
            ; ....
            __ExitFor  ; exit __ForEach
            ; ....
            RET        ; go to the next
            ; ....
         __Next

MyVariable : pointer to Variant

3. During the generation of macro properties, add a number to the properties of the same name within the same object.

4. the Injector: Solve the problem of lack success running on different OS
(http://gdurl.com/JZm2)

(http://gdurl.com/9vFe)
Title: Re: Masm32Ref
Post by: Zen on June 10, 2016, 07:07:26 AM
MABDELOUAHAB,
Hi, again. Yeah, after I posted yesterday about the BSTR$ Macro, I read the Masm32Ref.Inc file (listed at SourceForge), and noticed the different version of the BSTR$ Macro,...and, I wondered why there would be two versions. Anyway, I read the original BSTR$ Macro, and, I didn't even find any instructions,...much less an instruction or register that could be considered "Not accepted in the current CPU mode". I still HAVE NO IDEA why I'm getting these same errors when compiling,... :icon_eek: Maybe, this BSTR$ Macro should be a routine (or group of routines) instead of a Macro,...I'll try that,...just to see if I can actually locate the cause of the error,...

HUTCH,
Quote from: HUTCHWhat processor model are you using ?
Yeah, first thing I thought of. I'm using the .486 model directive (the same as MABDELOUAHAB is using in his include files). But, I did change it, and then tried to compile,...and got the same error. I'll have to play around with that macro some and see what happens,...
Thanks for the info on the IF/ELSE variants, (and, where to find the information),...

UPDATE: Ok, I downloaded the new Masm32Ref.Inc file from the MASMRef SourceForge site, substituted the "new, updated"  BSTR$ Macro into ComHelper.inc in my MASM project, and tried to re-compile. I got the same errors. Sorry,...
The only way I can get the MASM project to compile, is to comment out all the instances in the code of DotNetHelper.inc that have the  BSTR$ Macro in them (there are over 130 BSTR$ Macro invokes). Of course, I can't actually CALL any of those routines,...
Title: Re: Masm32Ref
Post by: mabdelouahab on June 10, 2016, 09:26:53 AM
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
Title: Re: Masm32Ref
Post by: Zen on June 11, 2016, 03:42:41 AM
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:
Title: Re: Masm32Ref
Post by: mabdelouahab on June 11, 2016, 03:53:48 AM
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:
Title: Re: Masm32Ref
Post by: Zen on June 11, 2016, 04:00:06 AM
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 ,...
Title: Re: Masm32Ref
Post by: mabdelouahab on June 11, 2016, 04:22:31 AM
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

Title: Re: Masm32Ref
Post by: Zen on June 11, 2016, 07:22:06 AM
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.
Title: Re: Masm32Ref
Post by: jj2007 on June 11, 2016, 07:58:39 AM
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 (https://msdn.microsoft.com/en-us/library/ms221069.aspx)
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).
Title: Re: Masm32Ref
Post by: Zen on June 11, 2016, 09:13:56 AM
JOCHEN and MABDELOUAHAB,
I'm reading through the MASM Programmer's Guide, Version 6.1, 1992 (http://people.sju.edu/~ggrevera/arch/references/MASM61PROGUIDE.pdf), 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:
Title: Re: Masm32Ref
Post by: mabdelouahab on June 11, 2016, 05:25:12 PM
Quote from: jj2007 on June 11, 2016, 07:58:39 AM
Sure?

BSTR Data Type (https://msdn.microsoft.com/en-us/library/ms221069.aspx)
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
Title: Re: Masm32Ref
Post by: jj2007 on June 11, 2016, 05:52:21 PM
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 (https://msdn.microsoft.com/en-us/library/ms221069.aspx)
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$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1139) for a reason ;-)
Title: Re: Masm32Ref
Post by: mabdelouahab on June 11, 2016, 07:56:59 PM
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  (https://msdn.microsoft.com/en-us/library/windows/desktop/ms221458(v=vs.85).aspx)

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.
Title: Re: Masm32Ref
Post by: jj2007 on June 11, 2016, 09:20:22 PM
Quote from: mabdelouahab on June 11, 2016, 07:56:59 PMjj2007  why not:SysAllocString  (https://msdn.microsoft.com/en-us/library/windows/desktop/ms221458(v=vs.85).aspx)

Because SysAllocString,chr$("mscorlib,") will not give you a Unicode string. And BSTR is explicitly defined as UNICODE.
Title: Re: Masm32Ref
Post by: mabdelouahab on June 12, 2016, 12:58:21 AM
JOCHEN

QuoteBSTR SysAllocString(
  OLECHAR FAR* sz
);

From SysAllocString (https://msdn.microsoft.com/en-us/library/ms891285.aspx)
Title: Re: Masm32Ref
Post by: jj2007 on June 12, 2016, 01:32:59 AM
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
Title: Re: Masm32Ref
Post by: mabdelouahab on June 12, 2016, 02:39:29 AM
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
Title: Re: Masm32Ref
Post by: jj2007 on June 12, 2016, 02:53:43 AM
Quote from: mabdelouahab on June 12, 2016, 02:39:29 AM
Jochen, Don't forget that the third line in ComHelper.inc is
Quote__UNICODE__    equ   1

... and chr$() becomes uni$()? I was not aware of that feature, thanks for informing me :(
Title: Re: Masm32Ref
Post by: Zen on June 12, 2016, 08:21:47 AM
EDIT: For those of you that are looking for information about MASMRef, ignore the following post. I have made a HUGE, INCREDIBLY STUPID blunder here. I'm actually quite embarrassed. :dazzled: The LoadLibrary call that I describe below, actually works perfectly. I apologize to MABDELOUAHAB. But, I've left the original post here, so that you can have a good laugh. :bgrin:

MABDELOUAHAB,
Hi, again. I've started writing a long procedure to create the BSTRs (with SysAllocString) that DotNetHelper.inc requires. Also, I've been modifying DotNetHelper.inc just to see what's working. So, naturally, I invoked __InitCLR, since it starts the whole .NET Framework Hosting. As you know, it calls a number of other routines in DotNetHelper.inc (__Private_MsCorEE, __Private_GetRuntimeHost2 , __Private_GetRuntimeHost4 , and, __ForEachInstalledRuntimes). In __Private_MsCorEE, the code calls LoadLibrary (https://msdn.microsoft.com/en-us/library/windows/desktop/ms684175(v=vs.85).aspx) like this:   

.IF !hMsCorEE
invoke LoadLibrary,BSTR$("mscoree")
MOV hMsCorEE ,EAX
.ENDIF


This call FAILS,...so, hMsCorEE is NULL. Consequently, everything else in __Private_MsCorEE fails to execute.

In the modified version that I'm testing, I simply use a normal ascii string in a .data section:
.data
szMSCore BYTE "mscoree.dll", 0   

...and call LoadLibrary like this:
invoke LoadLibrary, ADDR szMSCore    ;    Modified from original   
;    If the LoadLibrary function fails, the return value is NULL.     
                        mov hMsCorEE, eax   
                        .IF eax==NULL    ;    Modified from original (Added this Log File notification if LoadLibrary fails.)   
                        invoke LogEntry, ADDR szFAILLoadLib   
                        RET
                       .ENDIF


LogEntry is just a function that writes some data to a Log File, in this case: szFAILLoadLib BYTE "LoadLibrary FAILED for mscoree.dll.", 0Dh, 0Ah, 0
Title: Re: Masm32Ref
Post by: jj2007 on June 12, 2016, 08:37:03 AM
LoadLibraryW will work.
Title: Re: Masm32Ref
Post by: Zen on June 12, 2016, 08:38:58 AM
EDIT: Ok,...I go into more detail here with my demented LoadLibrary complaint. It's ridiculous at this point, so,...I've deleted the original post. :bgrin:

...And, oh, yes,...another apology to MABDELOUAHAB. :dazzled:
Title: Re: Masm32Ref
Post by: mabdelouahab on June 12, 2016, 08:48:42 AM
Zen
I made the DotNetHelper.inc in order to have the first file include, This means that if other files are included, so you should understand that all functions are designed to work with   __UNICODE__ 

Quote
.IF !hMsCorEE
   invoke LoadLibraryW,BSTR$("mscoree")
   MOV hMsCorEE   ,EAX
.ENDIF
OR

Quote
.IF !hMsCorEE
   invoke LoadLibrary,chr$("mscoree")
   MOV hMsCorEE   ,EAX
.ENDIF


Title: Re: Masm32Ref
Post by: Zen on June 12, 2016, 08:54:11 AM
MABDELOUAHAB,
Oh, sorry. (I must have been drunk :bgrin:)
Title: Re: Masm32Ref
Post by: Zen on June 21, 2016, 06:07:23 AM
Hi, MABDELOUAHAB,
Well,...I've been working through your code,...and I have a question. It's a long and involved question,...and, I'm kind of reluctant to ask, because of the LoadLibrary debacle above. :bgrin:
...Anyway, the question involves some code at the end of the function: __Private_GetRuntimeHost4, which is called from both, __InitCLR, and __GetDefaultDomain. In my Test App, I have a function, activated by a menu selection that just calls __InitCLR. It seems to work fine (I modified the code somewhat, and added numerous comments for English-speaking .NET Framework enthusiasts). I'm sure that you are familiar with the __Private_GetRuntimeHost4 function,...it basically obtains a number of COM interfaces that are necessary to load and initialize the .NET Framework CLR Version 4.
Here is the original version of __Private_GetRuntimeHost4 from DotNetHelper.inc:

__Private_GetRuntimeHost4 PROC
.IF !Curr_CLRRuntimeInfo
.IF !Curr_CLRMetaHost
    invoke CLRCreateInstance,addr CLSID_CLRMetaHost,addr IID_ICLRMetaHost,addr Curr_CLRMetaHost
.ENDIF
.IF Curr_CLRMetaHost
MOV Curr_CLRRuntimeInfo,0
PUSH 0
PUSH offset CallBackFunction_GetLastVersionInstaled
CALL __ForEachInstalledRuntimes
.ENDIF
.ENDIF
.IF Curr_CLRRuntimeInfo
        PUSH OFFSET Curr_CLRRuntimeHost
        PUSH OFFSET IID_ICLRRuntimeHost
        PUSH OFFSET CLSID_CLRRuntimeHost
        MOV EDX , Curr_CLRRuntimeInfo
        PUSH EDX   
        MOV EDX ,[EDX]   
        CALL DWORD PTR [EDX+36]
.IF !EAX
MOV EDX, Curr_CLRRuntimeHost
        PUSH EDX   
        MOV EDX,[EDX]   
        CALL DWORD PTR [EDX+12]
PUSH OFFSET Curr_CorRuntimeHost
        PUSH OFFSET IID_ICorRuntimeHost
        PUSH OFFSET CLSID_CorRuntimeHost
        MOV EDX , Curr_CLRRuntimeInfo
        PUSH EDX   
        MOV EDX ,[EDX]   
        CALL DWORD PTR [EDX+36]
.IF !eax
MOV EAX,TRUE
.ELSE
MOV EAX,FALSE
.ENDIF
.ELSE
MOV EAX,FALSE
.ENDIF

.ELSE
MOV EAX,FALSE
.ENDIF
ret
__Private_GetRuntimeHost4 endp


So,...here is the question: After loading the Common Language Runtime (CLR) version 4, and calling ICLRRuntimeHost:Start (which succeeds), you have a block of code that calls ICLRRuntimeInfo:GetInterface (https://msdn.microsoft.com/en-us/library/dd233135(v=vs.110).aspx) (using the ICLRRuntimeInfo interface pointer for version 4) to obtain an ICorRuntimeHost (https://msdn.microsoft.com/en-us/library/ms164320(v=vs.110).aspx) interface pointer. Why ??? The documentation for the ICorRuntimeHost interface states that: "In the .NET Framework version 2.0, this interface is superseded by ICLRRuntimeHost." I'm just wondering if this is necessary.
See, Deprecated CLR Hosting Functions (https://msdn.microsoft.com/en-us/library/aa964945(v=vs.110).aspx)

...By the way,...you can run this code in Process Explorer (https://technet.microsoft.com/en-us/sysinternals/processexplorer.aspx), and you can actually watch CLR.DLL load into the Test App's address space when the __InitCLR function executes. So, it works, no question. :bgrin:
Title: Re: Masm32Ref
Post by: mabdelouahab on June 22, 2016, 12:23:39 AM
Hi Zen
Quote from: Zen on June 21, 2016, 06:07:23 AM
So,...here is the question: After loading the Common Language Runtime (CLR) version 4, and calling ICLRRuntimeHost:Start (which succeeds), you have a block of code that calls ICLRRuntimeInfo:GetInterface (https://msdn.microsoft.com/en-us/library/dd233135(v=vs.110).aspx) (using the ICLRRuntimeInfo interface pointer for version 4) to obtain an ICorRuntimeHost (https://msdn.microsoft.com/en-us/library/ms164320(v=vs.110).aspx) interface pointer. Why ??? The documentation for the ICorRuntimeHost interface states that: "In the .NET Framework version 2.0, this interface is superseded by ICLRRuntimeHost." I'm just wondering if this is necessary.
Yes it is necessary, we must obtain an ICorRuntimeHost interface pointer to get the DefaultDomain
If you work for load CLR v1/v1.1/v2, you can obtain an ICorRuntimeHost interface pointer when you execute the function CorBindToRuntimeEx
but if  you work for load CLR v4, you should start with CLRCreateInstance Function because this function supersedes all the CorBindTo* functions listed in the .NET Framework 1.1 and 2.0 Hosting Global Static Functions, after you call this function you can obtain an ICLRMetaHost interface pointer, then call GetRuntime to obtain an ICLRRuntimeInfo interface pointer, then call GetInterface  to obtain an ICorRuntimeHost interface pointer
Title: Re: Masm32Ref
Post by: Zen on June 22, 2016, 08:22:48 AM
Thanks, MABDELOUAHAB,
So,...the only way in is the AppDomain Class (https://msdn.microsoft.com/en-us/library/system.appdomain(v=vs.110).aspx?cs-save-lang=1&cs-lang=cpp) ???
...And, the only way to obtain access to the AppDomain Class is through the ICorRuntimeHost Interface (https://msdn.microsoft.com/en-us/library/ms164320(v=vs.110).aspx) ???
Title: Update Masm32Ref
Post by: mabdelouahab on June 24, 2016, 02:19:58 AM
Update:
    - added a file wStrings.inc (https://sourceforge.net/projects/masm32ref/files/wStrings.inc/download), contains all the text strings used by DotNetHelper.inc (Placed in: \masm32\include)
    - added __Private_LoadMsCoreE proc to DotNetHelper.inc (https://sourceforge.net/projects/masm32ref/files/DotNetHelper.INC/download), to load MsCoreE library (x86/x64 OS)
Title: Re: Masm32Ref
Post by: Zen on June 24, 2016, 05:03:03 AM
Hi, again MABDELOUAHAB,
Thanks for the update. I've read the new files.
I've got another question (and this one is more annoying than all the others  :bgrin:).
I'm slowly and meticulously going through the code in the procedure: __GetDefaultDomain, and, I notice that you are calling interface methods of the AppDomain instance that represents the default application domain for the process, retrieved from ICorRuntimeHost:GetDefaultDomain (IID_AppDomain).
For example (from __ForEachAssemblyInIAppDomain):
.IF _rv(__InitCLR)
LEA ECX,Asm__s    ;    Asm__s is defined as a LOCAL variable
PUSH ECX
.IF IAppDom    ;    IAppDom is a parameter of __ForEachAssemblyInIAppDomain, which in this case is zero.   
        MOV EDX, IAppDom
.ELSE
        MOV EDX, IDefaultDomain
.ENDIF
        PUSH EDX   
        MOV EDX,[EDX]   
        CALL DWORD PTR [EDX+228]


What I'd like to know is how you determined the vtable order of the AppDomain (https://msdn.microsoft.com/en-us/library/system.appdomain(v=vs.110).aspx) object,...(or, is it the _AppDomain Interface (https://msdn.microsoft.com/en-us/library/system._appdomain(v=vs.110).aspx) ???) It's not in mscoree.h.
Title: Re: Masm32Ref
Post by: mabdelouahab on June 24, 2016, 06:45:28 AM
_AppDomain interface is in mscorlib.dll
Quote from: Zen on June 24, 2016, 05:03:03 AM
What I'd like to know is how you determined the vtable order of the AppDomain (https://msdn.microsoft.com/en-us/library/system.appdomain(v=vs.110).aspx) object,...(or, is it the _AppDomain Interface (https://msdn.microsoft.com/en-us/library/system._appdomain(v=vs.110).aspx) ???) It's not in mscoree.h.
the vtable order of the AppDomain object? There is no way to know this ( vtable order of the AppDomain object not equal vtable order of the _AppDomain interface)
Title: Re: Masm32Ref
Post by: Zen on June 24, 2016, 06:52:22 AM
That doesn't make sense.
How did you figure out what method was located at:
DWORD PTR [EDX+228] ???
The reason I'd like to know, is that I'm trying to verify your code in (DotNetHelper.inc), and when you have a line of code like,
CALL DWORD PTR [EDX+228]...
it looks like a COM interface method invocation. You do this at many places in your code, and if I have a reference to the interface virtual table, like the file, mscoree.h, then I can determine what it is you are calling with complete accuracy.
...So, I'm guessing that you used a .NET Framework disassembler, like ILSpy (http://ilspy.net/), or something,...:icon_eek:
...And, I'm also guessing that the call: DWORD PTR [EDX+228] ??? is something like: public Assembly[] GetAssemblies()

Here is the output of IL Spy for AppDomain (unfortunately, it doesn't show you the vtable order, or whatever structure the interface has):   
Title: Re: Masm32Ref
Post by: mabdelouahab on June 24, 2016, 07:41:14 AM
Quote from: Zen on June 24, 2016, 06:52:22 AM
That doesn't make sense.
How did you figure out what method was located at:
DWORD PTR [EDX+228] ???
is _AppDomain interface not AppDomain object  :biggrin: from mscorlib.tlb
I will explain to you when I have the time
Title: Re: Masm32Ref
Post by: Zen on June 24, 2016, 07:48:45 AM
This is REALLY getting exciting !!!
Interface Definitions and Type Libraries, MSDN (https://msdn.microsoft.com/en-us/library/windows/desktop/aa367061(v=vs.85).aspx)

...And, here (the zip file below), is the output from the OLE/COM Object Viewer for the mscorlib.tlb type library, version 4, for the _APPDomain interface (this is actually the 64-bit version):

And,...now,...I have my answer to the question (How did you figure out what method was located at: DWORD PTR [EDX+228] ??? ):
HRESULT _stdcall GetAssemblies([out, retval] SAFEARRAY(_Assembly*)* pRetVal);

DANG,...MABDELOUAHAB,...you must be a GENIUS !!! It would have taken me all eternity to figure all that out !!! And, on top of that, you had to translate all the documentation into arabic (so that you could understand it), write the code in English, post it to the MASM Forum, read all of our annoying comments in english, translate that back into arabic,...and, on and on and on,...:bgrin:
:dazzled: I'm AMAZED !!!  :dazzled:
Title: Re: Masm32Ref
Post by: GoneFishing on June 24, 2016, 11:28:24 PM
HELLO ZEN ,

I want to share with you my secret knowledge
First , please, read about   #import Directive (C++) (https://msdn.microsoft.com/en-us/en-en/library/8etzzkb6.aspx)

Now create a new project with your version of MS VS ( I assume you already have it installed )  with this code:


// TLBimports.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#import "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorlib.tlb" raw_interfaces_only
#import "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscoree.tlb" raw_interfaces_only

int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}


ATTENTION : In the  sample above I hardcoded the paths to the typelibs of .NET Framework v2

You may need to change it or write just typelib name without path to use the default runtime

Build the project and open its folder in explorer . Look for files with .tlh extension .

Here's the trick . You've got all interfaces defined. Convert them to MASM includes and you'll become extremly dangerous coder.
;-)

In a day or two I'll  polish one simple project  and possibly ( if you don't mind ) post it here . 
Title: Re: Masm32Ref
Post by: mabdelouahab on June 25, 2016, 03:37:05 AM
ZEN
When we are dealing with the Common Language Runtime, I think the first thing to do is to understand well what does it mean an managed Object instance in memory, and how it is converted from managed to unmanaged code (Marshaling)
this is an managed Object in memory (x86)
(http://i.msdn.microsoft.com/cc163791.fig09(en-us).gif)
You can not figure out the order of Methods because that order varies

This is an excerpt from this document (Default Marshaling for Objects (https://msdn.microsoft.com/en-us/library/2x07fbw8(v=vs.110).aspx)) that explains how to exposed an object to COM as an interface (What we are dealing with it)
Quote
Marshaling Object to Interface
When an object is exposed to COM as an interface, that interface is the class interface for the managed type Object (the _Object interface). This interface is typed as an IDispatch (UnmanagedType.IDispatch) or an IUnknown (UnmanagedType.IUnknown) in the resulting type library. COM clients can dynamically invoke the members of the managed class or any members implemented by its derived classes through the _Object interface. The client can also call QueryInterface to obtain any other interface explicitly implemented by the managed type.

ZEN
Did you know that the best way to deal with .Net objects are using reflection(System.Reflection), And this is the method used in Masm32Ref
QuoteThe classes in the System.Reflection namespace, together with System::Type, enable you to obtain information about loaded assemblies and the types defined within them, such as classes, interfaces, and value types. You can also use reflection to create type instances at run time, and to invoke and access them

See:
Reflection in the .NET Framework (https://msdn.microsoft.com/en-us/library/f7ykdhsy(v=vs.110).aspx)
Dynamic Programming in the .NET Framework (https://msdn.microsoft.com/en-us/library/hh156524(v=vs.110).aspx)

Remark: I reiterate my apology from my English bad
Title: Re: Masm32Ref
Post by: Zen on June 25, 2016, 03:41:44 AM
Excellent Intel, MABDELOUAHAB,...thanks,...I'll read up on everything,...:bgrin:
Undoubtedly, Il Spy uses reflection to produce its output (all the code that implements the methods of whatever object or class you're interested in),...

...And,...VERTOGRAD/GONEFISHING,...good to see you here again. :bgrin:
Quote from: VERTOGRAD...Here's the trick . You've got all interfaces defined. Convert them to MASM includes and you'll become extremly dangerous coder,...
I'm already the undisputed champion 'most annoying coder in the MASM Forum',...so, yes,...the yellow brick road to world domination extends out on my horizon. :bgrin: Thanks for the tip,...but, I don't have Visual Studio on my computer anymore,...but, I think I can figure out how to do it in MASM, if necessary,...
By the way,...this MASM32Ref Project of  MABDELOUAHAB's is really a great concept,...and, with just a few minor errors, it works well,...
Title: Re: Masm32Ref
Post by: Zen on June 28, 2016, 08:40:43 AM
Hi, again,...MABDELOUAHAB,
I have another problem,...in fact,...I'm completely stuck.

I'm going through the code in __GetDefaultDomain,...and, I'm trying to make sense out of the purpose of both functions, __ForEachAssemblyInIAppDomain and CallBackFunction_GetMsCorLibAssembly. I think I understand what is supposed to happen in __ForEachAssemblyInIAppDomain (the code iterates through all loaded assemblies in the AppDomain, calling CallBackFunction_GetMsCorLibAssembly for each one). But,...what is supposed to happen in CallBackFunction_GetMsCorLibAssembly ??? Specifically, I have absolutely no idea what this block of code is supposed to be doing:
     ;     (from procedure, CallBackFunction_GetMsCorLibAssembly)     
     .IF __Asm    ;    __Asm is a pointer to the data returned in SAFEARRAY (returned from _APPDomain:GetAssemblies).   
     LEA ECX,__lpstrname
     PUSH ECX
     MOV EDX, __Asm
     PUSH EDX   
     MOV EDX,[EDX]   
     CALL DWORD PTR [EDX+28]    ;    What the HECK are we calling here ??? GetType, or, GetName ???


...Right after the code calls: CALL DWORD PTR [EDX+28],...the code then immediately calls: CompareStringW (which does NOT return CSTR_EQUAL), so the CallBackFunction_GetMsCorLibAssembly function returns TRUE (meaning WHAT ???),...only that __ForEachAssemblyInIAppDomain then returns.
Returning then, to __GetDefaultDomain there is a long block of code that doesn't execute (which I assume is supposed to execute, or it wouldn't be there):
     .IF MsCorLib
     MOV EDX,BSTR$("System.AppDomain")    ;    If this block of code were executing the application would crash at the BSTR$ Macro. 
     LEA ECX,tAppDomain
     PUSH ECX
     PUSH EDX
     MOV EDX, MsCorLib
     PUSH EDX   
     MOV EDX,[EDX]   
     CALL DWORD PTR [EDX+68]
     .IF !EAX
     LEA ECX,aProperties
     PUSH ECX
     MOV EDX, tAppDomain
     PUSH EDX   
     MOV EDX,[EDX]   
     CALL DWORD PTR [EDX+308] 
     .IF !EAX
     MOV ECX,aProperties
     MOV EDX,[ECX].SAFEARRAY.rgsabound.cElements
     MOV ESI,[ECX].SAFEARRAY.pvData
     XOR ECX,ECX
     MOV CurrentDomainProperty,ECX
SPr__:
     CMP ECX,EDX
     JE EPr__
     PUSH ECX
     PUSH EDX
     MOV EAX,[ESI]
     LEA ECX,__lpstrname
     PUSH ECX
     MOV EDX, EAX
     PUSH EDX   
     MOV EDX,[EDX]   
     CALL DWORD PTR [EDX+48]
     .IF !EAX
     invoke CompareString, LOCALE_USER_DEFAULT, NORM_IGNORECASE, __lpstrname,-1,BSTR$("CurrentDomain"),13
     .IF EAX == CSTR_EQUAL
     invoke SysFreeString,__lpstrname
     MOV EAX,[ESI]
     MOV CurrentDomainProperty,EAX
     POP  EDX
     POP  ECX
     jmp EPr__
     .ENDIF
     invoke SysFreeString,__lpstrname
     .ENDIF
     POP  EDX
     POP  ECX
     INC  ECX
     ADD  ESI,4
     JMP SPr__
EPr__:
     .IF CurrentDomainProperty
     LEA ECX,vtDefaultDomain
     PUSH ECX
     PUSH 0
     PUSH 0
     PUSH 0
     PUSH 0
     PUSH 0
     MOV EDX, CurrentDomainProperty
     PUSH EDX   
     MOV EDX,[EDX]   
     CALL DWORD PTR [EDX+76]
     .IF !EAX
     MOV DefaultDomain ,offset vtDefaultDomain
     MOV EAX,DefaultDomain
     RET
     .ELSE
     __ExeptionMsg BSTR$("CurrentDomain.GetValue FAIL")
     MOV EAX,FALSE
     .ENDIF
     .ELSE
     __ExeptionMsg BSTR$("CurrentDomainProperty FAIL ")
     MOV EAX,FALSE
     .ENDIF
     .ELSE
     MOV EAX,FALSE
     .ENDIF
     .ELSE
     MOV EAX,FALSE
     .ENDIF
     .ENDIF


Also, if the above block of code does NOT execute, then __Private_GetBasicMethods doesn't execute,...:icon_eek:
Arrgh !!! I'm so confused here, that I'm not even sure I'm expressing the situation correctly,...:icon_eek:

...So,...I launched ProcessExplorer to see what DLLs were being loaded by the version 4 CLR when calling __GetDefaultDomain, and, weirdly enough, the DLL: mscorlib.ni.dll (https://blogs.msdn.microsoft.com/junfeng/2004/11/11/mscorlib-ni-dll/) is loaded into the process address space.
...And,...so,...finally,...what is supposed to be happening here ???
Title: Re: Masm32Ref
Post by: mabdelouahab on June 28, 2016, 09:54:44 PM
Hi ZEN again,
please send me the full code and I will explain to you what is the problem

Quote from: Zen on June 28, 2016, 08:40:43 AM
...So,...I launched ProcessExplorer to see what DLLs were being loaded by the version 4 CLR when calling __GetDefaultDomain, and, weirdly enough, the DLL: mscorlib.ni.dll (https://blogs.msdn.microsoft.com/junfeng/2004/11/11/mscorlib-ni-dll/) is loaded into the process address space.
...And,...so,...finally,...what is supposed to be happening here ???

.NI.Dll ( Native Image) it is just a Dll that contains the compiled code of an assembly
Title: Re: Masm32Ref
Post by: Zen on June 30, 2016, 05:09:18 AM
Good news,...MABDELOUAHAB,
I am now UNSTUCK. The procedure CallBackFunction_GetMsCorLibAssembly is clearly just there to confirm that Mscorlib was loaded by the version 4 CLR. I modified the code slightly, tested the code, and it works.
I added some code to your DotNetHelper.inc file so I could figure out what the COM interface method, CALL DWORD PTR [EDX+28] does. The Unicode string that is returned is: mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089. So, the reason that CompareStringW was NOT returning CSTR_EQUAL is simple. You wrote this in the original DotNetHelper.inc:
     invoke CompareString, LOCALE_USER_DEFAULT, NORM_IGNORECASE, __lpstrname,9,BSTR$("mscorlib,"),9   

I changed that by just substituting a BSTR pointer to the Unicode string, "mscorlib.ni.dll" for the string "mscorlib" in the BSTR$ Macro, and changed the number of characters in each string to be compared from 9 to 8. Like this:
     invoke CompareStringW, LOCALE_USER_DEFAULT, NORM_IGNORECASE, __lpstrname, 8, bstmscorlibni, 8    ;    Modified from original ("mscorlib.ni.dll")

The CompareStringW function now works (returning  CSTR_EQUAL) without having to change anything else. And, almost everything else in the .IF MsCorLib block (noted above) works after substituting BSTR strings for the BSTR$ Macro.
I'm almost done, and, then I will post the entire test app. I've modified the code in numerous places (just minor rearrangements, for the most part). I wanted it all to work correctly before posting it.
Title: Re: Masm32Ref
Post by: mabdelouahab on June 30, 2016, 09:27:55 AM
ZEN what is happening with you? you sed that:
Quote from: Zen on June 30, 2016, 05:09:18 AM
... The Unicode string that is returned is: mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089. So, the reason that CompareStringW was NOT returning CSTR_EQUAL is simple. You wrote this in the original DotNetHelper.inc:
     invoke CompareString, LOCALE_USER_DEFAULT, NORM_IGNORECASE, __lpstrname,9,BSTR$("mscorlib,"),9   

..
What are the first nine letters of :"mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" Of course, it is "mscorlib,"
Why not work with you ??????
Why do you use first 8 letters of "mscorlib.ni.dll"
Do "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" equal "mscorlib.ni.dll" ?????
I do not understand you

With different versions of CLR, sometimes it is loaded 2 assembly with each other:
Quote"mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
"mscorlib.resources"
What is the difference between the two strings  when we use CompareStringW, is that the 9 letters of the first is "mscorlib," and the 9 letters of the secend is "mscorlib."

ZEN
I have designed for you wStrings.inc, because you have a problem with BSTR$ Macro, Have you tried the new version of the DotNetHelper.inc, which does not contain BSTR$ macro?

Title: Re: Masm32Ref
Post by: Zen on July 01, 2016, 04:12:02 AM
Sorry, MABDELOUAHAB,
...But, that string "mscorlib" looked like it had a period at the end (yes, I've changed a few things in DotNetHelper.inc). And, I had no idea what type of string CompareStringW was comparing "mscorlib,"to (I naturally assumed that the string returned from CALL DWORD PTR [EDX+28] was, "mscorlib.dll", or some variant of that). Anyway, you could call CompareStringW twice, once comparing to "mscorlib" and, then comparing to "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089". This might produce better results especially if you have run MASM32Ref against a version four component assembly. Just an idea.

But, really, this is a minor issue, easily modified. What I'm REALLY interested in is what the COM interface method calls are for lines of code like:
     LEA ECX,__lpstrname
     PUSH ECX
     MOV EDX, __Asm    ;     __Asm must be a pointer, but, to what ???
     PUSH EDX   
     MOV EDX,[EDX]   
     CALL DWORD PTR [EDX+28]    ;    Unknown COM method call. 

...from, CallBackFunction_GetMsCorLibAssembly.   

...Or, these three, from __GetDefaultDomain:
     MOV EDX, MsCorLib
     PUSH EDX   
     MOV EDX,[EDX]   
     CALL DWORD PTR [EDX+68]    ;    Unknown COM method call.   


     MOV EDX, tAppDomain
     PUSH EDX   
     MOV EDX,[EDX]   
     CALL DWORD PTR [EDX+308]    ;    Unknown COM method call.     


     LEA ECX,__lpstrname
     PUSH ECX
     MOV EDX, EAX
     PUSH EDX   
     MOV EDX,[EDX]   
     CALL DWORD PTR [EDX+48]    ;    Unknown COM method call.     


...__Private_GetBasicMethods also contains a number of Unknown COM interface method calls,...

I realize that all my posts must seem annoying to you,...but, that is not my intent. I think that the difference in the native language that we each speak is making it unnecessarily difficult to communicate with each other. I'm just interested in understanding in great detail, how your source code works.
Title: Re: Masm32Ref
Post by: GoneFishing on July 01, 2016, 06:21:00 PM
HELLO GUYS,

Here's my little example I was talking about in my previous post .
It was written as an answer to  this question (http://masm32.com/board/index.php?topic=4648.msg50010#msg50010)
I use QWORD's METHOD macro to call methods of managed interfaces implemented as structures in CLRDEFS.INC :



... 

;   struct __declspec(uuid("05f696dc-2b29-3663-ad8b-c4389cf2a713"))
_AppDomain STRUCT
    IUnknown                            <>
    METHOD(GetTypeInfoCount ,          _this:LPVOID, pcTInfo:LPVOID )
    METHOD(GetTypeInfo ,               _this:LPVOID, iTInfo:UINT, lcid:LCID, ppTInfo:LPVOID )
    METHOD(GetIDsOfNames ,             _this:LPVOID, riid:LPVOID, rgszNames:LPOLESTR, cNames:UINT,lcid:LCID, rgDispId:LPVOID )
    METHOD(_Invoke ,                   _this:LPVOID, dispIdMember:DWORD, riid:LPVOID,lcid:LCID, wFlags:DWORD, pDispParams:LPVOID, pVarResult:LPVOID, pExcepInfo:LPVOID, puArgErr:LPVOID )
    METHOD(get_ToString ,              _this:LPVOID, pRetVal:BSTR  )
    METHOD(Equals ,                    _this:LPVOID, other:VARIANT, pRetVal:VARIANT_BOOL  )
    METHOD(GetHashCode ,               _this:LPVOID, pRetVal:LPVOID )
    METHOD(GetType ,                   _this:LPVOID, pRetVal: ptr _Type  )
    METHOD(InitializeLifetimeService , _this:LPVOID, pRetVal:VARIANT )
    METHOD(GetLifetimeService ,        _this:LPVOID, pRetVal:VARIANT )
    METHOD(get_Evidence ,              _this:LPVOID, pRetVal:ptr _Evidence )
    METHOD(add_DomainUnload ,          _this:LPVOID, value:ptr _EventHandler  )
    METHOD(remove_DomainUnload ,       _this:LPVOID, value:ptr _EventHandler  )
    METHOD(add_AssemblyLoad ,          _this:LPVOID, value:ptr _AssemblyLoadEventHandler  )
    METHOD(remove_AssemblyLoad ,       _this:LPVOID, value:ptr _AssemblyLoadEventHandler  )
    METHOD(add_ProcessExit ,           _this:LPVOID, value:ptr _EventHandler  )
    METHOD(remove_ProcessExit ,        _this:LPVOID, value:ptr _EventHandler  )
    METHOD(add_TypeResolve ,           _this:LPVOID, value:ptr _ResolveEventHandler )
    METHOD(remove_TypeResolve ,        _this:LPVOID, value:ptr _ResolveEventHandler )
    METHOD(add_ResourceResolve ,       _this:LPVOID, value:ptr _ResolveEventHandler )
    METHOD(remove_ResourceResolve ,    _this:LPVOID, value:ptr _ResolveEventHandler )
    METHOD(add_AssemblyResolve ,       _this:LPVOID, value:ptr _ResolveEventHandler )
    METHOD(remove_AssemblyResolve ,    _this:LPVOID, value:ptr _ResolveEventHandler )
    METHOD(add_UnhandledException ,    _this:LPVOID, value:ptr _UnhandledExceptionEventHandler  )
    METHOD(remove_UnhandledException , _this:LPVOID, value:ptr _UnhandledExceptionEventHandler  )
    METHOD(DefineDynamicAssembly ,     _this:LPVOID, _name:ptr _AssemblyName , access:AssemblyBuilderAccess , pRetVal:ptr _AssemblyBuilder  )
    METHOD(DefineDynamicAssembly_2 ,   _this:LPVOID, _name:ptr _AssemblyName , access:AssemblyBuilderAccess , dir:BSTR , pRetVal:ptr _AssemblyBuilder  )
    METHOD(DefineDynamicAssembly_3 ,   _this:LPVOID, _name:ptr _AssemblyName , access:AssemblyBuilderAccess , Evidence:ptr _Evidence , pRetVal:ptr _AssemblyBuilder  )
    METHOD(DefineDynamicAssembly_4 ,   _this:LPVOID, _name:ptr _AssemblyName , access:AssemblyBuilderAccess , requiredPermissions:ptr _PermissionSet, optionalPermissions:ptr _PermissionSet , refusedPermissions:ptr _PermissionSet, pRetVal:ptr _AssemblyBuilder  )
    METHOD(DefineDynamicAssembly_5 ,   _this:LPVOID, _name:ptr _AssemblyName , access:AssemblyBuilderAccess , dir:BSTR, Evidence:ptr _Evidence , pRetVal:ptr _AssemblyBuilder  )
    METHOD(DefineDynamicAssembly_6 ,   _this:LPVOID, _name:ptr _AssemblyName , access:AssemblyBuilderAccess , dir:BSTR, requiredPermissions:ptr _PermissionSet, optionalPermissions:ptr _PermissionSet , refusedPermissions:ptr _PermissionSet, pRetVal:ptr _AssemblyBuilder  )
    METHOD(DefineDynamicAssembly_7 ,   _this:LPVOID, _name:ptr _AssemblyName , access:AssemblyBuilderAccess , Evidence:ptr _Evidence , requiredPermissions:ptr _PermissionSet, optionalPermissions:ptr _PermissionSet , refusedPermissions:ptr _PermissionSet, pRetVal:ptr _AssemblyBuilder  )
    METHOD(DefineDynamicAssembly_8 ,   _this:LPVOID, _name:ptr _AssemblyName , access:AssemblyBuilderAccess , dir:BSTR, Evidence:ptr _Evidence , requiredPermissions:ptr _PermissionSet, optionalPermissions:ptr _PermissionSet , refusedPermissions:ptr _PermissionSet, pRetVal:ptr _AssemblyBuilder  )
    METHOD(DefineDynamicAssembly_9 ,   _this:LPVOID, _name:ptr _AssemblyName , access:AssemblyBuilderAccess , dir:BSTR, Evidence:ptr _Evidence , requiredPermissions:ptr _PermissionSet, optionalPermissions:ptr _PermissionSet , refusedPermissions:ptr _PermissionSet, IsSynchronized:VARIANT_BOOL , pRetVal:ptr _AssemblyBuilder  )
    METHOD(CreateInstance ,            _this:LPVOID, AssemblyName:BSTR, typeName:BSTR ,pRetVal:ptr  _ObjectHandle  )
    METHOD(CreateInstanceFrom ,        _this:LPVOID, assemblyFile:BSTR, typeName:BSTR ,pRetVal:ptr  _ObjectHandle  )
    METHOD(CreateInstance_2 ,          _this:LPVOID, AssemblyName:BSTR, typeName:BSTR , activationAttributes:SAFEARRAY,pRetVal:ptr  _ObjectHandle  )
    METHOD(CreateInstanceFrom_2 ,      _this:LPVOID, assemblyFile:BSTR, typeName:BSTR , activationAttributes:SAFEARRAY,pRetVal:ptr  _ObjectHandle  )
    METHOD(CreateInstance_3 ,          _this:LPVOID, AssemblyName:BSTR, typeName:BSTR , ignoreCase:VARIANT_BOOL,  bindingAttr:BindingFlags , Binder:ptr _Binder , args:SAFEARRAY , culture:ptr _CultureInfo, activationAttributes:SAFEARRAY,securityAttributes:ptr  _Evidence ,pRetVal:ptr  _ObjectHandle  )
    METHOD(CreateInstanceFrom_3 ,      _this:LPVOID, assemblyFile:BSTR, typeName:BSTR , ignoreCase:VARIANT_BOOL,  bindingAttr:BindingFlags , Binder:ptr _Binder , args:SAFEARRAY , culture:ptr _CultureInfo, activationAttributes:SAFEARRAY,securityAttributes:ptr  _Evidence ,pRetVal:ptr  _ObjectHandle  )
    METHOD(Load ,                      _this:LPVOID, assemblyRef:ptr _AssemblyName, pRetVal:ptr _Assembly  )
    METHOD(Load_2 ,                    _this:LPVOID, assemblyString:BSTR, pRetVal:ptr _Assembly  )
    METHOD(Load_3 ,                    _this:LPVOID, rawAssembly:SAFEARRAY , pRetVal:ptr _Assembly  )
    METHOD(Load_4 ,                    _this:LPVOID, rawAssembly:SAFEARRAY , rawSymbolStore:SAFEARRAY , pRetVal:ptr _Assembly  )
    METHOD(Load_5 ,                    _this:LPVOID, rawAssembly:SAFEARRAY , rawSymbolStore:SAFEARRAY , securityEvidence:ptr _Evidence , pRetVal:ptr _Assembly  )
    METHOD(Load_6 ,                    _this:LPVOID, assemblyRef:ptr _AssemblyName, assemblySecurity:ptr _Evidence , pRetVal:ptr _Assembly  )
    METHOD(Load_7 ,                    _this:LPVOID, assemblyString:BSTR, assemblySecurity:ptr _Evidence , pRetVal:ptr _Assembly  )
    METHOD(ExecuteAssembly ,           _this:LPVOID, assemblyFile:BSTR, assemblySecurity:ptr _Evidence , pRetVal:LPVOID )
    METHOD(ExecuteAssembly_2 ,         _this:LPVOID, assemblyFile:BSTR, pRetVal:LPVOID )
    METHOD(ExecuteAssembly_3 ,         _this:LPVOID, assemblyFile:BSTR, assemblySecurity:ptr _Evidence , args:SAFEARRAY , pRetVal:LPVOID )
    METHOD(get_FriendlyName ,          _this:LPVOID, pRetVal:BSTR  )
    METHOD(get_BaseDirectory ,         _this:LPVOID, pRetVal:BSTR  )
    METHOD(get_RelativeSearchPath ,    _this:LPVOID, pRetVal:BSTR  )
    METHOD(get_ShadowCopyFiles ,       _this:LPVOID, pRetVal:VARIANT_BOOL  )
    METHOD(GetAssemblies ,             _this:LPVOID, pRetVal:SAFEARRAY  )
    METHOD(AppendPrivatePath ,         _this:LPVOID, Path:BSTR )
    METHOD(ClearPrivatePath ,          _this:LPVOID)
    METHOD(SetShadowCopyPath ,         _this:LPVOID, s:BSTR )
    METHOD(ClearShadowCopyPath ,       _this:LPVOID)
    METHOD(SetCachePath ,              _this:LPVOID, s:BSTR )
    METHOD(SetData ,                   _this:LPVOID, _name:BSTR, data:VARIANT )
    METHOD(GetData ,                   _this:LPVOID, _name:BSTR, pRetVal:VARIANT)
    METHOD(SetAppDomainPolicy ,        _this:LPVOID, domainPolicy:ptr _PolicyLevel )
    METHOD(SetThreadPrincipal ,        _this:LPVOID, principal:ptr IPrincipal )
    METHOD(SetPrincipalPolicy ,        _this:LPVOID, policy:PrincipalPolicy )
    METHOD(DoCallBack ,                _this:LPVOID, theDelegate:ptr _CrossAppDomainDelegate )
    METHOD(get_DynamicDirectory ,      _this:LPVOID, pRetVal:BSTR  )
_AppDomain ENDS

....




Title: Re: Masm32Ref
Post by: GoneFishing on July 02, 2016, 06:29:43 PM
ZENEXIT or ZEXIT  :(
or even better ZeNxit which sounds like a  dangerous disease  :dazzled:

*** WHISH YOU WERE HERE ***
Title: Re: Masm32Ref
Post by: HSE on July 03, 2016, 01:21:36 AM
This subject is like tennis. I have not played in the last 30 years, but is funny to see in the TV. Now defiant favorite to contest ".NET-cup" surrender.  :(


          I vote for ZenIn !!!!
Title: Re: Masm32Ref
Post by: Zen on September 17, 2016, 09:06:56 AM
Well, I've been working on an independent .NET Framework Hosting Application. It basically uses the same techniques that MABDELOUAHAB uses in MASM32Ref, but it doesn't use any of the output files from MASM32Ref or, the procedures in DotNetHelper.inc. I've been doing this just to find out how difficult it is to create an unmanaged application in MASM assembly language that accesses .NET Framework classes and methods correctly.
It requires a RIDICULOUS amount of code,...and, you'd have to be COMPLETELY INSANE to write it,...but, it does work,...
If anyone is interested, I can post the source code, along with a tutorial. :bgrin:
I suspect that only MABDELOUAHAB will be interested in this. But, I have converted a number of MsCorLib.dll COM interface (IDL) files to MASM-compatible (COM) STRUCT include files, that might be useful and more convenient to use in second generation MASM32Ref (if there ever is one). For example: the _AppDomain Interface, MSDN (https://msdn.microsoft.com/en-us/library/system._appdomain(v=vs.110).aspx), the _Assembly Interface, MSDN (https://msdn.microsoft.com/en-us/library/system.runtime.interopservices._assembly(v=vs.110).aspx), the _Type Interface, NSDN (https://msdn.microsoft.com/en-us/library/system.runtime.interopservices._type(v=vs.110).aspx), and, the _MethodInfo Interface, MSDN (https://msdn.microsoft.com/en-us/library/system.runtime.interopservices._methodinfo(v=vs.110).aspx)

I also have a second application that I was working on which is the test app for the DotNetHelper.inc routines. I haven't been through all of MABDELOUAHAB's code,...but, it all seems to work pretty well (he definitely has the correct approach). This application is unfinished (I've kind of lost interest in it). But, I can also post the source code, if anyone is interested. Structurally, I haven't really changed much, but, I've altered the format extensively,...and added a Log File, which records the status of all of the routines tested, so that you can easily determine why the code is failing (if it does so). ...And, it can easily be extended.

There are some fairly significant problems inherent in this type of development. The most significant is the number of different .NET Framework Class Library Versions that are installed by default on the different Windows Operating System Versions. You can read all the gory details here: NET Framework Versions and Dependencies, MSDN (https://msdn.microsoft.com/en-us/library/bb822049(v=vs.110).aspx). Also, there is not a debugger (on this planet) that can follow the code execution in both native Win32 code and .NET Framework MSIL execution,...so, if you have an unresolved error,...it will, in all probability, stay unsolved for all eternity. And, the big mystery that I could not solve is capturing (or exporting) .NET Framework Exceptions (there are many types of them) to unmanaged MASM COM HRESULT program code (although in most cases, the .NET Framework does this for you). So,...unfortunately,  what you see are a lot of application crashes when things go wrong. This can be very annoying. :dazzled:

Below,...is a zip file containing a listing of all the types contained in MsCorLib.dll (the main .NET Framework assembly that the Common Language Runtime loads when it is started),...and, the System Assembly (Version Four):
Title: Re: Masm32Ref
Post by: HSE on September 17, 2016, 11:48:23 PM
Hi COM masters!
I'm a follower of "the ZEN adventures" just for fun. If someday I grow up, I will try seriously to use the XML reader, and not so seriously before that :biggrin:
Thanks for show these funny meanderings. :t
Title: Re: Masm32Ref
Post by: Zen on September 18, 2016, 06:43:34 AM
...Ah,...HAH !!!

...Just as I suspected,...nobody's really interested in this COM Interop .NET Framework stuff,...except, malcontents, and, the deranged,...:bgrin: