/
nsisUtils.c
executable file
·266 lines (229 loc) · 7.14 KB
/
nsisUtils.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
/* NSISutils contains various utility / useful functions
* that I've found useful for NSIS Plugins
* Each section is preceeded by its copyright and license
* information. Nothing more restrictive than NSIS
* license is used.
*
* Please note: all material here other than those by KJD
* have been taken from the respective author/copyright holder's
* work, do not contact them regarding these changes.
* Corrections/additions/ or information to obtain original
* versions, please contact me: jeremyd@computer.org
*
* Portions copyright:
* NullSoft, Tim Kosse
* Other portions (not copyrighted):
* KJD
*
*/
#include "nsisUtils.h" /* prototypes */
#include <commctrl.h> /* for listview stuff */
/* The following functions are from ExDLL.h
copyright NullSoft 2002,2003
*/
static unsigned int g_stringsize;
static stack_t **g_stacktop;
static TCHAR *g_variables;
#define EXDLL_INIT() { \
g_stringsize=string_size; \
g_stacktop=stacktop; \
g_variables=variables; }
/* utility functions (not required but often useful) */
int popstring(TCHAR *str)
{
stack_t *th;
if (!g_stacktop || !*g_stacktop) return 1;
th=(*g_stacktop);
_tcscpy(str,th->text);
*g_stacktop = th->next;
GlobalFree((HGLOBAL)th);
return 0;
}
void pushstring(TCHAR *str)
{
stack_t *th;
if (!g_stacktop) return;
th=(stack_t*)GlobalAlloc(GPTR,sizeof(stack_t)+g_stringsize);
_tcscpyn(th->text,str,g_stringsize);
th->next=*g_stacktop;
*g_stacktop=th;
}
TCHAR *getuservariable(int varnum)
{
if (varnum < 0 || varnum >= __INST_LAST) return NULL;
return g_variables+varnum*g_stringsize;
}
void setuservariable(int varnum, TCHAR *var)
{
if (var != NULL && varnum >= 0 && varnum < __INST_LAST)
_tcscpy(g_variables + varnum*g_stringsize, var);
}
/* The following functions from UnTGZ NSIS plugin:
KJD No copyright (other than that from NSIS & zlib & ExtractDLL)
*/
// each exported function should call this (unless you can guarentee its already been done)
//pluginInit(hwndParent, string_size, variables, stacktop);
void pluginInit(HWND hwndParent, int string_size, TCHAR *variables, stack_t **stacktop)
{
g_hwndParent=hwndParent;
g_hwndList = FindWindowEx(FindWindowEx(g_hwndParent,NULL,_T("#32770"),NULL),NULL,_T("SysListView32"),NULL);
EXDLL_INIT();
}
/*
* more printf like variant of below LogMessage from Tim (upon which it requires)
*/
void _cdecl PrintMessage(const TCHAR *msg, ...)
{
TCHAR buf[1024];
va_list argptr;
va_start(argptr, msg);
wvsprintf (buf, msg, argptr);
va_end(argptr);
DetailPrint(buf);
}
/*
// cheat a little with argument stack
// copies current stack item to str, where current top of
// stack is determined by stacktop (use NULL to get top of
// stack as popstring sees)
// returns a pointer to the next item on the argument stack
*/
stack_t * peekstring(TCHAR *str, stack_t *stacktop)
{
if (stacktop == NULL) stacktop = *g_stacktop;
if (!stacktop) return NULL;
_tcscpy(str,stacktop->text);
return stacktop->next;
}
/*
// fill in a char* list[] and its count with arguments up to
// next argument (-<arg>) or end of stack.
// returns 0 on success, nonzero on error
*/
int getArgList(int *argCnt, char **argList[], TCHAR *cmdline)
{
int cnt;
char **list;
TCHAR buf[1024];
register int i;
stack_t * stkptr = *g_stacktop;
/* some sanity checking */
if (argList == NULL)
{
PrintMessage(_T(__FILE__) _T("::getArgList() called with argList == NULL"));
return -1;
}
if (argCnt == NULL)
{
PrintMessage(_T(__FILE__) _T("::getArgList() called with argCnt == NULL"));
return -2;
}
cnt = *argCnt = 0;
list = NULL;
*argList = NULL;
*buf = (TCHAR)'\0';
// loop through until end of stack or next option found
while ( stkptr && (*buf != (TCHAR)'-') )
{
stkptr = peekstring(buf, stkptr);
cnt++;
}
if (*buf == (TCHAR)'-') cnt--;
if (cnt > 0)
{
if ((list = (char **)malloc(cnt * sizeof(char *))) == NULL)
{
PrintMessage(_T("WARNING: ") _T(__FILE__) _T("::getArgList() Unable to allocate memory required!"));
return 1;
}
for (i = 0; i < cnt; i++)
{
if (popstring(buf))
{
/* free all the memory we have allocated */
int j;
for (j = 0; j < i; j++)
if (list[j] != NULL) free(list[j]);
free(list);
PrintMessage(_T("WARNING: NSIS stack in undefined state!"));
return 2;
}
_tcscat(cmdline, _T("'"));
_tcscat(cmdline, buf);
_tcscat(cmdline, _T("' "));
list[i] = (char *)malloc((_tcslen(buf)+1)*sizeof(char));
if (list[i] == NULL)
{
/* free all the memory we have allocated */
int j;
for (j = 0; j < i; j++)
if (list[j] != NULL) free(list[j]);
free(list);
/* finish popping the stack so its in a known state */
for ( ; i < cnt; i++)
popstring(buf);
PrintMessage(_T("WARNING: ") _T(__FILE__) _T("::getArgList() Unable to allocate memory required!"));
return 3;
}
strcpy(list[i], _T2A(buf));
}
}
else if (cnt < 0)
{
PrintMessage(_T(__FILE__) _T("::getArgList() Internal Error: cnt < 0"));
return 333;
}
*argList = list;
*argCnt = cnt;
return 0;
}
/* End KJD's Functions */
/*
The following portions from [based upon] code in ExtractDLL NSIS plugin:
Copyright 2002
by Tim Kosse
tim.kosse@gmx.de
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 source 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 source distribution.
*/
int SetStatus(const TCHAR *pStr)
{
HWND hwndCtrl=GetDlgItem(g_hwndList, 1006);
if (hwndCtrl)
{
SetWindowText(hwndCtrl, pStr);
}
PrintMessage(pStr);
return 0;
}
/*
* Displays a message in NSIS details window, roughly the same as NSIS' DetailPrint
*/
void DetailPrint(const TCHAR *pStr) /* LogMessage() */
{
if (!g_hwndList) return;
if (!lstrlen(pStr)) return;
{
LVITEM item={0};
int nItemCount=SendMessage(g_hwndList, LVM_GETITEMCOUNT, 0, 0);
item.mask=LVIF_TEXT;
item.pszText=(TCHAR *)pStr;
item.cchTextMax=0; /* =6 */
item.iItem=nItemCount;
/* SendMessage(g_hwndList, LVM_INSERTITEM, 0, (LPARAM)&item); */
ListView_InsertItem(g_hwndList, &item);
ListView_EnsureVisible(g_hwndList, item.iItem, 0);
}
}
/* End Tim's Functions */