Utilizing memory is a sticky issue and as you can see by my subject line I am a little confused. MS says to drop GlobalAlloc in favor of HeapAlloc and then they start saying that it can become fragmented and several other issues. There seems to be a limit to how much memory that can be reserved using Heap, but I cannot find any solid documentation - according to this forum it is 65535.

Below is a piece of simple code that I would like to convert over and don't know what to expect. Will someone put me on the right path? Thanks....
		invoke CreateFile,ADDR buffer,\
                          GENERIC_READ or GENERIC_WRITE ,\
                          FILE_SHARE_READ or FILE_SHARE_WRITE,\
mov hFile,eax
mov  hMemory,eax
invoke GlobalLock,hMemory
mov  pMemory,eax
Posted on 2010-12-05 08:07:38 by nothere
Most memory allocation schemes eventually suffer from fragmentation.  Unless your program is working in a very constrained environment I personally wouldn't worry about it.  Replacing GlobalAlloc with HeapAlloc is rather straightforward.  One of the main differences is that you can now specify a specific heap or use the default when allocating memory.  Although both GlobalAlloc and HeapAlloc both allocate memory for your program they are not very different from malloc in terms of application functionality.  All provide a pointer to a section of memory that your program may read/write.  The GlobalAlloc / LocalAlloc routines are a carry-over from 16-bit land so you can avoid an extra layer of indirection by replacing the calls with the newer Heap* routines.  You will find quite a few C examples on MSDN showing examples that you can easily convert to assembly.  Hope that helps.
Posted on 2010-12-05 09:18:20 by p1ranha
Thanks p1ranha, but it doesn't. I tried the following and it does not read the file in.
	invoke GetOpenFileName, ADDR ofn

.if eax==TRUE
invoke CreateFile,ADDR buffer,\
                          GENERIC_READ or GENERIC_WRITE ,\
                          FILE_SHARE_READ or FILE_SHARE_WRITE,\
mov hFile,eax

invoke HeapCreate,0,0,50000
mov hHeapC, eax

invoke HeapAlloc,hHeapC,HEAP_ZERO_MEMORY,10000
mov pHeapA, eax

invoke ReadFile,hFile,pHeapA,MEMSIZE-1,ADDR SizeReadWrite,NULL
invoke SendMessage,hwndEdit,WM_SETTEXT,NULL,pHeapA
Posted on 2010-12-05 09:36:52 by nothere
What you can do, at the beginning of your program after say, GetModuleHande call
   invoke  GetProcessHeap
   mov     hMainHeap, eax

Then you can:
   invoke HeapAlloc, hMainHeap, HEAP_ZERO_MEMORY, 1000
   mov hTempMem, eax

When you are done with the pointer to memory, you have to free it:
invoke HeapFree, hMainHeap, 0, hTempMem

But if you are opening an existing file, you should get the file size + 1 and do a HeapAlloc with that.

Also, if you are worried about fragmentaion, there are low frag mem functions take a look at HeapSetInformation

Forgot, the MASM library has file functions that make life easier for you...

Test if file exists Get the disk file size
Read disk file into buffer
Write disk file from buffer
Load files into a list box

You could use
invoke read_disk_file, addr PathAndFileName, addr lpMem, addr lpLen
Posted on 2010-12-05 09:43:41 by Gunner
Appreciate the help, but can't get it to work. Back to GlobalAlloc until information is available.
Posted on 2010-12-05 10:10:15 by nothere
Finally found the problem - fSize was set to the wrong size:
invoke ReadFile,hFile,pHeapA,fSize,ADDR SizeReadWrite,NULL
This thing can be a pain.
Posted on 2010-12-05 11:19:21 by nothere
This work and returns all good values. Looking for comments:
Open_File proc

mov  ofn.Flags, OFN_FILEMUSTEXIST or \
                    OFN_PATHMUSTEXIST or OFN_LONGNAMES or\
                    OFN_EXPLORER or OFN_HIDEREADONLY
invoke GetOpenFileName, ADDR ofn

.if eax==TRUE
invoke CreateFile,ADDR buffer,\
                          GENERIC_READ or GENERIC_WRITE ,\
                          FILE_SHARE_READ or FILE_SHARE_WRITE,\
mov hFile,eax

        invoke GetFileSize,hFile,0
        inc eax
        mov fSize, eax ; File size + 1
        invoke GetProcessHeap
