News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

New function WriteToMemHeap

Started by ToutEnMasm, July 14, 2005, 02:10:59 PM

Previous topic - Next topic

ToutEnMasm

Hello,
It's a new function to make the heap easier to use,
What it do

   initiate and uninitiate the memory heap . Work like a disk buffer.
   Add dynamically strings or binarys to the heap,one by one
   
   Starting ---> The MEMHEAP structure can be Null or not.
       just add data to initiate
   Adding a string:
      the size of the string is optionnal,can be NULL if zero terminated
      Global size of the buffer (Theap) = size of string1 + size string2 + BYTE 0
      sample:invoke WriteToMemHeap,addr Blocheap,addr string1,NULL
         Theap is modified by adding a string
         Pheap is modified if necessary
   unititiate (free heap) ex:invoke WriteToMemHeap,addr Blocheap,NULL,NULL
      Pheap = 0 and Theap = 0
      Hheap don't change
   return eax == 1 success,0 failed
The heap bloc is zero terminated

What's can be made
A few work can be made for changing a string in the buffer,modify or delete.

                                                       ToutEnMasm

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

      .386                      ; force 32 bit code
      .model flat, stdcall      ; memory model & calling convention
      option casemap :none      ; case sensitive

MEMHEAP STRUCT
Hheap dd ? ;Handle heap,GetProcessHeap
Pheap dd ? ;Pointeur heap,HeapAlloc
Theap dd ? ;taille du bloc Heap
MEMHEAP ENDS
      PuPo MACRO M1, M2
        push M2
        pop  M1
      ENDM
; WriteToMemHeap PROTO  :DWORD,  :DWORD,  :DWORD
comment µ
initiate and uninitiate the memory heap . Work like a disk buffer.
Add dynamically strings or binarys to the heap
que l'on veut,on ne peut pas en retirer.
Starting ---> The MEMHEAP structure can be Null or not.
just add data to initiate
Adding a string:
the size of the string is optionnal,can be NULL if zero terminated
Global size of the buffer (Theap) = size of string1 + size string2 + BYTE 0
sample:invoke WriteToMemHeap,addr Blocheap,addr string1,NULL
Theap is modified by adding a string
Pheap is modified if necessary
unititiate (free heap) ex:invoke WriteToMemHeap,addr Blocheap,NULL,NULL
Pheap = 0 and Theap = 0
Hheap don't change
return eax == 1 success,0 failed

µ

       include \masm32\include\windows.inc
       include \masm32\include\kernel32.inc


      ;
      ;samples of externs definitions
      ; EXTERNDEF Copier :PROTO  :DWORD,:DWORD
      ; EXTERNDEF EtatMemoirePile :MEMORY_BASIC_INFORMATION
      ; EXTERNDEF PoriginePile:DWORD
EXTERNDEF RetrouveMessageErreur : PROTO  :DWORD

   .data
erreurhandleheap db "WriteToMemHeap GetProcessHeap",0
erreurPointeheap db "WriteToMemHeap HeapAlloc",0
erreurHeapReAlloc db "WriteToMemHeap HeapReAlloc",0
erreurHeapFree db "WriteToMemHeap HeapFree",0
    .code
