git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@2556 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
joostverburg 2003-05-21 12:24:22 +00:00
parent 9a092cb98f
commit fbc323c3db
11 changed files with 689 additions and 4 deletions

BIN
Contrib/VPatch/GenPat.exe Normal file

Binary file not shown.

189
Contrib/VPatch/Readme.html Normal file
View file

@ -0,0 +1,189 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>VPatch 2</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<style type="text/css">
body
{
padding: 10px;
background-color: #F0F0F0;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 10pt;
font-weight: normal;
}
center
{
text-align: center;
}
table
{
margin: auto;
text-align: left;
background-color: #FFFFFF;
}
.maintable
{
border: 2px solid #376EAB;
}
.margin
{
margin: 20px;
}
.text
{
margin: 20px;
}
.bold
{
font-weight: bold;
}
.italic
{
font-style: italic;
}
.bigheader
{
margin: 10px;
font-size: 24pt;
color: #333333;
text-align: center;
}
.header
{
font-size: 14pt;
color: #7A7272;
}
.subheader
{
margin: 20px;
font-size: 11pt;
font-weight: bold;
color: #303030;
}
.footer
{
margin: 5px 5px 5px 5px;
text-align: right;
font-size: 8pt;
color: #909090;
}
a:link, a:visited, a:active
{
color: #294F75;
text-decoration: none;
}
a:hover
{
color: #182634;
text-decoration: none;
}
</style>
</head>
<body>
<div class="center">
<table width="750" class="maintable" cellspacing="0" cellpadding="0">
<tr><td>
<table cellspacing="0" cellpadding="0">
<tr>
<td><p class="bigheader">VPatch 2</p></td>
</tr>
<tr>
<td><div class="margin">
<p class="header">Introduction</p>
<p class="text">VPatch allows to create a patch file to update previous versions of
your software. The GenPat utitily generates the patch file. The plug-in can use the
patch to update a file. Using a patch, you can reduce the download size of your
updates, because only the differences between the files are included in the patch
file.</p>
<p class="header">How to use</p>
<p class="subheader">Generate the patch file</p>
<p class="text">Make sure you have the source file (original version) and the target file (version
to update to). For example, DATA.DTA (currently on user system) and DATA_20.DTA
(version 2.0 of this data file). Now call the command line tool GenPat.exe:</p>
<pre class="margin">GENPAT data.dta data_20.dta data.pat</pre>
<p class="text">Now, the patch will be generated, this will take some time.</p>
<p class="text">Using the /B=(BlockSize) parameter of the GenPat utility (put it after
the filenames), you can use a different block size. A smaller block size may result in
a smaller patch, but the generation will take more time (the default blocksize is 64).</p>
<p class="subheader">Update the file in your installer</p>
<p class="text">Use the VPatch plug-in to update a file using a patch file:</p>
<pre class="margin">vpatch::vpatchfile "pathfile.pat" "source.file" "new.file"</pre>
<p class="text">Check <a href="example.nsi">example.nsi</a> for an example.</p>
<p class="subheader">Multiple patches in one file</p>
<p class="text">GenPat appends a patch to the file you specified. If there is already a patch
for the same orginal file in the patch file, the patch will be replaced. For example, if you want
to be able to upgrade version 1 and 2 to version 3, you can put a 1 &gt; 3 and 2 &gt; 3 patch in one
file.</p>
<p class="text">You can also put patches for different files in one patch file, for example, a
patch from file A version 1 to file A version 2 and a patch from file B version 1 to
file B version 2. Just call the plug-in multiple times with the same patch file. It
will automatically select the right patch (based on the file CRC).</p>
<p class="header">Version history</p>
<ul>
<li>2.0 beta 2
<ul>
<li>All new algorithm used in the patch generator: much faster (up to
90%) while using smaller block sizes (higher compression)</li>
<li>Created a NSIS 2 plugin</li>
<li>Works with small files</li>
<li>Replaces existing patch in file if original file CRC is identical</li>
</ul></li>
</ul>
<p class="header">Credits</p>
<p class="text">Written by Koen van de Sande<br />
C plug-in by Edgewize<br />
New documentation and example by Joost Verburg</p>
<p class="header">License</p>
<pre class="margin">Copyright (C) 2001-2002 Koen van de Sande
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute
it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented;
you must not claim that you wrote the original software.
If you use this software in a product, an acknowledgment in the
product documentation would be appreciated but is not required.
2. Altered versions must be plainly marked as such,
and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any distribution.
Please note that this version contains the plug-in source only,
not the source of the patch generator.
</pre>
</div></td>
</tr>
</table>
</td></tr>
</table>
</div>
</body>
</html>

View file

