The MASM Forum

Projects => Rarely Used Projects => RosAsm => Topic started by: guga on June 08, 2013, 01:56:26 PM

Title: HTML to RTF
Post by: guga on June 08, 2013, 01:56:26 PM
Can someone help me converting this code to assembly ?


VERSION 5.00
Object = "{3B7C8863-D78F-101B-B9B5-04021C009402}#1.2#0"; "Richtx32.ocx"
Begin VB.Form Form1
   Caption         =   "Rtf2Html"
   ClientHeight    =   8670
   ClientLeft      =   60
   ClientTop       =   345
   ClientWidth     =   13815
   LinkTopic       =   "Form1"
   ScaleHeight     =   8670
   ScaleWidth      =   13815
   StartUpPosition =   3  'Windows Default
   Begin VB.CommandButton Command2
      Caption         =   "Convertir HTML to RTF"
      BeginProperty Font
         Name            =   "Tahoma"
         Size            =   9
         Charset         =   0
         Weight          =   700
         Underline       =   0   'False
         Italic          =   0   'False
         Strikethrough   =   0   'False
      EndProperty
      Height          =   405
      Left            =   7515
      TabIndex        =   4
      Top             =   3660
      Width           =   5265
   End
   Begin VB.PictureBox picNet
      Height          =   3960
      Left            =   180
      ScaleHeight     =   3900
      ScaleWidth      =   6180
      TabIndex        =   3
      Top             =   4500
      Width           =   6240
   End
   Begin RichTextLib.RichTextBox RichTextBox1
      Height          =   2865
      Left            =   180
      TabIndex        =   2
      Top             =   1050
      Width           =   6270
      _ExtentX        =   11060
      _ExtentY        =   5054
      _Version        =   393217
      ScrollBars      =   3
      RightMargin     =   6270
      AutoVerbMenu    =   -1  'True
      FileName        =   "C:\Program Files\Microsoft Visual Studio\VB98\Rich2Html\EXEMPLE1.rtf"
      TextRTF         =   $"RTF 2 HTML 2 RTF.frx":0000
   End
   Begin VB.TextBox Text1
      Height          =   2985
      Left            =   6930
      MultiLine       =   -1  'True
      ScrollBars      =   2  'Vertical
      TabIndex        =   1
      Text            =   "RTF 2 HTML 2 RTF.frx":05D9
      Top             =   375
      Width           =   6405
   End
   Begin VB.CommandButton Command1
      Caption         =   "Convertir RTF to HTML"
      BeginProperty Font
         Name            =   "Tahoma"
         Size            =   9
         Charset         =   0
         Weight          =   700
         Underline       =   0   'False
         Italic          =   0   'False
         Strikethrough   =   0   'False
      EndProperty
      Height          =   405
      Left            =   180
      TabIndex        =   0
      Top             =   195
      Width           =   5550
   End
   Begin RichTextLib.RichTextBox RichTextBox2
      Height          =   4050
      Left            =   7125
      TabIndex        =   8
      Top             =   4485
      Width           =   6270
      _ExtentX        =   11060
      _ExtentY        =   7144
      _Version        =   393217
      ScrollBars      =   3
      RightMargin     =   6270
      AutoVerbMenu    =   -1  'True
      TextRTF         =   $"RTF 2 HTML 2 RTF.frx":05DF
   End
   Begin VB.Label Label5
      Caption         =   "--->"
      BeginProperty Font
         Name            =   "MS Sans Serif"
         Size            =   13.5
         Charset         =   0
         Weight          =   700
         Underline       =   0   'False
         Italic          =   0   'False
         Strikethrough   =   0   'False
      EndProperty
      Height          =   375
      Left            =   6510
      TabIndex        =   10
      Top             =   5790
      Width           =   510
   End
   Begin VB.Label Label4
      Caption         =   "Ceci est un un autre RichTextbox qui reçoi  le contenu du WebBrowser"
      Height          =   270
      Left            =   7125
      TabIndex        =   9
      Top             =   4155
      Width           =   5685
   End
   Begin VB.Label Label3
      Caption         =   "Ceci est la source HTML produite"
      Height          =   270
      Left            =   6930
      TabIndex        =   7
      Top             =   120
      Width           =   5685
   End
   Begin VB.Label Label2
      Caption         =   "Ceci est un replacement du contrôle WebBrowser de VB (éditable aussi):"
      Height          =   270
      Left            =   180
      TabIndex        =   6
      Top             =   4215
      Width           =   5685
   End
   Begin VB.Label Label1
      Caption         =   "Ceci est un RichTextbox qu'on peut éditer:"
      Height          =   270
      Left            =   180
      TabIndex        =   5
      Top             =   780
      Width           =   5685
   End
End
Attribute VB_Name = "Form1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Option Explicit
' But: ce petit programme converte du texte Rtf en code Html et vice-versa
' Auteur: vicosta (http://www.vbfrance.com)
' Notes: La gestion du clipboard n'est pas prise en charge
'        Il faut encore du code supplémentaire afin d'obtenir plus de précision

Dim WithEvents WebB As VBControlExtender
Attribute WebB.VB_VarHelpID = -1
Private Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags&, ByVal dwExtraInfo&)

Private Sub Form_Load()
Set WebB = GetMyBrowser(picNet)
End Sub

Private Sub Command1_Click() 'Convertir RTF to HTML
    Const OLECMDEXECOPT_DODEFAULT = 0
    Const OLECMDID_SELECTALL = 17
    Const OLECMDID_PASTE = 13
RichTextBox1.SetFocus
'SendKeys "^a^c" ' ne fonctionne pas en mode IDE, alors
SSendkeys vbKeyA, True 'sélectionner et ...
SSendkeys vbKeyC, True 'copier tout
RichTextBox1.SelLength = 0
With WebB.object
    .Document.DesignMode = "On"
    .ExecWB OLECMDID_SELECTALL, OLECMDEXECOPT_DODEFAULT
     DoEvents
    .ExecWB OLECMDID_PASTE, OLECMDEXECOPT_DODEFAULT
     DoEvents
     Text1 = .Document.body.innerHTML
'    .Document.DesignMode = "Off"
End With
End Sub

Private Sub Command2_Click() 'Convertir HTML to RTF
    Const OLECMDEXECOPT_DODEFAULT = 0
    Const OLECMDID_SELECTALL = 17
    Const OLECMDID_COPY = 12
    Const OLECMDID_CLEARSELECTION = 18
With WebB.object
    .ExecWB OLECMDID_SELECTALL, OLECMDEXECOPT_DODEFAULT
     DoEvents
    .ExecWB OLECMDID_COPY, OLECMDEXECOPT_DODEFAULT
    .ExecWB OLECMDID_CLEARSELECTION, OLECMDEXECOPT_DODEFAULT
End With
RichTextBox2.SetFocus
SSendkeys vbKeyA, True 'sélectionner tout et ...
SSendkeys vbKeyV, True 'remplacer par le contenu du ClipBoard
End Sub

' petite fonction pour ne pas rajouter le contrôle WebBrowser dans ce project
'
Function GetMyBrowser(objContainer As PictureBox, Optional Url As String = "about:blank") As VBControlExtender
'On Error GoTo IEMissing
Set GetMyBrowser = objContainer.Parent.Controls.Add("Shell.Explorer", "wcIE" & Int(Timer), objContainer)
With GetMyBrowser
    .object.Navigate2 Url '  , 14&
    .Move 0, 0, objContainer.ScaleWidth, objContainer.ScaleHeight
    .Visible = True
    .object.Silent = True
End With
Exit Function
IEMissing:
MsgBox Err.Description
End Function

' la fonction vb Sendkeys provoque erreur en mode IDE, alors on la remplace par SSendkeys
'
Sub SSendkeys(Key As KeyCodeConstants, Optional Ctrl As Boolean, Optional Shift As Boolean)
Const KEYEVENTF_EXTENDEDKEY = &H1
Const KEYEVENTF_KEYUP = &H2
If Ctrl Then keybd_event vbKeyControl, 0, 0, 0
If Shift Then keybd_event vbKeyShift, 0, 0, 0
DoEvents
keybd_event Key, 0, 0, 0
DoEvents
keybd_event Key, 0, KEYEVENTF_KEYUP, 0
DoEvents
If Ctrl Then keybd_event vbKeyControl, 0, KEYEVENTF_KEYUP, 0
If Shift Then keybd_event vbKeyShift, 0, KEYEVENTF_KEYUP, 0
DoEvents
End Sub


thanks in advance
Title: Re: HTML to RTF
Post by: TouEnMasm on June 08, 2013, 04:01:37 PM

Seem to be just a dialog box.
create it with resed (ketilo) giving it the same controls and same sizes (same look)  and it's done.
The CreateDialogParam fonction is used to show the dialog.
You need also a waiting loop.
code for dialog box is as follow:

invoke mybox
mybox PROTO
Dlgmybox   PROTO  :DWORD,:DWORD,:DWORD,:DWORD
;################################################################
mybox  PROC
local valeurinitialisation :DWORD
jmp overtxt
zzzzmybox db "IDD_MYBOX",0 ;enlever le #define IDD_MYBOX.. dans la ressource
overtxt:
mov eax,NULL
mov valeurinitialisation,eax
invoke CreateDialogParam,Hinst, addr zzzzmybox,Hwnd,OFFSET Dlgmybox,valeurinitialisation
; invoke DialogBoxParam,Hinst, addr zzzzmybox,Hwnd,OFFSET Dlgmybox,valeurinitialisation

Findemybox:
ret
mybox endp

;################################################################

Dlgmybox  PROC uses esi edi ebx HdialBox:DWORD,uMsg:DWORD,wParam:DWORD, lParam:DWORD
Local HListBox1:DWORD
Local phrase[MAX_PATH]:BYTE

; gere les evenements
.if     uMsg == WM_INITDIALOG
return TRUE ;windows attribue le focus
;return FALSE ; la boite a defini le focus
.elseif uMsg == WM_CLOSE
invoke PostMessage,HdialBox,WM_DESTROY,NULL,NULL
.elseif uMsg == WM_DESTROY
;invoke EndDialog,HdialBox,NULL ;DialogBoxParam
invoke DestroyWindow,HdialBox ;CreateDialogParam
;invoke PostQuitMessage,NULL ;stop loop messages
.elseif uMsg == WM_COMMAND
HIWORD wParam ;controls events
mov edx,eax
LOWORD wParam ;IDentificateurs de  commandes
mov ebx,lParam ; handle du controle
.if eax == 0 ;button id ....
.elseif eax == 1
.endif
.else
mov eax,FALSE
jmp FindeDlgmybox
.endif
mov  eax,TRUE
FindeDlgmybox:
ret
Dlgmybox endp

;#########################################################################

code for messages loop


;################################################################
Message_Loop PROC
local msg:MSG
@@:
INVOKE     GetMessage, addr msg, NULL, 0, 0
.if eax == 1         ;aucune erreur accepter
INVOKE     TranslateMessage, addr msg           ;prend le message
INVOKE     DispatchMessageA , addr msg          ;envoi les messages aux fenêtres
jmp @B
.endif
FindeMessage_Loop:
mov eax,msg.wParam
ret
Message_Loop endp


and then use it


  invoke mybox
invoke Message_Loop




Title: Re: HTML to RTF
Post by: guga on June 08, 2013, 04:14:03 PM
Hi ToutEnMasm

tks, but how to port the OLECMDEXECOPT_DODEFAULT (Com browsers for IID_IWebBrowser2) ?

It seems it used clsidWebBrowser2 to copy the contents of a html page and paste it as a full RTF file.
Title: Re: HTML to RTF
Post by: guga on June 08, 2013, 04:41:43 PM
OK, i´m quite finding it (i guess)

.ExecWB OLECMDID_SELECTALL, OLECMDEXECOPT_DODEFAULT seems to be equivalent to:



[OLECMDEXECOPT_DODEFAULT: D$ 0]
[IWEBBROWSER2_QUERYSTATUSWB 0D4]

iCall IWEBBROWSER2_QUERYSTATUSWB D$BrowserPointer, &OLECMDID_SELECTALL, OLECMDEXECOPT_DODEFAULT

Title: Re: HTML to RTF
Post by: TouEnMasm on June 09, 2013, 03:05:24 AM
The only valuable information i see in this source is that he use Richtx32.ocx.
Download it first.
Try to install it
Try to get is typelib, an idl file.
It can be a work to do that.

A good soluce,download a free one
HTMLtoRTF Converter Pro 3.0.0 (build October 27th, 2008).
Title: Re: HTML to RTF
Post by: jj2007 on June 09, 2013, 03:59:24 AM
Hi Guga,

If you just want character formatting, then EM_GETCHARFORMAT with SCF_SELECTION is the way to go. I use it to export code snippets in TechniColorTM to this forum, but it's not a big deal to do the same in HTML.
Title: Re: HTML to RTF
Post by: guga on June 09, 2013, 04:42:43 AM
Hi JJ

good idea, but this works mainly for copying from RTF to RTF. I was thinking on a way to copy the contents of a  html (I mean, what we see on the screen) and paste it as RTF without having to make a HTML parser for it.  I read on a  Forum that internally on the Ole com data there is a way  to  export html to rtf directly, but it seems to be undocumented.

On my previous thread, we can register a new clipboard format to get the html contents. On this way, it is possible to make a parser for it. But, the goal is not to use a parser at all, just let ole com do all the work.
Title: Re: HTML to RTF
Post by: Dubby on June 09, 2013, 05:12:40 AM
ahh.. finally I understand it partially.. I'm not a VB guy..

Ok so there are 2 "text boxes" which the first is the html box and the other is RTF box right?
and there are two button which convert RTF to HTML and vice versa... right...?

and I just found this MSDN page. I'm sure that it'll be useful:
http://msdn.microsoft.com/en-us/library/aa752127(v=vs.85).aspx