;################################################################
WriteToMemHeap PROC  AdrStruct:DWORD,  adrChaine:DWORD,  Taille:DWORD
Local   longueur:DWORD
LOCAL   PointeurEcriture:DWORD
Local  retour:DWORD
Pushad
mov esi,AdrStruct
;------------ vérifier la validité des arguments ---------------
;-----adrChaine NULL , libérer le tampon
.if adrChaine == 0 && Taille == 0
.if dword ptr [esi][MEMHEAP.Pheap] != 0
invoke HeapFree,dword ptr [esi][MEMHEAP.Hheap],NULL,dword ptr [esi][MEMHEAP.Pheap]
.if eax == NULL
invoke RetrouveMessageErreur,addr erreurHeapFree
mov retour,0
jmp FindeWriteToMemHeap
.endif
xor eax,eax
mov dword ptr [esi][MEMHEAP.Pheap],eax
mov dword ptr [esi][MEMHEAP.Theap],eax
mov retour,1
.else
mov retour,0
.endif
jmp FindeWriteToMemHeap
.endif
;---- taille de la chaine a écrire,si NULL ,rechercher sa longueur
.if Taille == 0
invoke lstrlen,adrChaine
mov longueur,eax
.if eax == 0
mov retour,0
jmp FindeWriteToMemHeap ;rien à écrire
.endif
.else
PuPo longueur,Taille
.endif
;---- handle heap
.if dword ptr [esi][MEMHEAP.Hheap] == 0 ;pas de handle,le créer
invoke GetProcessHeap
mov   dword ptr [esi][MEMHEAP.Hheap],eax
.if eax == NULL
invoke RetrouveMessageErreur,addr erreurhandleheap
mov retour,0
jmp FindeWriteToMemHeap
.endif
.endif
;---- pointeur heap
.if dword ptr [esi][MEMHEAP.Pheap] == 0
mov edx,longueur
inc edx ;pour le zero
invoke HeapAlloc,dword ptr [esi][MEMHEAP.Hheap],HEAP_ZERO_MEMORY,edx
.if eax == 0
invoke RetrouveMessageErreur,addr erreurPointeheap
mov retour,0
jmp FindeWriteToMemHeap
.endif
mov dword ptr [esi][MEMHEAP.Pheap],eax
mov eax,longueur
mov dword ptr [esi][MEMHEAP.Theap],eax
;---- écrire la première donnée pour éviter de rajouter de la mémoire inutile
mov ecx,longueur
mov edi,dword ptr [esi][MEMHEAP.Pheap]
mov esi,adrChaine
cld
rep movsb
mov retour,1
jmp FindeWriteToMemHeap

.endif
;tout est valide et une premiere opération d'écriture à déja été faite
mov edx,dword ptr [esi][MEMHEAP.Theap]
mov eax,longueur
add edx,eax
inc edx ;totale des données + le zero
invoke HeapReAlloc,dword ptr [esi][MEMHEAP.Hheap],HEAP_ZERO_MEMORY,\
dword ptr [esi][MEMHEAP.Pheap],edx
.if eax == 0
invoke RetrouveMessageErreur,addr erreurHeapReAlloc
mov retour,0
jmp FindeWriteToMemHeap
.endif
;l'éventuel nouveau pointeur
mov dword ptr [esi][MEMHEAP.Pheap],eax
;la nouvelle taille
mov edx,dword ptr [esi][MEMHEAP.Theap]
mov PointeurEcriture,edx ;le décalage à l'écriture
mov eax,longueur
add edx,eax
;inc edx ;totale des données sans le zero
mov dword ptr [esi][MEMHEAP.Theap],edx
;recopier les données
mov edi,dword ptr [esi][MEMHEAP.Pheap]
add edi,PointeurEcriture
mov ecx,longueur
mov esi,adrChaine
cld
rep movsb
       mov retour,1
FindeWriteToMemHeap:
popad
       mov eax,retour
         ret
WriteToMemHeap endp

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



find the error message (windows message)



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

    .386
    .model flat, stdcall  ; 32 bit memory model
    option casemap :none  ; case sensitive

include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc

    .code



; ########################################################################
;
; written by Dracon (andreas.theDragon@gmx.net)
;
; Most windows functions set in case of failure a global error ID. You
; can obtain this value by calling "GetLastError()". This number alone
; is of course not very usefull, but you can translate it into a
; readable message with "FormatMessage()".
;
; RetrouveMessageErrreur will exactly do this. The only parameter is the title of
; the messagebox which should be used (e.g. the name of the function).
; You will get a nice messagebox telling you what went wrong.
;
; Be aware: some messages are very strange. Unfortunately, I only know
; the german text and have translated them roughly, maybe someone can
; adjust them.
;
; Strange messages:
; * "This is only possible in Win32-mode."
; In most cases this means that you have provided an invalid windows-handle.
;
; * "The process was executed." (Der Vorgang wurde ausgeführt)
;   No error has occured.
;
; Okay, have fun and use it!
;
; ########################################################################


.code

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