@ -0,0 +1,43 @@
;VPatch example
;Written by Joost Verburg
;--------------------------------
; The name of the installer
Name "VPatch Test"
; The file to write
OutFile "vpatchtest.exe"
; The default installation directory
InstallDir "$PROGRAMFILES\VPatch Test"
; The text to prompt the user to enter a directory
DirText "Choose a folder in which to install the VPatch Test!"
; Show details
ShowInstDetails show
;--------------------------------
Section ""
; Set output path to the installation directory
SetOutPath $INSTDIR
; Extract the old file
File oldfile.txt
; Extract the patch to the plug-ins folder (temporary)
InitPluginsDir
File /oname=$PLUGINSDIR\patch.pat patch.pat
; Update the old file to the new file using the patch
DetailPrint "Updating oldfile.txt using patch..."
vpatch::vpatchfile "$PLUGINSDIR\patch.pat" "$INSTDIR\oldfile.txt" "$INSTDIR\newfile.txt"
; Show result
Pop $R0
DetailPrint "Result: $R0"
SectionEnd

View file

@ -0,0 +1,6 @@
*** THIS IS A TEST FILE FOR THE VPATCH EXAMPLE ***
*** COMPILE EXAMPLE.NSI TO TEST ***
newfile - vpatch
67890 - GHIJKL

View file

@ -0,0 +1,6 @@
*** THIS IS A TEST FILE FOR THE VPATCH EXAMPLE ***
*** COMPILE EXAMPLE.NSI TO TEST ***
oldfile - vpatch
12345 - ABCDEF

BIN
Contrib/VPatch/patch.pat Normal file

Binary file not shown.

273
Contrib/VPatch/vpatchdll.c Normal file
View file

