I'm working on a program that will grow as the user uses it. To do this variables will be saved in different files.
i.e. the variable for a picture location might be:

picLoc db 512 dup(?)

Then the user will locate the picture and the location will be stored in the picLoc variable.
Then the user willl chose a name for the picture.
Now it's LOCATION (the contents of picLoc) will be stored in a file with the user-defined name.

My question is how can i write from a variable to a file and read from a file to a variable?
Posted on 2003-03-05 19:08:52 by Homer
Use CreateFile to open a file then ReadFile to read from it, WriteFile to write to it. Use SetFilePointer to move around in the file. CloseHandle when you are done with it

i.e.
.data?

hFile DWORD ?
FilePath BYTE MAX_PATH DUP(?)
Buffer BYTE 4 DUP(?)
NumberOfBytesRead DWORD ?
NumberOfBytesWritten DWORD ?

.code
invoke CreateFile, ADDR FilePath, GENERIC_READ, NULL, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, NULL
mov hFile,eax
invoke SetFilePointer,hFile,16,NULL,FILE_BEGIN
invoke ReadFile,hFile,ADDR Buffer,4,OFFSET NumberOfBytesRead,NULL
invoke CloseHandle,hFile
; Your DWORD at file position 16 is now in Buffer

invoke CreateFile, ADDR FilePath, GENERIC_WRITE, NULL, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, NULL
mov hFile,eax
invoke SetFilePointer,hFile,16,NULL,FILE_BEGIN
invoke WriteFile,hFile,ADDR Buffer,4,OFFSET NumberOfBytesWritten ,NULL
invoke CloseHandle,hFile
; The DWORD in Buffer is now written to the file at position 16
Read the API reference on these commands to find the limitations of moving the pointer etc. that are specific to your application. I didn't check this for errors, I just typed it on the fly so use caution if you plan to cut and paste, it's only to give you an idea of how to do it.

Donkey
Posted on 2003-03-05 19:50:16 by donkey
Thanks Donkey,

I think I understand. So I use SetFilePointer to move around in the file. This is very interesting, perhaps instead of having seperate files for the physical disk locations of the pictures they can all be in one file?

Is this corret? if so that's awesome! But i wonder how many spaces are on a line? or should different locations be on different lines...
Posted on 2003-03-05 21:50:39 by Homer

Thanks Donkey,

I think I understand. So I use SetFilePointer to move around in the file. This is very interesting, perhaps instead of having seperate files for the physical disk locations of the pictures they can all be in one file?

Is this corret? if so that's awesome! But i wonder how many spaces are on a line? or should different locations be on different lines...


not quite sure what you mean by "on a line" - i'm assuming you mean before an 0dh,0ah line terminator?

since you're working directly with the file, it's basically just a chunk of memory that you can access. there is some api (which i can't recall the name of at the moment) that allows you to map a file to memory so that it's just like a chunk of RAM that is the file itself. If you want to create records of length 512, you can address a record like so:
mov eax,recordnum ;zero-based array
shl eax,9 ;2^9=512
add ebx,eax ;assuming ebx contains the base of your file pointer.

btw, your picLoc db 512 dup (?) allocates 512 bytes of memory. i think what you want is something like (sorry... i don't normally use arrays - and haven't used asm for a while):

picLoc db 100 dup (512 dup (?))

gives you 100 records of 512 bytes. you might even use a struct to make your data easier to manage :)
Posted on 2003-03-05 22:21:36 by jademtech

Thanks Donkey,

I think I understand. So I use SetFilePointer to move around in the file. This is very interesting, perhaps instead of having seperate files for the physical disk locations of the pictures they can all be in one file?

Is this corret? if so that's awesome! But i wonder how many spaces are on a line? or should different locations be on different lines...


Yah, it's just data, what you do with it is your affair. As long as the program knows where each image begins and ends it doesn't make any difference. Just load the raw data into memory then use the BitmapFromMemory function of MASM32, pass the memory address where you stuck the data and the size of the block. That way it doesn't even matter what type of image it is.

I'm not sure what you mean by spaces on a line, what does that have to do with images or files?

Donkey
Posted on 2003-03-05 22:21:47 by donkey
perhaps you could write what you are trying to accomplish in some other programming language to clarify.

in basic code, i think you're trying to do this:

open "bleh" for input as #1
line input #1,foo
'display the image file loaded in variable foo
close #1
Posted on 2003-03-05 22:25:31 by jademtech
I must be thinking of a data file in the wrong way.
i was imagining a file with different picture locations:


pic1.jpg
pic2.jpg
pic3.jpg


in this manner the different locations would be on different lines instead of pic1.jpg pic2.jpg pic3.jpg

but i guess as long as I point to the right location it doesnt matter. My question really is... if i had to could i do this:

invoke SetFilePointer,hFile,16000,NULL,FILE_BEGIN

which i suppose i could being that the writeFile will write to the file in one continuous line.

I will only be using files to store locations of images that the user defines. So when the user quits there will be something of a .cfg file that has the locations of the pictures the user is working with.
Posted on 2003-03-05 22:27:33 by Homer
Hi Jademtech,

I was going to suggest memory mapping the file (it's how I always access files) but it's a bit more complicated and adding later to the file can be difficult Best to stay with the simple solution for now. BTW it's something like this, it's my sniplet for mapping a file...
invoke CreateFileMapping, hFile, NULL, PAGE_READONLY, 0, 0, NULL

mov hMapFile,eax
invoke SetLastError,0
invoke MapViewOfFile, hMapFile, FILE_MAP_READ, 0, 0, 0
mov MapFileOffset,eax
invoke GetLastError
test eax,eax
jz @F
invoke CloseHandle,hMapFile
invoke CloseHandle,hFile
mov eax,INVALID_HANDLE_VALUE
ret
@@:
Donkey
Posted on 2003-03-05 22:30:29 by donkey
Hi Homer,

There are no lines in a file, just a contiguous series of bytes. The idea of a "line" is something that is an interpretation of the data, by convention a "line" is a text block terminated by 0D 0A (CR/LF). It is not necessary to have "lines" in a file, take for example an executable or database. In reality there are no lines, that is just a convention that HLL's use to make it easier to read text files or output text.

Donkey
Posted on 2003-03-05 22:40:01 by donkey
Thanks alot guys,

I appreciate all the fast responses i get and if i ever get this program devopled you'll be in the about dialog =]

time 4 bed gnite
Posted on 2003-03-05 23:35:59 by Homer
If you want to read CR/LF terminated lines, if you created them in notepad or some other program for example, you can write a simple function for parsing the string like the following (doing two bytes of comparing at a time to make it easier to follow.):



lea eax,BeginningOfFile
GetNextChar:
inc eax ;can put the increment right here because you probably will not have any null strings
cmp word ptr [eax],0a0dh ;reversed byte order
jne GetNextChar
;do processing of the filename here


you could probably make your life easier if you use null-terminated strings (character 0) at the end of each filename since most Windows API use them to delimit the end of a string.
Posted on 2003-03-06 10:36:19 by jademtech
you might wish to consider using a database, that way you don't have to code a lot of search logic yourself, you just need to stuff in the data and supply the search parameters.

http://sqlite.org sqlite is a nice little one that might suit you, it's standalone and only 1 DLL
Posted on 2003-03-06 10:37:23 by Hiroshimator
Homer,
Model it after the resources in a PE. You will have a directory tree containing information about each resource and it's location and then, the resources sequentially in the same file.
Posted on 2003-03-06 11:09:52 by pelaillo
Hi Homer,

From what I understand you have 3 things you have to store:

1: the raw picture data
2: some user defined name for the picture
3: the location of the picture within the file

There are several ways to do this, one is as Hiro suggested a database, that is by far the most elegant solution but it requires that the user have the right ODBC drivers installed as well as you having a knowledge of SQL and database structure. A second way is like your first idea, store everything seperately, this shouldn't be an option, the amount of data files would quickly get out of proportion. My suggestion would be as follows:

Use a page from MP3 files. They keep raw data in a file in the form of frames and use a frame header to distinguish them and a tag to id the file. You don't need frame headers in this type of a file but tags may be your solution. Store your pictures one after another in the file then add a tag to the end something like this...

; this would be the letters T A G (or whatever you want) to indicate the start of the tag
, 00 ; the ascii text of the picture name terminated by zero
; a dword size pointer to the address in the file
, 00 and so on till there are no more pictures

Read backwards in the file till you find "TAG" or whatever you decide to use then go to the start of the first picture name and add it to your listbox, use LB_SETITEMDATA to attach the pointer to the item in the listbox. The pointer will point to the start of the picture and the start of the next, this will give you the picture size in the file (ie subtract the start from the start of the next). When the user selects a picture you extract the item data and position your file pointer at the start of the picture, read the picture into memory then display it.

To make things even simpler you can make the picture descriptions a fixed length, i.e. 60 bytes. then you know exactly where your position information will be. And make the last DWORD of the file the tag size, that will guarantee a fast tag read.

Donkey
Posted on 2003-03-06 13:12:24 by donkey
simple things like sqlite do not require any dll but their own so you don't have to worry about odbc or similar
just it's own reasonably small dll
Posted on 2003-03-06 13:15:06 by Hiroshimator


From what I understand you have 3 things you have to store:

1: the raw picture data
2: some user defined name for the picture
3: the location of the picture within the file


I only need #3. The ideas you guys are suggesting are ideal, but this is my first program, and my expertise is NULL. I'm going to go with the seperate files for each USERNAME (not for each pictures, usernames can have multiple images.) maybe in the next version i'll have more elegant file management and code [.]. But for now please understand that i'm a total newb! I've got Hutch's masm, the Win32 help, and u guys which is great for what i am trying to make happen right now. If you want to take a look at what I'm planning so you can see it for yourself I can send u a copy.

Really this will be a nice looking program one day, hopfully, but right now it's just a way of applying the things in Iczelions tuts during my spare time.

Anyway, i love the way you guys all brainstorm on cool ideas, but they're really over my head :rolleyes:

i.e. right now i'm having a problem clearing my buffers:

mov buffer, 0

just isn't working... infact it does nothing! i've set up invoke MessageBox, Null, ADDR buffer to track whats going on and it really doesn't do anything. What's happening is when i read from a file to the buffer more than once it seems to just append it. Any ideas on how to clear a my buffers?
Posted on 2003-03-06 23:24:27 by Homer
mov ,0 would probably do the trick. buffer isn't really anything but an address you have to dereference it before you can use it. though you might try invoke memfill,ADDR buffer,SIZEOF buffer,0 it's more suitable for what you need.

Go with the format for your program you feel works best for you and that you feel capable of doing. It can always be changed later as you progress. The main objective is to learn and that can be long and boring if you don't get results even if those results aren't optimal.

In addition to iczelion's tuts I'd suggest the ASMINTRO.HLP file (it came with MASM32), it can explain alot of things like working with strings and how to do some of the more basic tasks.

Donkey
Posted on 2003-03-07 00:44:18 by donkey
Hmm, I think I need method two. What library is memfill in?
Posted on 2003-03-07 03:04:34 by Homer
include \masm32\include\masm32.inc
includelib \masm32\lib\masm32.lib

Donkey
Posted on 2003-03-07 03:07:08 by donkey
thx...

hey donkey, same results =?
Strange things are happening... The button to load the image by entering the keyword "works"

a) enter the keyword
b) press button
- File is opened
- ReadFile copies the locatoin of the pic to a buffer
-invoke BitmapFromFile, addr buffer <-- Not working

