Archive: CustomLicense plug-in


CustomLicense plug-in
  Introducing my new plugin. It loads a text file into a static buffer, then can set that text into a text or label control that has a HWND. I have already made a wiki page, the link is below.

http://nsis.sourceforge.net/CustomLicense_plug-in


Found out last week I have 3 weeks holiday, not 2 :D. So now I have released a new version. This loads the contents of the file into a dynamically created
buffer. Max file size 305 666 bytes (298KB). See the wiki page above.


Why not use EM_STREAMIN and void that malloc and free stuff


I will take a look at it. I used the first method I found which was malloc and free, because that what the system plugin uses.


Very Good.

I use an other technique:
I use the file open/write/close function to append the ini file with a large text.


Well... I saw your source code. Is nice and clean, but I found some things that you might want to check:

FileHandle= CreateFile(FileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

if (!
FileHandle) ...
According to msdn, when CreateFile fails, it returns INVALID_HANDLE_VALUE and as I remember is not zero.
TempVar== "/UNLOAD" 

I don't think that's possible, you loose data and always will be true :), maybe lstrcmp.

Yeah, I will change it to say:
if (!FileHandle || FileHandle == INVALID_HANDLE_VALUE)

Don't know about the 'Temp == "/UNLOAD"' expression, but it seems to work just fine in my tests.


I have modified the plugin again, and now it has just one function called 'LoadFile'. Usage:

CustomLicense::LoadFile "C:\path\filetoload.txt" "hwndofcontrol"

The first parameter is obvious, the second is the hwnd of the control to load the text into. Example:


Function Pre
installoptions::init "$PLUGINSDIR\inipage.ini"
Pop $0
; See the installoptions readme for info on how
; to get the field number.
; Put the code between here...
;FindWindow $0 "#32770" "" $HWNDPARENT
GetDlgItem $0 $0 1201
CustomLicense::LoadFile "$PLUGINSDIR\license.txt" "$0"
Pop $0
StrCmp $0 0 0 next
MessageBox MB_OK "Error with CustomLicense plug-in."
next:
; ...and here in the show function if you want to
; use this plugin with standard nsis pages.
installoptions::show
FunctionEnd

The actual plugin will probably be out on Monday next week.

@Joel: I had a go at the EM_STREAMIN, but I had no idea on how it is supposed to work. I kept getting errors when I ran the test installer, and it is because it can't understand '->'. I first tried '.', but it gave me an error and told me to use '->'. It crashed at (example): struct->structmember = FileName. So I stayed with my current configuration.

Shouldn't:
installoptions::init
Be:
InstallOptions:InitDialog

-Stu


True. I just have used installoptions passively with MUI and ISUI. Updated version is out. Go to the wiki page above to download.

[edit] fixed typo [/edit]


Your dll still depends on msvcrt.dll. You can easy change malloc-free to kernel.dll GloballAlloc-GlobalFree (Requires Windows 95 or later).


I suppose that is an innocent change to make. I will change it tonight. New version out tomorrow.


Well, I shouldn't get ahead of myself. I now have a small problem. There are now four weird characters at the end of the string after the text has been set in the control. If I take one byte off the number of bytes to read, it gets rid of the weird characters and chops off one byte off the string (a fullstop in my case).

One workaround is to put an extra character at the end of the license file (eg a fullstop), but I don't want to have to tell users to do this before using my plugin. Any ideas?

[edit] I could manually add a terminating NULL character to the string. Would that work?[/edit]


Yep, always make sure you put one on yourself: \0
I missed this in early versions of my array plugin and it caused a few issues.

Edit: Or make sure that you allocate an extra byte to allow for the null character on the end.

-Stu


OK, will do. New version due out on Monday (really).


The only comment in the script sample I wrote long ago is about terminating zero :) http://nsis.sourceforge.net/External_License_file


Surprisingly, that example is almost exactly the same as the internals of my plugin :blah:.

There is a new version out today. In the last version, I forgot to free the allocated memory, which is now fixed. Now uses GlobalAlloc and GlobalFree for memory allocation.

My initial test to see how big a file I can load went very well. I managed to load a 483KB file with no errors on the first go :D. Please tell me how big a file you have managed to load with this plugin without a crash (this is a good way to test my plugin).

When I was going to add the terminating zero, I relised I was not allocating enough memory for the whole file. I was always truncating the terminating zero, thus getting weird characters and some crashes from large files. Now I am allocating enough memory for the file and the terminating zero.

Go to wiki to download (probably the last version for a while).


It appears that if the file path argument is >= 64 characters then the function does not work. Initial debugging of DLL seemed to show that the file argument was in fact getting passed in and parsed (the correct file was opened and read) but perhaps return from DLL is failing?