@ -0,0 +1,273 @@
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "..\..\ExDLL\exdll.h"
int DoPatch(HANDLE hPatch, HANDLE hSource, HANDLE hDest);
void strcopy(char *tgt, const char *src);
char* chop_arg(char **args);
#define PATCH_SUCCESS 0
#define PATCH_ERROR 1
#define PATCH_CORRUPT 2
#define PATCH_NOMATCH 3
#define PATCH_UPTODATE 4
#define FILE_ERR_PATCH 5
#define FILE_ERR_SOURCE 6
#define FILE_ERR_DEST 7
HINSTANCE g_hInstance;
HWND g_hwndParent;
void __declspec(dllexport) vpatchfile(HWND hwndParent, int string_size,
char *variables, stack_t **stacktop)
{
g_hwndParent=hwndParent;
EXDLL_INIT();
// note if you want parameters from the stack, pop them off in order.
// i.e. if you are called via exdll::myFunction file.dat poop.dat
// calling popstring() the first time would give you file.dat,
// and the second time would give you poop.dat.
// you should empty the stack of your parameters, and ONLY your
// parameters.
// do your stuff here
{
static char source[1024];
static char dest[1024];
static char exename[1024];
HANDLE hPatch, hSource, hDest;
int result;
popstring(exename);
popstring(source);
popstring(dest);
hPatch = CreateFile(exename, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (hPatch == INVALID_HANDLE_VALUE) {
pushstring("Unable to open patch file");
return;
}
hSource = CreateFile(source, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (hSource == INVALID_HANDLE_VALUE) {
pushstring("Unable to open source file");
return;
}
hDest = CreateFile(dest, GENERIC_READ | GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if (hDest == INVALID_HANDLE_VALUE) {
pushstring("Unable to open output file");
return;
}
result = DoPatch(hPatch, hSource, hDest);
CloseHandle(hDest);
CloseHandle(hSource);
CloseHandle(hPatch);
if ((result != PATCH_SUCCESS)) {
if (result == PATCH_ERROR)
pushstring("An error occured while patching");
else if (result == PATCH_CORRUPT)
pushstring("Patch data is invalid or corrupt");
else if (result == PATCH_NOMATCH)
pushstring("No suitable patches were found");
else if (result == PATCH_UPTODATE)
pushstring("OK, new version already installed");
DeleteFile(dest);
} else {
pushstring("OK");
}
return;
}
}
BOOL WINAPI _DllMainCRTStartup(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
{
g_hInstance=hInst;
return TRUE;
}
UINT CRCTable[256];
BOOL bInitCRC = FALSE;
_inline void InitCRC() {
int i, j; unsigned long c;
for (c = i = 0; i < 256; c = ++i) {
for (j = 0; j < 8; j++) {
if (c & 1) c = (c>>1) ^ 0xEDB88320;
else c >>= 1;
}
CRCTable[i] = c;
}
bInitCRC = TRUE;
}
#define CRCBLOCKSIZE 4096
BOOL FileCRC(HANDLE hFile, DWORD *crc) {
static BYTE crcblock[CRCBLOCKSIZE];
DWORD read;
BYTE *p;
UINT c = 0xFFFFFFFF;
if (bInitCRC == FALSE)
InitCRC();
SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
do {
if (ReadFile(hFile, crcblock, CRCBLOCKSIZE, &read, NULL) == FALSE)
return FALSE;
for (p = crcblock; p < crcblock + read; p++)
c = CRCTable[(c & 0xFF) ^ *p] ^ (c >> 8);
} while (read);
*crc = (c ^ 0xFFFFFFFF);
return TRUE;
}
#define BLOCKSIZE 16384
int DoPatch(HANDLE hPatch, HANDLE hSource, HANDLE hDest) {
static char block[BLOCKSIZE];
unsigned long temp = 0;
unsigned long read;
unsigned long source_crc = 0;
unsigned long patch_dest_crc = 0;
long patches = 0;
int already_uptodate = 0;
// special 'addition' for the dll: since the patch file is now
// in a seperate file, the VPAT header might be right at the start
// of the file, and a pointer at the end of the file is probably missing
// (because all patch generator versions don't append it, the linker/gui
// does this).
SetFilePointer(hPatch, 0, NULL, FILE_BEGIN);
ReadFile(hPatch, &temp, 4, &read, NULL);
// it's not at the start of file -> there must be a pointer at the end of
// file then
if (temp != 0x54415056) {
SetFilePointer(hPatch, -4, NULL, FILE_END);
ReadFile(hPatch, &temp, 4, &read, NULL);
SetFilePointer(hPatch, temp, NULL, FILE_BEGIN);
ReadFile(hPatch, &temp, 4, &read, NULL);
if (temp != 0x54415056)
return PATCH_CORRUPT;
}
if (!FileCRC(hSource, &source_crc))
return PATCH_ERROR;
ReadFile(hPatch, &patches, 4, &read, NULL);
while (patches--) {
long patch_blocks = 0, patch_size = 0;
unsigned long patch_source_crc = 0;
ReadFile(hPatch, &patch_blocks, 4, &read, NULL);
ReadFile(hPatch, &patch_source_crc, 4, &read, NULL);
ReadFile(hPatch, &patch_dest_crc, 4, &read, NULL);
ReadFile(hPatch, &patch_size, 4, &read, NULL);
//added by Koen - check to see if it's already up-to-date for some patch (so
//we can tell NSIS this isn't an error, but we already have the latest version)
if (source_crc == patch_dest_crc) {
already_uptodate = 1;
}
if (source_crc == patch_source_crc) {
while (patch_blocks--) {
unsigned char blocktype = 0;
unsigned long blocksize = 0;
ReadFile(hPatch, &blocktype, 1, &read, NULL);
switch (blocktype) {
case 1:
case 2:
case 3:
if (blocktype == 1)
{ unsigned char x; blocksize = ReadFile(hPatch,&x,1,&read,NULL)? x:0; }
else if (blocktype == 2)
{ unsigned short x; blocksize = ReadFile(hPatch,&x,2,&read,NULL)? x:0; }
else
{ unsigned long x; blocksize = ReadFile(hPatch,&x,4,&read,NULL)? x:0; }
if (!blocksize || !ReadFile(hPatch, &temp, 4, &read, NULL) || read != 4)
return PATCH_CORRUPT;
SetFilePointer(hSource, temp, 0, FILE_BEGIN);
do {
ReadFile(hSource, block, min(BLOCKSIZE, blocksize), &read, NULL);
WriteFile(hDest, block, read, &temp, NULL);
if (temp != min(BLOCKSIZE, blocksize))
return PATCH_ERROR;
blocksize -= temp;
} while (temp);
break;
case 5:
case 6:
case 7:
if (blocktype == 5)
{ unsigned char x; blocksize = ReadFile(hPatch,&x,1,&read,NULL)? x:0; }
else if (blocktype == 6)
{ unsigned short x; blocksize = ReadFile(hPatch,&x,2,&read,NULL)? x:0; }
else
{ unsigned long x; blocksize = ReadFile(hPatch,&x,4,&read,NULL)? x:0; }
if (!blocksize)
return PATCH_CORRUPT;
do {
ReadFile(hPatch, block, min(BLOCKSIZE, blocksize), &read, NULL);
WriteFile(hDest, block, read, &temp, NULL);
if (temp != min(BLOCKSIZE, blocksize))
return PATCH_ERROR;
blocksize -= temp;
} while (temp);
break;
default:
return PATCH_CORRUPT;
}
}
{
unsigned long dest_crc = 0;
FileCRC(hDest, &dest_crc);
if (dest_crc != patch_dest_crc)
return PATCH_ERROR;
return PATCH_SUCCESS;
}
} else {
SetFilePointer(hPatch, patch_size, NULL, FILE_CURRENT);
}
}
//added by Koen - if already up to date, it doesn't matter that we didn't match
if(already_uptodate) {
return PATCH_UPTODATE;
} else {
return PATCH_NOMATCH;
}
}

View file

@ -0,0 +1,112 @@
# Microsoft Developer Studio Project File - Name="vpatchdll" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=vpatchdll - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "vpatchdll.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "vpatchdll.mak" CFG="vpatchdll - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "vpatchdll - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "vpatchdll - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "vpatchdll - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "vpatchdll_EXPORTS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "vpatchdll_EXPORTS" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /entry:"_DllMainCRTStartup" /dll /machine:I386 /nodefaultlib /out:"..\..\..\Plugins\VPatch.dll" /opt:nowin98
# SUBTRACT LINK32 /pdb:none
!ELSEIF "$(CFG)" == "vpatchdll - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "vpatchdll_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "vpatchdll_EXPORTS" /YX /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"Debug/VPatch.dll" /pdbtype:sept
!ENDIF
# Begin Target
# Name "vpatchdll - Win32 Release"
# Name "vpatchdll - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\vpatchdll.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\vpatchdll.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

View file

@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "vpatchdll"=.\vpatchdll.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

View file

@ -398,6 +398,18 @@ Section "Dialer" SecContribDialer
File ..\Contrib\Dialer\Dialer.txt
SectionEnd
Section "VPatch" SecContribVPatch
SectionIn 1 2
SetOutPath $INSTDIR\Plugins
File ..\Plugins\VPatch.dll
SetOutPath $INSTDIR\Contrib\VPatch
File ..\Contrib\VPatch\Readme.html
File ..\Contrib\VPatch\example.nsi
File ..\Contrib\VPatch\oldfile.txt
File ..\Contrib\VPatch\newfile.txt
File ..\Contrib\VPatch\patch.pat
SectionEnd
SubSectionEnd
Section "Zip2Exe" SecContribZ2E
@ -585,6 +597,14 @@ Section "Dialer Source" SecContribDialerS
File ..\Contrib\Dialer\dialer.dsw
SectionEnd
Section "VPatch Source" SecContribVPatchS
SectionIn 1
SetOutPath $INSTDIR\Contrib\VPatch
File ..\Contrib\VPatch\vpatchdll.c
File ..\Contrib\VPatch\vpatchdll.dsp
File ..\Contrib\VPatch\vpatchdll.dsw
SectionEnd
SubSectionEnd ; plugins
Section "Zip2Exe Source" SecContribZ2ES
@ -677,8 +697,8 @@ Section -post
Call AddWorkspaceToStartMenu
; InstallOptions
Push "InstallOptions\install options.html"
Push "InstallOptions readme"
Push "InstallOptions\Readme.html"
Push "InstallOptions Readme"
Call AddContribToStartMenu
Push "InstallOptions\io.dsw"
@ -694,7 +714,7 @@ Section -post
; Modern UI
Push "Modern UI\Readme.html"
Push "Modern UI readme"
Push "Modern UI Readme"
Call AddContribToStartMenu
; Splash
@ -761,6 +781,11 @@ Section -post
Push System\Source\System.sln
Push "Source\System project workspace"
Call AddContribToStartMenu
; VPatch
Push "VPatch\Readme.html"
Push "VPatch Readme"
Call AddContribToStartMenu
nofunshit:
!endif
@ -823,6 +848,8 @@ SectionEnd
!insertmacro MUI_DESCRIPTION_TEXT ${SecContribNSISDL} "Plugin that lets you create a web based installer"
!insertmacro MUI_DESCRIPTION_TEXT ${SecContribNSISDLS} "Source code to plugin that lets you create a web based installer"
!insertmacro MUI_DESCRIPTION_TEXT ${SecContribUiHolderS} "Source code to the UI Holder where you can put your recources in to preview your user interface"
!insertmacro MUI_DESCRIPTION_TEXT ${SecContribVPatch} "Plugin that lets you create patches to upgrade older files"
!insertmacro MUI_DESCRIPTION_TEXT ${SecContribVPatchS} "Source code to plugin that lets you create patches to upgrade older files"
!insertmacro MUI_DESCRIPTION_TEXT ${SecSrc} "Source code to NSIS and all related files"
!insertmacro MUI_DESCRIPTION_TEXT ${SecSrcNSIS} "Source code to NSIS"
!insertmacro MUI_DESCRIPTION_TEXT ${SecSrcContrib} "Source code to user contributed utilities"
@ -892,7 +919,7 @@ Function AddReadmeToStartMenu
IfFileExists $INSTDIR\Contrib\$0\Readme.txt 0 done
Push $0\Readme.txt
create:
Push "$0 readme"
Push "$0 Readme"
Call AddContribToStartMenu
done:
FunctionEnd

BIN
Plugins/VPatch.dll Normal file

Binary file not shown.