mov hHeapC, eax

        invoke  HeapAlloc, hHeapC, HEAP_ZERO_MEMORY, MEMSIZE ;If the function succeeds, the return value is a pointer to the allocated memory block.
mov pHeapA, eax
        lea edi, hi
        invoke HeapSetInformation,hHeapC,0,edi,MEMSIZE
        invoke HeapSize,hHeapC,0,pHeapA
invoke ReadFile,hFile,pHeapA,fSize,ADDR SizeReadWrite,NULL
invoke SendMessage,hwndEdit,WM_SETTEXT,NULL,pHeapA

; Close file and free memory.
invoke CloseHandle,hFile
invoke HeapFree,hHeapC,0,pHeapA
invoke SetFocus,hwndEdit
Open_File endp
Posted on 2010-12-05 11:50:39 by nothere
Don't call GetProcessHeap every time you are opening a file... Get a handle to the processes heap at program startup and save that handle, since you will be using it often.

What is MEMSIZE?  a const?  Just do HeapAlloc hHeapC,  HEAP_ZERO_MEMORY, fSize

Your calling HeapSize but not using the returned value!?  why call it?

Your setting the HeapCompatibilityInformation to 0 which is using the standard heap, if that is the case, then you don't need to call it...  or do you mean to set it to 2 to use the LFH?
Posted on 2010-12-05 12:36:40 by Gunner
Gunner, MEMSIZE was a static , HeapSize was a test and I am using LFH. This is the first time I have tried to use Heap and I have got an education. I noticed that if I set dwMaximumSize of HeapCreate to anything other that 0, it crashes??? Thanks for the info, it is very helpful.
Posted on 2010-12-05 13:04:39 by nothere
You don't have to call HeapCreate.  Just call GetProcessHeap, save the handle, then call HeapAlloc with that handle and the size you need, and the return value is a pointer to the memory you can use to store the file contents.  Then when you are done, call HeapFree 

Give me a few and I will come up with a sample...
Posted on 2010-12-05 13:11:14 by Gunner
Sorry this is a mess... it was a copy and paste of stuff but works
Posted on 2010-12-05 13:40:51 by Gunner
Thanks Gunner...
Posted on 2010-12-05 13:55:47 by nothere

Global/local allocating functions are based on HeapXxx(), but they're different: global functions can give you handle that is somewhat persistent between processes. Had you interact with clipboard yet?
Posted on 2010-12-05 15:06:06 by baldr
baldr - no I haven't taken that into consideration (looks like I need too). I was going by MSDN SDK and overhead:
The heap functions can also be used to manage memory in the process's default heap, using the handle returned by the GetProcessHeap function. New applications should use the heap functions instead of the global and local functions for this purpose.
Although the GlobalAlloc, LocalAlloc, and HeapAlloc functions ultimately allocate memory from the same heap, each provides a slightly different set of functionality. For example, HeapAlloc can be instructed to raise an exception if memory could not be allocated, a capability not available with LocalAlloc. LocalAlloc supports allocation of handles which permit the underlying memory to be moved by a reallocation without changing the handle value, a capability not available with HeapAlloc.

Starting with 32-bit Windows, GlobalAlloc and LocalAlloc are implemented as wrapper functions that call HeapAlloc using a handle to the process's default heap. Therefore, GlobalAlloc and LocalAlloc have greater overhead than HeapAlloc.

Because the different heap allocators provide distinctive functionality by using different mechanisms, you must free memory with the correct function. For example, memory allocated with HeapAlloc must be freed with HeapFree and not LocalFree or GlobalFree. Memory allocated with GlobalAlloc or LocalAlloc must be queried, validated, and released with the corresponding global or local function.

The VirtualAlloc function allows you to specify additional options for memory allocation. However, its allocations use a page granularity, so using VirtualAlloc can result in higher memory usage.

The malloc function has the disadvantage of being run-time dependent. The new operator has the disadvantage of being compiler dependent and language dependent.

The CoTaskMemAlloc function has the advantage of working well in either C, C++, or Visual Basic. It is also the only way to share memory in a COM-based application, since MIDL uses CoTaskMemAlloc and CoTaskMemFree to marshal memory.

Posted on 2010-12-05 15:26:18 by nothere