Well, it's quite obvious that the stack variables are only allocated 64 bytes in the DLL. This length is too short if the file passed in is in the $PLUGINSDIR. I will post a DLL with larger buffer unless JasonFriday13 wants to.


You are given the buffer length as one of the NSIS plug-in function arguments which you can use to allocate memory with LocalAlloc or GlobalAlloc.

Stu


Hi all,

...I've tried the last plug-in version and I've found the described bug (buffer overflow) still not solved (and I'm having random problems under Vista/7);

I think that in CustomLicense.c the line:
unsigned int LoadFileContents(char FileName[64], unsigned int hwnd)
^^^^
...should be changed to:
unsigned int LoadFileContents(char FileName[256], unsigned int hwnd)
^^^^^

...but I've no build environment to compile the fix and public the fixed plugin, can someone fix it?


I have followed Afrow's advice to take the buffer size from the arguments and have built both Ansi and Unicode versions. I've uploaded the build to:

http://nsis.sourceforge.net/CustomLicense_plug-in


Hi,

I have a requirement to set the license text from a string - all my installer's configuration is dynamically configured at runtime from a Json file, including the license text.

I have a couple of questions around Modern UI and the CustomLicense plugin.

Firstly, is there any way to assign a variable to the license text, with or without CustomLicense?

Secondly, if something like CustomLicense is needed, I could always write the license text to a temp file and then pass that to the plug-in but it would feel nicer to just pass the string. Would this be an appropriate patch for CustomLicense? Perhaps adding a new external function LoadText(...) Or should it be a new plug-in?

In general, what is the correct procedure for extensions to plug-ins for NSIS? Would I be able to code a patch and then submit it for approval, or would the change need to be developed by an already trusted developer?

Thanks,
David Hall


Firstly, is there any way to assign a variable to the license text, with or without CustomLicense?
Actually I do not know what you mean...
Do you want to set the text inside the RichEdit control on page License?
You can do it in usual way [for .txt and .rtf files]:
!insertmacro MUI_PAGE_LICENSE "..\..\readme.txt" 
-or-
You can use WM_SETTEXT to send message to this control, this should work for pure text, not RTF.

Secondly....... Perhaps adding a new external function LoadText(...)
LoadText for what? Loading .txt files?
Just create your file and load it with CustomeLicense (my example with nsDialogs):

RichEditLicense

nsDialogs
::CreateControl /NOUNLOAD RichEdit20A ${WS_VISIBLE}|${WS_CHILD}|${WS_TABSTOP}|${WS_VSCROLL}|${ES_MULTILINE}|${ES_WANTRETURN}|${ES_READONLY} ${__NSD_Text_EXSTYLE} 0 13u 100% 115u ''
>Pop $RichEditLicense

File/oname=$PLUGINSDIRLicense.rtf "License.rtf"
>CustomLicense::LoadFile $PLUGINSDIRLicense.rtf $RichEditLicense
>
I did not tried this with standard License page but I suppose it should work (get HWND or RichEdit with GetDlgItem, do not forget to erase text in it)

In general, what is the correct procedure for extensions to plug-ins for NSIS?
Simply download existing plugin, improve it and put new version on wiki (+ sources).
If you want to make large changes then rename this plugin to some cool name ant put it on wiki too (create new page for it).

PS:
There is bug in NSIS forums (php syntax) which hides backward slash "\" when this slash is not enclosed in quotation marks "" like here:

Invisible backslash: 

>Visible backslash: "\"
>

Loading the license text from a variable will not work because NSIS is limited to 1024 (or 8192: http://nsis.sf.net/Special_Builds) characters.

Stu


Used CustomLicense on ANSI NSIS with no issues.
Now moved to Unicode one and there it loads RTF incorrectly.

This code:

nsDialogs::CreateControl /NOUNLOAD "RichEdit20A"
${WS_VISIBLE}|${WS_CHILD}|${WS_CLIPSIBLINGS}|${WS_TABSTOP}|${ES_READONLY}|
${WS_VSCROLL}|${ES_MULTILINE}|${ES_WANTRETURN} ${WS_EX_STATICEDGE} 0 0 100% 100% "RichEdit"
Pop $dialog_text
CustomLicense::LoadFile "$PLUGINSDIR\$(MNHISTORY)" $dialog_text
nsDialogs::Show

in ANSI version loads RTF into RichEdit perfectly but in Unicode version it loads just ???????? ????????? ???? ????????????
But no problems loading TXT instead of the RTF into the same control.

I wrote this plug-in a couple of months back to replace CustomLicense in my projects:
http://nsis.sourceforge.net/NsRichEdit_plug-in

Edit: And why I decided to write a CustomLicense replacement:
http://forums.winamp.com/showthread.php?t=333267

Stu


Thanks! Yours works perfectly.