sorry I cannot go further,,,  :(

hope this helps...
Title: Re: HTML to RTF
Post by: jj2007 on June 09, 2013, 06:48:00 AM
Check Converting between RTF and HTML (http://code.msdn.microsoft.com/Converting-between-RTF-and-aaa02a6e), it looks promising smells of .not, unfortunately :icon_mrgreen:

But this works fine, provided you have MS Word:

include \masm32\MasmBasic\MasmBasic.inc        ; download (http://masm32.com/board/index.php?topic=94.0)

RtfClip$ MACRO MbLimit
  push rv(RegisterClipboardFormat, "Rich Text Format")
  push MbBufSize/4
  call MbClipP
  EXITM <MbC:>
ENDM

        Init
        MsgBox 0, cStyle$("Copy some formatted text\nfrom your browser,\nmake sure MS Word is running,\nthen click OK here"), "Html to RTF converter:", MB_OKCANCEL
        .if eax==IDOK
                SendWordCommands INIT        ; prepare a DDE session; MS Word must be running
                .if eax
                        SendWordCommands "[AppHide:ScreenUpdating 0:FileNewDefault:EditPaste:EditSelectAll:EditCopy:FileClose 2:AppMinimize]"
                        SendWordCommands EXIT        ; finish DDE session
                        Let esi=RtfClip$()
                        MsgBox 0, Left$(esi, 1000), "Does it look nice? Then paste it ...", MB_OK
                .else
                        MsgBox 0, "MS Word doesn't answer", "Sorry", MB_OK
                .endif
        .endif
        Exit
end start
Title: Re: HTML to RTF
Post by: guga on June 09, 2013, 08:26:42 AM
great work JJ

buyt, i guess i found the starting point yo an automated HTML o RTF and vice-versa.

There is something called encapsulated html inside a rtf file.
http://msdn.microsoft.com/en-us/library/ee204432%28v=exchg.80%29.aspx

It seems to be completelly browser independent. I just found this and will see if this algorithm is already coded inside one of the OS dlls. I remember seeing this inside cdosys.dll, but i´m not sure yet.

Title: Re: HTML to RTF
Post by: guga on June 09, 2013, 08:57:05 AM
Ok, i guess it is really cdosys.dll.

This file contains the code to encapsulate HTML to RTF and vice-versa. It was coded as a library, most probably belonging to outlook2003. There is a file called rtfhtml.dll from outlook2003 that is exactly a converter "Outlook RTF/HTML Converter". The problem is how to use this thing. Since i didn´t found any documentation for all of this yet, except the huge pdfs archives from M$

Also, here seems a valid information for converting back from RTF to HTMLand compressed RTF
http://ruby-msg.googlecode.com/svn/trunk/lib/mapi/rtf.rb
Title: Re: HTML to RTF
Post by: TouEnMasm on June 09, 2013, 10:34:15 PM

Have a look also on the clipbboard formats .I have an aplly who change html to rtf and rtf to html just changing the clipbaord format.
That seems to easy ...
Title: Re: HTML to RTF
Post by: jj2007 on June 09, 2013, 10:57:36 PM
Quote from: ToutEnMasm on June 09, 2013, 10:34:15 PM

Have a look also on the clipbboard formats .I have an aplly who change html to rtf and rtf to html just changing the clipbaord format.
That seems to easy ...

Post it, please :t
Title: Re: HTML to RTF
Post by: TouEnMasm on June 09, 2013, 11:18:56 PM
It's a c++ free code I find very well done.
Don't cry it's in french.
http://www.cppfrance.com//code.aspx?ID=54692 (http://www.cppfrance.com//code.aspx?ID=54692)
In case who you couldn't compile it,i post the executable.

I have posted also an richedit editor (source of mine) who use OLE to insert image in rtf.He accept also to do a little job with Html and can made a first step in the problem.

http://masm32.com/board/index.php?topic=646.msg5283#msg5283 (http://masm32.com/board/index.php?topic=646.msg5283#msg5283)
Title: Re: HTML to RTF
Post by: jj2007 on June 09, 2013, 11:45:22 PM
Quote from: ToutEnMasm on June 09, 2013, 11:18:56 PM
In case who you couldn't compile it,i post the executable.

No conversion HTML to RTF here:
Title: Re: HTML to RTF
Post by: TouEnMasm on June 10, 2013, 02:14:20 AM

Made a copy (clipboard) of an html page.Run the prog,the menu will not be the same.
Title: Re: HTML to RTF
Post by: jj2007 on June 10, 2013, 02:37:15 AM
Quote from: ToutEnMasm on June 10, 2013, 02:14:20 AM

Made a copy (clipboard) of an html page.Run the prog,the menu will not be the same.

That's true. It will show "RTF as text", and when you paste it e.g. in MS Word, you'll get the HTML codes. A truly intelligent solution but not to our problem.
Title: Re: HTML to RTF
Post by: guga on June 10, 2013, 05:09:43 AM
CPPFrance is an excelent site. I frequently have some convertionsand ideas done from this site, but, the clipboard viewer is not the solution yet.

I strongly believe that the solution is understanding how the encapsulation of a HTML to RTFworks and use this dll (or simply, build an app able to make full encapsulations) will do the job. But, since there is a lack of information about this encapsulation technique im not sure if we can be able to encapsulate images on the RTF (or even, is a richedit viewer will understand what is a css or js file encapsulated as well).
Title: Re: HTML to RTF
Post by: TouEnMasm on June 10, 2013, 03:15:27 PM
Quote
im not sure if we can be able to encapsulate images on the RTF
I am sure it is possible ,it is done by the sample for wich i have given a link.
I use this feature in my IDE to use title in image (wordart or free open office).
It use OLE and do not use all of his features.

The lazy method is to find a tool who made it and search the dll who made the job.
That's true.You will surely find this dll on free download on internet.
Free office do that and you have surely here the good path to have a fast soluce.

******** windbg can give you great knowledge ***********
Title: Re: HTML to RTF
Post by: guga on June 10, 2013, 05:11:00 PM
WinXp already provide this Dll.It is called cdosys.dll. It is inside windows/system directory. It seems that there is a Ole IID for acessing it Probably IID_IMAPIProp), but i´m not sure what it is, since there is a lack of information about it.

Here are some functions existent inside that dll, that makes me think that it is possible to use this windows dll to do the encapsulations without having to program one completelly.

It uses mapi library as defined here: http://www.codeproject.com/Articles/19139/Bridging-the-gap-between-NET-and-Extended-MAPI



; =============== S U B R O U T I N E =======================================

; Attributes: bp-based frame

; public: virtual long __stdcall HTMLRTF::QueryInterface(struct _GUID const &, void * *)
?QueryInterface@HTMLRTF@@UAGJABU_GUID@@PAPAX@Z proc near
; DATA XREF: .text:const HTMLRTF::`vftable'o
; .text:const RTFHTML::`vftable'o ...

arg_0 = dword ptr  8
arg_4 = dword ptr  0Ch
arg_8 = dword ptr  10h

mov edi, edi
push ebp
mov ebp, esp
push esi
mov esi, [ebp+arg_4]
push edi
push 4
pop ecx
mov edi, offset __GUID_00000000_0000_0000_c000_000000000046
xor eax, eax
repe cmpsd
jz short loc_4766EB9D
mov esi, [ebp+arg_4]
push 4
pop ecx
mov edi, offset _IID_IMAPIProp
xor eax, eax
repe cmpsd
jz short loc_4766EB9D
mov eax, [ebp+arg_8]
and dword ptr [eax], 0
mov eax, 80004002h
jmp short loc_4766EBAD
; ---------------------------------------------------------------------------

loc_4766EB9D: ; CODE XREF: HTMLRTF::QueryInterface(_GUID const &,void * *)+16j
; HTMLRTF::QueryInterface(_GUID const &,void * *)+27j
mov eax, [ebp+arg_0]
mov ecx, [ebp+arg_8]
mov [ecx], eax
mov ecx, [eax]
push eax
call dword ptr [ecx+4]
xor eax, eax

loc_4766EBAD: ; CODE XREF: HTMLRTF::QueryInterface(_GUID const &,void * *)+34j
pop edi
pop esi
pop ebp
retn 0Ch
?QueryInterface@HTMLRTF@@UAGJABU_GUID@@PAPAX@Z endp

; ---------------------------------------------------------------------------




; =============== S U B R O U T I N E =======================================

; Attributes: bp-based frame

; protected: long __thiscall HTMLRTF::ScEncapsulateTag(class HTMLTOKEN *, unsigned long)
?ScEncapsulateTag@HTMLRTF@@IAEJPAVHTMLTOKEN@@K@Z proc near
; CODE XREF: HTMLRTF::ScNInterpret(TOKEN *,ulong)+897p
; HTMLRTF::ScNInterpret(TOKEN *,ulong)+B76p

var_460 = dword ptr -460h
var_45C = dword ptr -45Ch
var_458 = dword ptr -458h
var_454 = byte ptr -454h
var_450 = dword ptr -450h
var_44C = dword ptr -44Ch
CodePage = dword ptr -448h
var_444 = dword ptr -444h
var_440 = dword ptr -440h
var_43C = dword ptr -43Ch
var_438 = dword ptr -438h
var_434 = dword ptr -434h
var_430 = dword ptr -430h
var_42C = dword ptr -42Ch
var_428 = dword ptr -428h
var_424 = dword ptr -424h
var_420 = dword ptr -420h
Dst = byte ptr -41Ch
var_1C = dword ptr -1Ch
ms_exc = CPPEH_RECORD ptr -18h
arg_0 = dword ptr  8
arg_4 = dword ptr  0Ch

push 450h
push offset stru_47611C00
call __SEH_prolog
mov eax, ___security_cookie
mov [ebp+var_1C], eax
mov [ebp+var_424], ecx
mov edi, [ebp+arg_0]
xor edx, edx
mov [ebp+var_420], edx
mov [ebp+var_42C], edx
mov [ebp+var_444], edx
or ebx, 0FFFFFFFFh
mov [ebp+var_430], edx
mov [ebp+var_428], edx
mov [ebp+var_450], 1
mov [ebp+var_44C], 3713001Eh
mov [ebp+ms_exc.disabled], edx
test byte ptr [edi+0Dh], 1
jz loc_476664DF
mov ecx, [ebp+arg_4]
mov eax, 0C00h
and ecx, eax
cmp ecx, eax
jnz loc_476664DF
xor ecx, ecx

loc_47665F75: ; CODE XREF: HTMLRTF::ScEncapsulateTag(HTMLTOKEN *,ulong)+562j
mov [ebp+var_43C], ecx
cmp ecx, [edi+14h]
jnb loc_47666464
lea eax, [ecx+ecx*2]
mov eax, [edi+eax*4+20h]
imul eax, 1Ch
add eax, offset ?rgHTMLTag@@3QBU_htmltag@@B ; _htmltag const * const rgHTMLTag
mov [ebp+var_460], eax
test byte ptr [eax+5], 80h
jz loc_47666456
mov [ebp+var_438], 400h
push edx
lea eax, [ebp+CodePage]
push eax
lea eax, [ebp+var_438]
push eax
lea eax, [ebp+Dst]
push eax
push ecx
push edi
mov ecx, [ebp+var_424]
call ?ScGetParamText@HTMLPARSE@@QAEJPAVHTMLTOKEN@@KPAEPAK2H@Z ; HTMLPARSE::ScGetParamText(HTMLTOKEN *,ulong,uchar *,ulong *,ulong *,int)
mov esi, eax
mov [ebp+var_420], esi
test esi, esi
jl loc_4766650B
push offset Control ; " \t\n\r"
lea eax, [ebp+Dst]
push eax ; Str
call ds:__imp__strspn
pop ecx
pop ecx
mov [ebp+var_440], eax
test eax, eax
jbe short loc_47666024
sub [ebp+var_438], eax
mov ecx, [ebp+var_438]
inc ecx
push ecx ; Size
lea eax, [ebp+eax+Dst]
push eax ; Src
lea eax, [ebp+Dst]
push eax ; Dst
call ds:__imp__memmove
add esp, 0Ch

loc_47666024: ; CODE XREF: HTMLRTF::ScEncapsulateTag(HTMLTOKEN *,ulong)+FFj
cmp [ebp+var_438], 0
jz loc_47666456
and [ebp+var_434], 0
cmp [ebp+Dst], 23h
jz loc_47666456
cmp [ebp+Dst], 3Fh
jz loc_47666153
cmp [ebp+Dst], 3Bh
jz loc_47666153
mov esi, 8004010Fh
mov [ebp+var_420], esi
mov eax, [ebp+var_424]
mov eax, [eax+15BCh]
test eax, 400000h
jz short loc_476660F2
test eax, 800000h
jz short loc_476660F2
push offset a?_1 ; "#?;"
lea eax, [ebp+Dst]
push eax ; Str
call ds:__imp__strcspn
pop ecx
pop ecx
lea eax, [ebp+eax+Dst]
mov [ebp+var_434], eax
movsx ecx, byte ptr [eax]
mov [ebp+var_444], ecx
test ecx, ecx
jz short loc_476660B7
mov byte ptr [eax], 0
jmp short loc_476660BE
; ---------------------------------------------------------------------------

loc_476660B7: ; CODE XREF: HTMLRTF::ScEncapsulateTag(HTMLTOKEN *,ulong)+1B3j
and [ebp+var_434], 0

loc_476660BE: ; CODE XREF: HTMLRTF::ScEncapsulateTag(HTMLTOKEN *,ulong)+1B8j
mov eax, [ebp+var_424]
mov ecx, [eax+1010h]
mov edx, [ecx]
lea esi, [ebp+var_430]
push esi
push 0FFFFFFFFh
push 400h
push dword ptr [eax+1590h]
lea eax, [ebp+Dst]
push eax
call dword ptr [edx+34h]
mov esi, eax
mov [ebp+var_420], esi

loc_476660F2: ; CODE XREF: HTMLRTF::ScEncapsulateTag(HTMLTOKEN *,ulong)+17Ej
; HTMLRTF::ScEncapsulateTag(HTMLTOKEN *,ulong)+185j
cmp esi, 8004010Fh
jnz loc_47666269
and [ebp+var_420], 0
and [ebp+var_440], 0
lea eax, [ebp+var_440]
push eax
push offset aAZaZ_N ; "%*[a-zA-Z.+-]:%n"
lea eax, [ebp+Dst]
push eax ; Src
call ds:__imp__sscanf
add esp, 0Ch
cmp [ebp+var_440], 1
ja loc_47666456
cmp [ebp+var_434], 0
jz short loc_47666153
mov al, byte ptr [ebp+var_444]
mov ecx, [ebp+var_434]
mov [ecx], al
and [ebp+var_434], 0

loc_47666153: ; CODE XREF: HTMLRTF::ScEncapsulateTag(HTMLTOKEN *,ulong)+14Fj
; HTMLRTF::ScEncapsulateTag(HTMLTOKEN *,ulong)+15Cj ...
push 400h ; int
lea eax, [ebp+Dst]
push eax ; MaxCount
mov eax, [ebp+var_424]
push dword ptr [eax+1590h] ; Buf
lea eax, [ebp+Dst]
push eax ; Src
call ?MdURLCombine@@YGJPAD00K@Z ; MdURLCombine(char *,char *,char *,ulong)
mov [ebp+var_458], eax
cmp eax, 1000h
jnz loc_47666456

loc_47666188: ; CODE XREF: HTMLRTF::ScEncapsulateTag(HTMLTOKEN *,ulong)+374j
; HTMLRTF::ScEncapsulateTag(HTMLTOKEN *,ulong)+380j
mov eax, [ebp+var_430]
test eax, eax
jz loc_47666228
and [ebp+var_428], 0
mov ecx, [eax]
lea edx, [ebp+var_428]
push edx
lea edx, [ebp+var_454]
push edx
push 0
lea edx, [ebp+var_450]
push edx
push eax
call dword ptr [ecx+14h]
mov esi, eax
mov [ebp+var_420], esi
cmp esi, 80040105h
jz loc_47666282
cmp esi, 800CCE06h
jz loc_47666282
test esi, esi
jl loc_4766650B
mov eax, [ebp+var_428]
mov eax, [eax]
and eax, 0FFFFh
cmp eax, 0Ah
jz loc_47666282
test esi, esi
jz short loc_47666202
mov [ebp+var_42C], esi

loc_47666202: ; CODE XREF: HTMLRTF::ScEncapsulateTag(HTMLTOKEN *,ulong)+2FDj
mov eax, [ebp+var_430]
mov ecx, [eax]
push 8
push eax
call dword ptr [ecx+10h]
mov esi, eax
mov [ebp+var_420], esi
test esi, esi
jl loc_4766650B
jz short loc_47666228
mov [ebp+var_42C], esi

loc_47666228: ; CODE XREF: HTMLRTF::ScEncapsulateTag(HTMLTOKEN *,ulong)+293j
; HTMLRTF::ScEncapsulateTag(HTMLTOKEN *,ulong)+323j
test ebx, ebx
jge loc_476662C2
mov eax, [ebp+arg_4]
and eax, 0FFFFF7BFh
or eax, 180h
push eax ; int
mov ecx, [ebp+var_424]
push dword ptr [ecx+114Ch] ; CodePage
mov eax, [ebp+var_43C]
lea eax, [eax+eax*2+6]
push dword ptr [edi+eax*4] ; int
push dword ptr [edi+4] ; int
call ?ScWriteBodyText@HTMLRTF@@QAEJPAEKKK@Z ; HTMLRTF::ScWriteBodyText(uchar *,ulong,ulong,ulong)
mov ebx, 9000h
jmp loc_47666307
; ---------------------------------------------------------------------------

loc_47666269: ; CODE XREF: HTMLRTF::ScEncapsulateTag(HTMLTOKEN *,ulong)+1FBj
test esi, esi
jl loc_4766650B
jz loc_47666188
mov [ebp+var_42C], esi
jmp loc_47666188
; ---------------------------------------------------------------------------

loc_47666282: ; CODE XREF: HTMLRTF::ScEncapsulateTag(HTMLTOKEN *,ulong)+2CBj
; HTMLRTF::ScEncapsulateTag(HTMLTOKEN *,ulong)+2D7j ...
xor esi, esi
cmp [ebp+var_428], esi
jz short loc_476662A5
mov ecx, [ebp+var_430]
mov eax, [ecx]
push [ebp+var_428]
push 1
call dword ptr [eax+38h]
mov [ebp+var_428], esi

loc_476662A5: ; CODE XREF: HTMLRTF::ScEncapsulateTag(HTMLTOKEN *,ulong)+38Dj
mov eax, [ebp+var_430]
mov ecx, [eax]
push eax
call dword ptr [ecx+8]
mov [ebp+var_430], esi
mov [ebp+var_420], esi
jmp loc_47666456
; ---------------------------------------------------------------------------

loc_476662C2: ; CODE XREF: HTMLRTF::ScEncapsulateTag(HTMLTOKEN *,ulong)+32Dj
lea eax, [ebx+ebx*2+6]
mov ecx, [edi+eax*4]
lea eax, [ebx+ebx*2]
mov edx, [edi+eax*4+1Ch]
mov ebx, 9000h
push ebx ; int
mov eax, [ebp+var_424]
push dword ptr [eax+114Ch] ; CodePage
mov eax, [ebp+var_43C]
lea eax, [eax+eax*2+6]
mov eax, [edi+eax*4]
sub eax, edx
sub eax, ecx
push eax ; int
mov eax, [edi+4]
add eax, edx
add eax, ecx
push eax ; int
mov ecx, [ebp+var_424]
call ?ScWriteBodyText@HTMLRTF@@QAEJPAEKKK@Z ; HTMLRTF::ScWriteBodyText(uchar *,ulong,ulong,ulong)

loc_47666307: ; CODE XREF: HTMLRTF::ScEncapsulateTag(HTMLTOKEN *,ulong)+367j
mov esi, eax
mov [ebp+var_420], esi
test esi, esi
jl loc_4766650B
jz short loc_4766631F
mov [ebp+var_42C], esi

loc_4766631F: ; CODE XREF: HTMLRTF::ScEncapsulateTag(HTMLTOKEN *,ulong)+41Aj
mov ecx, [ebp+var_424]
cmp [ebp+var_428], 0
jz loc_4766641D
push 9001h ; int
push 0 ; CodePage
push 0FFFFFFFFh ; int
push offset aHtmlbase ; "{\\htmlbase "
call ?ScWriteBodyText@HTMLRTF@@QAEJPAEKKK@Z ; HTMLRTF::ScWriteBodyText(uchar *,ulong,ulong,ulong)
mov esi, eax
mov [ebp+var_420], esi
test esi, esi
jl loc_4766650B
jz short loc_4766635D
mov [ebp+var_42C], esi

loc_4766635D: ; CODE XREF: HTMLRTF::ScEncapsulateTag(HTMLTOKEN *,ulong)+458j
push ebx ; int
push 0 ; CodePage
push 0FFFFFFFFh ; int
mov eax, [ebp+var_428]
push dword ptr [eax+8] ; int
mov ecx, [ebp+var_424]
call ?ScWriteBodyText@HTMLRTF@@QAEJPAEKKK@Z ; HTMLRTF::ScWriteBodyText(uchar *,ulong,ulong,ulong)
mov esi, eax
mov [ebp+var_420], esi
test esi, esi
jl loc_4766650B
jz short loc_4766638E
mov [ebp+var_42C], esi

loc_4766638E: ; CODE XREF: HTMLRTF::ScEncapsulateTag(HTMLTOKEN *,ulong)+489j
push 9001h ; int
push 0 ; CodePage
push 1 ; int
push offset asc_47611B4C ; "}"
mov ecx, [ebp+var_424]
call ?ScWriteBodyText@HTMLRTF@@QAEJPAEKKK@Z ; HTMLRTF::ScWriteBodyText(uchar *,ulong,ulong,ulong)
mov esi, eax
mov [ebp+var_420], esi
test esi, esi
jl loc_4766650B
jz short loc_476663BF
mov [ebp+var_42C], esi

loc_476663BF: ; CODE XREF: HTMLRTF::ScEncapsulateTag(HTMLTOKEN *,ulong)+4BAj
mov eax, [ebp+var_434]
test eax, eax
jz short loc_476663EE
mov cl, byte ptr [ebp+var_444]
mov [eax], cl
push ebx ; int
push [ebp+CodePage] ; CodePage
push 0FFFFFFFFh ; int
push eax ; int
mov ecx, [ebp+var_424]
call ?ScWriteBodyText@HTMLRTF@@QAEJPAEKKK@Z ; HTMLRTF::ScWriteBodyText(uchar *,ulong,ulong,ulong)
mov esi, eax
mov [ebp+var_420], esi

loc_476663EE: ; CODE XREF: HTMLRTF::ScEncapsulateTag(HTMLTOKEN *,ulong)+4CAj
mov ecx, [ebp+var_430]
mov eax, [ecx]
push [ebp+var_428]
push 1
call dword ptr [eax+38h]
and [ebp+var_428], 0
mov eax, [ebp+var_430]
mov ecx, [eax]
push eax
call dword ptr [ecx+8]
and [ebp+var_430], 0
jmp short loc_4766643A
; ---------------------------------------------------------------------------

loc_4766641D: ; CODE XREF: HTMLRTF::ScEncapsulateTag(HTMLTOKEN *,ulong)+42Fj
push ebx ; int
push [ebp+CodePage] ; CodePage
push 0FFFFFFFFh ; int
lea eax, [ebp+Dst]
push eax ; int
call ?ScWriteBodyText@HTMLRTF@@QAEJPAEKKK@Z ; HTMLRTF::ScWriteBodyText(uchar *,ulong,ulong,ulong)
mov esi, eax
mov [ebp+var_420], esi

loc_4766643A: ; CODE XREF: HTMLRTF::ScEncapsulateTag(HTMLTOKEN *,ulong)+51Ej
test esi, esi
jl loc_4766650B
jz short loc_4766644A
mov [ebp+var_42C], esi

loc_4766644A: ; CODE XREF: HTMLRTF::ScEncapsulateTag(HTMLTOKEN *,ulong)+545j
mov ebx, [ebp+var_43C]
mov [ebp+var_45C], ebx

loc_47666456: ; CODE XREF: HTMLRTF::ScEncapsulateTag(HTMLTOKEN *,ulong)+A0j
; HTMLRTF::ScEncapsulateTag(HTMLTOKEN *,ulong)+12Ej ...
mov ecx, [ebp+var_43C]
inc ecx
xor edx, edx
jmp loc_47665F75
; ---------------------------------------------------------------------------

loc_47666464: ; CODE XREF: HTMLRTF::ScEncapsulateTag(HTMLTOKEN *,ulong)+81j
cmp ebx, edx
jl short loc_476664DF
lea eax, [ebx+ebx*2+6]
mov eax, [edi+eax*4]
lea ecx, [ebx+ebx*2]
mov ecx, [edi+ecx*4+1Ch]
push 9000h ; int
mov edx, [ebp+var_424]
push dword ptr [edx+114Ch] ; CodePage
mov esi, [edi+8]
sub esi, ecx
sub esi, eax
push esi ; int
mov esi, [edi+4]
add esi, ecx
add esi, eax
push esi ; int
mov ecx, edx
call ?ScWriteBodyText@HTMLRTF@@QAEJPAEKKK@Z ; HTMLRTF::ScWriteBodyText(uchar *,ulong,ulong,ulong)
mov esi, eax
mov [ebp+var_420], esi
test esi, esi
jl short loc_4766650B
jz short loc_476664B2
mov [ebp+var_42C], esi

loc_476664B2: ; CODE XREF: HTMLRTF::ScEncapsulateTag(HTMLTOKEN *,ulong)+5ADj
push 9001h ; int
push 0 ; CodePage
push 2 ; int
push offset asc_47611B50 ; ">}"
mov ecx, [ebp+var_424]
call ?ScWriteBodyText@HTMLRTF@@QAEJPAEKKK@Z ; HTMLRTF::ScWriteBodyText(uchar *,ulong,ulong,ulong)
mov esi, eax
mov [ebp+var_420], esi
test esi, esi
jl short loc_4766650B
jz short loc_476664DF
mov [ebp+var_42C], esi

loc_476664DF: ; CODE XREF: HTMLRTF::ScEncapsulateTag(HTMLTOKEN *,ulong)+5Ej
; HTMLRTF::ScEncapsulateTag(HTMLTOKEN *,ulong)+70j ...
mov eax, [ebp+arg_4]
test ebx, ebx
jl short loc_476664EB
or eax, 100h

loc_476664EB: ; CODE XREF: HTMLRTF::ScEncapsulateTag(HTMLTOKEN *,ulong)+5E7j
push eax ; int
mov ecx, [ebp+var_424]
push dword ptr [ecx+114Ch] ; CodePage
push dword ptr [edi+8] ; int
push dword ptr [edi+4] ; int
call ?ScWriteBodyText@HTMLRTF@@QAEJPAEKKK@Z ; HTMLRTF::ScWriteBodyText(uchar *,ulong,ulong,ulong)
mov esi, eax
mov [ebp+var_420], esi

loc_4766650B: ; CODE XREF: HTMLRTF::ScEncapsulateTag(HTMLTOKEN *,ulong)+DDj
; HTMLRTF::ScEncapsulateTag(HTMLTOKEN *,ulong)+2DFj ...
or [ebp+ms_exc.disabled], 0FFFFFFFFh
call sub_47666536
test esi, esi
mov eax, esi
jnz short loc_47666520
mov eax, [ebp+var_42C]

loc_47666520: ; CODE XREF: HTMLRTF::ScEncapsulateTag(HTMLTOKEN *,ulong)+61Bj
mov ecx, [ebp+var_1C]
call @__security_check_cookie@4 ; __security_check_cookie(x)
call __SEH_epilog
retn 8
?ScEncapsulateTag@HTMLRTF@@IAEJPAVHTMLTOKEN@@K@Z endp




; =============== S U B R O U T I N E =======================================

; Attributes: bp-based frame

; protected: long __thiscall HTMLRTF::ScOutputRTFString(unsigned char *, unsigned long, unsigned long)
?ScOutputRTFString@HTMLRTF@@IAEJPAEKK@Z proc near
; CODE XREF: HTMLRTF::ScWriteRTFHeader(void)+78p
; HTMLRTF::ScWriteRTFHeader(void)+1E6p ...

arg_0 = dword ptr  8
arg_4 = dword ptr  0Ch
arg_8 = dword ptr  10h

mov edi, edi
push ebp
mov ebp, esp
push esi
push edi
xor edi, edi
cmp [ebp+arg_8], edi
mov esi, ecx
jz short loc_4766317B
push [ebp+arg_8]
mov ecx, [esi+15FCh]
call ?ScSetCpid@OUTSTM@@QAEJK@Z ; OUTSTM::ScSetCpid(ulong)
test eax, eax
jl short loc_47663195
jz short loc_4766317B
mov edi, eax

loc_4766317B: ; CODE XREF: HTMLRTF::ScOutputRTFString(uchar *,ulong,ulong)+Ej
; HTMLRTF::ScOutputRTFString(uchar *,ulong,ulong)+22j
push [ebp+arg_8]
mov ecx, [esi+15FCh]
push [ebp+arg_4]
mov eax, [ecx]
push [ebp+arg_0]
call dword ptr [eax+0Ch]
test eax, eax
jnz short loc_47663195
mov eax, edi

loc_47663195: ; CODE XREF: HTMLRTF::ScOutputRTFString(uchar *,ulong,ulong)+20j
; HTMLRTF::ScOutputRTFString(uchar *,ulong,ulong)+3Cj
pop edi
pop esi
pop ebp
retn 0Ch
?ScOutputRTFString@HTMLRTF@@IAEJPAEKK@Z endp

; ---------------------------------------------------------------------------



The same coding shows here:
http://www.astim.si/patch/zarafa-1250.diff
http://www.wischik.com/lu/programmer/mapi_utils.html
http://download.zarafa.com/community/final/7.1/7.1.4-41394/sourcecode/

So, for what i understood, MAPI objects already have inside a way to convert HTML toRTF and vice-versa. but, how to acess these this functions without having to use messages from outlook is another story :(

The goal is to have acess to mapi interface and use only the needed functions responsable for the conversion.
Title: Re: HTML to RTF
Post by: TouEnMasm on June 10, 2013, 06:16:07 PM

What you say cdosys.dll ?
And after a few seconds i get his typelib,you win.
Download my translator,he wil give you all the needed way to extract all declarations needed by masm.
you need midl (windows sdk) also to do that.
Title: Re: HTML to RTF
Post by: TouEnMasm on June 10, 2013, 06:36:49 PM

The idl file need msado15.dll
just replace it by it's full path:
C:\Program Files\Fichiers communs\System\ado\msado15.dll
Verify it.

Next order the declarations in the idl file,structures,enum, constants ..must be  on top of file.If not,you got errors like this
Quote
.\cdosys.idl(671) : error MIDL2025 : syntax error : expecting a constant expression near "<"
.\cdosys.idl(671) : error MIDL2035 : constant expression expected
.\cdosys.idl(671) : error MIDL2025 : syntax error : expecting ) near "IDispatch"
.\cdosys.idl(672) : error MIDL2025 : syntax error : expecting a type specification near "ConnectModeEnum"
.\cdosys.idl(673) : error MIDL2026 : cannot recover from earlier syntax errors; aborting compilation
Title: Re: HTML to RTF
Post by: TouEnMasm on June 10, 2013, 07:09:37 PM

It's a good day for you.
It's like a game for me now to do that,here the result.
All can be missed now is the full sdk translate.Download it from the "windows include" subforum.
Title: Re: HTML to RTF
Post by: guga on June 10, 2013, 10:09:45 PM
Good work, ToutEnMasm

Btw, i just suceeded to initialize that crappy mapi stuff. Now will ty to acess the Com data in order to convert the rtftohtml

here is the code i made:


;;
References:
http://www.outlookcode.com/archive0/d/mapi.htm
http://msdn.microsoft.com/en-us/library/office/cc963763%28v=office.12%29.aspx
http://msdn.microsoft.com/en-us/library/office/dd181963%28v=office.12%29.aspx
http://msdn.microsoft.com/en-us/library/office/cc815369%28v=office.12%29.aspx
http://www.wischik.com/lu/programmer/mapi_utils.html
http://www.clydesdalesoftware.com/Blog/05-05-15/Building_Outlook_Add-ins_with_ATL_C.aspx
https://www.google.com.br/search?q=rtf%20encapsulated&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:en-US:official&client=firefox-a&channel=np&source=hp
http://msdn.microsoft.com/en-us/library/ee159984%28v=exchg.80%29.aspx
http://msdn.microsoft.com/en-us/library/ee158614%28v=exchg.80%29.aspx
http://msdn.microsoft.com/en-us/library/ee217484%28v=exchg.80%29.aspx
http://social.msdn.microsoft.com/Forums/en-US/outlookdev/thread/bd852fb5-159d-4250-aaa5-3e2a32be0fcb
http://msdn.microsoft.com/en-us/library/office/dd162409%28v=office.12%29.aspx

;;

[szMAPIDLL: B$ 0 #&MAX_PATH]
[pfnMAPIInitialize: D$ 0]
[pfnMAPIUninitialize: D$ 0]
[Sz_MapiError1: B$ "The application could not access an Exchange Server 2010 server.
Try installing the hotfix 2685289 for it as described in:
http://support.microsoft.com/kb/2674185
http://support.microsoft.com/kb/2685289
http://support.microsoft.com/kb/892231/pt-br

If it also fails, it means that you don´t have uou probably don´t have
'Microsoft Exchange Server MAPI Client and Collaboration Data Objects 1.2.1'
installed on your machine, as describe in:
http://support.backup-connect.com/2010/01/21/insufficient-permissions-for-mailbox-backup

Error= Mapi_E_call_failed Detail= Unspecified error:
How to solve error: Error= Mapi_E_call_failed Detail= Unspecified error:
 
When configurating or performing a maillevel backup on a server 2003/2008, the following error can occur:
logonSession 'ERROR= MAPI_E_CALL_FAILED Detail= Unspecified error'
This problem is caused by the MAPI Files that are stored on the system. This is often caused by a previous used backup software.

* To resolve the issue, please verify if the Mapisp32.exe file does exist on the system (C:\WINDOWS\system32\mapisp32.exe).
  In some cases, the Mapisp32.exe file may have been removed or renamed by anti-virus software.
  You can restore this by reinstalling the Microsoft Exchange Server MAPI Client and Collaboration Data Objects 1.2.1 (ExchangeMAPICdo.exe).
  Make sure you uninstall the old version first. Then run Mapisp32.exe.

* Disable old back-up software (i.e. backup exec), and make sure outlook, outlook express or windows mail are not installed on the server.

____________________________________________________________
To install, download it at:
http://www.microsoft.com/en-us/download/confirmation.aspx?id=1004
or
http://download.microsoft.com/download/A/2/4/A24BD8F5-4475-4C3B-B051-7A264B660E90/ExchangeMapiCdo.EXE", 0]

Proc MapiWorks:
    Local @hMapiDLL

    call InitializeMapiFunctions szMAPIDLL, pfnMAPIInitialize, pfnMAPIUninitialize
    On eax = 0, ExitP
    mov D@hMapiDLL eax
    ; Initialize the MAPI subsystem
    call D$pfnMAPIInitialize &NULL
    ; &MAPI_E_INVALID_PARAMETER &MAPI_E_UNKNOWN_FLAGS &MAPI_E_NOT_ENOUGH_RESOURCES &MAPI_E_CALL_FAILED <---- DAMN IT ! &MAPI_E_NOT_INITIALIZED
    ; &MAPI_E_CALL_FAILED = need to install an update http://support.microsoft.com/kb/2674185 http://support.microsoft.com/hotfix/KBHotfix.aspx?kbnum=892231&kbln=pt-br
    ; http://support.backup-connect.com/2010/01/21/insufficient-permissions-for-mailbox-backup/
    ; http://www.microsoft.com/en-us/download/confirmation.aspx?id=1004
    ..If eax <> &S_OK
        .If eax = &MAPI_E_CALL_FAILED
            call 'USER32.MessageBoxA' 0, Sz_MapiError1, {'Error: Mapi Failed (MAPI_E_CALL_FAILED)', 0},  &MB_OK__&MB_ICONWARNING__&MB_SYSTEMMODAL
        .End_If
        call 'KERNEL32.FreeLibrary' D@hMapiDLL
        xor eax eax
        ExitP ; something wrong at initilization
    ..End_If

    ; Here's where you make calls to other MAPI APIs


    ; Uninitialize the MAPI subsystem
    call D$pfnMAPIUninitialize
    call 'KERNEL32.FreeLibrary' D@hMapiDLL
EndP




[s_szMSIApplicationLCID: B$ "Microsoft\\Office\\9.0\\Outlook\0LastUILanguage\0", 0]
[s_szMSIOfficeLCID: B$ "Microsoft\\Office\\9.0\\Common\\LanguageResources\0UILanguage\0InstallLanguage\0", 0]

[s_szMSIOfficeLCID2: B$ "Microsoft\Office\12.0\Common\LanguageResources\0InstalledUIs\0", 0]

Proc InitializeMapiFunctions:
    Arguments @szMAPIDir, @pMapiInit, @pMapiDeInit
    Local @hinstStub, @pfnFGetComponentPath
    Uses edi, ecx, ebx, edx, esi

    mov D@hinstStub 0
    mov D@pfnFGetComponentPath 0
    call 'KERNEL32.LoadLibraryA' {B$ "mapistub.dll", 0}
    If eax = 0
        call 'KERNEL32.LoadLibraryA' {B$ "mapi32.dll", 0} | On eax = 0, ExitP
    End_If
    mov D@hinstStub eax

    call 'KERNEL32.GetProcAddress' eax, {B$ "FGetComponentPath", 0} | mov D@pfnFGetComponentPath eax
    ...If eax <> 0
        mov edi D@szMAPIDir
        call D@pfnFGetComponentPath {B$ "FF1D0740-D227-11D1-A4B0-006008AF820E", 0}, s_szMSIApplicationLCID, edi, &MAX_PATH, &TRUE | on eax <> 0, jmp L1>
        call D@pfnFGetComponentPath {B$ "FF1D0740-D227-11D1-A4B0-006008AF820E", 0}, s_szMSIOfficeLCID, edi, &MAX_PATH, &TRUE | on eax <> 0, jmp L1>
        call D@pfnFGetComponentPath {B$ "FF1D0740-D227-11D1-A4B0-006008AF820E", 0}, s_szMSIOfficeLCID2, edi, &MAX_PATH, &TRUE | on eax <> 0, jmp L1>
        call D@pfnFGetComponentPath {B$ "473FF9A0-D659-11D1-A4B2-006008AF820E", 0}, &NULL, edi, &MAX_PATH, &TRUE
        If eax = 0
            call 'KERNEL32.FreeLibrary' D@hinstStub | xor eax eax | ExitP
        End_If
        L1:
            If B$edi = '\'
                mov B$edi 0
                inc edi
            End_If
    ...End_If
    call 'KERNEL32.GetProcAddress' D@hinstStub, {B$ "MAPIInitialize", 0}
    If eax <> 0
        mov esi D@pMapiInit
        mov D$esi eax
    End_If
    call 'KERNEL32.GetProcAddress' D@hinstStub, {B$ "MAPIUninitialize", 0}
    If eax <> 0
        mov esi D@pMapiDeInit
        mov D$esi eax
    End_If
    mov eax D@hinstStub

EndP



If the error shows up,follows the instructions and install the last hotfixor the "Microsoft Exchange Server MAPI Client and Collaboration Data Objects 1.2.1" at: http://www.microsoft.com/downloads/details.aspx?FamilyID=E17E7F31-079A-43A9-BFF2-0A110307611E&displaylang=en

I was having that crappy error and had no idea,untill i found the solution and install this thing



Of course, all the above code can be simply replaced by a call to the initialize function as:

call 'mapi32.MAPIInitialize' &NULL

But,since i was following M$ instructions, it lead me to that code  :greensml:
At least now i know why i was not being able to initialize the Mapi library.

Now is a matter of see the relationship between mapi32.dll and cdosys.dll, in order to achieve the proper convertion functions.
Title: Re: HTML to RTF
Post by: TouEnMasm on June 10, 2013, 10:47:43 PM

To begin by update your system don't seem to be the good way.Try to make it work as it is.
The header files i have posted don't need any update,try to follow the same path.
The dependances are clear.It is the msado15.dll perhaps another one on your system.If you update ,it could change.


Title: Re: HTML to RTF
Post by: jj2007 on June 11, 2013, 01:12:41 AM
Hi Guga,

I tried the other road, so far with success, at least on Win7. Here is the most important line:

           push ForeignToRtf32(srcfile$, 0, SrcBuf, Chr$(0), 0, offset cbRead)

I'm afraid it requires a well-known library (http://masm32.com/board/index.php?topic=94.0) ;-)

P.S.: Test it by dragging whatever.htm over the executable. Note that pages saved from Masm32 sometimes choke during conversion (but try the samples attached); in contrast, a plain Google.com gets converted but you may have to scroll down 20 pages to get past the css and javascript crap.

The archive contains a second sample, a MS Works doc called MASM32_SDK.wps
Conversion quality is much better...

EDIT: Version b attached, with improved commandline handling (test_tmp.rtf will be now created in the folder of the htm source). Test opening the RTF in MS Word, it looks pretty OK.
Title: Re: HTML to RTF
Post by: TouEnMasm on June 11, 2013, 04:33:33 AM

first step with :

invoke CoCreateInstance,addr CLSID_Message, NULL,CLSCTX_ALL,\
addr IID_IMessage,\
addr ppvIMessage ;ppv out
;eax S_OK réussite
.if ppvIMessage != 0 ;réussite
IMessage  Release
.else
;voir erreurs com
.endif

http://msdn.microsoft.com/en-us/library/ms526451(v=exchg.10).aspx (http://msdn.microsoft.com/en-us/library/ms526451(v=exchg.10).aspx)

Title: Re: HTML to RTF
Post by: guga on June 11, 2013, 11:25:22 AM
Good work guys

toutenasm here goes the msado15 classes and enumerations:

It links to the msado interface that will then call the  cdosys.dll


Also, see here to connect to this thing:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms677563%28v=vs.85%29.aspx



JJ. Excelent work, but it uses office to perform the convertion, right ? I was thinking in something more direct from the OS, and perhaps this encapsulation is the answer, since it seems to convert correctly RTF to HTML and vice-versa preserving the formattings
Title: Re: HTML to RTF
Post by: jj2007 on June 11, 2013, 03:20:15 PM
Quote from: guga on June 11, 2013, 11:25:22 AM
JJ. Excelent work, but it uses office to perform the convertion, right ?

Not really. Html.iec is part of the OS:
Quotehtml.iec........(Microsoft HTML Converter). Needed to be able to copy text from a Webpage and paste it to Wordpad (http://www.graphixanstuff.com/Forum/index.php?showtopic=4958&mode=threaded&pid=78007)

And it works remarkably well, see new attachment in reply #25.
The "embedded" strategy might work in some cases, but it implies that you have a fake RTF file with html containers. Test if that works with a simple RichEd control - I doubt it...
Title: Re: HTML to RTF
Post by: TouEnMasm on June 11, 2013, 04:07:36 PM

To jj,i have free office who is launched by your application.
I give better results when i run it myself.
Title: Re: HTML to RTF
Post by: jj2007 on June 11, 2013, 04:38:40 PM
Quote from: ToutEnMasm on June 11, 2013, 04:07:36 PM

To jj,i have free office who is launched by your application.
I give better results when i run it myself.

My app launches whatever your settings specify for RTF files, so if you have specified free office, you will see test_tmp.rtf in free office.

Re "better results": Post them, please. At least the executable.
Title: Re: HTML to RTF
Post by: TouEnMasm on June 11, 2013, 06:34:43 PM
For the result,i just see the file in a very short lenght window.

I advance in the problem.
With no CDO the Imessage can load html page and work with

invoke CreateBstr,addr sz_null
mov bstr_null,eax
invoke Bstr_Url_File,TXT("C:\Documents and Settings\Luce\Bureau\The MASM Forum - Index.htm")
;invoke CreateBstr,TXT("http://luce.yves.pagesperso-orange.fr")
mov ecx,eax
IMessage CreateMHTMLBody,ecx,cdoSuppressNone,bstr_null,bstr_null
invoke CreateBstr,TXT("IBodyPart")
mov ecx,eax
;IMessage GetInterface ,ecx,addr ppvIBodyPart

I can get the text,the html and view it is loaded with the debugger
other interfaces are accessible in various way

Quote
         invoke CreateBstr,TXT("IBodyPart")
         mov ecx,eax
         IMessage GetInterface ,ecx,addr ppvIBodyPart
Title: Re: HTML to RTF
Post by: guga on June 11, 2013, 07:06:24 PM
Hi JJ

this is an old word converter made in 97

It is old, but interesting, since it can convert some versions of rtf files.

The SDK is defined here:

http://support.microsoft.com/kb/q111716

I`m reading it and trying to port. As soon i finish i´ll post the equates i´m building for this

Aparently it can be done without opening any word processor.
Title: Re: HTML to RTF
Post by: TouEnMasm on June 11, 2013, 07:09:22 PM
Here the way folowed by microsoft to do the conversion
http://code.msdn.microsoft.com/windowsdesktop/Converting-between-RTF-and-aaa02a6e (http://code.msdn.microsoft.com/windowsdesktop/Converting-between-RTF-and-aaa02a6e)
Title: Re: HTML to RTF
Post by: jj2007 on June 11, 2013, 08:44:45 PM
Quote from: guga on June 11, 2013, 07:06:24 PM
Hi JJ

this is an old word converter made in 97

It is old, but interesting, since it can convert some versions of rtf files.

The SDK is defined here:

http://support.microsoft.com/kb/q111716

I`m reading it and trying to port. As soon i finish i´ll post the equates i´m building for this

Aparently it can be done without opening any word processor.

Yes, apparently :biggrin:

What do you call "old"?

C:\Windows\System32\html.iec, 17.2.2012:
Company Name   Microsoft Corporation
File Description   Microsoft HTML Converter
FileVersion   2019.0.0.16978 (WIN7 IE9 RTM.110308-0330)
InternalName   HTML.IEC
Legal Copyright   © Microsoft Corporation. All rights reserved
Title: Re: HTML to RTF
Post by: TouEnMasm on June 11, 2013, 11:57:08 PM

this one is cool
http://www.codeproject.com/Articles/7087/XHTML2RTF-An-HTML-to-RTF-conversion-tool-based-on (http://www.codeproject.com/Articles/7087/XHTML2RTF-An-HTML-to-RTF-conversion-tool-based-on)
Title: Re: HTML to RTF
Post by: jj2007 on June 12, 2013, 01:20:32 AM
QuoteYou have to adapt your application to generate XHTML documents if you want to use the XHTML2RTF conversion tool:

    Include an XML declaration at the beginning of the document:
    Collapse | Copy Code

    <?xml version="1.0" encoding="iso-8859-1" ?>

    Include XHTML namespace declaration (the default) and XHTML2RTF namespace declaration in tag <html>:
::)
Title: Re: HTML to RTF
Post by: TouEnMasm on June 12, 2013, 01:44:42 AM

Must be that can be call a puzzle.I had one page who refuse to be translate and one page (coming from the forum).Just search between the two what is the differences.
:idea:  :biggrin:

Title: Re: HTML to RTF
Post by: TouEnMasm on June 12, 2013, 02:07:42 AM
Making it enough little this give
this one work:
Quote
<?xml version="1.0" encoding="iso-8859-1" ?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:xhtml2rtf="http://www.lutecia.info/download/xmlns/xhtml2rtf">
  <head>
    <title>Hello, World! from file</title>
  </head>
  <body>
    <h1>Hello, World!</h1>
  </body>
</html>

The one who don't work
Quote
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<title>Sans titre</title>
<meta name="generator" content="Namo WebEditor v4.0">
</head>
<body bgcolor="white" text="black" link="blue" vlink="purple" alink="red">
<p>&nbsp;</p>
</body>
</html>

Soluce:
Quote
<?xml version="1.0" encoding="iso-8859-1" ?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:xhtml2rtf="http://www.lutecia.info/download/xmlns/xhtml2rtf">
<head>
<title>Sans titre</title>
</head>
<body bgcolor="white" text="black" link="blue" vlink="purple" alink="red">
</body>
</html>
follow the links and you have two namespaces :idea: :idea: :idea:
Title: Re: HTML to RTF
Post by: guga on June 12, 2013, 08:10:37 AM
Hi JJ....i called "old" because it is from 97. Tehre is no actualization on the documents so far, and the functions are undocumented on msdn (except for the sdk.doc i provided on the link).

I´m analysing the functionality of the functions to make the proper equates and structures for it. The functions seems interesting and it uses the convertes inside windows at:
HKEY_LOCAL_MACHINE\Software\Microsoft\Shared Tools\ (Import and Export subkeys)

I´m trying to make it work the function "GetReadNames", but so far, no success. It crashed all the time and now that i found how to fix, the result is always FALSE. I´m ot sure if the input i must provide the path of the registry (aparently not), or it will be only used as an output buffer for the files names/extentions/descriptions supported for import and export.
Title: Re: HTML to RTF
Post by: guga on June 12, 2013, 09:46:39 AM
OK, i guess i found it. this function GetReadNames needs an enumeration of the registry in order to get the proper buffers

There is a limit ? of 160 pointers to strings that can be used on the converter, but i didn´t check that yet
Title: Re: HTML to RTF
Post by: jj2007 on June 12, 2013, 03:39:46 PM
Quote from: guga on June 12, 2013, 08:10:37 AM
Hi JJ....i called "old" because it is from 97. Tehre is no actualization on the documents so far, and the functions are undocumented on msdn

That applies to most of Windows ;-)

Quote... uses the convertes inside windows at:
HKEY_LOCAL_MACHINE\Software\Microsoft\Shared Tools\ (Import and Export subkeys)

AFAIK it's the other way round: The HTML converter uses HTML.iec. The IEC probably stands for "Internet Explorer Converter", and MS produces a new version with every MSIE update, it seems.
Title: Re: HTML to RTF
Post by: TouEnMasm on June 12, 2013, 04:10:00 PM
If i understand well there is texts translators provided by the system at:
QuoteHKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Text Converters
the converters had a .cnv extension who are dll.
usage of those dll are given by the GC1039 (winword converter) who give codes and all needed informations to use them.
More clear like that,not ?.


Title: Re: HTML to RTF
Post by: jj2007 on June 12, 2013, 04:25:26 PM
Quote from: ToutEnMasm on June 12, 2013, 04:10:00 PM
If i understand well there is texts translators provided by the system at:
QuoteHKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Text Converters
the converters had a .cnv extension who are dll.

Try renaming one of them (you will succeed). Then try to rename C:\Windows\System32\html.iec, and you may understand that the latter is more important for the OS - simply because html.iec is the low level engine for the HTML version of the Shared Tools converters, and probably has some other uses, too.

What my application (http://masm32.com/board/index.php?topic=2006.msg21067#msg21067) (successfully) does is use the lowest level DLL directly, without making strange excursions to the wonderful world of COM.
Title: Re: HTML to RTF
Post by: TouEnMasm on June 12, 2013, 07:12:04 PM

Quote
rename C:\Windows\System32\html.iec
No need to rename

invoke LoadLibrary,TXT("C:\windows\system32\html.iec")

works
Title: Re: HTML to RTF
Post by: jj2007 on June 12, 2013, 07:57:43 PM
Quote from: ToutEnMasm on June 12, 2013, 07:12:04 PM

Quote
rename C:\Windows\System32\html.iec
No need to rename

invoke LoadLibrary,TXT("C:\windows\system32\html.iec")

works

Of course it works, debug my code and Olly will show you LoadLibrary :P

I told you to rename it because you can't rename it - access denied. That file is too important for Windows...
Title: Re: HTML to RTF
Post by: TouEnMasm on June 12, 2013, 11:40:06 PM

Perhaps a more up to date version,the one you posted had 16 bits code (strange)
http://msdn.microsoft.com/en-us/library/office/dd300649(v=office.12).aspx (http://msdn.microsoft.com/en-us/library/office/dd300649(v=office.12).aspx)
Title: Re: HTML to RTF
Post by: TouEnMasm on June 13, 2013, 12:03:49 AM

At this instant seems there is only the clipboard viewer and the script who can translate html to rtf (I don't count the run of any office or free office).
More sample ?
Title: Re: HTML to RTF
Post by: jj2007 on June 13, 2013, 01:09:16 AM
Quote from: ToutEnMasm on June 12, 2013, 11:40:06 PM
Perhaps a more up to date version,the one you posted had 16 bits code (strange)

The one I posted in reply #25 (http://masm32.com/board/index.php?topic=2006.msg21067#msg21067) has definitely no 16 bits code. Unless your browser does strange things to you ::)

Quote from: ToutEnMasm on June 13, 2013, 12:03:49 AM
At this instant seems there is only the clipboard viewer and the script who can translate html to rtf

There is no clipboard viewer in Win7*), and I doubt that the XP clipboard viewer is able to do the translation (but I will check tonight). Re "script", my code is not a script (and it's the only "sample" that is working so far, unless you are hiding something from us).

*) Microsoft (http://answers.microsoft.com/en-us/windows/forum/windows_7-windows_programs/view-clipboard-contents/4055ba8a-781b-44fe-946f-1779035510e9) recommends "How To View & Manage Clipboard In Windows 7 & Vista (http://www.thewindowsclub.com/windows-clipboard-manager-viewer)":

QuoteClipboard in Windows 7 | 8

In Windows XP this file was situated in C:\Windows\System32\clipbrd.exe. It is now missing as a part of the Windows 7 | 8 installation. You can try to copy it from a Windows XP installation, if you have access to it, and paste it in your System32 folder. In most cases this is known to work.
Clipboard Viewer

If you wish, you can download Windows Clipboard Viewer from here (http://www.thewindowsclub.com/downloads/Clipboard-Viewer.zip). But if it does not work or if you are confronted with a message of sorts : Entry Point Not Found, then you may try to run it in Windows XP/SP2 compatibility mode and see if it works.

That is great professional advice, Microsoft :t
Unfortunately, it doesn't display HTML or RTF formats, let alone convert them :(
Title: Re: HTML to RTF
Post by: TouEnMasm on June 13, 2013, 01:19:49 AM

I was talking about the GC1039 (winword converter) who show 16 bits and 32 bits documentation (SDK.DOC and SDK32.doc).
About it i had just find a sample who failed to convert a html to rtf (without office or same things)
Title: Re: HTML to RTF
Post by: jj2007 on June 13, 2013, 01:24:53 AM
Quote from: ToutEnMasm on June 13, 2013, 01:19:49 AM
I was talking about the GC1039 (winword converter) who show 16 bits and 32 bits documentation (SDK.DOC and SDK32.doc).

Oh sorry, I thought you were talking to me. Apologies.
Title: Re: HTML to RTF
Post by: guga on June 13, 2013, 09:37:03 AM
A couple of things about those functions:

1) Function GetReadNames seems to be completelly useless. I can´t make this stupidity to work on WinXPand all it does it check on the register for theconvertersavailable and supposedly register a new one (HTML.iec with only HTML data to be converted - no RTF, doc, Lotus etc etc). The documentation itself says to choose to use FRegisterConverter insetad....but...
All function FRegisterConverter is to create a new key on the register to insert the path, name and extension for the HTMLdata. So, for this to work weneed to do something like:


call EnumSubKeys esi, &HKEY_LOCAL_MACHINE, {B$ "SOFTWARE\Microsoft\Shared Tools\Text Converters\Import\Lotus123", 0}
call 'html.iec.FRegisterConverter' D$esi ; this create a newkey for each subkey. EX: on Lotus123 it will create a IMport/ExportSubkeys to HTML.iec
_________________________________________

Proc EnumSubKeys:
    Arguments @phKey, @dwKey, @szSubKey
    Local @cSubKeys
    Uses ebx, ecx, edx, esi

    mov esi D@phKey
    mov D$esi 0
    call 'advapi32.RegOpenKeyExA' &HKEY_LOCAL_MACHINE, D@szSubKey, 0, &KEY_ALL_ACCESS, esi
    ..If eax = &ERROR_SUCCESS
        mov D@cSubKeys 0
        lea ebx D@cSubKeys
        call 'advapi32.RegQueryInfoKeyA' D$esi, &NULL, &NULL, &NULL, ebx, &NULL, &NULL,
                                         &NULL, &NULL, &NULL, &NULL, &NULL
        If eax = &ERROR_SUCCESS
            mov eax D$ebx
        Else
            xor eax eax
        End_If
    ..Else
        xor eax eax
    ..End_If

EndP



This will create a key with the following specifications
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Text Converters\Import\HTML\Text Converters]

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Text Converters\Import\HTML\Text Converters\Export]

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Text Converters\Import\HTML\Text Converters\Export\HTML]
"Extensions"="htm html htx"
"Name"=""
"Path"="C:\\temp\\HTML.iec"

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Text Converters\Import\HTML\Text Converters\Import]

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Text Converters\Import\HTML\Text Converters\Import\HTML]
"Extensions"="htm html htx otm"
"Name"=""
"Path"="C:\\temp\\HTML.iec"