RetrouveMessageErreur proc lpTitle:DWORD

LOCAL lpMsgBuffer : LPVOID

; calculate language ID, asm version of MAKELANGID
mov cx, SUBLANG_DEFAULT
shl ecx, 10
;or  cx, LANG_NEUTRAL ; LANG_NEUTRAL = 0, nothing necessary

; Setup parameters for FormatMessage, normal pushing to use some
; params directly (e.g. GetLastError returns the ID in eax, but I
; can't use this register in "invoke")

push NULL ; we don't need this
push 0 ; min. size of output buffer if we use
; FORMAT_MESSAGE_ALLOCATE_BUFFER
lea  eax, lpMsgBuffer ; get address of our buffer
push eax ; address of buffer
push ecx ; our language ID, calculated above
invoke GetLastError ; get error number
push eax ; push return value = error ID
push NULL ; can be used to format a string, we don't need it
mov edx, FORMAT_MESSAGE_ALLOCATE_BUFFER or FORMAT_MESSAGE_FROM_SYSTEM
push edx ; some flags, check your doc for more
call FormatMessage ; here we go

; Display error-message
invoke MessageBox, NULL, lpMsgBuffer, lpTitle, MB_OK or MB_ICONSTOP

; free memory
invoke LocalFree, lpMsgBuffer

ret

RetrouveMessageErreur endp

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


end


Mark Jones

Hi ToutEnMasm, could you give an example of how to use WriteToMemHeap? Merci beaucoup. :wink
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08

ToutEnMasm

Ok

This sample create a buffer where he put zero terminated string.For each string he add a end of line.
When all the strings are written in text format,a messagebox show the result.

When it is made ,the heap memory is freed.

                                               ToutEnMasm

Quote
comment µ
   MEMHEAP STRUCT
                Hheap dd ?      ;Handle heap,GetProcessHeap
                Pheap dd ?      ;Pointeur heap,HeapAlloc
                Theap dd ?      ;taille du bloc Heap
        MEMHEAP ENDS

µ

;################################################################
Testmem PROC
         Local  retour:DWORD
         LOCAL  Sample:MEMHEAP         
   
   INVOKE  RtlZeroMemory, addr Sample, sizeof Sample

   jmp overtext
   EndLine db 13,10,0
   FirsrtPhrase    db "With WriteToMemHeap you have nothing to initialise",0
   deux          db "Just create a MEMHEAP structure",0
   trois       db "Call the function ,passing it the adresse of MEMHEAP",0
   quatre      db "The adresse of the data,the lenght of the data",0
   cinq         db "If the data are zero terminated, you can pass NULL as lenght",0
   six         db "You can create further structures MEMHEAP,if you want",0
   Titre         db "Example WriteToMemHeap",0   
   overtext:
   
            
   invoke       WriteToMemHeap,addr Sample,addr FirsrtPhrase,NULL
   invoke       WriteToMemHeap,addr Sample,addr EndLine,2
   invoke       WriteToMemHeap,addr Sample,addr deux,NULL
   invoke       WriteToMemHeap,addr Sample,addr EndLine,NULL
   invoke       WriteToMemHeap,addr Sample,addr trois,NULL
   invoke       WriteToMemHeap,addr Sample,addr EndLine,NULL   
   invoke       WriteToMemHeap,addr Sample,addr quatre,NULL
   invoke       WriteToMemHeap,addr Sample,addr EndLine,NULL
   invoke       WriteToMemHeap,addr Sample,addr cinq,NULL
   invoke       WriteToMemHeap,addr Sample,addr EndLine,NULL   
   invoke       WriteToMemHeap,addr Sample,addr six,NULL
   invoke       WriteToMemHeap,addr Sample,addr EndLine,NULL   
   
   ;the buffer at adress Sample.Pheap is zero terminated (zero not added to the size)   
   invoke MessageBox,NULL,Sample.Pheap,addr Titre,MB_OK
   ;free the memory
   invoke WriteToMemHeap,addr Sample,NULL,NULL
      
         mov retour,1

FindeTestmem:
         mov eax,retour
         ret
Testmem endp