The MASM Forum

General => The Campus => Topic started by: Fumio on September 17, 2013, 02:58:20 PM

Title: Iczelion tutorial 35 Highlighting
Post by: Fumio on September 17, 2013, 02:58:20 PM
I had worked through this tut some time ago on my old XP machine and all was well. Now on Vista I cannot get the "NewRicheditProc" to work at all. The problem has to be related to the subclassing procedure but I need assistance finding the problem. The error I get is "Access volation when writing to 129990"
Fumio
Title: Re: Iczelion tutorial 35 Highlighting
Post by: MichaelW on September 17, 2013, 03:39:57 PM
AFAICT the tutorial targets Rich Edit versions 2.0 or 3.0, and judging from  this (http://blogs.msdn.com/b/murrays/archive/2006/10/14/richedit-versions.aspx), Vista does not, or at least did not, include these versions.
Title: Re: Iczelion tutorial 35 Highlighting
Post by: jj2007 on September 17, 2013, 05:28:32 PM
Quote from: MichaelW on September 17, 2013, 03:39:57 PM
AFAICT the tutorial targets Rich Edit versions 2.0 or 3.0, and judging from  this (http://blogs.msdn.com/b/murrays/archive/2006/10/14/richedit-versions.aspx), Vista does not, or at least did not, include these versions.

Win7-32 includes
C:\Windows\System32\riched20.dll (20.11.2010)
C:\Program Files\Common Files\Microsoft Shared\OFFICE11 (17.5.2011)
C:\Program Files\Common Files\microsoft shared\OFFICE12\RICHED20.DLL (27.7.2011)
C:\Program Files\Common Files\Microsoft Shared\OFFICE14\RICHED20.DLL (28.12.2010)

For reading RTF files into the control, the Office11 version is about 20% faster than the other versions.

Note that EM_STREAMOUT is broken, at least in some versions (http://msdn.microsoft.com/en-us/library/bb787873%28VS.85%29.aspx#related_topics). Use EM_GETTEXTEX instead.
Title: Re: Iczelion tutorial 35 Highlighting
Post by: hutch-- on September 17, 2013, 08:09:06 PM
I have been writing richedit based editors for years and I have found that riched 2-3 works on everything from Win2000 to Win7 64 bit but note that I only process text, not RTF.
Title: Re: Iczelion tutorial 35 Highlighting
Post by: Fumio on September 18, 2013, 02:24:55 AM
Thanks to those who commented on my question. Still looking at the problem and found a makefile for the version that works and it has a cmd to expand the stack:
NAME=IczEdit
$(NAME).exe: $(NAME).obj $(NAME).res
        Link /STACK:2000000,2000000 /SUBSYSTEM:WINDOWS /LIBPATH:c:\masm32\lib $(NAME).obj $(NAME).res
$(NAME).res:$(NAME).rc
   rc $(NAME).rc
$(NAME).obj: $(NAME).asm
        ml /c /coff /Cp $(NAME).asm
And looking at the working exe vs the nonworking exe I see that there is a difference in the main thread stack size with working version being 78000 H bytes larger.
I also note that my non working program fails on an attempt to write to 00129990 which is outside the stack area.
Is there a cmd I can use in RadAsm that will expand the stack?
I have tried ".STACK 2000000; which compiles but still crashes with same error and stack is no bigger.
Title: Re: Iczelion tutorial 35 Highlighting
Post by: dedndave on September 18, 2013, 02:57:58 AM
nice find   :t
Title: Re: Iczelion tutorial 35 Highlighting
Post by: jj2007 on September 18, 2013, 03:17:52 AM
Just checked RichMasm, and it has standard stack size 100000h/1000h
So I wonder what exactly makes your app crash - it seems not to be the RichEd control.
Title: Re: Iczelion tutorial 35 Highlighting
Post by: Fumio on September 18, 2013, 04:45:41 AM
Hello dedndave and jj2007: The richedit control itself functions nicely, its only the subclassing of the control that is at issue.
The call in wndproc to invoke SetWindowLong,hwndRichEdit,GWL_WNDPROC, addr NewRichEditProc
      mov OldWndProc,eax
And the call within the newWndproc: invoke CallWindowProc,OldWndProc,hWnd,uMsg,wParam,lParam
to return control to the original WndProc seem to be causing the trouble.
Fumio
Title: Re: Iczelion tutorial 35 Highlighting
Post by: dedndave on September 18, 2013, 08:17:13 AM
i got it to work ok
i made a "MakeIt.bat" file to build it...
\masm32\bin\rc /v IczEdit.rc
if exist rsrc.res del rsrc.res
if exist IczEdit.res ren IczEdit.res rsrc.res
if exist rsrc.obj del rsrc.obj
\masm32\bin\cvtres /machine:ix86 rsrc.res
if exist rsrc.res del rsrc.res

if exist IczEdit.obj del IczEdit.obj
\masm32\bin\ml /c /coff IczEdit.asm

\masm32\bin\Link /STACK:2000000,2000000 /SUBSYSTEM:WINDOWS /OPT:NOREF IczEdit.obj rsrc.obj

if exist rsrc.obj del rsrc.obj
if exist IczEdit.obj del IczEdit.obj


it seems to be sublcassing the control just fine
the one problem i did see was....
.elseif uMsg==WM_CLOSE
invoke SetWindowLong,hWnd,GWL_WNDPROC,OldWndProc
.else
invoke CallWindowProc,OldWndProc,hWnd,uMsg,wParam,lParam
ret
.endif
NewRichEditProc endp

WM_CLOSE is received - it "un-subclasses" itself - then it goes out to lala land - lol
no RET or anything
probably ok to return 0 and RET, but i did it this way.....
.elseif uMsg==WM_CLOSE
invoke SetWindowLong,hWnd,GWL_WNDPROC,OldWndProc
invoke CallWindowProc,OldWndProc,hWnd,uMsg,wParam,lParam
ret
.else
invoke CallWindowProc,OldWndProc,hWnd,uMsg,wParam,lParam
ret
.endif
NewRichEditProc endp


as far as i know, that method of sub-classing works fine under vista
so - i think it's something else (in the WM_PAINT code)
Title: Re: Iczelion tutorial 35 Highlighting
Post by: jj2007 on September 18, 2013, 11:55:31 AM
My RichEd subclass is 500+ lines, and it works just fine with standard stack...
Your problem is where it writes "outside the stack area" at 12990h. That sounds really odd ::)

P.S.: In general, invoke SetWindowLong,hWnd,GWL_WNDPROC,OldWndProc is not necessary, the OS can handle that.
Title: Re: Iczelion tutorial 35 Highlighting
Post by: Fumio on September 18, 2013, 02:14:58 PM
Hello dedndave: I duplicated your process using the bat file and it works absolutely fine on my vista machine. I had been trying to build the tut35 exe via Radasm 2 and 3 neither worked. It seems as if that "/STACK:2000000,2000000 " option is the stickler. I tried several formats to implement that via the project options in Radasm but was unsuccessful. If you have any tips on how that could be done I sure would like to know. However it's good to know that Vista is not the problem. Thanks for the .bat
Hello jj2007: Yes it is odd the problem show up in the ShowWindow api. I have traced into it and still haven't found exactly where the problem occurs, but it is in the latter section of that routine and even if I find exactly where, I don't know if I would have the expertise to understand what is going wrong. As I mentioned before I compared the starting stack sizes and the exe that works has a much bigger stack than the one that doesn't.
I am able to work with the tut now so that is my main concern but I would like to find out how to make it work via Radasm. Again, I believe it has something to do with the
/STACK:2000000,2000000 option used in the bat file and original make file.
Thanks for your interest and help
Fumio
Title: Re: Iczelion tutorial 35 Highlighting
Post by: Fumio on September 18, 2013, 03:30:42 PM
Succeeded in increasing stack size but still crashes at with multiple .. 9990 :eusa_boohoo:

Fumio
Title: Re: Iczelion tutorial 35 Highlighting
Post by: dedndave on September 18, 2013, 05:37:13 PM
you can modify the EXE header after it has been linked by using editbin.exe
editbin /STACK:2000000,2000000 IczEdit.exe

other than that, i am not familiar enough with RadAsm to help, there   :P
Title: Re: Iczelion tutorial 35 Highlighting
Post by: Fumio on September 18, 2013, 10:44:17 PM
Here is the project file I have been using via Radasm 2.2.1.5 The files are exactly the same as the files used to make a working exe built via a bat file. Note that the asm, rc etc are unchanged versions of Iczelion's Tutorial 35, I have not intentionally changed any of the code.
Fumio
Title: Re: Iczelion tutorial 35 Highlighting
Post by: Fumio on September 18, 2013, 10:53:10 PM
Hi dedndave: I finally was able to increase stack size by using the link option /STACK: [number] I increased it to the exact size that existed in the working tut35.exe . I attached a pic of Project options tab in  Radasm.

Fumio
Title: Re: Iczelion tutorial 35 Highlighting
Post by: qWord on September 18, 2013, 11:12:55 PM
There is a missing RET in NewRichEditProc. You should also add a stack probe to that callback, because of the large buffer (more than 2 pages). Also, the USES directive for ESI, EDI and EBX would make the code more clear.

EDIT: BufferSize @ NewRichEditProc is filled with the buffer address!
Title: Re: Iczelion tutorial 35 Highlighting
Post by: jj2007 on September 19, 2013, 02:33:14 AM
Still crashing. There are also three pushads but four popads in that proc, but that's not the cause (there's a break in one of the branches).

This helps:
ScanMore:
                repne scasb
                ; je NextSkip
                jmp NoMoreHit

... but that's not a solution, of course. The crash happens after the rep scasb. Check the ecx value in particular.
Title: Re: Iczelion tutorial 35 Highlighting
Post by: Fumio on September 19, 2013, 05:32:13 AM
Hello jj2007: Here is another clue. As noted, dedndave's bat file allows the exe to compile and work fine; however, if the /STACK:2000000,2000000 is removed from the link options in the bat file the program builds and crashes. I have not been able to build in Radasm with the /STACK:2000000,2000000  option but only with the
option /STACK:2000000, although the number must be in its hex form I believe the problem is not in the code but in the linker
Fumio
Title: Re: Iczelion tutorial 35 Highlighting
Post by: Fumio on September 19, 2013, 06:11:50 AM
Hello: Remembered the Radasm foible of using a | in place of a comma to use option /STACK:2000000, 2000000. the program still crashes, but it is definitely doing something different. The window displays with green gibberish in top left corner and two alerts that the program has stopped working appear.
Title: Re: Iczelion tutorial 35 Highlighting
Post by: jj2007 on September 19, 2013, 08:36:39 AM
The stack error is only a symptom of a deeper problem.
ca. line 900:
      pop edi
      .while sdword ptr esi>0  ; esi can be negative

ca. line 932:
      ; invoke RtlZeroMemory,pString,ecx  ; pString is a bad pointer
Title: Re: Iczelion tutorial 35 Highlighting
Post by: Fumio on September 19, 2013, 02:56:07 PM
And the Thick Plottens: Attached is a working tut35 created in Radasm 2.2.1.5.  I hope I have attached all pertinent files in the two zip files. one shows the project options where the STACK option was added. It is late for me and I will experiment a bit more tomorrow. Absolutely nothing to do with the code itself; But two things I changed: first used the original Resource.h file and second, rather ten cut and paste Iczelion's code into Radasm I copied and then renamed the files and voila it worked. Note that I did not build a debug version of the working exe but the release. What ever the problem is I don't believe it can be the code but must have something to do with the cut and paste procedure in Radasm and the /STACK:2000000,2000000 option.
regards Fumio
Title: Re: Iczelion tutorial 35 Highlighting
Post by: jj2007 on September 19, 2013, 04:40:52 PM
Congrats, it seems to work, so you are lucky :P

Just for the record:
- While esi>0 is wrong. Depending on what kind of garbage you find on the stack, esi can assume negative values, and you enter into an almost endless loop (I've seen it crash).
- as qWord suggested, stack probing would be a nice idea. This is sufficient to solve your inexistent "not enough stack problem":
   LOCAL pt:POINT
   and dword ptr [esp+6*1024], 0
   and dword ptr [esp+2*1024], 0
   .if uMsg==WM_PAINT
- only two of the files are "pertinent" aka needed, *.asm and *.rc, all the rest serves only to please the IDE.
- there is still a missing ret in the WM_CLOSE handler, and the only reason why it doesn't crash is that this branch is never used.


Quote from: qWord on September 18, 2013, 11:12:55 PMthe USES directive for ESI, EDI and EBX would make the code more clear.

Good idea in principle but won't work with the big buffer because uses implies
add esp, -2850h
push ebp
... and bang!
Title: Re: Iczelion tutorial 35 Highlighting
Post by: Fumio on September 20, 2013, 01:07:58 AM
jj2007, dedndave, qword, and others, thank you for your interest and help concerning this issue. I will have another look at the two different .exe and if I find anything new I will let you know. I plan to imlement the stack probe and either remove the unused close branch or alter it as previously described.
Thanks again
Fumio
Title: Re: Iczelion tutorial 35 Highlighting
Post by: Antariy on September 20, 2013, 02:21:57 AM
The difference is:

      ;===================================================================
      ; Get the visible text into buffer
      ;===================================================================
      lea eax,buffer
      mov txtrange.lpstrText,eax
      invoke SendMessage,hWnd,EM_GETTEXTRANGE,0,addr txtrange
      mov esi,eax      ; esi == size of the text   
      .if esi>0
         mov BufferSize,eax
Title: Re: Iczelion tutorial 35 Highlighting
Post by: dedndave on September 20, 2013, 02:25:47 AM
Jochen is right - the WM_CLOSE message is only sent to the main window
child windows get WM_DESTROY, but not WM_CLOSE
i guess the proper place to un-subclass would be in the main window WndProc, WM_DESTROY
Title: Re: Iczelion tutorial 35 Highlighting
Post by: Antariy on September 20, 2013, 02:37:36 AM
Unsubclassing itself is buggy:

invoke SetWindowLong,hWnd,GWL_WNDPROC,addr OldWndProc   


But the main difference is still in this http://masm32.com/board/index.php?topic=2379.msg24746#msg24746 post.
Title: Re: Iczelion tutorial 35 Highlighting
Post by: Antariy on September 20, 2013, 02:51:34 AM
Add this http://masm32.com/board/index.php?topic=2379.msg24746#msg24746
and this:

mov [esp+8*1024],eax
mov [esp+4*1024],eax

after
   LOCAL pt:POINT


and delete bold from message above, so the prog posted in previous page will work :t
Title: Re: Iczelion tutorial 35 Highlighting
Post by: jj2007 on September 20, 2013, 02:55:25 AM
Quote from: Antariy on September 20, 2013, 02:21:57 AM
      invoke SendMessage,hWnd,EM_GETTEXTRANGE,0,addr txtrange

Looks extremely useful indeed :bgrin:
Title: Re: Iczelion tutorial 35 Highlighting
Post by: Antariy on September 20, 2013, 12:29:09 PM
Quote from: jj2007 on September 20, 2013, 02:55:25 AM
Quote from: Antariy on September 20, 2013, 02:21:57 AM
      invoke SendMessage,hWnd,EM_GETTEXTRANGE,0,addr txtrange

Looks extremely useful indeed :bgrin:

Jochen, I don't quite understand what you mean with this message, I did not really follow this "guess a bug" thread. But you may implement the changes mentioned and see that they fix the program.
Title: Re: Iczelion tutorial 35 Highlighting
Post by: jj2007 on September 20, 2013, 03:21:22 PM
Sorry, Alex, I forgot the "no irony" tag. That SendMessage is indeed missing, you are perfectly right :t
Title: Re: Iczelion tutorial 35 Highlighting
Post by: Antariy on September 20, 2013, 03:40:40 PM
Don't worry about that, Jochen :t

I see that you have found the need in probing, too, also the wrong ESI counter - what is close to the missed SendMessage call. The source from the previous page was changed from its original state.

Probably this is the place where those prologue and epilogue macroses may be used just nicely :biggrin:
Title: Re: Iczelion tutorial 35 Highlighting
Post by: Fumio on September 24, 2013, 10:17:22 AM
Hello: I'd like to add my thanks to Antariy for his interest in my issue. I implemented his suggestion of a stack probe but the program still crashes. On my vista machine using the original code from Izcelion Tutorial #35 the app will build and crash while using Radasm. If I add the following option to the link line in project options exactly as it is here /STACK:2000000|2000000 everything works fine.
So My Question would be does any one know how you determine before the crash that you would need to expand the stack?

Regards Fumio
Title: Re: Iczelion tutorial 35 Highlighting
Post by: dedndave on September 24, 2013, 10:28:11 AM
the first number is the stack "reserve" - there is no way to increase it dynamically
the second one is the "commit" - probing the stack can take care of this one

what i would do is try to re-design the program so that the limit is known and not exceeded
rather than using an increased stack size, use "normal" dynamic allocation, such as HeapAlloc or VirtualAlloc
that way, the stack limitation is not an issue

the heap is managed by the operating system
and - memory that isn't reserved for stack space is available for other types of allocation
the OS balances stack requirement with other memory requirements

you should be able to calculate the requirement before reading the data into memory
Title: Re: Iczelion tutorial 35 Highlighting
Post by: jj2007 on September 24, 2013, 03:29:19 PM
Quote from: Fumio on September 24, 2013, 10:17:22 AM
Hello: I'd like to add my thanks to Antariy for his interest in my issue. I implemented his suggestion of a stack probe but the program still crashes.

Hi Fumio,
You seem to be the only one in this thread whose version is still crashing, all others work. Can you post the crashing source?
Title: Re: Iczelion tutorial 35 Highlighting
Post by: dedndave on September 24, 2013, 07:10:27 PM
maybe a good design would implement file-mapping
but - it's better left to the guys that are familiar with rich text operations
Title: Re: Iczelion tutorial 35 Highlighting
Post by: Fumio on September 26, 2013, 02:48:43 AM
Hello jj2007: Unfortunately I had deleted the crashing project. Clearly I must have done something to the code as it would not run without crashing when implementing the stack Probe. Now I have just added the probe code to a new tut 35 project and yes it does work as it should.
Again thanks to all who participated in this thread. It has been informative.
Regards Fumio :icon_cool:
Title: Re: Iczelion tutorial 35 Highlighting
Post by: HSE on May 30, 2021, 05:02:51 AM
Hi All!!

I found a mistake, only you can see clearly the effect with files bigger than 64 kb (I think).

Say:
Code (NewRichEditProc proc) Select
;===================================================================
; Do syntax hiliting here!
;===================================================================
invoke SendMessage,hWnd,EM_GETRECT,0,addr rect
invoke SendMessage,hWnd,EM_CHARFROMPOS,0,addr rect
;========================================================
; obtain the line number
;========================================================
invoke SendMessage,hWnd,EM_LINEFROMCHAR,eax,0
invoke SendMessage,hWnd,EM_LINEINDEX,eax,0
mov txtrange.chrg.cpMin,eax
mov FirstChar,eax
invoke SendMessage,hWnd,EM_CHARFROMPOS,0,addr rect.right
mov txtrange.chrg.cpMax,eax


But must say:
Code (NewRichEditProc proc) Select
;===================================================================
; Do syntax hiliting here!
;===================================================================
invoke SendMessage,hWnd,EM_GETRECT,0,addr rect
invoke SendMessage,hWnd,EM_CHARFROMPOS,0,addr rect
mov txtrange.chrg.cpMin,eax
mov FirstChar,eax
invoke SendMessage,hWnd,EM_CHARFROMPOS,0,addr rect.right
mov txtrange.chrg.cpMax,eax

Line number is never used anyway :biggrin: Perhaps Iczelion try to erase those lines and accidentally pasted here.

With this modification now work well a 1.5 mb file.

Regards, HSE.
Title: Re: Iczelion tutorial 35 Highlighting
Post by: Mikl__ on May 31, 2021, 07:55:46 AM
Hi, HSE!
Win x64 Tutorial #35: IczEdit version 3.0 (http://masm32.com/board/index.php?topic=4190.msg47502#msg47502)
Title: Re: Iczelion tutorial 35 Highlighting
Post by: HSE on May 31, 2021, 07:59:37 AM
Hi Mikl__!

Quote from: Mikl__ on May 31, 2021, 07:55:46 AM
Win x64 Tutorial #35: IczEdit version 3.0 (http://masm32.com/board/index.php?topic=4190.msg47502#msg47502)

Yes, you have translated correctly... the error  :biggrin: :biggrin: :biggrin:
Title: Re: Iczelion tutorial 35 Highlighting
Post by: Mikl__ on May 31, 2021, 08:35:18 AM
HSE
Thanks for the bug you found. Perhaps did Iczelion inserted this error for educational purposes? (https://wasm.in/styles/smiles_s/mosking.gif)
Title: Re: Iczelion tutorial 35 Highlighting
Post by: HSE on May 31, 2021, 08:53:02 AM
Quote from: Mikl__ on May 31, 2021, 08:35:18 AMPerhaps did Iczelion inserted this error for educational purposes? (https://wasm.in/styles/smiles_s/mosking.gif)
Yes. He was learning (https://wasm.in/styles/smiles_s/mosking.gif)

Look like he tried something with line numbers that never was.