News:

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

filemapping globalalloc

Started by locche, January 28, 2012, 07:53:37 PM

Previous topic - Next topic

locche

Hello All
I had this idea to make a hex/ascii dump/edit utility.  I started out with GlobalAlloc but had some issues, mostly having to open, reopen files everytime I changed functions.  So I decided to try out the Filemapping calls, which seemed to help. I use a global byte ptr and pass it to various windows via LPCREATESTRUCT.
It's quite handy because I can do any manipulating to the file with the ptr.  So far, so good.
Then I decided to add a function to cut the size of a file using SetFilePtr.  This doesn't work.  Can someone explain this?  Through experimentation I have discovered a few things out. If I create a mapping object larger than the file, the file size increases. And any changes are irreversable.  And I can't dump the executable onto itself, not really an issue.  I did try FILE_SHARE_READ | FILE_SHARE_WRITE, and to open the file again, but I can/t do it.
1) is there a way to set the file ptr so as to cut the file size whilst the entire file is mapped?
2) if not,  would I be better off with globalalloc?  My problem w/the alloc is I haven't found a way to allocate it globally so I don't need to keep open/allocate/read/write the file everytime I change to a new window. Is there a way to allocate and keep the buffer alive without the crash.

Thanks
locche

Tedd

GlobalAlloc isn't global in the sense that another process can access it, the name is just a leftover from 'the good old days' - it's actually identical to LocalAlloc (they're the same function.)
You can share a file-mapping object if you give it a name (last parameter to CreateFileMapping); when another process opens the file-mapping with the same name, it will get the original mapping.
SetFilePtr only sets the current position in the file (for reading or writing,) it doesn't change the file size.
You can alter the size of the file directly using SetEndOfFile, but you can't do this while it's still in a file-mapping.
No snowflake in an avalanche feels responsible.

dedndave

i wonder if GlobalLock can be used with LocalAlloc   :P

hutch--

Tedd is correct here, GlobalAlloc() was GLOBAL before threaded hardware and hardware controlled separate memory for each process. In a 32 bit protected mode OS, (NT upwards) GlobalAlloc() allocates memory within a process like anything else.

File mapping is an OS defined inter-process communication technique and its size is not redefinable so you ensure that the file mapping buffer is always big enough to hold all of your data.. What you need to do depending on the file type (text or binary) is keep track of the file length and when you need to write it to disk you either copy it to allocated memory like GlobalAlloc() OR write the whole buffer to disk then re-open it and truncate the file to the length you require. If the file is very large you will need to do the latter.

RE: GlobalAlloc(), apart from a few legacy functions like the clipboard, it is only useful with fixed memory (GMEM_FIXED) where its return value is the pointer to the memory as it is generally easier to use than the alternatives.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

locche

Thanks, that's really helpful.  I did actually use SetEndofFile() but as hutch has pointed out, if the file's mapped, I can't change its size. Please be tolerant of my next question: I do most programming in C - am still a bit wobbly with assembler, so I'm not totally clear. My understanding till now was that a process was either an application or an application called forth by another application. I did however notice, when observing windows assembly code, what is called a function in c, winproc(HWND,UINT...) is called proc in asm.  So am I right in concluding that for any communication between 'functions()', we have inter-process communication?   If so, a light has been switch on over my desk.  That would explain a number of things.
The memory allocation thing is pretty tricky stuff.  In my case, the problem was I am using a vertical scrollbar with the pattern,
if text then count the linebreaks, if hex than mod 16 for a newline. Count the lines and pass the linecount to either a hex display function or textdisplay function.  Then I had a similar function for the hex editing.  I found that each function had to allocate the buffer, open the file, read the linenumber again, read the file to buffer, InvalidateRect, close, deallocate.  It seemed like inefficient, repetetive.  But any attempts to read the file to a global(to the program) buffer caused a 'yourcrapapplication.exe has done an access violation so goodbye'. 
That's what brought me to the filemapping arena.  It does spare you the trouble of repetitive allocation and file operations. And you have this handy pointer to pass to any function you like.  I was still having trouble when I read, say a 50megabyte  file with the scrollbars. They just don't scroll properly after, say a couple of megabytes. So I thought, 'well try the doubleing the mapping size'.  The scrollbars were beautiful, did everything they were supposed to do.  But I ended up with an 80 meg file.  That's were I got the idea to cut the file. I even tried closing the mapping, but could reopen the file. Got INVALID_HANDLE_VALUE everytime. The mapping seems to lock the file until the applicaiton quits.
It's not the end of the world.  This mapping stuff seems quite good, at least no access violations until now.  You can drag a 40 meg file on the app and it loads instantaneously, whereas such a file gives notepad doubles over, wheezes as if to say 'I'll be allright, just give me a minute'. 
Thanks again locche

jj2007

Quote from: locche on January 28, 2012, 07:53:37 PM
Then I decided to add a function to cut the size of a file using SetFilePtr.  This doesn't work.

Use SetFilePointer, then
SetEndOfFile
Sets the physical file size for the specified file to the current position of the file pointer.

Re other problems: No need to read a megabyte file into memory. You would typically allocate once a "window" of, say, 32k and then read in the 32k you need. If the user scrolls down and the resulting pointer is outside of the window, read the next 32k etc. Blazingly fast - but I am sure somebody will tell you that you can save some nanoseconds with CreateFileMapping :wink

MichaelW

File mapping can save more that nanoseconds, it can save several microseconds  :bg
eschew obfuscation