If path is  {B$ "SOFTWARE\Microsoft\Shared Tools\Text Converters\Import\Lotus123", 0} will use Lotus123 to save the new key
If Path is  {B$ "SOFTWARE\Microsoft\Shared Tools\Text Converters\Import\Word12", 0} will use Word12 to save the new key
etc
If we set  {B$ "SOFTWARE\Microsoft\Shared Tools\", 0} will use create the HTML.iec path as the new import/export converter to be used with. The problem is, it will overwritte any other converters with the same name.For instance i had on the converter path html32.cnv, that was saved onto the register. After applying the FRegisterConverter it replaces the html32.cnv with html.iec (which seems to be the same btw), except for the file versions
html.iec = 2018.0.0.23486
html32.cnv= 2003.1100.8165.0
both are: Microsoft HTML Converter, but html.iec is the newer one.

So, get FRegisterConverter and GetNames seems to be useless, because all they do is get the path for the converters, that can be used on a OpenDialog,for example to display a list of possible imports/exports extensions.

The only point of interest on this function is that it register newformats to be imported or exported for use with images inside html, by creting the KEys:
MSWORD
WINWORD
MSPUB
MSWORKS
WORDPAD
FRONTPG

So, if the register contains this keys, it will create the subkeys (text convert) as:
SOFTWARE\Microsoft\Shared Tools\Text Converters\Import\MSWORD\Text Converters\Import\

Which means that "MSWORD", "WINWORD" etc are the module names for this converter to work properly
Those are responsable for determining the type of Codepage for the exported/imported html files. he codePage that seems available are:
CP_UTF8
CP_950
CP_932
CP_949
CP_936

So, thinking on that we may add registry entries for MSWORD", "WINWORD etc and simply use them as paths for the InitConverter32 function choose which CodePagewill be outputed on html.iec.
For example, even if i don´t have winword installed, i can still usehtml.iec to produce a html from a RTF similar (if not equal) as if i had winword,simply adding a keyword on the registry such as:
SOFTWARE\Microsoft\Shared Tools\Text Converters\Import\MSWORD
and setting the values for path, name and description accordly.

2) Also since getreadnames are a pain to use and not work as expected and FRegisterConverter is not suitable if we already have other converters o the registry we can replace them with:


Proc GetReadNames::
    Arguments @haszClass, @haszDescrip, @haszExt
    Local @hKey, @Index
    Uses esi, ecx, edx


    mov D@hKey 0
    lea esi D@hKey
    call EnumSubKeys esi, &HKEY_LOCAL_MACHINE, {B$ "SOFTWARE\Microsoft\Shared Tools\Text Converters\Import", 0}
    On eax = 0, ExitP
    mov D@Index eax
    call RegGetKeyValue D$esi, D@Index, D@haszClass, D@haszDescrip, D@haszExt

    ; close the main key before exiting
    call 'advapi32.RegCloseKey' D$esi

EndP


Proc EnumSubKeys:
    Arguments @phKey, @dwKey, @szSubKey
    Local @cSubKeys
    Uses ebx, ecx, edx, esi

    mov esi D@phKey
    mov D$esi 0
    call 'advapi32.RegOpenKeyExA' &HKEY_LOCAL_MACHINE, D@szSubKey, 0, &KEY_ALL_ACCESS, esi
    ..If eax = &ERROR_SUCCESS
        mov D@cSubKeys 0
        lea ebx D@cSubKeys
        call 'advapi32.RegQueryInfoKeyA' D$esi, &NULL, &NULL, &NULL, ebx, &NULL, &NULL,
                                         &NULL, &NULL, &NULL, &NULL, &NULL
        If eax = &ERROR_SUCCESS
            mov eax D$ebx
        Else
            xor eax eax
        End_If
    ..Else
        xor eax eax
    ..End_If

EndP