you see:


.ELSEIF ax==LoadSNButtonID
shr eax,16
.IF ax==BN_CLICKED
invoke GetWindowText, hwndLoadEditSN, addr buffer, 36
invoke lstrcat, addr SNFile, addr buffer
invoke MessageBox,NULL, addr SNFile, addr AppName,MB_OK
invoke CreateFile, addr SNFile, GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL
mov hFile, eax
invoke SetFilePointer, hFile, 1, NULL,FILE_CURRENT
invoke ReadFile, hFile, addr FileBuffer,21,OFFSET NumberOfBytesRead,NULL
invoke CloseHandle,hFile
invoke MessageBox, NULL,addr FileBuffer,Addr AppName,MB_OK
invoke BitmapFromFile, addr FileBuffer
mov hBitmap,eax
invoke InvalidateRect, hWnd, NULL, TRUE
.ENDIF


That is the code that handles the sequence i mapped out up there... it did work once. I'm not sure what i did to mess it up though. How does that look to you, see any reason it shouldn't work? [ps The MessageBox 'flags' verify the ReadFile is working correctly. But if i click the button twice the buffer just starts appending the keyword on to itself (yep i tried invoke memfill too; same result!?).

Well I'm gonna sleep on it. 5am here! We need more faces, wheres the tired one? =D
gnite
Posted on 2003-03-07 03:57:44 by Homer