Gushe Posted April 19, 2009 Posted April 19, 2009 (edited) Hey all! I am working on my first project in MASM at the moment, and it is actually going quite well. Though I ran into a small problem. I want to read a file into memory and save it to another file, with some changes (yeah, I want to encrypt a file), and for doing this I am creating a new procedure. Now, because of everbody has a different amount of memory I let the user define how much bytes they want to be loaded in memory at once for encrypting. The more bytes loaded at once, the less ReadFile has to be called, and the quicker the encrypting will be. But what if the last block of bytes is to be read? (I reach EOF) the lpNumberOfBytesRead parameter should be set to 0 when EOF is reached, but for my encryption loop I will need to know how many iterations the loop has to make, and therefore the amount of bytes looaded into memory. What would be the best approach for this? (If anybody understands what I want to say ) Because I do not want to be too lazy, here are two idea's I've had. Idea One: This one is more secure if lpNumberOfBytesRead (here bytesRead) doesn't return 0 when the filesize is actually smaller than lpNumberOfBytesToRead. mov eax, bytesRead .IF eax <= blockSize mov isFinished, TRUE .ENDIF .IF bytesRead == 0 invoke GetFileSize, hInputFile, NULL mov bytesRead, eax .ENDIF Second: Depends on correctness of lpNumberOfBytesToRead, but this one is faster in a loop. (Since the blocks are read in a loop also) .IF bytesRead == 0 mov isFinished, TRUE invoke GetFileSize, hInputFile, NULL mov bytesRead, eax .ENDIF What would you guys do? ~ GuShe Edited April 19, 2009 by Gushe
Gushe Posted April 19, 2009 Author Posted April 19, 2009 I'll try to explain better. I want to use the ReadFile function to read a specified amount of bytes from a certain file. BOOL WINAPI ReadFile( __in HANDLE hFile, __out LPVOID lpBuffer, __in DWORD nNumberOfBytesToRead, __out_opt LPDWORD lpNumberOfBytesRead, __inout_opt LPOVERLAPPED lpOverlapped); Now, what if the value in nNumberOfBytesToRead is larger than the actual file? msdn says the following: When a synchronous read operation gets to the end of a file, ReadFile returns TRUE and sets the variable pointed to by the lpNumberOfBytesRead parameter to zero. But even in this case, I need to know the exact amount of bytes read by the function, because I need them for an encryption algorythm. My problem is how to get that number.
MACH4 Posted April 19, 2009 Posted April 19, 2009 Easy, just call GetFileSize:; ------------ Get File size ----------invoke GetFileSize, hFile, addr lpFileSizeHighmov fileSize, eaxThen fileSize will hold the number of bytes to base your array on, like: ; ------------ Create compatible array ----------invoke VirtualAlloc, NULL, FileSize, MEM_COMMIT, PAGE_READWRITEmov [pArray], eaxinvoke VirtualLock, addr [pArray], fileSizeDon't forget to always check the return value in case it returns INVALID.MACH4
diablo2oo2 Posted April 19, 2009 Posted April 19, 2009 sure, use GetFileSize... where is the problem?
Gushe Posted April 19, 2009 Author Posted April 19, 2009 I didn't know if the result would be accurate enough. Thanks for help!
Gushe Posted April 19, 2009 Author Posted April 19, 2009 I stumbled upon another problem.Let's say I am reading a file with a size of 10, and I am reading it per blocks of 3.I can read 3 complete blocks, but then only 1 is left. The Read operation will succesfully read the 1 sized block, but I will not have any information on the size of that last block. GetFileSize would give me the size of the complete file, not only the last block.Does anyone has an idea on how to solve this?(without creating loads of new variables that will slow my application down o.O)Thanks in Advance.
MACH4 Posted April 19, 2009 Posted April 19, 2009 Just add bytesRead to your filePtr to know where you are!Depending on just what your doing, it might be more convenient to read the file into an array to start with!the same operation either way...MACH4
Gushe Posted April 19, 2009 Author Posted April 19, 2009 It's not to know where I am, it's to determine the amount of bytes read into memory. Does something as arrays exist in MASM anyway? I do not completely understand what you mean, excuse me.
Killboy Posted April 20, 2009 Posted April 20, 2009 well, just save the bytes read ie. for every successful WriteFile, add +3 to a var and loop until var >= filesize one variable sure as hell won't slow your app down lol optimization is okay, but certainly not worth thinking about more than a minute if you're dealing with file operations. say your writing and reading the var takes 10 cycles tops, the file operation will take up to 100 ms considering 1Ghz means around 1 billion cycles per second, what's the point
enhzflep Posted April 20, 2009 Posted April 20, 2009 Here you go. Did it a year ago for another programming forum, where I post as simonb2It's masm code to read in and xor encrypt a file. Files are specified from the command line (or dropped onto the executable - select src then target and drop onto executable), while user is prompted to enter the char to xor encrypt with.It runs at around 26 MB/sec on a 2.6 ghz celeron. Hope it's of some use.ASM_Encrypter.zip
Gushe Posted April 20, 2009 Author Posted April 20, 2009 enhzflep, thanks for the code, but I do not understand how you get the amount of iterations needed when the filesize limit is reached.Or I only get it half.When does the application exactly determine you reached OEP, the last ReadFile that actually reads bytes (that reads one byte in my example above) or a readfile operation after that one, when no byte has been read? That would ease things up.. a LOT! =D~ GuShe
diablo2oo2 Posted April 20, 2009 Posted April 20, 2009 (edited) Let's say I am reading a file with a size of 10, and I am reading it per blocks of 3.I can read 3 complete blocks, but then only 1 is left. The Read operation will succesfully read the 1 sized block, but I will not have any information on the size of that last block. GetFileSize would give me the size of the complete file, not only the last block.so, you know the filesize and you know the blocksize? then you can easily calculate the size of the last block.filesize mod blocksize = lastblocksizeor in asm:mov eax,filesizemov ecx,blocksizecdqdiv ecxresult in edx is lastblocksize...result in eax is number of iterations to read the file with your blocksize Edited April 20, 2009 by diablo2oo2
enhzflep Posted April 21, 2009 Posted April 21, 2009 When does the application exactly determine you reached EOF, the last ReadFile that actually reads bytes (that reads one byte in my example above) or a readfile operation after that one, when no byte has been read? That would ease things up.. a LOT! =D~ GuSheThe last time ReadFile is called, it will read 0 bytes since it has hit the end of the file. This condition will berecognized by the fact that the variable bytesActuallyRead contains the number 0. When bytesActuallyRead = 0,I break out of the loop. I never bother to work out the size of the file, or the number of iterations needed to process it - I just keep going till I can't read any more bytes from the input file. invoke ReadFile, [inputFileHandle], ADDR readBuffer, bufLength, ADDR bytesActuallyRead, NULL cmp [bytesActuallyRead], 0 je readingDoneE.g10 byte file, 4 bytes read per iteration1st loop: ReadFile, bytesActuallyRead = 4 ---> continue2nd loop: ReadFile, bytesActuallyRead = 4 ----> continue3rd loop: ReadFile, bytesActuallyRead = 2 ----> continue4th loop: ReadFile, bytesActuallyRead = 0 -----> stop
Gushe Posted April 21, 2009 Author Posted April 21, 2009 When does the application exactly determine you reached EOF, the last ReadFile that actually reads bytes (that reads one byte in my example above) or a readfile operation after that one, when no byte has been read? That would ease things up.. a LOT! =D~ GuShe The last time ReadFile is called, it will read 0 bytes since it has hit the end of the file. This condition will be recognized by the fact that the variable bytesActuallyRead contains the number 0. When bytesActuallyRead = 0, I break out of the loop. I never bother to work out the size of the file, or the number of iterations needed to process it - I just keep going till I can't read any more bytes from the input file. invoke ReadFile, [inputFileHandle], ADDR readBuffer, bufLength, ADDR bytesActuallyRead, NULL cmp [bytesActuallyRead], 0 je readingDone E.g 10 byte file, 4 bytes read per iteration 1st loop: ReadFile, bytesActuallyRead = 4 ---> continue 2nd loop: ReadFile, bytesActuallyRead = 4 ----> continue 3rd loop: ReadFile, bytesActuallyRead = 2 ----> continue 4th loop: ReadFile, bytesActuallyRead = 0 -----> stop That's what I used. Thanks anyay.
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now