[achKey: B$ 0 #Size_Of_String]
[lngData: B$ 0 #2000]
[lngDataLen: D$ 2000]

[VALENT:
VALENT.ve_valuename: D$ SzPath
VALENT.ve_valuelen: D$ Size_Of_String
VALENT.ve_valueptr: D$ 0
VALENT.ve_type: D$ &REG_SZ

VALENT.ve_valuename2: D$ SzName
VALENT.ve_valuelen2: D$ Size_Of_String
VALENT.ve_valueptr2: D$ 0
VALENT.ve_type2: D$ &REG_SZ

VALENT.ve_valuename3: D$ SzExtensions
VALENT.ve_valuelen3: D$ Size_Of_String
VALENT.ve_valueptr3: D$ 0
VALENT.ve_type3: D$ &REG_SZ]

[SzPath: B$ "Path", 0]
[SzName: B$ "Name", 0]
[SzExtensions: B$ "Extensions", 0]

Proc RegGetKeyValue:
    Arguments @dwKey, @Index, @haszClass, @haszDescrip, @haszExt
    Local @cbName, @SubKeyLen, @lngDataLen, @NewIndex, @phKey2, @Path, @Descr, @Ext
    Uses ebx, ecx, esi, edi, edx, eax
   
    lea ebx D@cbName
    mov D$ebx 255
    mov edi D@haszClass | mov edi D$edi | mov D@Path edi
    mov edi D@haszDescrip | mov edi D$edi | mov D@Descr edi
    mov edi D@haszExt | mov edi D$edi | mov D@Ext edi
    xor esi esi
    .While esi < D@Index
   
        ; get the subkey name.Ex: HTML, Lotus123,
        call 'advapi32.RegEnumKeyExA' D@dwKey, esi, achKey, ebx, &NULL, &NULL, &NULL, &NULL
        ...If eax = &ERROR_SUCCESS
            lea edi D@phKey2
            mov D$edi 0
            call 'advapi32.RegOpenKeyExA' D@dwKey, achKey, 0, &KEY_ALL_ACCESS, edi
            ..If eax = &ERROR_SUCCESS
                ; get the values of the subkey and store them on the proper buffers
                call 'advapi32.RegQueryMultipleValuesA' D$edi, VALENT, 3, lngData, lngDataLen
                .If eax = &ERROR_SUCCESS
               
                    ; Path
                    mov edi D@Path
                    call StrCpy D$VALENT.ve_valueptr, edi
                    mov edi D@Path | add edi Size_Of_String | mov D@Path edi

                    ; Description
                    mov edi D@Descr
                    call StrCpy D$VALENT.ve_valueptr2, edi
                    mov edi D@Descr | add edi Size_Of_String | mov D@Descr edi

                    ; Extension
                    mov edi D@Ext
                    call StrCpy D$VALENT.ve_valueptr3, edi
                    mov edi D@Ext | add edi Size_Of_String | mov D@Ext edi

                    call ClearBuffer lngData, 2000
                .End_If
            ..End_If
            ; close this subkey on each loop
            call 'advapi32.RegCloseKey' D$edi

        ...End_If
        mov D$ebx Size_Of_String
        inc esi
    .End_While
EndP



The GetReadNames function can handle 160 converters and their parameters are pointers to an array of strinsg related to path,description and extension. Exampleof usage:


[Teste1: D$ SzPath]
[Teste2: D$ SzDescription]
[Teste3: D$ SzExtension]
[SzPath: B$ ? #(160*Size_Of_String)]
[SzDescription: B$ ? #(160*Size_Of_String)]
[SzExtension: B$ ? #(160*Size_Of_String)]

[Size_Of_String 255]
call GetReadNames Teste1, Teste2, Teste3
Title: Re: HTML to RTF
Post by: guga on June 13, 2013, 10:04:18 AM
The RegisterApp is described as follows:



;;
    Function: RegisterApp

    Learn about calling app, and teach it about us.
    The RegisterApp API is the means by which the converter and application can negotiate details about the conversion to follow.
    The application calls the converter with a list of preferences from the application and the converter returns a list of its own preferences.
    Having both sets of preferences, both the application and the converter can deduce the correct behavior for this particular conversion.
    The lists are self-describing and may be extended in future. This mechanism is designed to be used for all new refinements to the conversions API,
    and there should consequently be no extensions to older mechanisms such as the flags in PFN_RTF or even the flags to RegisterApp.
    It is strongly recommended that all converters implement this API. However, not all legacy applications will call it.

    Arguments
   
    lFlags: A group of flags specifying options to the converter, defined below:

            NAME                    Value   Description
            REGAPP_VER              01      Specifies major and minor version of Word with which the RTF of the converter is compliant.
                                            A converter using this opcode must specify at least Word 6.0 level RTF; newer versions of Word
                                            are not guaranteed to be able to provide RTF compatible with older readers.
                                            This opcode takes two short arguments, the major and minor version numbers.
            REGAPP_DOCFILE          02      Specifies whether or not the converter can handle Word document files, and whether or not the converter
                                            can handle regular files. This opcode takes one short argument. Bit 0 indicates whether the converter
                                            accepts docfiles, bit 1 indicates whether the converter accepts non-docfiles.
            REGAPP_CHARSET          03      Specifies the character set (either ANSI or OEM) in which file names should be encoded.
                                            The default is OEM, in which case the converter must convert the OEM file names to ANSI itself,
                                            using the Win32 OemToChar function. Using this opcode to specify that the converter can handle
                                            ANSI file namesis preferable, as the conversion from ANSI to OEM and then back to ANSI is flawed,
                                            making some file names impossible to pass to a converter. This opcode takes a single byte argument
                                            which is the character set.
            REGAPP_RELOADONSAVE     04      The presence of this opcode specifies that Word should reload the document from the newly-saved file after
                                            an export conversion. This opcode takes no arguments.
            REGAPP_PICPLACEHOLD     05      The presence of this opcode specifies that Word should include placeholder pictures with size information
                                            when emitting RTF for INCLUDEPICTURE fields. This opcode takes no arguments.
            REGAPP_FAVOURUNICODE    06      The presence of this opcode specifies that Word should prefer Unicode over other character representations,
                                            such as DBCS, when emitting RTF. This opcode takes no arguments.
            REGAPP_NOCLASSIFYCHARS  07      The presence of this opcode specifies that Word should not break text runs by character set classification.
                                            This opcode takes no arguments.
            REGAPP_FILE NAME        080     Word exports documents through converters to temporary files and renames the temporary files after the
                                            conversion completes successfully. This opcode takes one variable length argument which specifies the
                                            final filename to which Word will rename the finished conversion. The filename is not '\0'-terminated.
                                            Its length is inferred from the opcode's cbSize field. This filename is always in the ANSI character set.
            REGAPP_INTERIMPATH      081     The presence of this opcode indicates that Word will move the file after the export operation completes;
                                            for example to an FTP server. This opcode takes no arguments.

            RegisterApp still supports the flags passed from the application to the converter in its first argument.
            This is why the function was originally provided. The aditional equates below can be used in combination with the above ones.

            NAME                        Value   Bit     Description
            REGAPP_FREGAPPPCTCOMP        01     0       The application sets this flag if it is prepared to accept percent complete numbers from the
                                                        converter on RtfToForeign32 calls. When this bit is set, the application is required to pass
                                                        a valid handle to a PCVT structure inside the ghBuff buffer on the RtfToForeign32 call.
                                                        The setting of this bit does not require that the converter provide percent complete numbers but
                                                        it can if you like.
            REGAPP_FREGAPPNOBINARY      02      1       This flag is set if the application is not prepared to deal with binary data in the RTF stream
                                                        from the converter. If this flag is set, the converter will provide all picture data in hexadecimal
                                                        form rather than binary. Because some older RTF readers do not correctly handle binary data,
                                                        this flag is assumed set if RegisterApp is not called.
            REGAPP_FREGAPPPREVIEW       04      2       This flag is set if the converter is being called in a preview mode (such as the Find preview in Word).
                                                        The converter can respond to this setting by not displaying dialog boxes, using default responses,
                                                        and taking other actions to enhance performance when previewing a document.
            REGAPP_FREGAPPSUPPORTNONOEM 08      3       If this flag is set, the application is prepared to provide non-OEM (that is, ANSI) file names.
                                                        If this flag is set by the application and the converter provides the Charset opcode with an ANSI
                                                        argument in its preferences list, then it is understood by both the application and the converter
                                                        that file names will be passed in ANSI.
            REGAPP_FREGAPPINDEXING      16      4       This flag is set to indicate that the calling application is only indexing textual content,
                                                        and does not need layout and other information. When this flag is set, the converter can omit most
                                                        RTF to significantly speed up the conversion.
            REGAPP_UNUSED                       5-31    Available for future use. Must be set to 0.

    lpFuture: A pointer to a list of application preferences. May be NULL, indicating there are no application preferences.
   
    Returns:
        handle to a GlobalAlloc'd RegAppRet structure.  Caller must use GlobalLock() to access it, and MUST free it if the return value is non-NULL.

    Remarks:

        The converter will return an HGLOBAL handle to a GlobalAlloc-retrieved list of its own preferences. The converter can return NULL
        if it has no preferences. The calling application must use GlobalFree on this list of converter preferences if non-NULL to avoid memory leaks.
        The converter should not free the list of application preferences; the application is responsible for that memory also.
       
        Both preference lists have similar structure. A preference list is a packed string of bytes, with no padding. The first two bytes are a
        short value containing the length of the entire string, including the size of the size short itself. The rest of the string consists
        of arbitrary records. Each record begins with a size byte, followed by an opcode byte. Each size byte includes itself in the size.
       
        The rest of each record contains record-specific data. See the structure below for an example.
       
        To parse the preferences list of the application, a converter must look at the list byte-by-byte, not exceeding the number of bytes
        in the size word, and it must neither assume any particular ordering of opcodes, nor should it assume the presence of any particular opcodes.
       
        Because each record includes its own size, a converter can and should skip unknown opcodes. Parsing the preferences list is somewhat
        analogous to parsing RTF in this respect. The application must parse the preference list from the converter in a similar way.
       
        Because the opcode list is transient and is communicated between two components running on the same system, there is no need for byte-swapping.
        All values should be in native byte order.
       
        While parsing of preference lists must be done byte-by-byte, the lists do not need to be constructed that way. Typically, the list generated
        by a converter is fairly static. It is convenient to build it using a structure:
       
            #pragma pack(1)
            typedef struct
            {
                short cbStruct;  // size of entire structure

                    // version of Word with which converter's Rtf is compliant
                char cbSizeVer;  // == 1 + 1 + 2 + 2
                char opcodeVer;
                short verMajor;  // major version of Word
                short verMinor;  // minor version of Word

                    // character set we want all file names to be in
                char cbSizeCharset; // == 1 + 1 + 1
                char opcodeCharset;
                char charset;

                    // additional values can be added here
            } REGAPPRET;
            #pragma pack()

        This mechanism allows the set of opcodes to grow in a backwards-compatible fashion.
        See the conversions API file Convapi.h for the complete list of currently defined opcodes and their record structures.
        These are the records defined as of Word 97. Many are esoteric and not of general interest. The 'small' valued opcodes are
        for the converter to pass to Word. The opcodes valued 0x80 and above are for Word to pass to the converter.

    Example:
       
        call RegisterApp &REGAPP_PICPLACEHOLD, &NULL
;;

;;
[REGAPPRET:
REGAPPRET.cbStruct: W$ 0 ; size of this structure
REGAPPRET.cbSizefDocfile: B$ 0 ; Does this converter understand docfiles and/or non-docfiles?
REGAPPRET.opcodefDocfile: B$ 0 ; Does this converter understand docfiles and/or non-docfiles?
REGAPPRET.grfType: W$ 0 ; If bit 1 is set it is a doc file
REGAPPRET.cbSizeVer: B$ 0 ; Version of Word for which converter's Rtf is compliant. Always 6 = Is the sum of the byte len above, orsimply: REGAPPRET.cbSizeVerDis
REGAPPRET.opcodeVer: B$ 0 ; idem above
REGAPPRET.verMajor: W$ 0 ; Major version of Word for which Rtf is compliant
REGAPPRET.verMinor: W$ 0 ; Minor version of Word for which Rtf is compliant
REGAPPRET.cbSizeCharset: B$ 0 ; What character set do we want all filenames to be in. Value is always 3
REGAPPRET.opcodeCharset: B$ 0 ; What character set do we want all filenames to be in.
REGAPPRET.charset: B$ 0 ; ANSI &ANSI_CHARSET &OEM_CHARSET
REGAPPRET.opcodesOptional_Val64: B$ 0 ; Is set value is 2.Unknown 871 0367 32 64 067
REGAPPRET.opcodesOptional2_Val64: B$ 0 ;  Is set value is 4
REGAPPRET.opcodesOptional3_Val64: B$ 0 ;  Is set value is 2
REGAPPRET.opcodesOptional_Val256: B$ 0 ; Is set value is 2
REGAPPRET.opcodesOptional2_Val256: B$ 0 ;  Is set value is 5
REGAPPRET.opcodesOptional_Val512: B$ 0 ; Is set value is 2
REGAPPRET.opcodesOptional2_Val512: B$ 0 ;  Is set value is 6
REGAPPRET.opcodesOptional_Val2048: B$ 0 ; Is set value is 2
REGAPPRET.opcodesOptional2_Val2048: B$ 0 ;  Is set value is 11
REGAPPRET.opcodesOptionalReserved: B$ 0 ;  Seems to be an error on the creation of the structure.It is always zero
]

[REGAPPRET.cbStructDis 0
REGAPPRET.cbSizefDocfileDis 2
REGAPPRET.opcodefDocfileDis 3
REGAPPRET.grfTypeDis 4
REGAPPRET.cbSizeVerDis 6
REGAPPRET.opcodeVerDis 7
REGAPPRET.verMajorDis 8
REGAPPRET.verMinorDis 10
REGAPPRET.cbSizeCharsetDis 12
REGAPPRET.opcodeCharsetDis 13
REGAPPRET.charsetDis 14]

[Size_of_REGAPPRET 15] ; unaligned

; Unknown Optional equates
WORD_VERSION 32
OPTIONAL64 64
OPTIONAL256 256
OPTIONAL512 512
OPTIONAL2048 2048
;;


Proc RegisterApp:
    Arguments @lFlags, @lpFuture

    call 'html.iec.RegisterApp' D@lFlags, D@lpFuture

EndP

Title: Re: HTML to RTF
Post by: guga on June 13, 2013, 10:11:36 AM
InitConverter32 is described as:


;;
    Function: InitConverter32

    An application will call InitConverter32 before any other converter entry point, to pass information not conveniently obtainable
    by the converter any other way, and to permit the converter to perform any necessary global initialization.
   
    Required entrypoint.  Preserve hwndCaller or szModule if you care to use them later.  Provide a DllMain entrypoint and preserve its
    hInstance argument if you care to use that value later, or to protect the DLL from multiple callers if not re-entrant.

    Arguments:
        hWndCaller: A handle to the top-level client window of the application to be used as a parent window for the converter.
                    For example, after displaying and closing a dialog box, a converter should reset the focus to this hwnd.
       
        szModule:   The calling application's module name. The caller must leave the module name accessible throughout
                    the converter session, so that the converter may store this value in a global and access it during a subsequent call.
                    However, it is preferable to copy the string to the converter's data space rather than relying on it remaining in the
                    caller's space. The module name can be used to modify the converter's behavior for different applications.
                    The available module names are:
                        MSWORD
                        WINWORD
                        MSPUB
                        MSWORKS
                        WORDPAD
                        FRONTPG

    Returns:
        True, on suceed
        False, on failure

    Remarks:
            The szModule defines the CodePage of the HTML to be exported as well information about the Generator of the HTML

    Example of usage:
       call 'html.iec.InitConverter32' D$hInstance, {B$ 'MSWORD', 0}
;;

Proc InitConverter32:
    Arguments @hWndCaller, @pSzModule

    call 'html.iec.InitConverter32' D@hWndCaller, D@pSzModule

EndP




WARNING ! Both functions are preliminary, i´m trying to fully understand this dll in order to correctly use it, and make a library for us.
Title: Re: HTML to RTF
Post by: jj2007 on June 13, 2013, 03:39:38 PM
Excellent detective work, Guga :t

These converters are really badly documented, so it is a lot of trial and error until you get it running (and in one case you must do the contrary of what the docs recommend to make it work).

The good thing about HTML.IEC is that it is available even if MS Office is not installed. The bad thing is that Office seems to have much more sophisticated internal HTML converters which can load even complex HTML pages correctly. In some cases, HTML.IEC converts such stuff (e.g. a Google results page) but the usable part is surrounded by a lot of Javascript...
Title: Re: HTML to RTF
Post by: guga on June 13, 2013, 06:36:29 PM
html.iec is the newer version. We should use this instead html32.cnv.The problem seems to be the flags to be used on the register function. The converter seems to be able to manage javascript, images etc, the problem is mainly understand how this shit works.

The documentation is a complete mess, and we must not rely on that completely. It is old (from 97) never got updated, and i doubt M$ will updated it, since, so far i understood, this is the way M$ uses to convert html from rtf and vice-versa without using Office installed.

Once we can understand the exported functions correctly, we can be able to make a single converter to manage all dlls (iec´s and cnv´s) inside the shared tools directory. For example, we can make a function that is able to scan on that directory for all converters available and make a open/save dialog biased on the converters found. Since all iec have the same (or similar) exports, we mainly need that the converter tool, uses a variable that holds the handle of each exported function.

Example:

When we are converting Lotus123 to HTML we can use the lotus converter to open the file. (that will points, for example to call 'lotus32.cnv.RegisterApp'). use the lotus converter to open and manage the file and put it on a memory buffer - or stream them on a richedit control - or any document that is usable on both converters. Example, if lotus123 can export rtf, we use it to export rtf.

Once it is opened (andconverted to rtf), we simply, close the lotus converter and open the html converter on the export functions. So it will get the rtf (that was converted by lotus) and export it to html.


It seems that this is how those converters works, the problem is to make them work.

How you managed to work ForeignToRtf32 ? Can you post an example (to work on masm)


Also, we have an excel.cnv on the shared directory to use, but this is not listed on the registry (Which is not  problem,btw, as long we understand how the export functions works for all cnv files)


Here is what i have in my C:\Program Files\Common Files\Microsoft Shared\TextConv directory
They are vailable here: My Converter dlls (https://mega.co.nz/#!j55WlQwS!UUPAgwjNAd5prqbhBchfhE13fnd3PMImdR8tI214-kc)
I had do that due to the limitatinsof atachment size on the forum.
Title: Re: HTML to RTF
Post by: TouEnMasm on June 14, 2013, 12:23:04 AM

This one is a dll called by a c executable,masm if we want.
Use string,i had only "problems" with files(need perhaps some money?).
String is valuable and simple to use.
http://www.htmltortf.com/convert-html-to-rtf-withphp/component-html-text-to-rtf-withphp.php (http://www.htmltortf.com/convert-html-to-rtf-withphp/component-html-text-to-rtf-withphp.php)
Title: Re: HTML to RTF
Post by: guga on June 14, 2013, 02:23:11 AM
well for U$ 600 and made on .NET i´ll prefer to not even start analysing tis dll  :greensml:
Title: Re: HTML to RTF
Post by: jj2007 on June 14, 2013, 03:18:08 AM
For US$ 600 you could buy office and use my attached 33-lines snippet... MS Word is horribly slow in converting, but the results are convincing  ;)
Title: Re: HTML to RTF
Post by: TouEnMasm on June 14, 2013, 04:50:31 AM
For nothing the string.exe translate html to the console.
I have made several test and i need no more.
I have just had to modify the c source code calling the dll to made it accept parameters.
I am generous this day,I join it.
Just put it in the same directory than the dll,and view.
The only thing needed is the dll.
Title: Re: HTML to RTF
Post by: jj2007 on June 14, 2013, 05:34:30 AM
Quote from: ToutEnMasm on June 14, 2013, 12:23:04 AM

This one is a dll called by a c executable,masm if we want.
Use string,i had only "problems" with files(need perhaps some money?).
String is valuable and simple to use.
http://www.htmltortf.com/convert-html-to-rtf-withphp/component-html-text-to-rtf-withphp.php (http://www.htmltortf.com/convert-html-to-rtf-withphp/component-html-text-to-rtf-withphp.php)

OMG ::)
QuoteYou are permitted to copy the documentation only for your own use. You are permitted to make only one back-up copy. The sale and sub-licensing of the software are forbidden

114 files, 500k alone for the DLL... and string.exe uses IsDebuggerPresent - any idea why?
Title: Re: HTML to RTF
Post by: TouEnMasm on June 14, 2013, 05:54:04 AM

the IsDebuggerPresent don't appear in the source code.Must be an addin of the c++.Generally he is used to know if a chain could be send to the debugger or not.
Masm had not this.
Title: Re: HTML to RTF
Post by: guga on June 14, 2013, 09:40:26 AM
 :dazzled: I can´t make this shit stops crashing  :icon_confused:

JJ, i triedexactly what you did and nothing. On the callback, i tried to simply returnemptied and nothing....I don´t know what a f. i´m doing wrong here.

This seems to be a stack problem, but i´m unable to find out why.

Whenever it calls to that crappy ForeignToRtf32

I´m tired and pissed for this dont´work. Can someone please help ? I have no more ideas why this is not working:(
Title: Re: HTML to RTF
Post by: guga on June 14, 2013, 03:04:03 PM
That´s weird. Your´s alsogenerate an exception, but instead crashing and exiting, after it pass the exception, it goes to the callback function
Title: Re: HTML to RTF
Post by: jj2007 on June 14, 2013, 04:11:16 PM
Quote from: guga on June 14, 2013, 03:04:03 PM
That´s weird. Your´s (edit JJ: reply #25?) also generate an exception, but instead crashing and exiting, after it pass the exception, it goes to the callback function

Yes, I've noticed that. It's not so uncommon to see "internal" exceptions that are somewhat handled by the OS, e.g. in the OpenFile dialogs.

I tried your code posted above, it says C/C++ comment remover - is that intentional? My hard disk is at its limits, so some time ago I had to remove RosAsm, unfortunately... could you post the relevant parts of the source only?
Title: Re: HTML to RTF
Post by: guga on June 14, 2013, 05:10:26 PM
Hi JJ,

yes comment remover was only the skeleton i used to test this functions. I didn´t wanted to start from scratch, so i used an old app that already have a dialog and opens a rtf file for testing the converter routines.

On the main dialogproc i have:


        ..Else_If D@wParam = IDC_OPEN

                mov B$HeaderSaveFilter 0
                move D$ofn.hwndOwner D@Adressee
                move D$ofn.hInstance D$hInstance
                mov D$ofn.lpstrFilter HeaderFileFilter
                call 'comdlg32.GetOpenFileNameA' ofn
                (...)
                call OpenHeaderFile D@Adressee ; the file (html or rtf) is loaded in memory here
                (...)
                call 'KERNEL32.GlobalAlloc' 042, 010000 | mov D$OutbutBuff eax
                [color=red]call 'html.iec.ForeignToRtf32' HeaderSaveFilter, 0, D$OutbutBuff, ghszConvtrVersion, 0, RtfOut [/color]
                (...)
    ...Else_If D@Message = &WM_INITDIALOG
        move D$hwnd D@Adressee
        call 'kernel32.GetModuleFileNameA' D$hInstance, Sz_ModuleName, &MAX_PATH
        call InitConverter32 D$hInstance, Sz_ModuleName [color=red]; <------- same as: call 'html.iec.InitConverter32' D$hInstance, Sz_ModuleName[/color]
        call RegisterApp 02, &NULL[color=red] ; <----- simply a: call 'html.iec.RegisterApp' 02, &NULL. Return value is a pointer to the structure REGAPPRET[/color]
        call GetReadNames IPath, IDescription, IExtension[color=red] ; the functions i post before to enumerate the registry import. Not related to the converter[/color]
        call GetWriteNames EPath, EDescription, EExtension ; ... and export



; The bastard  :greensml:



Proc RtfOut:
    Arguments @cchBuff, @nPercentComplete;, @Shit

    ;If D@cchBuff = 0 ; I removed the If case, justto test if it will make any difference if i directly call the functions below...but....:(
        call 'KERNEL32.GlobalLock' D$OutbutBuff;D@cchBuff
        call LpszBltLpszCchMax HeaderSaveFilter, eax, 259 ; <---- internally on the dll there is a function named as this, and the functionality is as the one i ported
                                                                                         ; It was a desperate attempt to make this crap works without crashing, and understand which function is using this callback
        call 'KERNEL32.GlobalUnlock' D$OutbutBuff;D@cchBuff
    ;End_If

EndP
____________________________________________

Proc LpszBltLpszCchMax:
    Arguments @Input, @Output, @Flag1
    Uses edx, esi, edi, ecx

    .If D@Flag1 <> 0
        mov edx D@Input
        mov esi D@Output ; < --------- Here is always set to ZERO ????
        Do
            mov cl B$esi ; <--------------- and then.....Internally is where it crashes
            dec D@Flag1
            On cl = 0, jmp L1>

            mov cl B$edx
            inc edx
            inc esi
        Loop_Until D@Flag1 = 0   
    .End_If
L1:
   
EndP



I have no more clue why it is crashing :(
I tried to reproduce exactly what you did, and even if i use the same arguments, parameter, buffers, it still crashes badly.

For what i saw the ForeignToRtf32 uses as parameters the members of some structure. It points to a function named: FceForeignToRtf that adds 2 more fixed parameters "Char = value always 10" and "Integer = value always 871"  - Both values, btw are the same ones as returned by the structure REGAPPRET resultant from RegisterApp.



; int __stdcall FceForeignToRtf(HGLOBAL ghszFile, int pstgForeign, int ghBuff, int ghszClass, int ghszSubset, int lpfnOut, char Char, int Integer)
_FceForeignToRtf@32 proc near ; CODE XREF: ForeignToRtf32(x,x,x,x,x,x)+4Fp

Tmp_ghszFile = dword ptr -268h
Tmp_ghszSubset = dword ptr -264h
Tmp_ghszClass = dword ptr -260h
Tmp_pstgForeign = dword ptr -25Ch
var_258 = dword ptr -258h
pDst = byte ptr -150h
String = byte ptr -48h
DummyVar = dword ptr -4
ghszFile = dword ptr  8
pstgForeign = dword ptr  0Ch
ghBuff = dword ptr  10h
ghszClass = dword ptr  14h
ghszSubset = dword ptr  18h
lpfnOut = dword ptr  1Ch
Char = dword ptr  20h
Integer = dword ptr  24h

mov edi, edi
push ebp
mov ebp, esp
sub esp, 268h
mov eax, ___security_cookie
xor eax, ebp
mov [ebp+DummyVar], eax
mov eax, [ebp+pstgForeign]
mov [ebp+Tmp_pstgForeign], eax
mov eax, [ebp+ghBuff]
push ebx
mov ebx, [ebp+ghszFile]
mov [ebp+Tmp_ghszFile], eax
mov eax, [ebp+ghszClass]
push esi
mov [ebp+Tmp_ghszClass], eax
mov eax, [ebp+ghszSubset]
push edi
mov [ebp+Tmp_ghszSubset], eax
call _InitExceptions@0 ; InitExceptions()
call _FInitHeaps@0 ; FInitHeaps()
test eax, eax
jnz short loc_42B5D3
push 0FFFFFFF8h
call _ShutdownProc@4 ; ShutdownProc(x)

loc_42B5D3: ; CODE XREF: FceForeignToRtf(x,x,x,x,x,x,x,x)+4Bj
mov eax, [ebp+lpfnOut]
push 0
push 0
mov function, eax
call _SetImportPercentOptions@8 ; SetImportPercentOptions(x,x)
mov edi, [ebp+Integer]
mov eax, [ebp+Integer]
mov esi, [ebp+Char]
and edi, 80h
and eax, 400h
shl edi, 8
or edi, eax
mov eax, [ebp+Integer]
shl eax, 0Ch
not eax
shl edi, 4
and eax, 10000h
and esi, 1Ch
or edi, eax
shl esi, 7
test ebx, ebx
mov __fForeignToRtf, 1
jz short loc_42B671
push ebx ; hMem
lea eax, [ebp+pDst]
push eax ; Input
call _LpchBltLpszHx@8 ; LpchBltLpszHx(x,x)[color=red] <---------------- THIS IS WHERE IT CRASHES INTERNALLY, because "pDst" is always Zero.[/color]
test byte ptr _vcpref, 8
jnz short loc_42B647
lea eax, [ebp+pDst]
push eax ; pDst
push eax ; pSrc
call ds:__imp__OemToCharA@8 ; OemToCharA(x,x)

loc_42B647: ; CODE XREF: FceForeignToRtf(x,x,x,x,x,x,x,x)+B8j
xor eax, eax
push eax ; int
push eax ; int
push eax ; int
push eax ; int
push 104h ; int
lea eax, [ebp+var_258]
push eax ; int
lea eax, [ebp+pDst]
push eax ; lpString
call _FileNameSplit@28 ; FileNameSplit(x,x,x,x,x,x,x)
push [ebp+Char]
lea eax, [ebp+var_258]
push eax
jmp short loc_42B67F
; ---------------------------------------------------------------------------

loc_42B671: ; CODE XREF: FceForeignToRtf(x,x,x,x,x,x,x,x)+A2j
test byte ptr [ebp+Char], 1
jz short loc_42B68E
push [ebp+Char] ; char
push offset Class ; lpString

loc_42B67F: ; CODE XREF: FceForeignToRtf(x,x,x,x,x,x,x,x)+F0j
push _hInstance ; int
call _FInitConvIO@12 ; FInitConvIO(x,x,x)
test eax, eax
jnz short loc_42B695

loc_42B68E: ; CODE XREF: FceForeignToRtf(x,x,x,x,x,x,x,x)+F6j
push 0FFFFFFFFh
call _ShutdownProc@4 ; ShutdownProc(x)

loc_42B695: ; CODE XREF: FceForeignToRtf(x,x,x,x,x,x,x,x)+10Dj
test byte ptr [ebp+Integer], 1
jz loc_42B730
test byte ptr [ebp+Char], 1
mov ebx, 8001h
jz short loc_42B6E8
lea eax, [ebp+String]
push eax
call _CchFetchMainStream@4 ; CchFetchMainStream(x)
mov eax, esi
or eax, edi
or eax, ebx
cmp [ebp+Tmp_pstgForeign], 0
push eax ; int
lea eax, [ebp+String]
jz short loc_42B6D4
push [ebp+Tmp_pstgForeign] ; int
push eax ; lpMultiByteStr
call _FnOpenStmPstg@12 ; FnOpenStmPstg(x,x,x)
jmp short loc_42B6E3
; ---------------------------------------------------------------------------

loc_42B6D4: ; CODE XREF: FceForeignToRtf(x,x,x,x,x,x,x,x)+145j
push 0 ; int
push eax ; lpString
lea eax, [ebp+pDst]
push eax ; int
call _FnOpen@16 ; FnOpen(x,x,x,x)

loc_42B6E3: ; CODE XREF: FceForeignToRtf(x,x,x,x,x,x,x,x)+153j
mov dword_456388, eax

loc_42B6E8: ; CODE XREF: FceForeignToRtf(x,x,x,x,x,x,x,x)+129j
cmp dword_456388, 0FFFFFFFFh
jnz short loc_42B737
test byte ptr [ebp+Char], 2
jz short loc_42B716
or esi, edi
or esi, ebx
push esi ; int
push 0 ; int
push 0 ; lpString
lea eax, [ebp+pDst]
push eax ; int
call _FnOpen@16 ; FnOpen(x,x,x,x)
cmp eax, 0FFFFFFFFh
mov dword_456388, eax
jnz short loc_42B737

loc_42B716: ; CODE XREF: FceForeignToRtf(x,x,x,x,x,x,x,x)+176j
call _FeGetError@0 ; FeGetError()
sub eax, 6
neg eax
sbb eax, eax
and eax, 0Dh
add eax, 0FFFFFFF2h
push eax
call _ShutdownProc@4 ; ShutdownProc(x)
jmp short loc_42B737
; ---------------------------------------------------------------------------

loc_42B730: ; CODE XREF: FceForeignToRtf(x,x,x,x,x,x,x,x)+11Aj
or dword_456388, 0FFFFFFFFh

loc_42B737: ; CODE XREF: FceForeignToRtf(x,x,x,x,x,x,x,x)+170j
; FceForeignToRtf(x,x,x,x,x,x,x,x)+195j ...
push [ebp+Tmp_ghszClass] ; hMem
call _HxCloneHx@4 ; HxCloneHx(x)
push [ebp+Tmp_ghszClass] ; int
xor edi, edi
push edi ; hMem
push dword_456388 ; int
mov esi, eax
call _FFileRecognized32@12 ; FFileRecognized32(x,x,x)
test eax, eax
jnz short loc_42B763
push 0FFFFFFF2h
call _ShutdownProc@4 ; ShutdownProc(x)

loc_42B763: ; CODE XREF: FceForeignToRtf(x,x,x,x,x,x,x,x)+1DBj
push 202h
push offset _LcbWriteMoreRtf@16 ; LcbWriteMoreRtf(x,x,x,x)
lea eax, [ebp+Tmp_ghszFile]
push eax
call _FnOpenMemory@12 ; FnOpenMemory(x,x,x)
cmp eax, 0FFFFFFFFh
mov dword_45638C, eax
jnz short loc_42B78A
push 0FFFFFFF4h
call _ShutdownProc@4 ; ShutdownProc(x)

loc_42B78A: ; CODE XREF: FceForeignToRtf(x,x,x,x,x,x,x,x)+202j
mov eax, dword_456388
cmp eax, 0FFFFFFFFh
jz short loc_42B79C
push edi
push edi
push eax
call _FcSeekFn@12 ; FcSeekFn(x,x,x)

loc_42B79C: ; CODE XREF: FceForeignToRtf(x,x,x,x,x,x,x,x)+213j
push [ebp+Tmp_ghszSubset]
push esi
push dword_45638C
push dword_456388
call _ConvertForeignToRtf@16 ; ConvertForeignToRtf(x,x,x,x)
push esi ; hMem
call ds:__imp__GlobalFree@4 ; GlobalFree(x)
push dword_45638C
call _FCloseFn@4 ; FCloseFn(x)
call _UninitConvIO@0 ; UninitConvIO()
call _UnensureOleAvail@0 ; UnensureOleAvail()
call _UninitHeaps@0 ; UninitHeaps()
mov ecx, [ebp+DummyVar]
pop edi
pop esi
xor ecx, ebp
xor ax, ax
pop ebx
call @__security_check_cookie@4 ; __security_check_cookie(x)
leave
retn 32
_FceForeignToRtf@32 endp
; ---------------------------------------------------------------------------

Title: Re: HTML to RTF
Post by: TouEnMasm on June 14, 2013, 07:40:07 PM

"Seems there is a stack problem"

Seems also there is different prototypes for 16 bits and 32 bits.
There is a sample provided who don't use the same numbers of paramaters (functions) than in the declarations prototypes.
Must gone of this.
When i see that i had just let it.


Title: Re: HTML to RTF
Post by: jj2007 on June 14, 2013, 08:36:46 PM
call 'KERNEL32.GlobalLock' D$OutbutBuff;D@cchBuff
int 3

Post the exe with that interrupt - Olly answers many questions ;-)

But otherwise, it looks pretty identical to what I have used ::)
Title: Re: HTML to RTF
Post by: guga on June 15, 2013, 02:19:10 AM
here is the exe

yours also crashes, but it returns from the callback, at least 6 or 8 times before entering onto the RtfOut function. If you have Idapro, try debugging your version you see what is happenning. I debugged in RosAs, but i  didn´t make RosAsm shows the source when is debugging inside a external file (dll for example) - It would be needed a codelevel debbuging and not a source level debugging as it is current.

This cnv files seems a huge pile of crap due to those errors, but, once we are able to fix it, we can use all converters dispites those problems and make a correct documentation on how to use them. Damn M$!

I tried to add more parameters for that function, and nothing. The original  C code for this is:



/* F O R E I G N  T O  R T F  3  2 */
/*----------------------------------------------------------------------------
%%Function: ForeignToRtf32

Purpose:
Convert a file to Rtf using the format specified in ghszClass.

Parameters:
ghszFile : global handle to '\0'-terminated filename to be read
pstgForeign : pointer to IStorage of embedding being converted,
NULL for non-OLE2 docfile converters.
ghBuff : global handle to buffer in which chunks of Rtf are passed
to WinWord.
ghszClass: identifies which file format to translate.  This
string is the one selected by the user in the 'Confirm
Conversions' dialog box in Word.
ghszSubset: identifies which subset of the file is to be converted.
Typically used by spreadsheet converters to identify
subranges of the entire spreadsheet to import.
lpfnOut: callback function provided by WinWord to be called whenever
we have a chunk of Rtf to return.

Returns:
fce indicating success or failure and cause
----------------------------------------------------------------------------*/
FCE PASCAL ForeignToRtf32(HANDLE ghszFile, IStorage *pstgForeign, HANDLE ghBuff, HANDLE ghszClass, HANDLE ghszSubset, PFN_RTF lpfnOut)
{
#ifndef CANT_IMPORT
HANDLE hFile;
char FAR *lpBuff;
char szFileName[260];
long cbFile;
long cbOrig;
short cbPass;
FCE fceRet = fceNoErr;
char rgb[cchFilePrefix];
long cbr;

AssertSz(((ghszFile == NULL) ^ (pstgForeign == NULL)),
"Need exactly one of ghszFile and pstgForeign");

if (pstgForeign)
return fceInvalidDoc;

// copy filename locally; file open doesn't want a global handle
AssertSz(ghszFile != NULL, "NULL filename in ForeignToRtf");
if (!PchBltSzHx(szFileName, ghszFile))
return fceNoMemory;
// translate filename from the oem character set to the windows set
if (!lfRegApp.fDontNeedOemConvert)
OemToChar((LPCSTR)szFileName, (LPSTR)szFileName);

// open file and read sufficient bytes to identify file type.
// Note that we cannot assume that IsFormatCorrect was previously called;
// we must check ourselves, again.
if ((hFile = CreateFile((LPSTR)szFileName, GENERIC_READ,
FILE_SHARE_READ, (LPSECURITY_ATTRIBUTES)0,
OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN,
(HANDLE)NULL)) == INVALID_HANDLE_VALUE)
{
return fceOpenInFileErr;
}
ReadFile(hFile, rgb, cchFilePrefix, &cbr, NULL);
if (strncmp(szFilePrefix, rgb, cchFilePrefix) != 0)
{
CloseHandle(hFile);
return fceInvalidFile;
}

// determine file size and restore current file position
cbOrig = cbFile = SetFilePointer(hFile, 0L, NULL, FILE_END) - (long)cchFilePrefix;
SetFilePointer(hFile, cchFilePrefix, NULL, FILE_BEGIN);

// do the actual file import conversion.  We've already read the prefix,
// all that remains is to copy the remainder of the file.
for (; cbFile > 0 && fceRet >= 0; cbFile -= (long)cbPass)
{
// write at most 2K of Rtf on each WinWord callback
cbPass = (cbFile > 2048L) ? 2048 : (short)cbFile;

// we must resize the buffer, each time, ourselves.
if (GlobalReAlloc(ghBuff, (long)cbPass, GMEM_MOVEABLE) == NULL)
{
CloseHandle(hFile);
return fceNoMemory;
}

if ((lpBuff = (char FAR *)GlobalLock(ghBuff)) == NULL)
{
CloseHandle(hFile);
return fceNoMemory;
}

ReadFile(hFile, lpBuff, cbPass, &cbr, NULL);
GlobalUnlock(ghBuff);

// pass the Rtf to WinWord.  Word will check for a user abort and
// may return any of our fce values to us.  If negative, we need to
// ourselves abort and return that same fce.
fceRet = (FCE)((lpfnOut)(cbPass, (long)((cbOrig - cbFile) * 100 / cbOrig)));
}

CloseHandle(hFile);

return fceRet;
#else
AssertSz(fFalse, "ForeignToRtf32: This converter can't import.");
return fceOpenConvErr;
#endif // !CANT_IMPORT
}


#ifndef CANT_EXPORT


/* R T F  T O  F O R E I G N  3  2 */


I tried to compile this, but Visual Studio refuses it.
Title: Re: HTML to RTF
Post by: Dubby on June 15, 2013, 03:24:08 AM
Hi all,

been download jj' file and guga's..
and analyze them...

the problem I found is the return from GlobalLock which is always zero from guga's file.. inside the internal function..
but the jj's is not..

from what I understand after analyze them:
the function expect the file name to be allocated from GlobalAlloc (the 1st argument). try it. it might work...
put an eye how the 1st argument is being transferred inside the calls..

but don't ask me how jj's escape from GlobalLock... no idea about it..  :dazzled:

goodluck  :t
Title: Re: HTML to RTF
Post by: jj2007 on June 15, 2013, 03:26:47 AM
Quote from: guga on June 15, 2013, 02:19:10 AM
here is the exe

When I press Open, I get a file dialog for .c files. Can you call the converter directly in WM_CREATE with a predefined html name, so that I can jump straight to the int 3? Thanks.

> return from GlobalLock which is always zero from guga's file
@Dubby: In case you are using Olly: What does it show as last error? invalid handle?
@Guga: call 'KERNEL32.GlobalAlloc' 042, 010000: 42h=GHND, but is it really radix 16?? You know RosAsm much better ;-)
Title: Re: HTML to RTF
Post by: TouEnMasm on June 15, 2013, 06:17:47 AM

Here is my own translator.
A simple richedit who accept images.
Just made a copy from the html page
Add the images by copy and you got the sample provided,That's all.
Title: Re: HTML to RTF
Post by: Dubby on June 15, 2013, 06:36:27 AM
@jj:
yes, the last error shows invalid handle.
Title: Re: HTML to RTF
Post by: jj2007 on June 15, 2013, 06:57:49 AM
10025F19                8BEC                     mov ebp, esp
10025F1B                68 03010000              push 103
10025F20                FF75 0C                  push dword ptr [ebp+0C] <<<<<<<<<<<
10025F23                FF15 0C110010            call near [<&KERNEL32.GlobalLock>]


What gets pushed here (somewhere deep inside the DLL) is a pointer to a DWORD that contains the address in the .data section of the HTM file name. And the lock fails. Guga, how do you pass the file name to the proc? Try using GlobalAlloc, GPTR, 100h for the buffer that contains the source file name.
Title: Re: HTML to RTF
Post by: guga on June 15, 2013, 08:07:08 AM
I´m reproducing exactly the same you did:

....opendialog....ofn.lpstrFile = pointer to c:\temp\bbb.html
..ghszConvtrVersion pointer to a buffer to hold the path ? [ghszConvtrVersion: B$ 0 #019C]
call 'KERNEL32.GlobalAlloc' 042, 010000 | mov D$OutbutBuff eax
call 'html.iec.ForeignToRtf32' ofn.lpstrFile, 0, D$OutbutBuff, ghszConvtrVersion, 0, RtfOut

; it returns on the 10th time (on yours, not in mine)
Proc RtfOut:
    Arguments @cchBuff, @nPercentComplete;, @Shit

    ;If D@nPercentComplete = 0
        call 'KERNEL32.GlobalLock' D$OutbutBuff;D@cchBuff
        call LpszBltLpszCchMax ofn.lpstrFile, D$eax, 259 ; crashes :(
;        call LpszBltLpszCchMax ofn.lpstrFile, eax, 259 ; crashes :
        call 'KERNEL32.GlobalUnlock' D$OutbutBuff;D@cchBuff
    ;End_If

EndP


The only thing i know for sure is that LpszBltLpszCchMax is not being pointing to the path of the html file. There is a serious stack error internally on that function. The parameters seems to be pointers to a structure. I have no more clue what i´m doing wrong here.


For instance, yours RtfOut loops back 10 times, before passing through GlobalLock function. I mean, the 1st time of the callback, nPercentComplete = 0, then it will jmp over and return....the next time it return, it always return to RtfOut, untill the 10th time, where nPercentComplete = 0400, making it don´t jmp and go throught GlobalLock


It is a stack problem, because the function RTFOut have 2 parameters @cchBuff, @nPercentComplete, while ForeignToRtf32 have only 6 (8, if you count the2 additionals ones from RtfOut).So, there is no reason why it is coming back 10 times to the callback, if the total count of arguments is at most 8 !!!


The modified version does exactly the same as yours, but....it crashes....(The opendialog,now contains only html/rtf to you open)


Btw: GlobalAlloc, GPTR, 100h still crashed


The problem seems to be that the original function puts some many junk on the stack (unaligned data) that when it will points to the path, it looses the pointer. They placed a structure to hold it with 612 bytes, but they should use a global variable to hold it and not a local one. The only solution i see for that crap is do the same as they did. I´ll be forced to put a structure on the stack before ForeignToRtf32, zero it and let ForeignToRtf32 do it´s mess alone. I´ll give a try and see what happens.
Title: Re: HTML to RTF
Post by: guga on June 15, 2013, 11:04:53 AM
Ok, definitelly it is something utterly weird with those functions.

I tried another one to simulate what happens, and the error is exactly the same

If you try this:

[FileType: B$ 0 #260]
call 'html.iec.IsFormatCorrect32' {B$ "C:\temp\bbb.htm", 0}, FileType


The app will still crash due to that dumb LpszBltLpszCchMax. It will point there. The full C source code is attached here
Inside this function there is the same "structure" as the one i reported. It is a function called: FceCheckFormat that will call to  LpszBltLpszCchMax

The problem relies on the C source


FCE PASCAL IsFormatCorrect32(HANDLE ghszFile, HANDLE ghszClass)
{
#ifndef CANT_IMPORT
HANDLE hFile;
char szFileName[260];
char rgb[cchFilePrefix];
long cbr;

// copy filename locally; file open doesn't want a global handle
AssertSz(ghszFile != NULL, "NULL filename in IsFormatCorrect");
if (!PchBltSzHx(szFileName, ghszFile))
return fFalse;
// translate filename from the oem character set to the windows set
if (!lfRegApp.fDontNeedOemConvert)
OemToChar((LPCSTR)szFileName, (LPSTR)szFileName);

// open file, read sufficient bytes to identify file type, and close.
if ((hFile = CreateFile((LPSTR)szFileName, GENERIC_READ,
FILE_SHARE_READ, (LPSECURITY_ATTRIBUTES)0,
OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN,
(HANDLE)NULL)) == INVALID_HANDLE_VALUE)
{
return fceOpenInFileErr;
}
ReadFile(hFile, rgb, cchFilePrefix, &cbr, NULL);
CloseHandle(hFile);

// if the file begins with our szFilePrefix, it's most likely in our
// file format
if (strncmp(szFilePrefix, rgb, cchFilePrefix) != 0)
return fFalse;

// there is only one read class
HxBltHxSz(ghszClass, szzReadClasses);

return fTrue;
#else
AssertSz(fFalse, "IsFormatCorrect32: This converter can't import.");
return fceOpenConvErr;
#endif // !CANT_IMPORT
}


Can someone try to compile this and see the result ? VS2008 is not being able to compile the old source
Title: Re: HTML to RTF
Post by: Antariy on June 15, 2013, 01:04:38 PM
Hi Guga, it seems that this source isn't really an example of usage of the Word import-filter, but rather the example how to implement Word import filter, i.e. it's rough model and not the real source related to the html.iec.
I.e., using this source you may find how to call the converter in an "old Word" way, but not understand how the html.iec works or which things it does (not) support. And from examination html.iec filter - which bits it tests from the flag passed to a RegisterApp function - shows that this filter does not have options to improve the "quality" of HTML tags processing, i.e., for complex pages it probably will anyway produce a bit of not required stuff (like not recignized tags or labels or something such).
Title: Re: HTML to RTF
Post by: jj2007 on June 15, 2013, 04:02:31 PM
Did some checks inside the CB, interesting:

.code        ; some error checking
cbRead proc uses ebx bytes, percent        ; % unused
  SetGlobals
  inc cbct
  .if oldEsp!=esp
        inc ctEspChg
  .endif
  mov ecx, bytes
  jecxz @F
  inc ctWithBytes
  push ecx
  push rv(GlobalLock, SrcBuf)        ; source is a 4k buffer filled with Rtf stuff
  push pBuf$
  call MbCopy                ; invoke MbCopy, pBuf$, eax, ecx
  mov pBuf$, eax        ; set new pointer returned by MbCopy
  invoke GlobalUnlock, SrcBuf
@@:
  ret
cbRead endp


Result:
cbct            56
ctWithBytes     15
ctEspChg        56


Source & exe attached.

Folks, I am off for holidays - have fun :icon14:
Title: Re: HTML to RTF
Post by: TouEnMasm on June 15, 2013, 05:01:51 PM
Is someone able to compile the converter sample ?
HERE IT IS
Hope this make a end to the crash.
I have not modified the type of call.
The only modified is build environnement,VC++ express 10,Ihaven't use the provided windows.inc and used the make32 with a change in the lib.
libc begin libcmt.
Let's me know if it work for you.

Title: Re: HTML to RTF
Post by: MichaelW on June 15, 2013, 05:23:43 PM
I tried with the VC++ Toolkit 2003 compiler, the nmake.exe from the PSDK, and this batch file in the SAMPCNV directory:

set PATH=C:\Program Files\Microsoft Visual C++ Toolkit 2003\bin;C:\Program Files\Microsoft Platform SDK\bin;
set INCLUDE=C:\Downloads\HTMLTORTF\gc1039\DISK\SAMPCNV
set LIB=C:\Downloads\HTMLTORTF\gc1039\DISK\SAMPCNV
nmake -f sample32.mak
pause


And I don't see any errors that suggest to me that my batch file is wrong...

EDIT: My batch file was wrong, in multiple places. I still get a few warnings but it does create the library.


C:\Downloads\HTMLTORTF\gc1039\DISK\SAMPCNV>set PATH=C:\Program Files\Microsoft V
isual C++ Toolkit 2003\bin;C:\Program Files\Microsoft Platform SDK\bin;C:\masm32
\bin

C:\Downloads\HTMLTORTF\gc1039\DISK\SAMPCNV>set INCLUDE=C:\Program Files\Microsof
t Platform SDK\include;C:\Program Files\Microsoft Platform SDK\include\crt

C:\Downloads\HTMLTORTF\gc1039\DISK\SAMPCNV>set LIB=C:\Program Files\Microsoft Vi
sual C++ Toolkit 2003\lib;C:\Program Files\Microsoft Platform SDK\lib

C:\Downloads\HTMLTORTF\gc1039\DISK\SAMPCNV>nmake -f sample32.mak full

Microsoft (R) Program Maintenance Utility   Version 7.00.8882
Copyright (C) Microsoft Corp 1988-2000. All rights reserved.

        cl /c /I. /I.. /Gs /Ox /W3 /WX /DWIN32 /Fo.\sample32.obj .\sample32.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86
Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.

sample32.c
        cl /c /I. /I.. /Gs /Ox /W3 /WX /DWIN32 /Fo.\util.obj .\util.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86
Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.

util.c
        cl /c /I. /I.. /Gs /Ox /W3 /WX /DWIN32 /Fo.\dbg.obj .\dbg.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86
Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.

dbg.c
        rc /i.  /r /fo .\resource.res resource.rc
        link /NODEFAULTLIB /dll /machine:i386 /entry:_DllMainCRTStartup@12 /base
:0x01400000 /out:.\sample32.cnv /def:sample32.def .\sample32.obj .\util.obj .\db
g.obj libc.lib kernel32.lib user32.lib gdi32.lib advapi32.lib version.lib .\reso
urce.res
Microsoft (R) Incremental Linker Version 7.10.3077
Copyright (C) Microsoft Corporation.  All rights reserved.

sample32.def(2) : warning LNK4017: DESCRIPTION statement not supported for the t
arget platform; ignored
sample32.def(4) : warning LNK4017: CODE statement not supported for the target p
latform; ignored
sample32.def(5) : warning LNK4017: DATA statement not supported for the target p
latform; ignored
   Creating library .\sample32.lib and object .\sample32.exp



Title: Re: HTML to RTF
Post by: TWell on June 15, 2013, 07:29:28 PM
small example in C to use html.iec#define WIN32_LEAN_AND_MEAN
#include <windows.h>

typedef int (WINAPI INITCONVERTER32)(HANDLE, char *);
long WINAPI InitConverter32(HANDLE hWnd, char *szModule);

typedef int (WINAPI UNINITCONVERTER)(void);
void WINAPI UninitConverter(void);

// callback type
typedef long (PASCAL *PFN_RTF)();
short WINAPI ForeignToRtf32(HANDLE ghszFile, void *pstgForeign, HANDLE ghBuff, HANDLE ghszClass, HANDLE ghszSubset, PFN_RTF lpfnOut);
typedef int (WINAPI FOREIGNTORTF32)(HANDLE, void *, HANDLE, HANDLE, HANDLE, HANDLE);

char szModule[] = "TestModule";

HGLOBAL ghgBuf;
HANDLE hFile;

HGLOBAL GlobalAllocString(TCHAR *szStr)
{
HGLOBAL hgStr = GlobalAlloc(GMEM_MOVEABLE, lstrlen(szStr) + 1);
if (hgStr) {
char* p = (char*) GlobalLock(hgStr);
lstrcpy(p, szStr);
GlobalUnlock(hgStr);
}
return hgStr;
}

long WINAPI RTFCallback(long cchBuff, long nPercent)
{
char* p = (char*) GlobalLock(ghgBuf);
DWORD dwWrite;
WriteFile(hFile, p, cchBuff, &dwWrite, NULL);
GlobalUnlock(ghgBuf);
return 0;
}

int __cdecl mainCRTStartup(void)
{
HANDLE hLib = LoadLibrary("html.iec");
INITCONVERTER32* InitConverter32 = (INITCONVERTER32*)GetProcAddress(hLib, "InitConverter32");
UNINITCONVERTER* UninitConverter = (UNINITCONVERTER*)GetProcAddress(hLib, "UninitConverter");
FOREIGNTORTF32* ForeignToRtf32 = (FOREIGNTORTF32*)GetProcAddress(hLib, "ForeignToRtf32");
if (ForeignToRtf32) {
int rc;
InitConverter32(0, szModule);
hFile = CreateFile("test.rtf", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
HANDLE ghszFile = GlobalAllocString("test.htm");
HANDLE ghBuf = GlobalAlloc(GHND, 4096);
ghgBuf = ghBuf;
rc = ForeignToRtf32(ghszFile, NULL, ghBuf, NULL, NULL, &RTFCallback);
CloseHandle(hFile);
GlobalFree(ghszFile);
GlobalFree(ghBuf);
UninitConverter();
}
FreeLibrary(hLib);
return 0;
}
Title: Re: HTML to RTF
Post by: TouEnMasm on June 16, 2013, 02:24:30 AM
Don't work for me
Quote
   invoke GetModuleFileName,NULL,addr modulefilename,sizeof modulefilename
   mov eax,output.Hwnd
   invoke InitConverter32,0,addr modulefilename
debugger answer
Quote
Invalid parameter passed to C runtime function
Other Handles,Hwnd (top level window of the caller) ... don't  work
Your  TEXT("TestModule") (test of despair) don't work

Title: Re: HTML to RTF
Post by: TouEnMasm on June 16, 2013, 03:10:40 AM
Ouf! :eusa_dance:
Made it work declaring all prototypes as STDCALL and not PASCAL or C.

With some test,no better results than a copy paste in the richedit using msfedit.dll.
One difference,the richedit is better in table and the html.iec is better in free texte.

declarations for dynamique link

.const

PInitConverter32 TYPEDEF PROTO hwndCaller:DWORD,pszModule:DWORD
FInitConverter32 TYPEDEF PTR PInitConverter32
InitConverter32 TEXTEQU <FInitConverter32 ptr ADRInitConverter32>

PUninitConverter TYPEDEF PROTO
FUninitConverter TYPEDEF PTR PUninitConverter
UninitConverter TEXTEQU <FUninitConverter ptr ADRUninitConverter>

PIsFormatCorrect32 TYPEDEF PROTO ghszFile:DWORD,ghszClass:DWORD
FIsFormatCorrect32 TYPEDEF PTR PIsFormatCorrect32
IsFormatCorrect32 TEXTEQU <FIsFormatCorrect32 ptr ADRIsFormatCorrect32>

PForeignToRtf32 TYPEDEF PROTO ghszFile:DWORD, ppvIStorage:DWORD,ghBuff:DWORD, ghszClass:DWORD,ghszSubset:DWORD,lpfnOut:DWORD
FForeignToRtf32 TYPEDEF PTR PForeignToRtf32
ForeignToRtf32 TEXTEQU <FForeignToRtf32 ptr ADRForeignToRtf32>

PRtfToForeign32 TYPEDEF PROTO ghszFile:DWORD,ppvIStorage:DWORD,ghBuff:DWORD,ghszClass:DWORD,lpfnIn:DWORD ; PFN_RTF
FRtfToForeign32 TYPEDEF PTR PRtfToForeign32
RtfToForeign32 TEXTEQU <FRtfToForeign32 ptr ADRRtfToForeign32>

PGetReadNames TYPEDEF PROTO haszClass:DWORD,haszDescrip:DWORD,haszExt:DWORD
FGetReadNames TYPEDEF PTR PGetReadNames
GetReadNames TEXTEQU <FGetReadNames ptr ADRGetReadNames>

PGetWriteNames TYPEDEF PROTO haszClass:DWORD,haszDescrip:DWORD,haszExt:DWORD
FGetWriteNames TYPEDEF PTR PGetWriteNames
GetWriteNames TEXTEQU <FGetWriteNames ptr ADRGetWriteNames>

.data
Hlibrairie dd 0
ADRInitConverter32 dd 0
db "InitConverter32",0
ADRUninitConverter dd 0
db "UninitConverter",0
ADRIsFormatCorrect32 dd 0
db "IsFormatCorrect32",0
ADRForeignToRtf32 dd 0
db "ForeignToRtf32",0
ADRRtfToForeign32 dd 0
db "RtfToForeign32",0
ADRGetReadNames dd 0
db "GetReadNames",0
ADRGetWriteNames dd 0
db "GetWriteNames",0
dd 0,0
.code

;used of the proc
;adress of the dll name IN
;adress of the dll handle OUT
;adress of the created array of functions and dword,first dword of this array
;example
;invoke SearchAdresse,SADR("user32.dll"),addr Hlibrairie,addr ADRInitConverter32
SearchAdresse PROC uses esi edi pNomDLL:DWORD,pHdll:DWORD,pFirstAdresse:DWORD
Local  retour:DWORD
Local  Hdll:DWORD
;Local    [LimiteMaxPhrase]:BYTE
      mov retour,0
invoke LoadLibrary,pNomDLL
mov edi,pHdll
mov [edi],eax
mov Hdll,eax
.if eax == 0
;invoke RetrouveMessageErreur, SADR("LoadLibrary failed")"
jmp FindeSearchAdresse
.endif
mov esi,pFirstAdresse
NouvelleAdresse:
mov edi,esi
add esi,4
invoke GetProcAddress,Hdll,esi
mov [edi],eax
.if eax == 0
; invoke RetrouveMessageErreur,esi
;jmp FindeSearchAdresse
.endif
;passer le nom
@@:
.if byte ptr [esi] != 0
inc esi
jmp @B
.endif
inc esi ;passe le zero de fin de nom
.if dword ptr [esi+4] != 0
jmp NouvelleAdresse
.endif
mov retour,1
FindeSearchAdresse:
         mov eax,retour
         ret
SearchAdresse endp


Source code

.data
;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Text Converters
hFile dd 0
ghBuf dd 0
.code
GlobalAllocString PROC pszStr:DWORD
Local hgStr:DWORD,taille
invoke lstrlen,pszStr
inc eax ;+0
mov taille,eax
mov hgStr,Fr(GlobalAlloc,GMEM_MOVEABLE,taille)
.if hgStr != 0
mov edx,Fr(GlobalLock,hgStr)
invoke lstrcpy,edx,pszStr
invoke GlobalUnlock,hgStr
.endif
mov eax,hgStr
ret
GlobalAllocString ENDP
RTFCallback PROC cchBuff:DWORD,nPercent:DWORD
Local p:DWORD,dwWrite

mov p,Fr(GlobalLock,ghBuf)
invoke WriteFile,hFile, p, cchBuff,addr dwWrite, NULL
invoke GlobalUnlock,ghBuf
mov eax,0
ret
RTFCallback ENDP
;################################################################
Debut_Programme PROC
Local ghszFile:DWORD,ghszClass[50]:BYTE
Local modulefilename[MAX_PATH]:BYTE
Local  retour:DWORD

         mov retour,1
invoke GetModuleFileName,NULL,addr modulefilename,sizeof modulefilename
mov eax,output.Hwnd
invoke InitConverter32,0,addr modulefilename
.if eax != 0
invoke CreateFile,TXT("test.rtf"), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,\
FILE_FLAG_SEQUENTIAL_SCAN, NULL
mov hFile,eax
invoke GlobalAllocString,TXT("C:\Documents and Settings\Luce\Bureau\sansnom1.htm")
mov ghszFile,eax
mov ghBuf,Fr(GlobalAlloc,GHND, 4096)
;pas de istorage ,ghszClass retourne la classe
;--------------------------------------------------------------------
invoke ForeignToRtf32,ghszFile, NULL, ghBuf,addr ghszClass, NULL,RTFCallback
;--------------------------------------------------------------------
invoke CloseHandle,hFile
invoke GlobalFree,ghszFile
invoke GlobalFree,ghBuf
invoke UninitConverter
.endif
FindeDebut_Programme:
         mov eax,retour
         ret
Debut_Programme endp

;################################################################


Init

;init
invoke SearchAdresse,TXT("html.iec"),addr Hlibrairie,addr ADRInitConverter32
;end
invoke FreeLibrary,Hlibrairie




Title: Re: HTML to RTF
Post by: TouEnMasm on June 16, 2013, 04:58:22 AM
erratum , after a control of the stack,the prototypes are just standard.
The two works,i have replace the zip and the declare.

Here how are writing proc in a library:
Quote
      118 ABASIC      ;no low case A=a
      118 AFORTRAN   ;no low case A=a   
      118 APASCAL      ;no low case A=a
      118 _aC      ;work with stack problem      
      118 _aSTDCALL@4   ;work --------- ForeignToRtf32 -------
      118 aSYSCALL      ;  stack problem
The STDCALL is not write in his standard form but is the only one without problems,I have not tested the BASIC and the FORTRAN

The calls can be made with the defines of an PROLOGUE and EPILOGUE perfectly compatible with the STDCALL ,a register can be passed to the functions and made problems ,if not passed ,only in certain  cases.
need verifies.
More recent sample i found:
http://msdn.microsoft.com/en-us/library/dd300649.aspx (http://msdn.microsoft.com/en-us/library/dd300649.aspx)

Title: Re: HTML to RTF
Post by: guga on June 18, 2013, 04:46:06 AM
Very good work guys.

I´m giving a test on the routines to see if i can make it work properly.
Title: Re: HTML to RTF
Post by: guga on June 20, 2013, 09:21:38 PM
I don´t get it.

I´m being able to do the converstions, but there is a not enough memory all over the time.

Do it always needs to use globalalloc/globallock ? I´m using virtuallloc memory...maybe VirtualLock is needed ?
Title: Re: HTML to RTF
Post by: guga on June 20, 2013, 10:49:35 PM
Oops

never mind....I found why the error. I put html.iec on a temp directory i was testing. So it was using the temp path and not the system path which have others dlls used by it.

It seems to work with virtualloc, btw. I´ll create a routine to concatenate the data, since these routines converts the data from 1024 to 1024 bytes.
Title: Re: HTML to RTF
Post by: TouEnMasm on June 21, 2013, 01:48:19 AM

Better way to test the functions is to don't use any windows.
The same proc with same parameters don't work if it is called from a window.
No window,no problem.
Title: Re: HTML to RTF
Post by: TouEnMasm on June 21, 2013, 03:20:59 AM

a sample in c to follow
http://msxnet.org/word2rtf/files/wordcnv.c (http://msxnet.org/word2rtf/files/wordcnv.c)
Title: Re: HTML to RTF
Post by: jj2007 on June 21, 2013, 06:12:21 AM
Re reply #77:
  .if oldEsp!=esp
   inc ctEspChg
   mov oldEsp, esp
  .endif

And it turns out that the stack changes occur when bytes are present, and they don't follow any system, i.e. not +8 every time or so, it may be +120 or -96 etc....

For me it works just fine, and the callback doesn't care if I return 0 or 1.
Title: Re: HTML to RTF
Post by: guga on June 21, 2013, 07:07:53 AM
Hi JJ, the stack is working now. I succeed to make it work on a dialog. It checks for the existence of other converters etc. It converts fine word97 to rtf etc, but when it comes to html.iec, it do the conversion but a messagebox popups up saying that there is a problem with the file and the conversion may not work properly and it then don´t display it on the richedit control.

I´m following the wordpad source for do this. And for what i understood the code, it was fine But debugging the app it does not even call the conversion routines (but they are inside the source and are active).

I´m fixing a couple of routines on the test i´m making and will post it complete later. I plan to build a dll for us that do the conversions to we use it in whatever converter editors we want to build. But, understanding exactly how the Apis works just following the sdk documentations reveals to be a pain.


Tout en masm, tks, i´ll analyse this source to see w2hat i´m doing wrong.
Title: Re: HTML to RTF
Post by: guga on June 21, 2013, 08:45:18 AM
Tout en masm, the source works fine.

I compiled it and placed a teste.bat on the debug directory. It do converts some html files. File"teste.html" is correctly converted (err...kind of, it seems the converter don´t like some javascript tokens - needed to parse the buffer to remove some of them to works properly and also, it don´t seems to parse properly some commented html files - again...writting a parser to remove the comments seems better to avoid bad convertions )

For images, it is a question of configuration, but i´ll take a look at it later, when i try to reproduce the source.

The compiled file is here (https://mega.co.nz/#!X0wU2TBR!DVMPjm-JIs4E2c-QbqnI3DVR6ANRdV75dTHSIAgVLBI)
The executable is only 22 Kb, since i used tinylib and some masm libs ins9de to reduce the compiled size.
Title: Re: HTML to RTF
Post by: TouEnMasm on June 21, 2013, 03:06:24 PM
Quote
The compiled file is here
The link just show advertisement for a navigator.
Title: Re: HTML to RTF
Post by: guga on June 21, 2013, 03:37:58 PM
?

that´s weird. I sent the link to the new mega upload.

try it here
https://mega.co.nz/#!X0wU2TBR!DVMPjm-JIs4E2c-QbqnI3DVR6ANRdV75dTHSIAgVLBI

the filename is Testingsrc.zip

If it still not work try it at RosAsmboard here:
http://rosasm.freeforums.org/rtftohtml-t126.html
Title: Re: HTML to RTF
Post by: TouEnMasm on June 21, 2013, 04:48:42 PM

Ok thanks,
Here a sample of what can be done,The pecoff in html format.Could make a help file with it.
I could kow import any file in rtf,but i could only export to Html ,any idea ?.
Title: Re: HTML to RTF
Post by: TouEnMasm on June 21, 2013, 05:14:07 PM

Your compile of wordcnv.c show a problem with -l option.
I have recompiled it with visual c++ express 10 and it seems to work.
Title: Re: HTML to RTF
Post by: guga on June 21, 2013, 06:39:38 PM
It exports only in html because i changed the c source to use only the html.iec file. (I need to debug the working version to compare of what i´m doing wrong. Yours are better then wordpad source, since it correctly points to the converter functions to be compared)

To make it import and export other formats you need to grab the converters through the registry and use them (wpc, iec and cnv extensions).I made a app that is able to grab all converters existent on the System, scanning from the registry. I´m currently cleaning the code before i upload the 1st test (actually, it is the 20th test i made  :greensml:).

After cleaning i´ll make an alternative routine to use the known directories from the system where the converters are stored, and a error check if the user don´t have any converters on the proper folders and neither on the registry. On such cases, the best will be opening a messagebox to the user asking him to browse the proper folder of his converters.

I could upload now for you take a look at the work i´m doing, but the code is kinda messy. It was a real pain not only enumerating all the registry subkeys, comparing the newer converter versions to be used, making the proper filter buffer to be displayed on a dialogbox, see which converters can export or not, but also make that crappy converters works relativelly well.

The good news is that once they are working and running it will be relativelly easy understand the returned values that they register to enable the user to chose if he wants to export images, waves and other embededed objects that each converter eventually are able to export. For instance, i found out that internally html.iec (and the others) varies the export when the appname is WORDPAD or WINWORD or other tokens. So, in fact, each converter can be configurable to use those tokens as simple equates related to the quality of the export (or the type of objects that the converter can embed at export).

There are still some road to go before making it work for all converters, but i´m suceeding to work with some of them. The problem is being in make it work for the html to rtf, because an weird error message is showing and i suspect it is due to the lack of registration of the converter. The damn SDK document does not help at all.The C source you found will be extremelly helpfull on this, btw, since the one i had (wordpad source) was a mess and had those damn stack faults while on the one you provides it seems that there are no stack problems whatsoever  :t

Tell me if you want to take a look at the file on the current development and i´ll upload it.


All other problems of the export related to html.iec like table sizes (they are not exactly the same as the import) can be fixed simple parsing the exported RTF value (or even better,justparse the html on input related to the table token which html.iec is unable to parse) and altering it to it looks relativelly equal to the ones imported. For tables i suspect html.iec is unable to understand some tokens related to the table size, that´s why tables looks different at export, but it seems easy to fix once we can make all of this fully working.
Title: Re: HTML to RTF
Post by: guga on June 21, 2013, 08:50:14 PM
A note of interest. M$ converters dispites all of it´s annoyances of internal codage,uses Bison Yacc parser to parse the RTF and HTML tags. I keep wondering why M$ programmers don´t make their own code to parse those tokens and avoid using 16 bits programming techniques. It would be way much better if html.iec, and all the other Office converters could simply be updated to migrate from 16 to full 32 bits and using simpler parsers to use inside Office package.

Analysing html.iec shows that it have most necessary for an excelent converter, but the code is such a mess that keeps me wondering why they don´t update the source in order to make Office an ever more efficient word processor ?

The converters sources don´t seems to be that big and they are relativelly the same - except for the targeted files routines used onto the parsing functions.
Title: Re: HTML to RTF
Post by: TouEnMasm on June 21, 2013, 11:40:58 PM

I am now working on my own source code (in asm):
General import and exports are soluce.
Enumeration of exports and  imports is also made threw a menu.
The only difficult I have is to exports rtf to docx..
Don't want to work.
Here is the draft of my code.
Just declare the import,export file (menu files) and use the menu "conversion".It will show you the export and import functions in your computer.
The result will be in test.rtf and testeur.doc (same dir as richedit.exe).
Perhaps if export rtf to doc failed,it is because i haven't word.Just give an unknown error.


Title: Re: HTML to RTF
Post by: guga on June 22, 2013, 04:26:01 AM
docx

the converter  is located in C:\Program Files\Microsoft Office\Office12\Wordcnvpxy.cnv

do you want me to send to you for you test ?
Title: Re: HTML to RTF
Post by: jj2007 on June 22, 2013, 04:57:17 AM
Quote from: ToutEnMasm on June 21, 2013, 11:40:58 PM
Here is the draft of my code.

No source?? Which role does Kernel32's "Cancello" have in your code??
And why do I get an empty box "format", then testeur.doc "réussite" but with 0 bytes??
Title: Re: HTML to RTF
Post by: guga on June 22, 2013, 06:58:41 AM
what is kernel32 cancello ?
Title: Re: HTML to RTF
Post by: TouEnMasm on June 22, 2013, 02:53:54 PM
Here the source code
The most important file is convert.inc
The lib made the dynamic link with any converter you want.
There is nothing to search,the export and import menu give all is needed to run the various converters present in your system.
The last question to solve is why the exports word converters don't work ?.
(rtf to word).
Quote
Which role does Kernel32's "Cancello" have in your code??
I don't see Cancello in my code ??????.

one answer:
The RtfToForeign32 return a 16 bits error code,to have a 32 modify eax as follow.

      .if eax != 1
         or eax,0FFFF0000h
      .endif


Title: Re: HTML to RTF
Post by: guga on June 22, 2013, 10:55:55 PM
Another issue about the converters

This time is with write.wpc.

On my machine (WinXP), there seems to be an error on the registry. Internally,this converter have both extensions for import and export, but the registration is disallowed somehow. In the text converters registry key, it have the extensions and path for the import (This converter don´t seems to export), but, when we try to get the extensions with GetReadname the function returns 1 (which accordying to the sdk should also be equivalent to no error), but, in fact, i suspect this is more likely to means that the converter is not registered.

This is because write.wpc should have a key on the registry at: Software\Microsoft\Windows\CurrentVersion\Applets\Wordpad

But, this key simply don´t exists on my OS.

The same problems seems to happens on lotus32.cnv.

Even if both seems correctly registered inside the text converters registry key, when we try to use them it will fail, if other keys are not properly find.
The same happens on html32.cnv, mswrd832.cnv, mswrd632.cnv (this one causes a stack error inside nt.dll, due to the failure of releasing memory from globalalloc - Also, on this the extension values, instead returning".doc" or something, returns a binary data starting with 0FF)

All of these files points internally to msconv97.dll functions.

I´ll analyse them better to see if this sort of return value (1) is really what i´m thinking (unregistered converter)

Why analysing all of this, instead simply forcing the convertion ?

Well...it is better know what those converters really returns and warn the user to update his system or allow that the app can update it for him.

About write.wpc errors there are some material here
http://www.wincert.net/tips/microsoft-windows/windows-7/1786-word-cannot-start-the-converter-mswrd632wpc-error
http://support.microsoft.com/kb/973904/pt-br
http://support.microsoft.com/kb/973904/en-us
Title: Re: HTML to RTF
Post by: TouEnMasm on June 23, 2013, 12:39:21 AM
Mswrite and mswrd632 (\Import\MSWord6.wpc) don't work for me also.

Fix from microsoft are simples,delet the key ,that is don't use the converter.
I can do these myself choosing another converter.
On xp i have six words converters,two can be on defaut,4 are enough.

The word export converters seems to have a special usage.
They don't need a rtf file (as expexted from the RtfToForeign32 function) but need a word file to export.They give an "invalid format" with RTF.
There is a search to do , find which output format they accept (ghclass) .
The value of ghclass in:
RtfToForeign32,ghszFile, NULL, ghBuf,ghclass,ReadCallback
Explain of this is in in the sdk32.doc
Quote
Converting RTF into a Foreign Binary File or Embedding
Word saves documents to non-Word formats by calling RtfToForeign32.

Title: Re: HTML to RTF
Post by: guga on June 23, 2013, 02:40:23 AM
I have between 16 and18 converters here, and i´m testing them one by one, to make all of this work.

Btw, don´t trust too much on the documentation. It is utterly outdated and have lots of things missing or wrong there.

To know which extension can be exported you need to use the Getread/Getwrite functions. I was using before a check for RTFtoForeign/ForeitgntoRTF, but it proovesme to be not the way to go, since some converters although have this functions as exports,they simply do nothing.

Also, GetRead/GetWrite wil not work all the time, if the dll is not registered properly, this is why i believe that when it return 1 on GetReadNamesit means that the converter is not registered.

I used one routine to fecth the error messages(there is a fecth exportfor that), in conjunction with pre-defined error messages (similar to the source you provided).

I´m tired right now to test, but will take a look later.

All of the 16/18 converters will work eventually, but i need to fully understand what a hell M$ made on them, specially to avoid that some converters shows stack problems when other don´t.

Also, many of them uses msconv97.dll, and the converters (some of them) are some sort of wrapper to it.

One thing that seems valid to analyse is the return valeus from RegisterApp. The structure REGAPPRET contains information that can be modified at runtime to better configure the converter


Below is my function to check forth error


Proc GetErrorMessage::
    Arguments @ErrValue
    Structure @BufferName &MAX_PATH, @BufferStartDis 0
    Uses edx, ecx, esi, edi, ebx

    mov eax D@ErrValue
    movzx eax ax
    ..If D$CConverter.m_CchFetchLpszError <> 0
        call ZeroMemory D@BufferName, &MAX_PATH
        call D$CConverter.m_CchFetchLpszError D@ErrValue, D@BufferName, &MAX_PATH
        mov eax D@BufferName
    ..Else
        If eax = 0
            mov eax {B$ "IsFormatCorrect32 did not recognize the input file.", 0}
        Else_If eax = 1
            mov eax {B$ "The converter seems to not be registered. Please update it or register", 0}
        Else_If eax = 0-1
            mov eax {B$ "IsFormatCorrect32 or ForeignToRtf32 was unable to open the input file.", 0}
        Else_If eax = 0-2
            mov eax {B$ "There was an error reading from a file.", 0}
        Else_If eax = 0-4
            mov eax {B$ "There was an error writing to a file.", 0}
        Else_If eax = 0-5
            mov eax {B$ "There was invalid data in a document being imported through ForeignToRtf32.", 0}
        Else_If eax = 0-8
            mov eax {B$ "The converter was unable to allocate memory for this operation.", 0}
        Else_If eax = 0-12
            mov eax {B$ "RtfToForeign32 was unable to create its output file.", 0}
        Else_If eax = 0-13
            mov eax {B$ "The user cancelled the conversion operation", 0}
        Else_If eax = 0-14
            mov eax {B$ "ForeignToRtf32 did not recognize the input file while attempting to convert it.", 0}
        Else
            mov eax {B$ "Unknown Error", 0}
        End_If
    ..End_If

EndP


I´m using CchFetchLpszError to check the correlation between the error messages from the different converters. For example return 1 shows one type of message on one converter, but the same value returns no string on another (but, both values are the same error). So, this function is temporary. I´ll probably remove the check for CchFetchLpszError is all values are exactly the same meaning for all converters
Title: Re: HTML to RTF
Post by: guga on June 23, 2013, 03:05:33 AM
testing the check for imports and exports is made here


Proc CheckForImportExport:
    Arguments @pDocType
    Local @GetReadNames, @GetWriteNames, @InitConverter, @UnitConverter, @hClass, @hDesc, @hExt, @pBuff
    Structure @BufferName 1024, @BufferStartDis 0
    Uses ebx, ecx, edx,esi, edi, eax

    ;move D@pConverterPath D$esi+DocType.pszPathDis
    mov esi D@pDocType
    call ConverterGetLibrary D$esi+DocType.pszPathDis;D@pConverterPath
    ...If eax = &TRUE
        call 'KERNEL32.GetProcAddress' D$CConverter.m_hLibCnv, {B$ "InitConverter32", 0} | mov D@InitConverter eax
        call 'KERNEL32.GetProcAddress' D$CConverter.m_hLibCnv, {B$ "CchFetchLpszError", 0} | mov D$CConverter.m_CchFetchLpszError eax
        call GetModuleName
        call D@InitConverter &NULL, eax

        call 'KERNEL32.GetProcAddress' D$CConverter.m_hLibCnv, {B$ "GetReadNames", 0} | mov D$CConverter.m_GetReadNames eax
        ..If eax <> &FALSE
            call VMemAlloc D@BufferName, 1024 | mov D@pBuff eax
            call GetReadNames &NULL, &NULL, D@BufferName
            mov ebx D@BufferName
            .If eax <> &FCENOERR;&TRUE
                mov edx D$esi+DocType.pszPathDis
                call ShowError eax
            .Else_If B$ebx <> 0 ; <---- why here is showing 0FF as the 1st byte ????????????
                mov eax D$esi+DocType.pszPathDis;eax
                mov D$esi+DocType.bReadDis &TRUE
            .Else
                mov eax D$esi+DocType.pszPathDis;D@pConverterPath
                mov D$esi+DocType.bReadDis &FALSE
            .End_If
        ..Else
            mov eax D$esi+DocType.pszPathDis;D@pConverterPath
        ..End_If

        call 'KERNEL32.GetProcAddress' D$CConverter.m_hLibCnv, {B$ "GetWriteNames", 0} | mov D@GetWriteNames eax

        call 'KERNEL32.GetProcAddress' D$CConverter.m_hLibCnv, {B$ "UninitConverter", 0} | mov D@UnitConverter eax
        call eax
        call VMemFree D@pBuff
    ...End_if

    call 'KERNEL32.FreeLibrary' D$CConverter.m_hLibCnv

EndP



Proc GetReadNames::
    Arguments @pOutName, @pOutDesc, @pOutExt
    Local @hClass, @hDesc, @hExt, @pMem
    Uses ebx, ecx, edx

    call 'KERNEL32.GlobalAlloc' &GHND, 1024 | mov D@hClass eax
    call 'KERNEL32.GlobalAlloc' &GHND, 1024 | mov D@hDesc eax
    call 'KERNEL32.GlobalAlloc' &GHND, 1024 | mov D@hExt eax
    call D$CConverter.m_GetReadNames D@hClass, D@hDesc, D@hExt
    movzx eax ax
    .If eax = &FCENOERR
        If D@pOutName <> &NULL
            call 'kernel32.GlobalLock' D@hClass
            call StrCpy eax, D@pOutName
            call 'kernel32.GlobalUnlock' D@hClass
        End_If

        If D@pOutDesc <> &NULL
            call 'kernel32.GlobalLock' D@hDesc
            call StrCpy eax, D@pOutDesc
            call 'kernel32.GlobalUnlock' D@hDesc
        End_If

        If D@pOutExt <> &NULL
            call 'kernel32.GlobalLock' D@hExt
            call StrCpy eax, D@pOutExt
            call 'kernel32.GlobalUnlock' D@hExt
        End_If
        mov ebx &FCENOERR;&TRUE
    .Else
        mov ebx eax
    .End_If

    call 'kernel32.GlobalFree' D@hClass
    call 'kernel32.GlobalFree' D@hDesc
    call 'kernel32.GlobalFree' D@hExt

    mov eax ebx

EndP



Proc ShowError::
    Arguments @ErrValue
    Uses edx, ecx, esi, edi, ebx

    call GetErrorMessage D@ErrValue
    call 'USER32.MessageBoxA' 0, eax, {'Warning !!!', 0}, &MB_OK__&MB_ICONWARNING__&MB_SYSTEMMODAL

EndP


This is not the final function yet, beca8use i need to understand why some converters returns valid (FCENOERR),but the  1st byte of he extension is 0FF (after it had a stack problem on mine GetReadNames function.
Title: Re: HTML to RTF
Post by: TouEnMasm on June 23, 2013, 03:35:10 AM

If you have stack problem search in your code.
All is clear now for me.
The last problem is gone , I have succeed to export a rtf files to Word97 format
It is really stupid ghclass must be the same than in the registry,that is Word97 for the corresponding dll in the registry.
Errors must be filtered and there is to not take care of unknown errors.
After that all work.
Title: Re: HTML to RTF
Post by: TouEnMasm on June 23, 2013, 03:59:39 AM
Quote
To know which extension can be exported you need to use the Getread/Getwrite functions.
The GetReadNames and getWriteNames functions return something only with the html.cnv dll ,others dll return empt strings.
This point is tested with my code and c codes.
If you find others dll who answer something,put them here.

Another stupid thing,to know them read the value "Extensions" of the registry keys.
For each format,the Extensions values are given.

Title: Re: HTML to RTF
Post by: jj2007 on June 23, 2013, 06:35:21 AM
Yves, Guga,
Compliments - you really take that seriously :t
Title: Re: HTML to RTF
Post by: guga on June 23, 2013, 07:00:32 AM
Reading from the registry is not a bad technique.

ReadNames and WriteNames only shows the extension IF the converter is registered. Ex: Lotus32.cnv who returns 0. But on my registry it do have the extension on the proper key.

html.iec does not return an empty string. It returns a pointer to the extension.


docx and docm extensions, the converter don´t have getreadname or getwritename functions
C:\Program Files\Microsoft Office\Office12\Wordcnvpxy.cnv


Write32.wpc, mswrd632.wpc returns 1, and it don´t grab the extensions, which make my assumption correct. When it returns 1 , the converter is not registered and, therefore,may not work.

On the opposite side, mswrd832.cnv, returns 1, have the extension on the registry, shows the extension on getwritenames, and so, it works. Also, it returs on getwritenames the pointer to the extension(which, don´t exists btw)


Other returns 0FFFFFFFB etc

See ? You can´t trust alone on the returned values of getReadnames/GetWriteNames according to the documentation, because each converter TRIES to make more or less similar to the sdk doc, but they fail badly on this. You need to use the registry values and also analyses the returned values from those functions (when they do exists, of course) to make a proper error case that works for all of them.

I´ll make a routine to grab all the return values from both functions and see what is going on. I´ll post it here too, when i finish. It maybe helpful for you.

Maybe for you analysing only 5 or 6 converters should solve the problem, but, it is definitely not the case for all users who have more then 5/6. I, for instance, have 18 of the newer version for different kinds of conversions. (I have more, but i forced the app to choose only the newer versions of each converter to use)
Title: Re: HTML to RTF
Post by: guga on June 23, 2013, 07:08:57 AM
Tks JJ.


Yep, we are trying to make that crappy stuff works properly.  Some of them are really usefull and may be worth the effords.

I was original planning to make it simple, only for RTFtoHTML and vice-versa, so i can finish my downloader and parser for the msdn doc, but, now that i saw some converters doing a good job, it is good to make everything works fine for all purposes.
Title: Re: HTML to RTF
Post by: guga on June 23, 2013, 10:53:00 AM
Hi Yves

prepare for the mess  :greensml:

Those are the results of the returned values from GetReadName and GetWriteName exports


(Imported) Converter name: c:\WINDOWS\system32\HTML.iec    |   ReturnedValue: 0x1810A8h    |   Extension Addr:  0x1810A8h    |   Ext.Data:  htm html htx otm
(Exported) Converter name: c:\WINDOWS\system32\HTML.iec    |   ReturnedValue: 0x1810A8h    |   Extension Addr:  0x1810A8h    |   Ext.Data:  htm html htx

(Imported) Converter name: c:\PROGRA~1\COMMON~1\MICROS~1\TextConv\LOTUS32.CNV    |   ReturnedValue: 0x0h    |   Extension Addr:  0x1810A8h    |   Ext.Data:  wk1 wk3 wk4
(Exported) Converter name: c:\PROGRA~1\COMMON~1\MICROS~1\TextConv\LOTUS32.CNV    |   ReturnedValue: 0xC00014h    |   Extension Addr:  0x1810A8h    |   Ext.Data:  ---- Nothing here ----

(Imported) Converter name: c:\PROGRA~1\COMMON~1\MICROS~1\TextConv\EXCEL32.CNV    |   ReturnedValue: 0x0h    |   Extension Addr:  0x1810A8h    |   Ext.Data:  xls xlw xl5
(Exported) Converter name: c:\PROGRA~1\COMMON~1\MICROS~1\TextConv\EXCEL32.CNV    |   ReturnedValue: 0xC00014h    |   Extension Addr:  0x1810A8h    |   Ext.Data:  ---- Nothing here ----

(Imported) Converter name: c:\Program Files\Common Files\Microsoft Shared\TextConv\write32.wpc    |   ReturnedValue: 0x1h    |   Extension Addr:  0x1810A8h    |   Ext.Data:  ---- Nothing here ----
(Exported) Converter name: c:\Program Files\Common Files\Microsoft Shared\TextConv\write32.wpc    |   ReturnedValue: 0x1h    |   Extension Addr:  0x1810A8h    |   Ext.Data:  ---- Nothing here ----

(Imported) Converter name: c:\Program Files\Common Files\Microsoft Shared\TextConv\mswrd632.wpc    |   ReturnedValue: 0x1h    |   Extension Addr:  0x1810A8h    |   Ext.Data:  ---- Nothing here ----
(Exported) Converter name: c:\Program Files\Common Files\Microsoft Shared\TextConv\mswrd632.wpc    |   ReturnedValue: 0x1h    |   Extension Addr:  0x1810A8h    |   Ext.Data:  ---- Nothing here ----

(Imported) Converter name: c:\Program Files\Common Files\Microsoft Shared\TextConv\mswrd832.cnv    |   ReturnedValue: 0x1h    |   Extension Addr:  0x1810A8h    |   Ext.Data:  doc
(Exported) Converter name: c:\Program Files\Common Files\Microsoft Shared\TextConv\mswrd832.cnv    |   ReturnedValue: 0xC00014h    |   Extension Addr:  0x1810A8h    |   Ext.Data:  ---- Nothing here ----

(Imported) Converter name: c:\PROGRA~1\COMMON~1\MICROS~1\TextConv\MACWRD32.CNV    |   ReturnedValue: 0x0h    |   Extension Addr:  0x1810A8h    |   Ext.Data:  mcw
(Exported) Converter name: c:\PROGRA~1\COMMON~1\MICROS~1\TextConv\MACWRD32.CNV    |   ReturnedValue: 0x0h    |   Extension Addr:  0x1810A8h    |   Ext.Data:  mcw

(Imported) Converter name: c:\PROGRA~1\COMMON~1\MICROS~1\TextConv\WNWRD232.CNV    |   ReturnedValue: 0x182AC0h    |   Extension Addr:  0x182AC0h    |   Ext.Data:  doc
(Exported) Converter name: c:\PROGRA~1\COMMON~1\MICROS~1\TextConv\WNWRD232.CNV    |   ReturnedValue: 0x182AC0h    |   Extension Addr:  0x182AC0h    |   Ext.Data:  doc

(Imported) Converter name: c:\PROGRA~1\COMMON~1\MICROS~1\TextConv\WORKS432.CNV    |   ReturnedValue: 0xFFFFFFF8h    |   Extension Addr:  0x182ED8h    |   Ext.Data:  ---- Nothing here ----
(Exported) Converter name: c:\PROGRA~1\COMMON~1\MICROS~1\TextConv\WORKS432.CNV    |   ReturnedValue: 0xFFFFFFF8h    |   Extension Addr:  0x182E90h    |   Ext.Data:  ---- Nothing here ----

(Imported) Converter name: c:\PROGRA~1\COMMON~1\MICROS~1\TextConv\WORKS532.CNV    |   ReturnedValue: 0xC0001Ch    |   Extension Addr:  0x16C078h    |   Ext.Data:  wps
(Exported) Converter name: c:\PROGRA~1\COMMON~1\MICROS~1\TextConv\WORKS532.CNV    |   ReturnedValue: 0xC00054h    |   Extension Addr:  0x16C078h    |   Ext.Data:  wps

(Imported) Converter name: c:\PROGRA~1\COMMON~1\MICROS~1\TEXTCONV\RECOVR32.CNV    |   ReturnedValue: 0x1h    |   Extension Addr:  0x16C078h    |   Ext.Data:  *
(Exported) Converter name: c:\PROGRA~1\COMMON~1\MICROS~1\TEXTCONV\RECOVR32.CNV    |   ReturnedValue: 0xC00054h    |   Extension Addr:  0x16C078h    |   Ext.Data:  ---- Nothing here ----

(Imported) Converter name: c:\PROGRA~1\COMMON~1\MICROS~1\TEXTCONV\WPFT632.CNV    |   ReturnedValue: 0x1h    |   Extension Addr:  0x16C078h    |   Ext.Data:  wpd doc
(Exported) Converter name: c:\PROGRA~1\COMMON~1\MICROS~1\TEXTCONV\WPFT632.CNV    |   ReturnedValue: 0xC00054h    |   Extension Addr:  0x16C078h    |   Ext.Data:  ---- Nothing here ----

(Imported) Converter name: c:\PROGRA~1\COMMON~1\MICROS~1\TEXTCONV\WPFT532.CNV    |   ReturnedValue: 0x1h    |   Extension Addr:  0x16C078h    |   Ext.Data:  doc
(Exported) Converter name: c:\PROGRA~1\COMMON~1\MICROS~1\TEXTCONV\WPFT532.CNV    |   ReturnedValue: 0xC00054h    |   Extension Addr:  0x16C078h    |   Ext.Data:  ---- Nothing here ----

(Imported) Converter name: c:\Program Files\Common Files\Microsoft Shared\TextConv\TXTLYT32.CNV    |   ReturnedValue: 0x0h    |   Extension Addr:  0x16C078h    |   Ext.Data:  ANS
(Exported) Converter name: c:\Program Files\Common Files\Microsoft Shared\TextConv\TXTLYT32.CNV    |   ReturnedValue: 0x0h    |   Extension Addr:  0x16C078h    |   Ext.Data:  ANS

(Imported) Converter name: c:\Program Files\Microsoft Office\Office10\WWPAB.CNV    |   ReturnedValue: 0x0h    |   Extension Addr:  0x16C078h    |   Ext.Data:  PAB
(Exported) Converter name: c:\Program Files\Microsoft Office\Office10\WWPAB.CNV    |   ReturnedValue: 0xC00054h    |   Extension Addr:  0x16C078h    |   Ext.Data:  ---- Nothing here ----

(Imported) Converter name: c:\PROGRA~1\COMMON~1\MICROS~1\TextConv\WRD6EX32.CNV    |   ReturnedValue: 0xC0001Ch    |   Extension Addr:  0x16C078h    |   Ext.Data:  ---- Nothing here ----
(Exported) Converter name: c:\PROGRA~1\COMMON~1\MICROS~1\TextConv\WRD6EX32.CNV    |   ReturnedValue: 0xC00054h    |   Extension Addr:  0x16C078h    |   Ext.Data:  doc

(Imported) Converter name: c:\PROGRA~1\COMMON~1\MICROS~1\TextConv\WRD6ER32.CNV    |   ReturnedValue: 0xC0001Ch    |   Extension Addr:  0x16C078h    |   Ext.Data:  ---- Nothing here ----
(Exported) Converter name: c:\PROGRA~1\COMMON~1\MICROS~1\TextConv\WRD6ER32.CNV    |   ReturnedValue: 0xC00054h    |   Extension Addr:  0x16C078h    |   Ext.Data:  doc




Returned value can be
1, 0 or any other regular error formats 0-1 to 0-14
A pointer to the extension (0x182AC0h, 0x16C078h etc)
A LongPointer to a Pointer to the extension (0xC00054, 0xC0001C etc), which may contain or not valid extensions

The "nothing here" string i made can refer to 2 situations:
a) The functions does not export or import
b) The function can import or export but it was not correctly registered

When the return value is a pointer (or a LongPointer) it is ALWAYS related to the extension,whose address may or may not contain the extension strings.

And things get a bit worst when you try to fetch the error messages with CchFetchLpszError export, because it will not report the correct error string all the time.

Now you see why is important also get the values from the registry and not to follow the SDK doc only? This is a way to compare to trhe results from GetReadNames/GetWriteNames to see either the converter was registered or not.

It is clear for me that who made those converters had no idea on the work of others and neither had a common official documentation for that. They simply was (and still are) using the old SDK doc, to make all sort of mess they want.

The return values should be kept simple: 0, 0-1, or other negative numbers (as the SDK paper refers to), and NEVER pointers to Addresses.
Title: Re: HTML to RTF
Post by: TWell on June 23, 2013, 07:00:27 PM
Wordcnvpxy.cnv is in this package here (http://www.microsoft.com/en-us/download/details.aspx?id=3)
Title: Re: HTML to RTF
Post by: guga on June 23, 2013, 11:30:22 PM
Many tks tWell

I have it installed, but would be a good idea warn the user to go to the link if it is not registered, or making a download routine for that. The reason why it don´t show on the reports is because Wordcnvpxy.cnv don´t have GetReadnames and GetWriteNames exports
Title: Re: HTML to RTF
Post by: guga on June 24, 2013, 12:10:25 AM
Yves i changed the equates of error messages. There is no reason why to keep them on 16 bits. Since we may find error messages for other converters from 16 and 32 bits for the same error, the better will be keeping them all on 32 bits basis, and allow the app make a routine to find for the 16bits variation of them. I also created another equate called "FCEUNREGISTERED" to be used only with GetReadNames/GetWriteNames that have the same values as FCETRUE to keep the documentation more or less equal to the original SDK purposes. Eventually, i´ll writean SDK doc for these Apis to make it updated.

FCEINVALIDFILE 0FFFFFFFB
FCENOERR 0
FCENOMEMORY 0FFFFFFF8
FCEOPENINFILEERR 0FFFFFFFF
FCEOPENOUTFILEERR 0FFFFFFF4
FCEREADERR 0FFFFFFFE
FCETRUE 01
FCEUSERCANCEL 0FFFFFFF3
FCEWRITEERR 0FFFFFFFC
FCEWRONGFILETYPE 0FFFFFFF2
FCEUNREGISTERED 01


An error check for invalid functions (the ones that are not 0 or 1) can then simply be made as

    If_And eax >= &FCEWRONGFILETYPE, eax <= &FCEOPENINFILEERR, eax > &FCETRUE, ax <= (&FCEOPENINFILEERR  shr 16)
        mov eax 0 ; < ----- or call other error functions/messages/routines here
    End_If
Title: Re: HTML to RTF
Post by: guga on June 24, 2013, 01:36:32 AM
Ok,guys...i guess i found it.


I made a routine for check for the returned values and i figured it out when it is really unregistered and when the app cannot import/export.

On the previous equate i made. I created a unregistered equate. In fact, it is related to the non existence of a import/export for that function. The trick is that, when both functions GetReadnames and GetWritenames returns this flag, it means that the converter cannot import/export anything, meaning that it is truly unregistered.

But, when GetReadNames or getWritenames contains at least one valid import/export then the converter is registered, but it can only import or export and not do both operations.

I´ll post the proper code for all that stuff as soon i finish and also will post the results from the report i previously made.
Title: Re: HTML to RTF
Post by: TouEnMasm on June 24, 2013, 01:47:29 AM

My own code is finish.I have just to change the extension of the export file.
Instead of changing all the constantes errors code i have just made this.
or eax,0FFFF0000h ;and the rerror code is in 32 bits.
Title: Re: HTML to RTF
Post by: dedndave on June 24, 2013, 03:13:36 AM
what if it is positive ?

maybe something like this
    movsx   eax,ax
Title: Re: HTML to RTF
Post by: guga on June 24, 2013, 03:28:57 AM
HI dedndave

From the documentation the error messages are all in negative form (except for FCETRUE that carries a value of 1), but since the several different converters seems to emmit different returns, i´ll have to compare each export functions of them to see what is being returned to make the proper changes.

The idea is make a unique library that can hold all the converters functions and make them return the exact same values for the same situations. For example, there is no reason why getReadnames returns 0 when it finds a registered converter with a valid extension and on another one it returns an adress on the same situation (ie. it is registered and contains exports or imports)

Probably other exported functions from the converters behave on this same strange way. I believe that there are no more then 18 - 20 converters available from those packages, so the new ones should not be a problem, but the older ones, needs to be fixed. If i suceed, i´ll make a dll that can hold all of them (or the vast majority, at least), so we can use it on all aplications we want to build.

The idea is make it simple and easy configurable Apis for the user handle all possible situations of the converters currently available. If yu have more then those 18 converters, let me know. I would like to take a look at others that i don´t have here.
Title: Re: HTML to RTF
Post by: guga on June 24, 2013, 03:33:24 AM
Yves, how many converters are you testing ? (and which ones ?) - If possible can you tell me the version of them ?

Forcing them to or "eax,0FFFF0000h" will work only when the return value is the ones existent on the documentation,i.e. the negative 16 bits values. But it won´t work when they return an address.
Title: Re: HTML to RTF
Post by: TouEnMasm on June 24, 2013, 04:06:47 AM
values  1 and 0 don't need change
all negative values are in 16 bits,and or eax,0FFFF0000h give the soluce.
Here how to filters the errors:
**** usage ********
put it just after the functions call,he is valid for the three named
He return a chain in pbuffer
eax == 1 ;no error
eax == 0 ;error pbuffer give the text of the error
the movzx instruction failed to transform a negative value of 16 bits in 32 bits.
I don't take care of the undocumented adress they return.
The doc give a good advise,use the registry.This method come in first in the doc.


;IsFormatCorrect32, ForeignToRtf32, and RtfToForeign32.
Errors PROC  uses edi pbuffer:DWORD
Local  retour:DWORD
         mov retour,0
mov edi,pbuffer
.if eax == 1
invoke lstrcpy,edi,TXT("IsFormatCorrect32 recognized the input file.")
mov retour,1
jmp FindeErrors
.elseif eax == 0
invoke lstrcpy,edi,TXT("IsFormatCorrect32 did not recognize the input file.",13,10,"Operation completed successfully for other APIs")
jmp FindeErrors
.endif
or eax,0FFFF0000h   ;16 32 bits
.if eax == -1
invoke lstrcpy,edi,TXT("IsFormatCorrect32 or ForeignToRtf32 was unable to open the input file.")
.elseif eax == -2
invoke lstrcpy,edi,TXT("There was an error reading from a file.")
.elseif eax == -4
invoke lstrcpy,edi,TXT("There was an error writing to a file.")
.elseif eax == -5
invoke lstrcpy,edi,TXT("There was invalid data in a document being",13,10,"imported through ForeignToRtf32.")
.elseif eax == -8
invoke lstrcpy,edi,TXT("The converter was unable to allocate memory for an operation.")
.elseif eax == -12
invoke lstrcpy,edi,TXT("RtfToForeign32 was unable to create its output file")
.elseif eax == -13
invoke lstrcpy,edi,TXT("The user cancelled the conversion operation")
.elseif eax == -14
invoke lstrcpy,edi,TXT("ForeignToRtf32 did not recognize the input file while attempting to convert it.")
.else
invoke lstrcpy,edi,TXT("Unknown error")
mov retour,1
.endif

FindeErrors:
         mov eax,retour
         ret
Errors endp
;################################################################


the doc on the subject
Quote
A converter can define and return additional error codes of its own, with numeric values more negative than -14. An application cannot be expected to know the meaning of any such codes, and should report a generic "Cannot open file" message. However, if the converter supplies the following optional API, the calling application may choose to call it to obtain a textual representation of any return value and use this to provide better diagnostics to the user.
long CchFetchLpszError(long fce, char *lpszError, long cb);
<fce>   ::=   An error code previously returned by the converter.
<lspzError>   ::=   A string into which the textual representation of fce should be copied.
<cb>   ::=   The size of lpszError in bytes.
If a converter chooses to provide this function, it must provide textual representations for all of the error values it returns, including the standard codes defined above. If lpszError is not large enough to contain the textual representation (including a terminating '\0'), or if fce does not refer to a valid error code, the converter should return 0. Otherwise, the converter should return the length of the error text in bytes, not counting the terminating '\0'. Because the strings provided by CchFetchLpszError may be displayed to the user, they need to be localized for foreign language versions of the converter.

all converters respects this:
Quote
When searching for a converter, an application searches this registry information. An application will likely search through its private converters first, and then it will search the shared converters. A converter may store additional information of its own under any class name key associated with it.
Here is an example set of registry entries for a shared converter that reads and writes WordPerfect 5.0 and 5.1 files. When exporting, it is important for the user to be able to select a specific minor version to save to, and so there are separate entries for 5.0 and 5.1. When importing, the converter can handle files of both minor version types, so only one entry is required.
HKEY_LOCAL_MACHINE\Software\Microsoft\Shared Tools\
   Text Converters\
      Export\
         WrdPrfctDos50\
            Extensions   "doc wpd"
            Name         "WordPerfect 5.0"
            Path         "C:\Progra~1\...\TextConv\wpft532.cnv"
         WrdPrfctDos51\
            Extensions   "doc"
            Name         "WordPerfect 5.1 for DOS"
            Path         "C:\Progra~1\...\TextConv\wpft532.cnv"
      Import\
         WrdPrfctDos\
            Extensions   "doc"
            Name         "WordPerfect 5.x"
            Path         "C:\Progra~1\...\TextConv\wpft532.cnv"

Title: Re: HTML to RTF
Post by: TouEnMasm on June 24, 2013, 05:03:16 AM
Here my final release

The Imported file in rtf is named test.rtf and is located in the same directory as the execute
Export file will be named testeur with extension needed by the converter.
                                    Same directory as the execute
If one converter failed to initialise,choose another.
Begin by the menu files.Choose an export or import file,then convert menu, choose an export or import converter.

The richedit use the msfedit.dll and is a good converter by copy paste.Images can be added by another copy paste of the image.

Title: Re: HTML to RTF
Post by: guga on June 26, 2013, 05:38:07 PM
Yves how you manages to make it works fully ?

I´m stuck on something and i cannot find what a hell i´m doing wrong. I changed my code so many times, and then i reproduces what you did and yet...Nothing.

Some stupid "this file maybe corrupt" shows ups,while on yours, the same file is converted completelly.

This is yours routine
;################################################################
Importe_File PROC  pdll:DWORD,  pfile:DWORD
Local ghszFile:DWORD,ghszClass[50]:BYTE,gardesp:DWORD,ghClass
Local modulefilename[MAX_PATH]:BYTE,outputfile[MAX_PATH]:BYTE
Local  retour:DWORD
      mov retour,1
invoke convert_SearchAdresse,pdll
.if eax == 0
jmp FindeImporte_File
.endif
      mov retour,1
invoke GetModuleFileName,NULL,addr modulefilename,sizeof modulefilename
invoke lstrcpy,addr outputfile,addr modulefilename
invoke lstrlen,addr outputfile
lea edx,outputfile
add edx,eax
@@:
.if byte ptr [edx]!= "\"
dec edx
jmp @B
.endif
inc edx
invoke lstrcpy,edx,TXT("test.rtf")
mov edx,output.Hwnd
invoke InitConverter32,0,addr modulefilename
;invoke InitConverter32,NULL,NULL
.if eax != 0
;écriture de l'import
invoke CreateFile,addr outputfile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,\
FILE_FLAG_SEQUENTIAL_SCAN, NULL
mov Converted_File,eax
mov ghClass,Fr(GlobalAlloc,GHND,4096)
invoke StringToGlobal,pfile ;addr parametre ;TXT("C:\Documents and Settings\Luce\Bureau\sansnom1.htm")
mov ghszFile,eax
mov ghBuf,Fr(GlobalAlloc,GHND, 4096)
;pas de istorage ,ghszClass retourne la classe
;verifie
invoke IsFormatCorrect32,ghszFile,ghClass
invoke GlobalToString,ghClass,addr ghszClass
;mov ghszClass,0
invoke MessageBox,NULL,addr ghszClass,TXT("format correct"),MB_OK

;---------------------------------------------------------------------

;--------------------------------------------------------------------
invoke     ForeignToRtf32,ghszFile, NULL, ghBuf,ghClass, NULL,WriteCallback
;--------------------------------------------------------------------
.if eax == 0
invoke MessageBox,NULL,TXT("reussite"),addr ghszClass,MB_OK
.else

invoke MessageBox,NULL,TXT("Failed"),addr ghszClass,MB_OK
.endif
invoke CloseHandle,Converted_File
invoke GlobalFree,ghszFile
invoke GlobalFree,ghBuf
invoke UninitConverter
.endif
invoke convert_FreeLibrary

FindeImporte_File:
         mov eax,retour
         ret
Importe_File endp



Mine is:

Proc DoConvert::
    Arguments @DocFileStruct, @lpszFileName, @FileLen
    Local @hMem, @ghClass
    Uses esi, edi, ecx, ebx
   
    call RegisterApp &NULL, &NULL
    On eax = 0, ExitP

    mov esi D@DocFileStruct
    mov eax D@FileLen | shl eax 8
    call VMemAlloc MemConvertedBuff, eax | mov D$CConverter.m_hBuff eax | mov D@hMem eax

    call 'kernel32.GlobalAlloc' &GHND, 4096 | mov D@ghClass eax
    call StringtoHGlobal D@lpszFileName | mov D$ghszFile eax
    call 'kernel32.GlobalAlloc' &GHND, 4096 | mov D$ghBuf eax
    ; here should be isformatcorrect32 ?
    call StringtoHGlobal D$esi+DocType.pszClassNameDis | mov D@ghClass eax

    call D$CConverter.m_ForeignToRtf  D$ghszFile, &NULL, D$ghBuf, D@ghClass, &NULL, WriteOut

    call 'kernel32.GlobalFree' D$ghszFile
    call 'kernel32.GlobalFree' D$ghBuf
    call 'kernel32.GlobalFree' D@ghclass
    mov eax D@hMem

EndP



Proc WriteOut:
    Arguments @cch, @nPercentComplete
    Local @size, @pMem

    mov eax D$CConverter.m_nPercent
    If eax <> D@nPercentComplete
        ; do something to print the percentage
        move D$CConverter.m_nPercent D@nPercentComplete
    End_If

    ;..If D@nPercentComplete <> 0
        ;move D$CConverter.m_nPercent D@nPercentComplete
        .If D@cch <> 0
            call 'KERNEL32.GlobalLock' D$ghBuf | mov D@pMem eax
            call StrCpyEx eax, D$CConverter.m_hBuff, D@cch
            mov eax D@cch
            add D$CConverter.m_hBuff eax
            If D$CConverter.m_nPercent = 100
                mov eax eax ; do something latwer. After fix this crap
            End_If

            call 'KERNEL32.GlobalUnlock' D$ghBuf
            mov eax 0
        ;.Else;_If eax = 0400

        .End_If
        mov eax 0
    ;..End_If

EndP


I have no more clues why it is refusing to translate completelly.

I´m uploading the file i´m using. The source code is embeded on it. You may open the file in rosasm to see the source code.

Btw: The registerapp makes no difference on the error, neither also the VirtualMemory allocation for the exports (Instead making it export directly, i intended to the rtf shows on the richtextbox, but the error message shows before the VirtualMemory is used - if i remove the VirtualMemoryit won´t change anything. The problem is somewhere else in the ghClass for example. Isn´t ghClass, in fact, part of a structure ?


What i noticed is that on mine callback, the percentage goes directly to 82 (or something), meaning that the converter idn´t parsed 100% of the file, while on yours, it goes from 0 to 2 4 6 8 .... 100

When you open/save a file you will see their classes and extensions and the path. (I´ll remove from the opendialog  filter the path later. I was just leave there to make sure it was using the correct converter
Title: Re: HTML to RTF
Post by: TouEnMasm on June 27, 2013, 01:42:15 AM
I don't know very well the rosasm syntax.
I can give you some advices.
-------- Don't use virtualloc to reserve memory,use GlobalAlloc
-------- All prototypes are STDCALL
-------- use dynamic link (getprocadress)
-------- The import functions are the more easy to use,try to made them work at first.
-------- load and unload dll needed to convert one file.

here is the final source code i used



Title: Re: HTML to RTF
Post by: guga on June 27, 2013, 04:21:55 AM
That´s weird. I tried on a simpler way using the same routines i made before, and now it worked !

There should be a problem somewhere else inside my code. Maybe a stack error that don´t crash.
Title: Re: HTML to RTF
Post by: guga on June 27, 2013, 10:09:02 PM
OK, i´m quite done. The previous erroron the message was due to the usage of malloc in one of the routines.

There is a problem with the global alloc. I found where but don´t know how to fix it. The faultive routine is at:

Proc GetReadNames:
    Arguments @pOutName, @pOutDesc, @pOutExt
    Local @hClass, @hDesc, @hExt
    Uses ebx, ecx, edx

    call 'KERNEL32.GlobalAlloc' &GHND, 4096 | mov D@hClass eax
    call 'KERNEL32.GlobalAlloc' &GHND, 4096 | mov D@hDesc eax
    call 'KERNEL32.GlobalAlloc' &GHND, 4096 | mov D@hExt eax
    call D$CConverter.m_GetReadNames D@hClass, D@hDesc, D@hExt
    mov ecx D@hExt
    ...If_And eax >= &FCEWRONGFILETYPE, eax <= &FCEOPENINFILEERR, eax > &FCEUNREGISTERED, ax <= (&FCEOPENINFILEERR  shr 16)

        or eax 0FFFF0000 ; to keep the error in a 32 bits basis
        mov ebx eax

        mov eax D$ecx
        On B$eax <> 0, jmp L1> ; Ok, the extension address contains valid strings go to the proper routine
        mov ebx &FCEUNREGISTERED

    ...Else_If eax = D$ecx

        On B$eax <> 0, jmp L1> ; Ok, the extension address contains valid strings go to the proper routine
        mov ebx &FCEUNREGISTERED

    ...Else_If eax = &FCEUNREGISTERED
        ; aparently unregistered. Let´s check
        mov eax D$ecx
        On B$eax <> 0, jmp L1> ; Ok, the extension address contains valid strings go to the proper routine
        mov ebx &FCEUNREGISTERED

    ...Else_If eax = &FCENOERR
L1:
        mov eax D$ecx
        .If B$eax <> 0
            call GlobalToString D@hClass, D@pOutName; | mov eax D@pOutName
            call GlobalToString D@hDesc, D@pOutDesc
            call GlobalToString D@hExt, D@pOutExt
            mov ebx &FCENOERR
        .Else
            mov ebx &FCEUNREGISTERED ; seems trully unregistered
        .End_If
    ...Else
        ..If eax = ecx
            mov eax D$eax
            On B$eax <> 0, jmp L1<< ; There is a extension string inside, go back and copy to the proper buffers
            mov ebx &FCEUNREGISTERED
        ..Else
            mov ebx eax
        ..End_If
    ...End_If

    call 'kernel32.GlobalFree' D@hExt ; <---- here a internal error is generated
    call 'kernel32.GlobalFree' D@hDesc
    call 'kernel32.GlobalFree' D@hClass

    mov eax ebx
        ;for developments only
        ;call StoreReturnedValues D$PathStore, eax, D@pOutExt, 0
EndP


The function that calls it is:


________________________________________________________________________________________________________________________

[InfoStruct:
InfoStruct.ClassName: B$ 0 #260
InfoStruct.Desc: B$ 0 #260
InfoStruct.Ext: B$ 0 #260]
[Size_Of_InfoStruct 780]

Proc CheckForImportExport:
    Arguments @pDocType
    Local @GetReadNames, @GetWriteNames, @InitConverter, @UnitConverter, @hClass, @hDesc, @hExt, @pBuff
    Uses ebx, ecx, edx, esi, edi, eax

    mov esi D@pDocType
    call ConverterGetLibrary D$esi+DocType.pszPathDis
    ...If eax = &TRUE
                ; for development only
                ;move D$PathStore D$esi+DocType.pszPathDis
        call 'KERNEL32.GetProcAddress' D$CConverter.m_hLibCnv, {B$ "InitConverter32", 0} | mov D@InitConverter eax
        call 'KERNEL32.GetProcAddress' D$CConverter.m_hLibCnv, {B$ "CchFetchLpszError", 0} | mov D$CConverter.m_CchFetchLpszError eax
        call GetModuleName
        call D@InitConverter &NULL, eax
        .If eax <> &FCETRUE
            mov D$esi+DocType.bReadDis &FALSE
            mov D$esi+DocType.bWriteDis &FALSE
            mov D$esi+DocType.IsConverterRegisteredDis &FALSE
            jmp L8>>
        .End_If
        call ZeroMemory InfoStruct, Size_Of_InfoStruct
        call 'KERNEL32.GetProcAddress' D$CConverter.m_hLibCnv, {B$ "GetReadNames", 0} | mov D$CConverter.m_GetReadNames eax
        mov edi D$esi+DocType.pszPathDis
        ..If eax <> &FALSE
            mov edi InfoStruct.ClassName
            mov ebx InfoStruct.Desc
            mov ecx InfoStruct.Ext

            call GetReadNames edi, ebx, ecx
            .If eax = &FCEUNREGISTERED
                mov D$esi+DocType.bReadDis &FALSE
            .Else_If eax = &FCENOERR
                mov edx InfoStruct.Ext
                call AdjustExtensionsforEquality2 esi, edx, 0
                mov D$esi+DocType.bReadDis &TRUE
            .Else
                call ShowError eax
                mov eax D$esi+DocType.pszPathDis
                mov D$esi+DocType.bReadDis &FALSE
            .End_If
            mov eax D$esi+DocType.pszClassNameDis | call StrCpy edi, eax
            mov eax D$esi+DocType.pszDescriptionDis | call StrCpy ebx, eax
        ..Else
            ; special case for docm
            mov eax D$esi+DocType.pszDescriptionDis; | call StrCpy ebx, eax
        ..End_If

        call ZeroMemory InfoStruct, Size_Of_InfoStruct
        call 'KERNEL32.GetProcAddress' D$CConverter.m_hLibCnv, {B$ "GetWriteNames", 0} | mov D$CConverter.m_GetWriteNames eax
        ..If eax <> &FALSE

            mov edi InfoStruct.ClassName
            mov ebx InfoStruct.Desc
            mov ecx InfoStruct.Ext
            call GetWriteNames edi, ebx, ecx
            .If eax = &FCEUNREGISTERED
                mov D$esi+DocType.bWriteDis &FALSE
            .Else_If eax = &FCENOERR
                mov edx InfoStruct.Ext
                call AdjustExtensionsforEquality2 esi, edx, 1
                mov D$esi+DocType.bWriteDis &TRUE
            .Else
                call ShowError eax
                mov D$esi+DocType.bWriteDis &FALSE
            .End_If
            mov eax D$esi+DocType.pszExportClassNameDis | call StrCpy edi, eax
            mov eax D$esi+DocType.pszExportDescriptionDis | call StrCpy ebx, eax
        ..Else
            ; special case for docm
            move D$esi+DocType.pszExportDescriptionDis D$esi+DocType.pszDescriptionDis
        ..End_If

        If_And D$esi+DocType.bReadDis = &FALSE, D$esi+DocType.bWriteDis = &FALSE
            mov D$esi+DocType.IsConverterRegisteredDis &FALSE
        Else
            mov D$esi+DocType.IsConverterRegisteredDis &TRUE
        End_If
L1:

        call 'KERNEL32.GetProcAddress' D$CConverter.m_hLibCnv, {B$ "UninitConverter", 0} | mov D@UnitConverter eax
        If eax <> 0
            call eax
        End_If
    ...End_if
L8:
    call 'KERNEL32.FreeLibrary' D$CConverter.m_hLibCnv

EndP



Proc GlobalToString:
    Arguments @hGlobal, @pOutString
    Uses ecx, esi, edi, edx

    call 'KERNEL32.GlobalLock' D@hGlobal; | mov D@pGlob eax
    If D@pOutString <> 0
        call 'KERNEL32.lstrcpyA' D@pOutString, eax
    End_If
    call 'KERNEL32.GlobalUnlock' D@hGlobal
    mov eax &TRUE

EndP


Yves, the usage of globallloc on GetReadNames is correct ?
Title: Re: HTML to RTF
Post by: TouEnMasm on June 27, 2013, 11:56:59 PM
Quote
Yves, the usage of globallloc on GetReadNames is correct ?

Perfectly correct.All parameters in any functions use it.


Title: Re: HTML to RTF
Post by: guga on June 29, 2013, 07:52:14 AM
Damn..this globalalloc crappy functions are giving on my nervs :greensml:

I removed all virtuallloc, all thatwas supposedly to make this beats stops, and now..the error message showed up all over again.

Welll..i´ll gave a try recreating  the kernel32 globallloc to see what this thing is doing.

This is teh code i rebuilt so far


[BaseHeap: D$ 0]
[BaseHeapHandleTable:
BaseHeapHandleTable.Data1: D$ 0;0FFFF
BaseHeapHandleTable.Data2: D$ 0;8
BaseHeapHandleTable.Data3: D$ 0
BaseHeapHandleTable.Data4: D$ 0
BaseHeapHandleTable.Data5: D$ 0
BaseHeapHandleTable.Data6: D$ 0
BaseHeapHandleTable.Data7: D$ 0
BaseHeapHandleTable.Data8: D$ 0]
[BaseDllTag: D$ 0] ; always zero
; http://doxygen.reactos.org/d8/de2/heapmem_8c_ac2b59a3cb0f93ded5f4a6a3322ee6530.html#ac2b59a3cb0f93ded5f4a6a3322ee6530
[HeapHandle: D$ 0]

;;
// The handle structure for global heap handles.
// Notice that it nicely overlays with RTL_HANDLE_ENTRY.
// KEEP IT THAT WAY! ;-)
//
typedef struct _BASE_HEAP_HANDLE_ENTRY
{
    USHORT Flags;
    USHORT LockCount;
    union
    {
        PVOID Object;
        ULONG OldSize;
    };
} BASE_HEAP_HANDLE_ENTRY, *PBASE_HEAP_HANDLE_ENTRY;

http://www.ex-designz.net/apidetail.asp?api_id=235
http://pastebin.com/dLsdrRfe
http://typedescriptor.net/browse/members/1537452-System.Windows.Forms.XplatUIWin32+GAllocFlags.GMEM_NODISCARD#
http://doxygen.reactos.org/d1/d03/xdk_2mmtypes_8h_source.html
http://doxygen.reactos.org/d8/de2/heapmem_8c_ac2b59a3cb0f93ded5f4a6a3322ee6530.html#ac2b59a3cb0f93ded5f4a6a3322ee6530
http://doxygen.reactos.org/dd/dee/lib_2rtl_2handle_8c_a6885d17211e5cf96535a91eac5bb555e.html#a6885d17211e5cf96535a91eac5bb555e
_BaseDllInitializeMemoryManager@0 inside kernel32.dll


API Explanation
GlobalAlloc allocates a series of bytes in the computer's global memory. The memory can be used for any purpose necessary.
The function's return value, if successful, depends on the flags specified in wFlags. It will either be a pointer to the block of
allocated memory or a handle to the block of allocated memory. Although they both identify the same thing,
they will most likely not be equal and cannot be used interchangably! If the function fails, a value of 0 will be returned.
Note that Windows will not allocate a memory block starting at base address 0.

Parameter Information
Declare Function GlobalAlloc Lib "kernel32.dll" (ByVal wFlags _As Long, ByVal dwBytes As Long) As Long

wFlags:     One or more of the following flags specifying how to allocate the block of memory:
                GHND = &H40 Same as combining GMEM_MOVEABLE with GMEM_ZEROINIT.
                GMEM_DDESHARE = &H2000 Optimize the allocated memory for use in DDE conversations.
                GMEM_DISCARDABLE = &H100 Allocate discardable memory. (Cannot be combined with GMEM_FIXED.)
                GMEM_FIXED = &H0 Allocate fixed memory. The function's return value is a pointer to the beginning of the memory block. (Cannot be
                                 combined with GMEM_DISCARDABLE or GMEM_MOVEABLE.)
                GMEM_MOVEABLE = &H2 Allocate moveable memory. The memory block's lock count is initialized at 0 (unlocked). The function's return value
                                    is a handle to the beginning of the memory block. (Cannot be combined with GMEM_FIXED.)
                GMEM_NOCOMPACT = &H10 Do not compact any memory or discard any discardable memory to allocate the requested block.
                GMEM_NODISCARD = &H20 Do not discard any discardable memory to allocate the requested block.
                GMEM_SHARE = &H2000 Same as GMEM_DDESHARE.
                GMEM_ZEROINIT = &H40 Initialize the contents of the memory block to 0.
                GPTR = &H42 Same as combining GMEM_FIXED with GMEM_ZEROINIT.

dwBytes:    The number of bytes to allocate; i.e., the size of the memory block to allocate.

;;

[BASE_HEAP_HANDLE_ENTRY:
BASE_HEAP_HANDLE_ENTRY.Flags: W$ 0
BASE_HEAP_HANDLE_ENTRY.LockCount: W$ 0
BASE_HEAP_HANDLE_ENTRY.Object: D$ 0]

[BASE_HEAP_HANDLE_ENTRY.FlagsDis 0
BASE_HEAP_HANDLE_ENTRY.LockCountDis 2
BASE_HEAP_HANDLE_ENTRY.ObjectDis 4]

[Size_Of_BASE_HEAP_HANDLE_ENTRY 8]

[BASE_HEAP_ENTRY_FLAG_REUSABLE 4]
[HEAP_SETTABLE_USER_VALUE 0100]
[HEAP_SETTABLE_USER_FLAG1 0200]
[HEAP_SETTABLE_USER_FLAG2 0400]
[HEAP_SETTABLE_USER_FLAG3 0800]
[HEAP_SETTABLE_USER_FLAG4 0E00]

Proc GlobalAlloc2:
    Arguments @uFlags, @dwBytes
    Local @Flags, @Ptr, @hMemory

    ; probably createheap is better
    call 'kernel32.GetProcessHeap' | mov D$BaseHeap eax
    ;call 'ntdll.RtlInitializeHandleTable' 0FFFF, 8, BaseHeapHandleTable
    call RtlInitializeHandleTable 0FFFF, 8, BaseHeapHandleTable
    ; call 'ntdll.RtlCreateTagHeap' D$BaseHeap, &NULL, {U$ "BASEDLL!", 0}, {U$ "TMP", 0} <---Borrowed this crappy thing from the beginning of kernel32.dll. It simply initializes it and  return the BaseDllTag flags (Which are neeed for this function). Since BaseDllTag is always zero. This can be commented out.

    ; Make sure the flags are valid
    mov eax D@uFlags
    Test_If eax (not &GMEM_VALID_FLAGS)
        call 'KERNEL32.SetLastError' &ERROR_INVALID_PARAMETER
        xor eax eax
        ExitP
    Test_End

    xor edi edi
    mov D@Flags 0

    ; Convert ZEROINIT
    Test_If al &GMEM_ZEROINIT
        mov D@Flags &HEAP_ZERO_MEMORY
    Test_End

    ; Check if we're not movable, which means pointer-based heap
    ...Test_If al &GMEM_MOVEABLE
       
        ; This is heap based, so lock it in first
        call 'ntdll.RtlLockHeap' D$BaseHeap
        ; Disable locking, enable custom flags, and write the movable flag (deprecated)
        or W@Flags (&HEAP_NO_SERIALIZE+HEAP_SETTABLE_USER_VALUE+HEAP_SETTABLE_USER_FLAG1)
        ; Allocate the handle
        mov ebx BaseHeapHandleTable
        call 'ntdll.RtlAllocateHandle' BaseHeapHandleTable, &NULL
        mov esi eax
        mov D$HeapHandle esi

        ; Get the object and make sure we have size
        lea eax D$esi+BASE_HEAP_HANDLE_ENTRY.ObjectDis | mov D@hMemory eax

        ..If_or esi = 0, D@dwBytes = 0
            ; Fail
            call 'KERNEL32.SetLastError' &ERROR_NOT_ENOUGH_MEMORY
            call 'ntdll.RtlUnlockHeap' D$BaseHeap
            xor eax eax
            ExitP
        ..Else
           
            ; Allocate the actual memory for it; &MEM_TOP_DOWN
            mov edx D$BaseDllTag | add edx &MEM_TOP_DOWN | or edx D@Flags
            call 'ntdll.RtlAllocateHeap' D$BaseHeap, edx, D@dwBytes | mov D@Ptr eax
            .If eax = 0
                ;We failed, manually set the allocate flag and free the handle
                mov W$esi+BASE_HEAP_HANDLE_ENTRY.FlagsDis 1
                call 'ntdll.RtlFreeHandle' ebx, esi

                call 'KERNEL32.SetLastError' &ERROR_NOT_ENOUGH_MEMORY;&HEAP_ZERO_MEMORY
                call 'ntdll.RtlUnlockHeap' D$BaseHeap

                ;  For the cleanup case
                mov D$HeapHandle 0
                xor eax eax
                ExitP
            .Else
                ; All worked well, save our heap entry
                call 'ntdll.RtlSetUserValueHeap' D$BaseHeap, &HEAP_NO_SERIALIZE, D@Ptr, D@hMemory
            .End_If

            ; Cleanup! First unlock the heap
            call 'ntdll.RtlUnlockHeap' D$BaseHeap

        ..End_If

        mov edi D@Ptr
        mov D$esi+BASE_HEAP_HANDLE_ENTRY.ObjectDis edi

        If edi = 0
            mov eax (&HEAP_ZERO_MEMORY__&HEAP_NO_SERIALIZE)
        Else
            mov eax &HEAP_NO_SERIALIZE
        End_If


        mov W$esi+BASE_HEAP_HANDLE_ENTRY.FlagsDis ax
   
        Test_If D@uFlags 01 ; &GMEM_DISCARDABLE <---- What a hell this is doing inside WinXP ?????? There are no exceptions routines inside of this function. Except 2 not used local variables. (Remainings from VC compiler options? )
            or W$esi+BASE_HEAP_HANDLE_ENTRY.FlagsDis &HEAP_GENERATE_EXCEPTIONS;BASE_HEAP_ENTRY_FLAG_REUSABLE
        Test_End
   
        Test_If D@uFlags &GMEM_MOVEABLE
            or W$esi+BASE_HEAP_HANDLE_ENTRY.FlagsDis &HEAP_GROWABLE
        Test_End

        Test_If D@uFlags &GMEM_NODISCARD <---- What a hell this is doing inside WinXP ????
            or W$esi+BASE_HEAP_HANDLE_ENTRY.FlagsDis &HEAP_DISABLE_COALESCE_ON_FREE
        Test_End
   
        mov eax D@hMemory

    ...Test_Else
        ; Check if this is GMEM_NODISCARD (obsolete) <---- What a hell this is doing inside WinXP ????
        Test_If ah &GMEM_NODISCARD
            or D@Flags &HEAP_GENERATE_EXCEPTIONS; or BASE_HEAP_ENTRY_FLAG_REUSABLE;B$ebp-01B 04
        Test_End
   
        ; Allocate heap for it
        If D@dwBytes = 0
            inc D@dwBytes
        End_If
        mov edx D$BaseDllTag | add edx &MEM_TOP_DOWN | or edx D@Flags
        call 'ntdll.RtlAllocateHeap' D$BaseHeap, edx, D@dwBytes
        If eax = 0
            call 'KERNEL32.SetLastError' &ERROR_NOT_ENOUGH_MEMORY
            xor eax eax
        End_If
    ...Test_End

EndP




;;
PARAMS
MaxHandleCount  [In] The maximum number of handles the handle table will support.
HandleSize  [In] The size of each handle.
HandleTable  [In/Out] The handle table.

from ntdll.dll RtlInitializeHandleTable
http://source.winehq.org/WineAPI/RtlInitializeHandleTable.html
;;

Proc RtlInitializeHandleTable:
    Arguments @MaxHandleCount, @HandleSize, @pHandleTable
    Uses edi, edx, ecx

    mov edx D@pHandleTable
    mov edi edx
    xor eax eax
    mov ecx 8
    rep stosd
    mov eax D@MaxHandleCount
    mov D$edx eax
    mov eax D@HandleSize
    mov D$edx+4 eax
EndP


The more i saw inside kernel32 the more weird it looks, the globalalloc function is fully framed and contains obsolete flags. Well....i recreated and it was and will try to test and update fix later. Now it is missing globallock, globalfree and globarealloc.

I´ll try to recode at least globallock and globalfree to test on my app those routines. Later i´ll fire RosAsm debugger on all of them to see where exactly it is crashing and why.
Title: Re: HTML to RTF
Post by: guga on June 29, 2013, 10:26:36 AM
Well..at the end....no matter how i´m struggling with this, i´m also updating RosAsm code as well :bgrin:


Here are some undocumented nt equates added for the NtQuerySystemInformation function

SYS_NFO_MAX_SYSTEM_INFOCLASS 095
SYS_NFO_SYSTEM_ACPIAUDIT_INFORMATION 07A
SYS_NFO_SYSTEM_AITSAMPLINGVALUE 06F
SYS_NFO_SYSTEM_BADPAGE_INFORMATION 080
SYS_NFO_SYSTEM_BASIC_INFORMATION 0
SYS_NFO_SYSTEM_BASICPERFORMANCE_INFORMATION 07B
SYS_NFO_SYSTEM_BIGPOOL_INFORMATION 042
SYS_NFO_SYSTEM_BOOTENTROPY_INFORMATION 075
SYS_NFO_SYSTEM_BOOTENVIRONMENT_INFORMATION 05A
SYS_NFO_SYSTEM_BOOTGRAPHICS_INFORMATION 07E
SYS_NFO_SYSTEM_BOOTLOGO_INFORMATION 08C
SYS_NFO_SYSTEM_CALLCOUNT_INFORMATION 06
SYS_NFO_SYSTEM_CALLTIME_INFORMATION 0A
SYS_NFO_SYSTEM_CODEINTEGRITY_INFORMATION 067
SYS_NFO_SYSTEM_COMBINEPHYSICALMEMORY_INFORMATION 082
SYS_NFO_SYSTEM_COMPLUSPACKAGE 03B
SYS_NFO_SYSTEM_CONSOLE_INFORMATION 084
SYS_NFO_SYSTEM_CONTEXTSWITCH_INFORMATION 024
SYS_NFO_SYSTEM_COVERAGE_INFORMATION 05F
SYS_NFO_SYSTEM_CPUQUOTA_INFORMATION 071
SYS_NFO_SYSTEM_CRASHDUMP_INFORMATION 020
SYS_NFO_SYSTEM_CRASHDUMPSTATE_INFORMATION 022
SYS_NFO_SYSTEM_CURRENTTIMEZONE_INFORMATION 02C
SYS_NFO_SYSTEM_DEVICE_INFORMATION 07
SYS_NFO_SYSTEM_DEVICEDATA_INFORMATION 088
SYS_NFO_SYSTEM_DEVICEDATAENUMERATION_INFORMATION 089
SYS_NFO_SYSTEM_DPCBEHAVIOR_INFORMATION 018
SYS_NFO_SYSTEM_DYNAMICTIMEZONE_INFORMATION 066
SYS_NFO_SYSTEM_EMULATIONBASIC_INFORMATION 03E
SYS_NFO_SYSTEM_EMULATIONPROCESSOR_INFORMATION 03F
SYS_NFO_SYSTEM_ENTROPYINTERRUPTTIMING_INFORMATION 083
SYS_NFO_SYSTEM_ENTROPYINTERRUPTTIMINGRAW_INFORMATION 092
SYS_NFO_SYSTEM_ERRORPORT_INFORMATION 059
SYS_NFO_SYSTEM_ERRORPORTTIMEOUTS 073
SYS_NFO_SYSTEM_EXCEPTION_INFORMATION 021
SYS_NFO_SYSTEM_EXTENDEDHANDLE_INFORMATION 040
SYS_NFO_SYSTEM_EXTENDEDPROCESS_INFORMATION 039
SYS_NFO_SYSTEM_EXTENDSERVICETABLE_INFORMATION 026
SYS_NFO_SYSTEM_FILECACHE_INFORMATION 015
SYS_NFO_SYSTEM_FILECACHEINFORMATIONEX 051
SYS_NFO_SYSTEM_FIRMWARETABLE_INFORMATION 04C
SYS_NFO_SYSTEM_FLAGS_INFORMATION 09
SYS_NFO_SYSTEM_FULLMEMORY_INFORMATION 019
SYS_NFO_SYSTEM_FULLPROCESS_INFORMATION 094
SYS_NFO_SYSTEM_HANDLE_INFORMATION 010
SYS_NFO_SYSTEM_HOTPATCH_INFORMATION 045
SYS_NFO_SYSTEM_HYPERVISOR_INFORMATION 05B
SYS_NFO_SYSTEM_HYPERVISORPROCESSORCOUNT_INFORMATION 087
SYS_NFO_SYSTEM_IMAGEFILEEXECUTIONOPTIONS_INFORMATION 05E
SYS_NFO_SYSTEM_INTERRUPT_INFORMATION 017
SYS_NFO_SYSTEM_KERNELDEBUGGER_INFORMATION 023
SYS_NFO_SYSTEM_LEGACYDRIVER_INFORMATION 02B
SYS_NFO_SYSTEM_LOADGDIDRIVER_INFORMATION 01A
SYS_NFO_SYSTEM_LOADGDIDRIVERIN_SYSTEM_SPACE 036
SYS_NFO_SYSTEM_LOCKS_INFORMATION 0C
SYS_NFO_SYSTEM_LOGICALPROCESSOR_INFORMATION 049
SYS_NFO_SYSTEM_LOGICALPROCESSORANDGROUP_INFORMATION 06B
SYS_NFO_SYSTEM_LOOKASIDE_INFORMATION 02D
SYS_NFO_SYSTEM_LOSTDELAYEDWRITE_INFORMATION 041
SYS_NFO_SYSTEM_LOWPRIORITYIO_INFORMATION 074
SYS_NFO_SYSTEM_MEMORYCHANNEL_INFORMATION 08B
SYS_NFO_SYSTEM_MEMORYLIST_INFORMATION 050
SYS_NFO_SYSTEM_MEMORYTOPOLOGY_INFORMATION 08A
SYS_NFO_SYSTEM_MIRRORMEMORY_INFORMATION 01E
SYS_NFO_SYSTEM_MODULE_INFORMATION 0B
SYS_NFO_SYSTEM_MODULEINFORMATIONEX 04D
SYS_NFO_SYSTEM_NATIVEBASIC_INFORMATION 072
SYS_NFO_SYSTEM_NODEDISTANCE_INFORMATION 079
SYS_NFO_SYSTEM_NONPAGEDPOOL_INFORMATION 0F
SYS_NFO_SYSTEM_NUMAAVAILABLEMEMORY 03C
SYS_NFO_SYSTEM_NUMAPROCESSORMAP 037
SYS_NFO_SYSTEM_NUMAPROXIMITYNODE_INFORMATION 065
SYS_NFO_SYSTEM_OBJECT_INFORMATION 011
SYS_NFO_SYSTEM_OBJECTSECURITYMODE 046
SYS_NFO_SYSTEM_PAGEDPOOL_INFORMATION 0E
SYS_NFO_SYSTEM_PAGEDPOOLINFORMATIONEX 077
SYS_NFO_SYSTEM_PAGEFILE_INFORMATION 012
SYS_NFO_SYSTEM_PAGEFILEINFORMATIONEX 090
SYS_NFO_SYSTEM_PATH_INFORMATION 04
SYS_NFO_SYSTEM_PERFORMANCE_INFORMATION 02
SYS_NFO_SYSTEM_PERFORMANCETRACE_INFORMATION 01F
SYS_NFO_SYSTEM_PLATFORMBINARY_INFORMATION 085
SYS_NFO_SYSTEM_POOLTAG_INFORMATION 016
SYS_NFO_SYSTEM_PORTABLEWORKSPACEEFILAUNCHER_INFORMATION 093
SYS_NFO_SYSTEM_PREFETCHER_INFORMATION 038
SYS_NFO_SYSTEM_PREFETCHPATCH_INFORMATION 060
SYS_NFO_SYSTEM_PRIORITYSEPERATION 027
SYS_NFO_SYSTEM_PROCESS_INFORMATION 05
SYS_NFO_SYSTEM_PROCESSID_INFORMATION 058
SYS_NFO_SYSTEM_PROCESSOR_INFORMATION 01
SYS_NFO_SYSTEM_PROCESSORBRANDSTRING 069
SYS_NFO_SYSTEM_PROCESSORCYCLETIME_INFORMATION 06C
SYS_NFO_SYSTEM_PROCESSORIDLE_INFORMATION 02A
SYS_NFO_SYSTEM_PROCESSORIDLECYCLETIME_INFORMATION 053
SYS_NFO_SYSTEM_PROCESSORMICROCODEUPDATE_INFORMATION 068
SYS_NFO_SYSTEM_PROCESSORPERFORMANCE_INFORMATION 08
SYS_NFO_SYSTEM_PROCESSORPERFORMANCEDISTRIBUTION 064
SYS_NFO_SYSTEM_PROCESSORPERFORMANCEINFORMATIONEX 08D
SYS_NFO_SYSTEM_PROCESSORPOWER_INFORMATION 03D
SYS_NFO_SYSTEM_PROCESSORPOWERINFORMATIONEX 055
SYS_NFO_SYSTEM_PROCESSORPROFILECONTROLAREA 081
SYS_NFO_SYSTEM_QUERYPERFORMANCECOUNTER_INFORMATION 07C
SYS_NFO_SYSTEM_RANGESTART_INFORMATION 032
SYS_NFO_SYSTEM_RECOMMENDEDSHAREDDATAALIGNMENT 03A
SYS_NFO_SYSTEM_REFTRACE_INFORMATION 056
SYS_NFO_SYSTEM_REGISTERFIRMWARETABLEINFORMATIONHANDLER 04B
SYS_NFO_SYSTEM_REGISTRYAPPENDSTRING 06E
SYS_NFO_SYSTEM_REGISTRYQUOTA_INFORMATION 025
SYS_NFO_SYSTEM_SCRUBPHYSICALMEMORY_INFORMATION 07F
SYS_NFO_SYSTEM_SECUREBOOT_INFORMATION 091
SYS_NFO_SYSTEM_SECUREBOOTPOLICY_INFORMATION 08F
SYS_NFO_SYSTEM_SESSION_INFORMATION 031
SYS_NFO_SYSTEM_SESSIONBIGPOOL_INFORMATION 07D
SYS_NFO_SYSTEM_SESSIONCREATE 02F
SYS_NFO_SYSTEM_SESSIONDETACH 030
SYS_NFO_SYSTEM_SESSIONMAPPEDVIEW_INFORMATION 044
SYS_NFO_SYSTEM_SESSIONPOOLTAG_INFORMATION 043
SYS_NFO_SYSTEM_SESSIONPROCESS_INFORMATION 035
SYS_NFO_SYSTEM_SPARE0 08E
SYS_NFO_SYSTEM_SPECIALPOOL_INFORMATION 057
SYS_NFO_SYSTEM_STACKTRACE_INFORMATION 0D
SYS_NFO_SYSTEM_STORE_INFORMATION 06D
SYS_NFO_SYSTEM_SUMMARYMEMORY_INFORMATION 01D
SYS_NFO_SYSTEM_SUPERFETCH_INFORMATION 04F
SYS_NFO_SYSTEM_SYSTEM_DISK_INFORMATION 063
SYS_NFO_SYSTEM_SYSTEM_PARTITION_INFORMATION 062
SYS_NFO_SYSTEM_SYSTEM_PTESINFORMATIONEX 078
SYS_NFO_SYSTEM_THREADPRIORITYCLIENTID_INFORMATION 052
SYS_NFO_SYSTEM_THROTTLENOTIFICATION_INFORMATION 086
SYS_NFO_SYSTEM_TIMEADJUSTMENT_INFORMATION 01C
SYS_NFO_SYSTEM_TIMEOFDAY_INFORMATION 03
SYS_NFO_SYSTEM_TIMESLIPNOTIFICATION 02E
SYS_NFO_SYSTEM_TIMEZONE_INFORMATION 05D
SYS_NFO_SYSTEM_UNLOADGDIDRIVER_INFORMATION 01B
SYS_NFO_SYSTEM_VDMBOP_INFORMATION 014
SYS_NFO_SYSTEM_VDMINSTEMUL_INFORMATION 013
SYS_NFO_SYSTEM_VERIFIER_INFORMATION 033
SYS_NFO_SYSTEM_VERIFIERADDDRIVER_INFORMATION 028
SYS_NFO_SYSTEM_VERIFIERCANCELLATION_INFORMATION 054
SYS_NFO_SYSTEM_VERIFIERCOUNTERS_INFORMATION 076
SYS_NFO_SYSTEM_VERIFIERFAULTS_INFORMATION 061
SYS_NFO_SYSTEM_VERIFIERINFORMATIONEX 05C
SYS_NFO_SYSTEM_VERIFIERREMOVEDRIVER_INFORMATION 029
SYS_NFO_SYSTEM_VERIFIERTHUNKEXTEND 034
SYS_NFO_SYSTEM_VERIFIERTRIAGE_INFORMATION 04E
SYS_NFO_SYSTEM_VHDBOOT_INFORMATION 070
SYS_NFO_SYSTEM_VIRTUALADDRESS_INFORMATION 06A
SYS_NFO_SYSTEM_WATCHDOGTIMER_INFORMATION 048
SYS_NFO_SYSTEM_WATCHDOGTIMERHANDLER 047
SYS_NFO_SYSTEM_WOW64SHAREDINFORMATIONOBSOLETE 04A


Example of usage:

; SYSTEM_RANGE_START_INFORMATION Structure. Only 1 dword
[SystemRangeStart: D$ 0]

[Size_Of_SYSTEM_RANGE_START_INFORMATION 4]

call 'ntdll.NtQuerySystemInformation' &SYS_NFO_SYSTEM_RANGESTART_INFORMATION, SystemRangeStart, Size_Of_SYSTEM_RANGE_START_INFORMATION, 0


Ref: http://www.exploit-monday.com/2013/06/undocumented-ntquerysysteminformation.html
http://home.aubg.bg/students/TNG104/Dev-Cpp/include/ddk/ntapi.h
http://msdn.microsoft.com/en-us/library/windows/desktop/ms724509%28v=vs.85%29.aspx
Title: Re: HTML to RTF
Post by: guga on July 01, 2013, 11:54:35 PM
GlobalLock and GlobalHandle functions


Proc GlobalLock:
    Arguments @hMem
    Uses ebx, edi, ecx, esi, edx

    mov ebx D@hMem

    ; Check if this was a simple allocated heap entry. I.e.: this is a simple alignment check for memory aligned at 4 bytes
    .Test_If bl &BASE_HANDLE_MARK_BIT

        call 'ntdll.RtlLockHeap' D$BaseHeap

        lea esi D$ebx-BASE_HANDLE_TABLE_ENTRY.ObjectDis ; points to BASE_HANDLE_TABLE_ENTRY
        call 'ntdll.RtlIsValidHandle' BaseHeapHandleTable, esi

        mov edi D$esi+BASE_HANDLE_TABLE_ENTRY.ObjectDis

        .If al = 0
            call 'KERNEL32.SetLastError' &ERROR_INVALID_HANDLE
            xor edi edi ;i added here
        .Else_If edi = 0
            call 'KERNEL32.SetLastError' &ERROR_DISCARDED
        .Else
            xor eax eax
            mov ax W$esi+BASE_HANDLE_TABLE_ENTRY.LockCountDis
            lea ecx D$eax+1 ;what happens if ecx > &GMEM_LOCKCOUNT ???
            mov W$esi+BASE_HANDLE_TABLE_ENTRY.LockCountDis cx
            If ax = &GMEM_LOCKCOUNT
                dec W$esi+BASE_HANDLE_TABLE_ENTRY.LockCountDis
            End_If
        .End_If

        call 'ntdll.RtlUnlockHeap' D$BaseHeap
        mov eax edi

    .Test_Else
        ; Otherwise, lock the heap
        call 'kernel32.IsBadReadPtr' ebx, 1  ; Make sure it's not a kernel or invalid address
        .If_Or ebx >= D$SystemRangeStart, eax <> 0
            call 'KERNEL32.SetLastError' &ERROR_INVALID_HANDLE
            xor eax eax
        .Else
            ; It's all good
            mov eax ebx
        .End_If

    .Test_End

EndP



Proc GlobalHandle:
    Arguments @pMem
    Local @Flags, @Handle, @ReturnValue
    Uses ebx, ecx, edx, esi

    call 'ntdll.RtlLockHeap' D$BaseHeap
    mov D@ReturnValue 0
    mov D@Handle 0
    mov D@Flags 0
    lea ebx D@Flags
    lea eax D@Handle
    call 'ntdll.RtlGetUserInfoHeap' D$BaseHeap, &HEAP_NO_SERIALIZE, D@pMem, eax, ebx
    .If al = 0
        call 'kernel32.SetLastError' &ERROR_INVALID_HANDLE
    .Else
        If D@Handle <> 0
            Test_If D@Flags &BASE_HEAP_FLAG_MOVEABLE
                move D@ReturnValue D@Handle
            Test_End
        End_If
    .End_If
    call 'ntdll.RtlUnlockHeap' D$BaseHeap
    mov eax D@ReturnValue

EndP



For those equates and structures eventually posted here that are undocumented. I updated it in RosAsm files at:
Portal (http://rosasm.freeforums.org/portal.php)


The internal variables inside kernel32 are initialized by each system on the user´s current process. For example, the variable BaseHeap is easily achieved with:
call 'kernel32.GetProcessHeap' | mov D$BaseHeap eax
The returned value is the exact same one as inside kernel32.dll that uses this variable to deal with the global/local functions.

Other internal initializtions variables, i inserted on a own function called "InitGlobalMem". This functionshould be initialized any time you want to use the global functions.(or, i´ll create a separated dll for all of them, which is better, IMHO)

Why rebuilding global functions ? Well, because the ones inside kernel32 are utterly faultive. Some apps and dlls still uses them, instead using virtual allocation memory functions or heap functions. And since the RTFtoHTML converters uses them, and it is common to lead to stack problems, i´m rebuilding them to seek exactly why/how/where they are giving randomic errors, fix them so we can use them more easily without so much pain.
Title: Re: HTML to RTF
Post by: guga on July 03, 2013, 08:27:43 PM
I´m updating GlobalAlloc.Imade a wrong translation of the original source,and i found out that, the older version of it inside windowsNT is exact teh same one as existent in WinXP. The only difference is the amount of allocated bytes for the heap. According to the WindowsNT source code (The one that was leaked) the function is:


Proc GlobalAlloc_NT:
    Arguments @uFlags, @dwBytes
    Local @Flags, @Ptr, @hMemory, @TmpBytes, @HandleEntry
    Uses ebx, ecx, edx, edi, esi

    ; Make sure the flags are valid
    mov eax D@uFlags
    Test_If eax (not &GMEM_VALID_FLAGS)
        call 'KERNEL32.SetLastError' &ERROR_INVALID_PARAMETER
        xor eax eax
        ExitP
    Test_End

    ;xor edi edi
    mov D@Flags 0

    ; Convert ZEROINIT
    Test_If D@Flags &GMEM_ZEROINIT
        mov D@Flags &HEAP_ZERO_MEMORY
    Test_End

    ; Check if we're not movable, which means pointer-based heap
    .Test_If_Not D@uFlags &GMEM_MOVEABLE
        Test_If D@uFlags &GMEM_DDESHARE
            or D@Flags &BASE_HEAP_FLAG_DDESHARE
        Test_End
        If D@dwBytes <> 0
            move D@TmpBytes D@dwBytes
        Else
            mov D@TmpBytes 1
        End_If
        MAKE_TAG &GMEM_TAG | or eax D@Flags
        call 'ntdll.RtlAllocateHeap' D$BaseHeap, eax, D@TmpBytes | mov D@Ptr eax
        If eax = 0
            call 'KERNEL32.SetLastError' &ERROR_NOT_ENOUGH_MEMORY
            mov eax D@Ptr
            ExitP
        End_If
        ExitP
    .Test_End

    mov D@Ptr 0
    ; This is heap based, so lock it in first
    call 'ntdll.RtlLockHeap' D$BaseHeap
    ; Disable locking, enable custom flags, and write the movable flag (deprecated)
    or D@Flags (&HEAP_NO_SERIALIZE+&HEAP_SETTABLE_USER_VALUE+&BASE_HEAP_FLAG_MOVEABLE)
    ; Allocate the handle
    call 'ntdll.RtlAllocateHandle' BaseHeapHandleTable, &NULL | mov D@HandleEntry eax
    If eax = 0
        call 'KERNEL32.SetLastError' &ERROR_NOT_ENOUGH_MEMORY
        jmp @Fail
    End_If
    mov eax D@HandleEntry | add eax BASE_HANDLE_TABLE_ENTRY.ObjectDis | mov D@hMemory eax

    .If D@dwBytes <> 0
        MAKE_TAG &GMEM_TAG | or eax D@Flags
        call 'ntdll.RtlAllocateHeap' D$BaseHeap, eax, D@dwBytes | mov D@Ptr eax
        If eax = 0
            mov esi D@HandleEntry
            mov W$esi+BASE_HANDLE_TABLE_ENTRY.FlagsDis &RTL_HANDLE_ALLOCATED
            call 'ntdll.RtlFreeHandle' BaseHeapHandleTable, esi
            call 'KERNEL32.SetLastError' &ERROR_NOT_ENOUGH_MEMORY
        Else
            call 'ntdll.RtlSetUserValueHeap' D$BaseHeap, &HEAP_NO_SERIALIZE, D@Ptr, D@hMemory
        End_If
    .End_If

@Fail:

    ; Cleanup! First unlock the heap
    call 'ntdll.RtlUnlockHeap' D$BaseHeap
    ...If D@HandleEntry <> 0
        mov edx D@HandleEntry
        mov eax D@Ptr
        mov D$edx+BASE_HANDLE_TABLE_ENTRY.ObjectDis eax
        If D@Ptr <> 0
            mov W$edx+BASE_HANDLE_TABLE_ENTRY.FlagsDis &RTL_HANDLE_ALLOCATED
        Else
            mov W$edx+BASE_HANDLE_TABLE_ENTRY.FlagsDis &RTL_HANDLE_ALLOCATED__&BASE_HANDLE_DISCARDED
        End_If

        Test_If D@Flags &GMEM_DISCARDABLE
            or W$edx+BASE_HANDLE_TABLE_ENTRY.FlagsDis &BASE_HANDLE_DISCARDABLE
        Test_End

        Test_If D@Flags &GMEM_MOVEABLE
            or W$edx+BASE_HANDLE_TABLE_ENTRY.FlagsDis &BASE_HANDLE_MOVEABLE
        Test_End

        Test_If D@Flags &GMEM_DDESHARE
            or W$edx+BASE_HANDLE_TABLE_ENTRY.FlagsDis &BASE_HANDLE_SHARED
        Test_End

        move D@Ptr D@hMemory
    ...End_If
    mov eax D@Ptr

EndP


But, on newer Windows versions the only change Microsoft programmers did was change GMEM_TAG equate from MAKE_TAG macro with HEAP_TAG_SHIFT equate. So, the GloballAlloc function since WindowsXp is translated as:


Proc GlobalAlloc3::
    Arguments @uFlags, @dwBytes
    Local @Flags, @Ptr, @hMemory, @HandleEntry
    Uses ebx, ecx, edx, edi, esi

    ; Make sure the flags are valid
    mov eax D@uFlags
    Test_If D@uFlags (not &GMEM_VALID_FLAGS)
        call 'KERNEL32.SetLastError' &ERROR_INVALID_PARAMETER
        xor eax eax
        ExitP
    Test_End

    xor edi edi
    mov D@Flags 0

    ; Convert ZEROINIT
    Test_If D@uFlags &GMEM_ZEROINIT
        mov D@Flags &HEAP_ZERO_MEMORY
    Test_End

    ; Check if we're not movable, which means pointer-based heap
    .Test_If_Not D@uFlags &GMEM_MOVEABLE
        Test_If D@uFlags &GMEM_DDESHARE
            or D@Flags &BASE_HANDLE_DISCARDABLE
        Test_End
        If D@dwBytes = 0
            inc D@dwBytes
        End_If
        MAKE_TAG &HEAP_TAG_SHIFT | or eax D@Flags
        call 'ntdll.RtlAllocateHeap' D$BaseHeap, eax, D@dwBytes | mov D@Ptr eax
        If eax = 0
            call 'KERNEL32.SetLastError' &ERROR_NOT_ENOUGH_MEMORY
            xor eax eax
            ExitP
        End_If
        mov eax D@Ptr
        ExitP
    .Test_End

    mov D@Ptr 0
    ; This is heap based, so lock it in first
    call 'ntdll.RtlLockHeap' D$BaseHeap
    ; Disable locking, enable custom flags, and write the movable flag (deprecated)
    or D@Flags (&HEAP_NO_SERIALIZE+&HEAP_SETTABLE_USER_VALUE+&BASE_HEAP_FLAG_MOVEABLE)
    ; Allocate the handle
    call 'ntdll.RtlAllocateHandle' BaseHeapHandleTable, &NULL | mov esi eax
    mov D@HandleEntry esi
    ..If eax = 0
        call 'KERNEL32.SetLastError' &ERROR_NOT_ENOUGH_MEMORY
    ..Else

        lea eax D$esi+BASE_HANDLE_TABLE_ENTRY.ObjectDis
        mov D@hMemory eax
   
        .If D@dwBytes <> 0
            MAKE_TAG &HEAP_TAG_SHIFT | or eax D@Flags
            call 'ntdll.RtlAllocateHeap' D$BaseHeap, eax, D@dwBytes | mov edi eax
            mov D@Ptr edi
            If edi = 0
                mov W$esi+BASE_HANDLE_TABLE_ENTRY.FlagsDis &RTL_HANDLE_ALLOCATED
                call 'ntdll.RtlFreeHandle' BaseHeapHandleTable, esi
                xor esi esi
                mov D@HandleEntry 0
                call 'KERNEL32.SetLastError' &ERROR_NOT_ENOUGH_MEMORY
            Else
                call 'ntdll.RtlSetUserValueHeap' D$BaseHeap, &HEAP_NO_SERIALIZE, D@Ptr, D@hMemory
            End_If
        .End_If

    ..End_If
; Fail

    ; Cleanup! First unlock the heap
    call 'ntdll.RtlUnlockHeap' D$BaseHeap
    .If esi = 0
        mov D$esi+BASE_HANDLE_TABLE_ENTRY.ObjectDis edi

        If edi = &NULL
            mov eax (&BASE_HANDLE_DISCARDED__&RTL_HANDLE_ALLOCATED)
        Else
            mov eax &RTL_HANDLE_ALLOCATED
        End_If
        mov W$esi+BASE_HANDLE_TABLE_ENTRY.FlagsDis ax

        Test_If D@Flags &GMEM_DISCARDABLE
            or W$esi+BASE_HANDLE_TABLE_ENTRY.FlagsDis &BASE_HANDLE_DISCARDABLE
        Test_End

        Test_If D@Flags &GMEM_MOVEABLE
            or W$esi+BASE_HANDLE_TABLE_ENTRY.FlagsDis &BASE_HANDLE_MOVEABLE
        Test_End   

        Test_If D@Flags &GMEM_DDESHARE
            or W$esi+BASE_HANDLE_TABLE_ENTRY.FlagsDis &BASE_HANDLE_SHARED
        Test_End

        mov edi D@hMemory
    .End_If
    mov eax edi

EndP


So, the current C source code for globallalloc is:


HGLOBAL
WINAPI
GlobalAlloc(
UINT uFlags,
DWORD dwBytes
)
{
PBASE_HANDLE_TABLE_ENTRY HandleEntry;
HANDLE hMem;
LPSTR p;
ULONG Flags;

if (uFlags & ~GMEM_VALID_FLAGS) {
SetLastError( ERROR_INVALID_PARAMETER );
return( NULL );
}

Flags = 0;
if (uFlags & GMEM_ZEROINIT) {
Flags |= HEAP_ZERO_MEMORY;
}

if (!(uFlags & GMEM_MOVEABLE)) {
if (uFlags & GMEM_DDESHARE) {
Flags |= BASE_HEAP_FLAG_DDESHARE;
}

p = RtlAllocateHeap( BaseHeap,
MAKE_TAG( HEAP_TAG_SHIFT ) | Flags,
dwBytes ? dwBytes : 1
);

if (p == NULL) {
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
}

return p;
}

p = NULL;
RtlLockHeap( BaseHeap );
Flags |= HEAP_NO_SERIALIZE | HEAP_SETTABLE_USER_VALUE | BASE_HEAP_FLAG_MOVEABLE;
try {
HandleEntry = (PBASE_HANDLE_TABLE_ENTRY)RtlAllocateHandle( &BaseHeapHandleTable, NULL );
if (HandleEntry == NULL) {
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
goto Fail;
}

hMem = (HANDLE)&HandleEntry->Object;
if (dwBytes != 0) {
p = (LPSTR)RtlAllocateHeap( BaseHeap, MAKE_TAG( HEAP_TAG_SHIFT ) | Flags, dwBytes );
if (p == NULL) {
HandleEntry->Flags = RTL_HANDLE_ALLOCATED;
RtlFreeHandle( &BaseHeapHandleTable, (PRTL_HANDLE_TABLE_ENTRY)HandleEntry );
HandleEntry = NULL;
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
}
else {
RtlSetUserValueHeap( BaseHeap, HEAP_NO_SERIALIZE, p, hMem );
}
}
Fail:   ;
}
except (EXCEPTION_EXECUTE_HANDLER) {
BaseSetLastNTError( GetExceptionCode() );
}

RtlUnlockHeap( BaseHeap );

if (HandleEntry != NULL) {
HandleEntry->Object = p;
if (p != NULL) {
HandleEntry->Flags = RTL_HANDLE_ALLOCATED;
}
else {
HandleEntry->Flags = RTL_HANDLE_ALLOCATED | BASE_HANDLE_DISCARDED;
}

if (uFlags & GMEM_DISCARDABLE) {
HandleEntry->Flags |= BASE_HANDLE_DISCARDABLE;
}

if (uFlags & GMEM_MOVEABLE) {
HandleEntry->Flags |= BASE_HANDLE_MOVEABLE;
}

if (uFlags & GMEM_DDESHARE) {
HandleEntry->Flags |= BASE_HANDLE_SHARED;
}

p = (LPSTR)hMem;
}

return( (HANDLE)p );
}


Kernel32.dll source was compiled with the ommiting FramePoint checkbox enabled on the VisualStudio compiler, this explains the mess inside.
Title: Re: HTML to RTF
Post by: guga on July 07, 2013, 04:57:41 PM
Finally got it working as expected.

The problem was at IsFormatCorrect function. When it was being used, there was a overloading of global memory usage causing the converter to not convert completely the file. I simply removed this function and will build later a new routine to use it, but it seems that each function to be used for the converter must be uninitialized (at least some of them) ?

Anyway...here is the preliminary tests of the alpha version of the app. Now that it is working i can start building the proper converter dll and apis for us to use on any projects we want.

Note: Rebuilding the kernel32 global functions did not succeeded as expected, probably because to the internal pointers and heap allocations of those functions...But....some of the global functions i made can be used, but as far i saw not in sequence. I removed them from my project anyway, since now it is starting to work as expected.

Btw..the name of the file "finalmente2b.exe" is only a joke which means "finally" in portuguese (It was what i said when this worked)  :greensml:

The next versions will name it accordingly :bgrin:

And..no...it cannot export in html, etc, yet...The exported files will be always in rtf format no matter the extension you name it. (This is another stage)....it was hard enough make this thing import anyway...export is another story ;)
Title: Re: HTML to RTF
Post by: jj2007 on July 07, 2013, 08:42:08 PM
Quote from: guga on July 07, 2013, 04:57:41 PM
The problem was at IsFormatCorrect function.

Yes, I had noticed that, too. And in fact, you don't need it because ForeignToRtf32 reports errors anyway.
Title: Re: HTML to RTF
Post by: guga on July 07, 2013, 10:23:51 PM
HI JJ

QuoteForeignToRtf32 reports errors anyway

Not always. I have some html files that simply crashes when passing to ForeignToRtf32. Some crashes when the html contains at 1st the string "<xml", because the converter is limited and cannot parse correctly the full file. When it finds this kind of error it simply keeps looping inside it´s own dll untill the crash happens.

Also....it is better to never use registerapp, since it completely ruins the registry. I had a lot of trouble trying to identify the error after the registry was ruined by  this function. I´ll take a look inside this function to see how it alters the registry in order to fix the internal errors.

The file i upload now is able to check the converters for import and export, choose automatically for the last version of them (when you have different versions of the same converter, of course) ,  check if the the converter is  registered (and therefore can be used - specially the new ones that does a registry check internally), and finally can convert html to rtf, doc to rtf, xls to rtf, lotus to rtf, docm/docx to rtf, mcw to rtf, wps/wpt to rtf, wpd to rtf,ans to rtf, outlook scheduler to rtf, doc (word2x untill officeXp (that ins installed here) for windows and Macintosh to RTF.

Also, the app identify the vulnerable converters that are not registered, such as:
    write32.wpc - vulnerable
    mswrd632.wpc - vulnerable
    works432.cnv - vulnerable

I was thinking in enabling a routine to warn the user if he wants to register those kind of files,but after reading M$ security updates and some forums, i choose not to enable them. Better would be write later a converter for wri files.

The next versions i´ll clean up the code, create a function to export the proper config files (to avoid scanning the registry every time the app is loaded.
Title: Re: HTML to RTF
Post by: TouEnMasm on July 08, 2013, 04:09:56 PM

The IsFormatCorrect function return correct values.See my source code who use it.
To use it,filters the return values as i have posted in my upper post.
The unknown errors are not interpreted as errors,they can be only various messages given by the dll.
Title: Re: HTML to RTF
Post by: guga on July 08, 2013, 06:31:02 PM
Hi Yves....i know, but it is crashing here, due to the overloading of the globallalloc function.

Some of these functions may be unitialized to clear the allocated memory in order to not break internally. It seems to be the case of IsFormatCorrect. Since i already used globalalloc heavily, it broke inside. The documentation says we must unitiliaze some functions. The problem is only figure it out which ones and how to make them work properly for all converters without breaking.

I did the same as you using IsFormatCorrect and the app simply showed the error. I tried many different variatonsfor the function....I used my own global alloc routines to better points internally what was happenning. The problem was that, before the IsFormatCorrect was used, the app was making heavy usage of globalalloc/globalloc/globalfree functions. This is why the doc says that some functions maybe unitilialized.

Now that it is working, it is better to figure it out exactly where/which functions needs better attention. I´m finishing the routine to create a config file, and will restore the usage of IsFormatCorrect checkings.


Proc IsFormatCorrect:
    Arguments @szAppName
    Local @hFileName, @hDest
    Uses ecx, ebx, edx

    xor eax eax
    On D$CConverter.m_hLibCnv = 0, ExitP
    On D$CConverter.m_IsFormatCorrect = 0, ExitP

    ;call StrCpyEx D@szAppName, StringCheckBuff, Size_Of_String
    ;call 'user32.CharToOemA' StringCheckBuff, StringCheckBuff
    call StringtoHGlobal D@szAppName | mov D@hFileName eax

    ;mov D@hDest 0
    ;lea eax D@hDest
    ;call 'RosMem.VMemAlloc' eax, 256

    call 'kernel32.GlobalAlloc' &GHND, 4096 | mov D@hDest eax
    ;call 'kernel32.GlobalAlloc'2 &GHND, 1024 | mov D@hDest eax
    ;call 'kernel32.GlobalLock' eax
    ;call 'kernel32.GlobalHandle' eax
    ;call GlobalHandle eax

    ;call 'kernel32.GlobalAlloc'2 &GHND, 1024 | mov D@hDest eax
    call D$CConverter.m_IsFormatCorrect D@hFileName, eax

    mov ebx eax
    call 'kernel32.GlobalFree' D@hFileName
    call 'kernel32.GlobalFree' D@hDest
    ;call 'kernel32.GlobalFree' D@hDest
    ;call 'kernel32.GlobalFree' D@hFileName
    ;call 'RosMem.VMemFree' D@hDest
    ;call 'RosMem.VMemFree' D@hFileName
    mov eax ebx

EndP