|
1 // Unicode support added by Jim Park -- 07/27/2007 |
|
2 // Unicode support requires that all plugins take TCHARs instead as well. This |
|
3 // means existing plugins will not work for the Unicode version of NSIS unless |
|
4 // recompiled. You have been warned. |
|
5 |
|
6 #ifndef _EXDLL_H_ |
|
7 #define _EXDLL_H_ |
|
8 |
|
9 #include <windows.h> |
|
10 #include "tchar.h" |
|
11 |
|
12 #if defined(__GNUC__) |
|
13 #define UNUSED __attribute__((unused)) |
|
14 #else |
|
15 #define UNUSED |
|
16 #endif |
|
17 |
|
18 // only include this file from one place in your DLL. |
|
19 // (it is all static, if you use it in two places it will fail) |
|
20 |
|
21 #define EXDLL_INIT() { \ |
|
22 g_stringsize=string_size; \ |
|
23 g_stacktop=stacktop; \ |
|
24 g_variables=variables; } |
|
25 |
|
26 // For page showing plug-ins |
|
27 #define WM_NOTIFY_OUTER_NEXT (WM_USER+0x8) |
|
28 #define WM_NOTIFY_CUSTOM_READY (WM_USER+0xd) |
|
29 |
|
30 /* Jim Park: This char is compared as an int value and therefore |
|
31 it's fine as an ASCII. Do not need to change to wchar_t since |
|
32 it will get the same integer value. */ |
|
33 #define NOTIFY_BYE_BYE _T('x') |
|
34 |
|
35 typedef struct _stack_t { |
|
36 struct _stack_t *next; |
|
37 TCHAR text[1]; // this should be the length of string_size |
|
38 } stack_t; |
|
39 |
|
40 |
|
41 static unsigned int g_stringsize; |
|
42 static stack_t **g_stacktop; |
|
43 static TCHAR *g_variables; |
|
44 |
|
45 static int __stdcall popstring(TCHAR *str) UNUSED; // 0 on success, 1 on empty stack |
|
46 static void __stdcall pushstring(const TCHAR *str) UNUSED; |
|
47 static TCHAR * __stdcall getuservariable(const int varnum) UNUSED; |
|
48 static void __stdcall setuservariable(const int varnum, const TCHAR *var) UNUSED; |
|
49 |
|
50 enum |
|
51 { |
|
52 INST_0, // $0 |
|
53 INST_1, // $1 |
|
54 INST_2, // $2 |
|
55 INST_3, // $3 |
|
56 INST_4, // $4 |
|
57 INST_5, // $5 |
|
58 INST_6, // $6 |
|
59 INST_7, // $7 |
|
60 INST_8, // $8 |
|
61 INST_9, // $9 |
|
62 INST_R0, // $R0 |
|
63 INST_R1, // $R1 |
|
64 INST_R2, // $R2 |
|
65 INST_R3, // $R3 |
|
66 INST_R4, // $R4 |
|
67 INST_R5, // $R5 |
|
68 INST_R6, // $R6 |
|
69 INST_R7, // $R7 |
|
70 INST_R8, // $R8 |
|
71 INST_R9, // $R9 |
|
72 INST_CMDLINE, // $CMDLINE |
|
73 INST_INSTDIR, // $INSTDIR |
|
74 INST_OUTDIR, // $OUTDIR |
|
75 INST_EXEDIR, // $EXEDIR |
|
76 INST_LANG, // $LANGUAGE |
|
77 __INST_LAST |
|
78 }; |
|
79 |
|
80 typedef struct { |
|
81 int autoclose; |
|
82 int all_user_var; |
|
83 int exec_error; |
|
84 int abort; |
|
85 int exec_reboot; |
|
86 int reboot_called; |
|
87 int XXX_cur_insttype; // deprecated |
|
88 int XXX_insttype_changed; // deprecated |
|
89 int silent; |
|
90 int instdir_error; |
|
91 int rtl; |
|
92 int errlvl; |
|
93 int alter_reg_view; |
|
94 int status_update; |
|
95 } exec_flags_type; |
|
96 |
|
97 typedef struct { |
|
98 exec_flags_type *exec_flags; |
|
99 int (__stdcall *ExecuteCodeSegment)(int, HWND); |
|
100 void (__stdcall *validate_filename)(TCHAR *); |
|
101 } extra_parameters; |
|
102 |
|
103 // utility functions (not required but often useful) |
|
104 static int __stdcall popstring(TCHAR *str) |
|
105 { |
|
106 stack_t *th; |
|
107 if (!g_stacktop || !*g_stacktop) return 1; |
|
108 th=(*g_stacktop); |
|
109 lstrcpy(str,th->text); |
|
110 *g_stacktop = th->next; |
|
111 GlobalFree((HGLOBAL)th); |
|
112 return 0; |
|
113 } |
|
114 |
|
115 static void __stdcall pushstring(const TCHAR *str) |
|
116 { |
|
117 stack_t *th; |
|
118 if (!g_stacktop) return; |
|
119 th=(stack_t*)GlobalAlloc(GPTR,(sizeof(stack_t)+(g_stringsize)*sizeof(TCHAR))); |
|
120 lstrcpyn(th->text,str,g_stringsize); |
|
121 th->next=*g_stacktop; |
|
122 *g_stacktop=th; |
|
123 } |
|
124 |
|
125 static TCHAR * __stdcall getuservariable(const int varnum) |
|
126 { |
|
127 if (varnum < 0 || varnum >= __INST_LAST) return NULL; |
|
128 return g_variables+varnum*g_stringsize; |
|
129 } |
|
130 |
|
131 static void __stdcall setuservariable(const int varnum, const TCHAR *var) |
|
132 { |
|
133 if (var != NULL && varnum >= 0 && varnum < __INST_LAST) |
|
134 lstrcpy(g_variables + varnum*g_stringsize, var); |
|
135 } |
|
136 |
|
137 #ifdef _UNICODE |
|
138 #define PopStringW(x) popstring(x) |
|
139 #define PushStringW(x) pushstring(x) |
|
140 #define SetUserVariableW(x,y) setuservariable(x,y) |
|
141 |
|
142 static int __stdcall PopStringA(char* ansiStr) |
|
143 { |
|
144 wchar_t* wideStr = (wchar_t*) GlobalAlloc(GPTR, g_stringsize*sizeof(wchar_t)); |
|
145 int rval = popstring(wideStr); |
|
146 WideCharToMultiByte(CP_ACP, 0, wideStr, -1, ansiStr, g_stringsize, NULL, NULL); |
|
147 GlobalFree((HGLOBAL)wideStr); |
|
148 return rval; |
|
149 } |
|
150 |
|
151 static void __stdcall PushStringA(const char* ansiStr) |
|
152 { |
|
153 wchar_t* wideStr = (wchar_t*) GlobalAlloc(GPTR, g_stringsize*sizeof(wchar_t)); |
|
154 MultiByteToWideChar(CP_ACP, 0, ansiStr, -1, wideStr, g_stringsize); |
|
155 pushstring(wideStr); |
|
156 GlobalFree((HGLOBAL)wideStr); |
|
157 return; |
|
158 } |
|
159 |
|
160 static void __stdcall GetUserVariableW(const int varnum, wchar_t* wideStr) |
|
161 { |
|
162 lstrcpyW(wideStr, getuservariable(varnum)); |
|
163 } |
|
164 |
|
165 static void __stdcall GetUserVariableA(const int varnum, char* ansiStr) |
|
166 { |
|
167 wchar_t* wideStr = getuservariable(varnum); |
|
168 WideCharToMultiByte(CP_ACP, 0, wideStr, -1, ansiStr, g_stringsize, NULL, NULL); |
|
169 } |
|
170 |
|
171 static void __stdcall SetUserVariableA(const int varnum, const char* ansiStr) |
|
172 { |
|
173 if (ansiStr != NULL && varnum >= 0 && varnum < __INST_LAST) |
|
174 { |
|
175 wchar_t* wideStr = g_variables + varnum * g_stringsize; |
|
176 MultiByteToWideChar(CP_ACP, 0, ansiStr, -1, wideStr, g_stringsize); |
|
177 } |
|
178 } |
|
179 |
|
180 #else |
|
181 // ANSI defs |
|
182 |
|
183 #define PopStringA(x) popstring(x) |
|
184 #define PushStringA(x) pushstring(x) |
|
185 #define SetUserVariableA(x,y) setuservariable(x,y) |
|
186 |
|
187 static int __stdcall PopStringW(wchar_t* wideStr) |
|
188 { |
|
189 char* ansiStr = (char*) GlobalAlloc(GPTR, g_stringsize); |
|
190 int rval = popstring(ansiStr); |
|
191 MultiByteToWideChar(CP_ACP, 0, ansiStr, -1, wideStr, g_stringsize); |
|
192 GlobalFree((HGLOBAL)ansiStr); |
|
193 return rval; |
|
194 } |
|
195 |
|
196 static void __stdcall PushStringW(wchar_t* wideStr) |
|
197 { |
|
198 char* ansiStr = (char*) GlobalAlloc(GPTR, g_stringsize); |
|
199 WideCharToMultiByte(CP_ACP, 0, wideStr, -1, ansiStr, g_stringsize, NULL, NULL); |
|
200 pushstring(ansiStr); |
|
201 GlobalFree((HGLOBAL)ansiStr); |
|
202 } |
|
203 |
|
204 static void __stdcall GetUserVariableW(const int varnum, wchar_t* wideStr) |
|
205 { |
|
206 char* ansiStr = getuservariable(varnum); |
|
207 MultiByteToWideChar(CP_ACP, 0, ansiStr, -1, wideStr, g_stringsize); |
|
208 } |
|
209 |
|
210 static void __stdcall GetUserVariableA(const int varnum, char* ansiStr) |
|
211 { |
|
212 lstrcpyA(ansiStr, getuservariable(varnum)); |
|
213 } |
|
214 |
|
215 static void __stdcall SetUserVariableW(const int varnum, const wchar_t* wideStr) |
|
216 { |
|
217 if (wideStr != NULL && varnum >= 0 && varnum < __INST_LAST) |
|
218 { |
|
219 char* ansiStr = g_variables + varnum * g_stringsize; |
|
220 WideCharToMultiByte(CP_ACP, 0, wideStr, -1, ansiStr, g_stringsize, NULL, NULL); |
|
221 } |
|
222 } |
|
223 #endif |
|
224 |
|
225 static BOOL __stdcall IsUnicode(void) |
|
226 { |
|
227 #ifdef _UNICODE |
|
228 return TRUE; |
|
229 #else |
|
230 return FALSE; |
|
231 #endif |
|
232 } |
|
233 |
|
234 #endif//_EXDLL_H_ |