News:

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

Main Menu

HTML to RTF

Started by guga, June 08, 2013, 01:56:26 PM

Previous topic - Next topic

guga

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
Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com

Antariy

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).

jj2007

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:

TouEnMasm

#78
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.

Fa is a musical note to play with CL

MichaelW

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



Well Microsoft, here's another nice mess you've gotten us into.

TWell

#80
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;
}

TouEnMasm

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

Fa is a musical note to play with CL

TouEnMasm

#82
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




Fa is a musical note to play with CL

TouEnMasm

#83
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

Fa is a musical note to play with CL

guga

Very good work guys.

I´m giving a test on the routines to see if i can make it work properly.
Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com

guga

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 ?
Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com

guga

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.
Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com

TouEnMasm


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.
Fa is a musical note to play with CL

TouEnMasm

Fa is a musical note to play with CL

jj2007

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.