Winamp & Shoutcast Forums

Winamp & Shoutcast Forums (http://forums.winamp.com/index.php)
-   NSIS Discussion (http://forums.winamp.com/forumdisplay.php?f=65)
-   -   Binary read (http://forums.winamp.com/showthread.php?t=204832)

superruzafa 13th January 2005 19:35

Binary read
 
Hi,

I must modify some parts of a 153 Mb binary file. The only function I've found that performs this is FileReadByte and FileWriteByte but are toooooooooo slow.

Is there any way to read/write strings of non-character bytes using FileRead/FileWrite? Or I must making an external program who performs that?

Thanks

kichik 13th January 2005 19:44

If you want to patch a binary file, why not use VPatch?

superruzafa 13th January 2005 19:58

Could you write the link?

kichik 13th January 2005 20:00

It's in your Contrib folder.

superruzafa 13th January 2005 20:13

Sorry, I'm a total newbie and I don't know where that folder is. I'll search other posts ;)

kichik 13th January 2005 20:15

Where you installed NSIS, there's a folder named Contrib. Inside that folder, there's a folder named VPatch. Normally, that should be:

C:\Program Files\NSIS\Contrib\VPatch

Afrow UK 13th January 2005 20:40

Have a good look around your NSIS directory. It's always a good idea to know what's available to you :)

-Stu

Takhir 14th January 2005 10:31

1 Attachment(s)
I had to write my own binary read script for license page. It was empty installer with all files located in CVS folders including installer itself and license file, and like Joost wrote long ago we can use WM_SETTEXT for txt files. The only problem I found - System plug-in can not allocate variable size memory (&t$1), but calloc() can ;) Sample script attached.
Might be good to allow users to skip License file name for such situations in MUI page definition, 0 parameters may create warning only, in this script I had to use additional short "dummy.txt" file (not committed to our CVS, this may create problems with later installer rebuilds :( ).

kichik 14th January 2005 10:49

The System.dll plug-in should have no problem allocating variable size memory blocks. The problem you've encountered is probably NSIS's string size limit (1024 by default). If you read using FileRead and then append using a call to lstrcat, it should be OK.

BTW, it's not a good idea to allocate using calloc and free using System::Free. They use two different allocation methods. In the worst case, it can cause a crash. Usually, it should just create a memory leak.

Takhir 14th January 2005 11:27

1 Attachment(s)
Thanks, KichiK!
Might be something was wrong in my syntax, this not worked with System::Call allocation, but looks OK now with Alloc and Free.
BTW I used
System::Alloc '$1 .r0'
syntax in the updated file, and this works fine, but System.htm uses
System::Alloc 64
Pop $0
Is my variant correct?

kichik 14th January 2005 11:32

Your variant is incorrect. Take a look at Contrib\System\Source\Buffers.c. Alloc is right on the top.

Takhir 14th January 2005 11:52

OK, I'll better use my favourite msvcrt calls ;)

superruzafa 14th January 2005 13:47

I've found very interesting all you have talk.

Where can I find more info about system calls and the parameters for that functions?

BTW, I made an patch.exe file which does the patching logic and I call externally.

kichik 14th January 2005 13:49

You can find information about the System plug-in in its readme. You can find the readme, the source code and some examples in <nsis folder>\Contrib\System.

superruzafa 14th January 2005 15:07

Take a look of that code. I have a binary file "prueba.bin" who is 1024 bytes and I try to copy into another file, but nothing happens.

Need more code? (includes, defines) or simplily the params are wrong?

code:

System::Call 'msvcrt.dll::calloc(i 1024, i 1) i .r0' ; creates a 1024 size buffer

System::Call 'msvcrt.dll::_open(t "$INSTDIR\prueba.bin, i 0x8000) i .r1' ; open first file
System::Call 'msvcrt.dll::_open(t "$INSTDIR\prueba2.bin, i 0x8101) i .r2' ; open second file
System::Call 'msvcrt.dll::_read(i r1, i r0, 1024) i .r3' ;read the first file
System::Call 'msvcrt.dll::_write(i r2, i r0, 1024) i .r3' ;and writes to the second

System::Call 'msvcrt.dll::_close(i r1)' ; close file 1
System::Call 'msvcrt.dll::_close(i r2)' ; close file 2


kichik 14th January 2005 15:09

You're missing closing quotes for the file names in both _open calls.

superruzafa 14th January 2005 15:20

Quote:

Originally posted by kichik
You're missing closing quotes for the file names in both _open calls.
:eek: Ups. Now file is created but nothing is readed nor writed. I'll continue investigating about that :cool:

kichik 14th January 2005 15:22

It might be because you're missing an `i` before 1024 in the _read and _write lines.

superruzafa 14th January 2005 15:24

I got it! :D

It failed type for 1024. Well, hope this will serve for others.

code:

System::Call 'msvcrt.dll::_read(i r1, i r0, /* this -> */ i 1024) i .r3'
System::Call 'msvcrt.dll::_write(i r2, i r0, /* and this -> */ i 1024) i .r3'


superruzafa 14th January 2005 15:26

It seems we are writing at time, ;)

Thanks for all, guys

Takhir 15th January 2005 09:56

And
System::Call 'msvcrt.dll::free(i ro)'
at the end of code :)

superruzafa 15th January 2005 10:02

I've used System::Alloc and System::Free for that.

Is a good idea to allocate memory with those functions and then use the memory allocated with msvcrt.dll call functions?

Takhir 15th January 2005 10:08

This is not a problem I guess, both allocs should work with this code 100%. But System::Alloc + Pop take 2 lines of script :( - this is the only reason why I used direct msvcrt calls.

superruzafa 17th January 2005 12:37

What if msvcrt.dll isn't installed? Must I include in the installer? And then, extract and installing?

Takhir 17th January 2005 12:46

Don't worry about msvcrt.dll ;)
Only msvcrtd.dll (debug version) may not present.


All times are GMT. The time now is 17:58.

Copyright © 1999 - 2010 Nullsoft. All Rights Reserved.