Adding Unicode support to System plugin
git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6050 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
parent
9852de80be
commit
57d296e159
5 changed files with 1348 additions and 1252 deletions
|
@ -1,3 +1,5 @@
|
||||||
|
// Unicode support by Jim Park -- 08/23/2007
|
||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "Plugin.h"
|
#include "Plugin.h"
|
||||||
#include "System.h"
|
#include "System.h"
|
||||||
|
@ -23,6 +25,18 @@ PLUGINFUNCTIONSHORT(Alloc)
|
||||||
}
|
}
|
||||||
PLUGINFUNCTIONEND
|
PLUGINFUNCTIONEND
|
||||||
|
|
||||||
|
PLUGINFUNCTIONSHORT(StrAlloc)
|
||||||
|
{
|
||||||
|
int size;
|
||||||
|
if ((size = popint64()) == 0)
|
||||||
|
{
|
||||||
|
system_pushint(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
system_pushint((int) GlobalAlloc(GPTR, size * sizeof(TCHAR)));
|
||||||
|
}
|
||||||
|
PLUGINFUNCTIONEND
|
||||||
|
|
||||||
PLUGINFUNCTIONSHORT(Copy)
|
PLUGINFUNCTIONSHORT(Copy)
|
||||||
{
|
{
|
||||||
int size = 0;
|
int size = 0;
|
||||||
|
|
|
@ -14,7 +14,7 @@ TCHAR *AllocString()
|
||||||
|
|
||||||
TCHAR *AllocStr(TCHAR *str)
|
TCHAR *AllocStr(TCHAR *str)
|
||||||
{
|
{
|
||||||
return lstrcpy(AllocString(), str);
|
return lstrcpyn(AllocString(), str, g_stringsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
TCHAR* system_popstring()
|
TCHAR* system_popstring()
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
// System.cpp : Defines the entry point for the DLL application.
|
// System.cpp : Defines the entry point for the DLL application.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
// Unicode support by Jim Park & Olivier Marcoux
|
||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "Plugin.h"
|
#include "Plugin.h"
|
||||||
#include "Buffers.h"
|
#include "Buffers.h"
|
||||||
|
@ -37,6 +39,16 @@ const int ParamSizeByType[7] = {0, // PAT_VOID (Size will be equal to 1)
|
||||||
1, // PAT_GUID
|
1, // PAT_GUID
|
||||||
0}; // PAT_CALLBACK (Size will be equal to 1)
|
0}; // PAT_CALLBACK (Size will be equal to 1)
|
||||||
|
|
||||||
|
// Thomas needs to look at this.
|
||||||
|
const int ByteSizeByType[7] = {
|
||||||
|
1, // PAT_VOID
|
||||||
|
1, // PAT_INT
|
||||||
|
1, // PAT_LONG
|
||||||
|
1, // PAT_STRING
|
||||||
|
2, // PAT_WSTRING (special case for &wN notation: N is a number of WCHAR, not a number of bytes)
|
||||||
|
1, // PAT_GUID
|
||||||
|
1}; // PAT_CALLBACK
|
||||||
|
|
||||||
int LastStackPlace;
|
int LastStackPlace;
|
||||||
int LastStackReal;
|
int LastStackReal;
|
||||||
DWORD LastError;
|
DWORD LastError;
|
||||||
|
@ -151,6 +163,34 @@ PLUGINFUNCTION(Debug)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function is useful for Unicode support. Since the Windows
|
||||||
|
* GetProcAddress function always takes a char*, this function wraps
|
||||||
|
* the windows call and does the appropriate translation when
|
||||||
|
* appropriate.
|
||||||
|
*
|
||||||
|
* @param dllHandle Handle to the DLL loaded by LoadLibraryEx.
|
||||||
|
* @param funcName The name of the function to get the address of.
|
||||||
|
* @return The pointer to the function. Null if failure.
|
||||||
|
*/
|
||||||
|
void * NSISGetProcAddress(HMODULE dllHandle, TCHAR* funcName)
|
||||||
|
{
|
||||||
|
#ifdef _UNICODE
|
||||||
|
char* ansiName = NULL;
|
||||||
|
int len;
|
||||||
|
void* funcPtr = NULL;
|
||||||
|
|
||||||
|
len = WideCharToMultiByte(CP_ACP, 0, funcName, -1, ansiName, 0, NULL, NULL);
|
||||||
|
ansiName = (char*) GlobalAlloc(GPTR, len);
|
||||||
|
WideCharToMultiByte(CP_ACP, 0, funcName, -1, ansiName, len, NULL, NULL);
|
||||||
|
funcPtr = GetProcAddress(dllHandle, ansiName);
|
||||||
|
GlobalFree(ansiName);
|
||||||
|
return funcPtr;
|
||||||
|
#else
|
||||||
|
return GetProcAddress(dllHandle, funcName);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
PLUGINFUNCTIONSHORT(Free)
|
PLUGINFUNCTIONSHORT(Free)
|
||||||
{
|
{
|
||||||
HANDLE memtofree = (HANDLE)popint64();
|
HANDLE memtofree = (HANDLE)popint64();
|
||||||
|
@ -265,7 +305,7 @@ PLUGINFUNCTION(Call)
|
||||||
|
|
||||||
// Return result instead of return value
|
// Return result instead of return value
|
||||||
proc->Params[0].Value = (int) GetResultStr(proc);
|
proc->Params[0].Value = (int) GetResultStr(proc);
|
||||||
proc->Params[0].Type = PAT_STRING;
|
proc->Params[0].Type = PAT_TSTRING;
|
||||||
// Return all params
|
// Return all params
|
||||||
ParamsOut(proc);
|
ParamsOut(proc);
|
||||||
|
|
||||||
|
@ -559,7 +599,7 @@ SystemProc *PrepareProc(BOOL NeedForCall)
|
||||||
case _T('m'):
|
case _T('m'):
|
||||||
case _T('M'): temp2 = PAT_STRING; break;
|
case _T('M'): temp2 = PAT_STRING; break;
|
||||||
case _T('t'):
|
case _T('t'):
|
||||||
case _T('T'): temp2 = PAT_STRING; break; // will be PAT_WSTRING for Unicode NSIS
|
case _T('T'): temp2 = PAT_TSTRING; break;
|
||||||
case _T('g'):
|
case _T('g'):
|
||||||
case _T('G'): temp2 = PAT_GUID; break;
|
case _T('G'): temp2 = PAT_GUID; break;
|
||||||
case _T('w'):
|
case _T('w'):
|
||||||
|
@ -761,7 +801,7 @@ SystemProc *PrepareProc(BOOL NeedForCall)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get proc address
|
// Get proc address
|
||||||
if ((proc->Proc = GetProcAddress(proc->Dll, proc->ProcName)) == NULL)
|
if ((proc->Proc = NSISGetProcAddress(proc->Dll, proc->ProcName)) == NULL)
|
||||||
{
|
{
|
||||||
#ifdef _UNICODE
|
#ifdef _UNICODE
|
||||||
// automatic W discover
|
// automatic W discover
|
||||||
|
@ -770,7 +810,7 @@ SystemProc *PrepareProc(BOOL NeedForCall)
|
||||||
// automatic A discover
|
// automatic A discover
|
||||||
lstrcat(proc->ProcName, "A");
|
lstrcat(proc->ProcName, "A");
|
||||||
#endif
|
#endif
|
||||||
if ((proc->Proc = GetProcAddress(proc->Dll, proc->ProcName)) == NULL)
|
if ((proc->Proc = NSISGetProcAddress(proc->Dll, proc->ProcName)) == NULL)
|
||||||
proc->ProcResult = PR_ERROR;
|
proc->ProcResult = PR_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -797,7 +837,8 @@ void ParamAllocate(SystemProc *proc)
|
||||||
|
|
||||||
void ParamsIn(SystemProc *proc)
|
void ParamsIn(SystemProc *proc)
|
||||||
{
|
{
|
||||||
int i, *place;
|
int i;
|
||||||
|
HGLOBAL* place;
|
||||||
TCHAR *realbuf;
|
TCHAR *realbuf;
|
||||||
LPWSTR wstr;
|
LPWSTR wstr;
|
||||||
|
|
||||||
|
@ -819,8 +860,8 @@ void ParamsIn(SystemProc *proc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retreive pointer to place
|
// Retreive pointer to place
|
||||||
if (par->Option == -1) place = (int*) par->Value;
|
if (par->Option == -1) place = (HGLOBAL*) par->Value;
|
||||||
else place = (int*) &(par->Value);
|
else place = (HGLOBAL*) &(par->Value);
|
||||||
|
|
||||||
// by default no blocks are allocated
|
// by default no blocks are allocated
|
||||||
par->allocatedBlock = NULL;
|
par->allocatedBlock = NULL;
|
||||||
|
@ -832,29 +873,40 @@ void ParamsIn(SystemProc *proc)
|
||||||
par->Value = 0;
|
par->Value = 0;
|
||||||
break;
|
break;
|
||||||
case PAT_INT:
|
case PAT_INT:
|
||||||
*((int*) place) = (int) myatoi64(realbuf);
|
*(int*)place = (int) myatoi64(realbuf);
|
||||||
break;
|
break;
|
||||||
case PAT_LONG:
|
case PAT_LONG:
|
||||||
*((__int64*) place) = myatoi64(realbuf);
|
*(__int64*)place = myatoi64(realbuf);
|
||||||
break;
|
break;
|
||||||
case PAT_STRING:
|
case PAT_TSTRING:
|
||||||
/* if (par->Input == IOT_NONE)
|
/* if (par->Input == IOT_NONE)
|
||||||
*((int*) place) = (int) NULL;
|
*((int*) place) = (int) NULL;
|
||||||
else*/
|
else*/
|
||||||
*((int*) place) = (int) (par->allocatedBlock = AllocStr(realbuf));
|
*place = par->allocatedBlock = AllocStr(realbuf);
|
||||||
break;
|
break;
|
||||||
|
#ifdef _UNICODE
|
||||||
|
case PAT_STRING:
|
||||||
|
*place = par->allocatedBlock = GlobalAlloc(GPTR, g_stringsize);
|
||||||
|
WideCharToMultiByte(CP_ACP, 0, realbuf, g_stringsize, *(LPSTR*)place, g_stringsize, NULL, NULL);
|
||||||
|
break;
|
||||||
|
case PAT_GUID:
|
||||||
|
*place = par->allocatedBlock = GlobalAlloc(GPTR, 16);
|
||||||
|
CLSIDFromString(realbuf, *(LPCLSID*)place);
|
||||||
|
break;
|
||||||
|
#else
|
||||||
case PAT_WSTRING:
|
case PAT_WSTRING:
|
||||||
case PAT_GUID:
|
case PAT_GUID:
|
||||||
wstr = (LPWSTR) (par->allocatedBlock = GlobalAlloc(GPTR, g_stringsize*sizeof(WCHAR)));
|
wstr = (LPWSTR) GlobalAlloc(GPTR, g_stringsize*sizeof(WCHAR));
|
||||||
MultiByteToWideChar(CP_ACP, 0, realbuf, g_stringsize, wstr, g_stringsize);
|
MultiByteToWideChar(CP_ACP, 0, realbuf, g_stringsize, wstr, g_stringsize);
|
||||||
if (par->Type == PAT_GUID)
|
if (par->Type == PAT_GUID)
|
||||||
{
|
{
|
||||||
*((HGLOBAL*)place) = (par->allocatedBlock = GlobalAlloc(GPTR, 16));
|
*place = par->allocatedBlock = GlobalAlloc(GPTR, 16);
|
||||||
CLSIDFromString(wstr, *((LPCLSID*)place));
|
CLSIDFromString(wstr, *(LPCLSID*)place);
|
||||||
GlobalFree((HGLOBAL) wstr);
|
GlobalFree((HGLOBAL) wstr);
|
||||||
} else
|
} else
|
||||||
*((LPWSTR*)place) = wstr;
|
*place = par->allocatedBlock = (HGLOBAL)wstr;
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
case PAT_CALLBACK:
|
case PAT_CALLBACK:
|
||||||
// Generate new or use old callback
|
// Generate new or use old callback
|
||||||
if (lstrlen(realbuf) > 0)
|
if (lstrlen(realbuf) > 0)
|
||||||
|
@ -918,22 +970,31 @@ void ParamsOut(SystemProc *proc)
|
||||||
myitoa64(*((__int64*) place), realbuf);
|
myitoa64(*((__int64*) place), realbuf);
|
||||||
break;
|
break;
|
||||||
case PAT_STRING:
|
case PAT_STRING:
|
||||||
{
|
#ifdef _UNICODE
|
||||||
unsigned int num = lstrlen(*((TCHAR**) place));
|
MultiByteToWideChar(CP_ACP, 0, *((char**) place), g_stringsize, realbuf, g_stringsize-1);
|
||||||
if (num >= g_stringsize) num = g_stringsize-1;
|
realbuf[g_stringsize-1] = _T('\0'); // make sure we have a null terminator
|
||||||
lstrcpyn(realbuf,*((TCHAR**) place), num+1);
|
#else
|
||||||
realbuf[num] = 0;
|
lstrcpyn(realbuf,*((TCHAR**) place), g_stringsize); // note: lstrcpyn always include a null terminator (unlike strncpy)
|
||||||
}
|
#endif
|
||||||
break;
|
break;
|
||||||
case PAT_GUID:
|
case PAT_GUID:
|
||||||
|
#ifdef _UNICODE
|
||||||
|
StringFromGUID2(*((REFGUID*)place), realbuf, g_stringsize);
|
||||||
|
#else
|
||||||
wstr = (LPWSTR) GlobalAlloc(GPTR, g_stringsize*2);
|
wstr = (LPWSTR) GlobalAlloc(GPTR, g_stringsize*2);
|
||||||
StringFromGUID2(*((REFGUID*)place), wstr, g_stringsize);
|
StringFromGUID2(*((REFGUID*)place), wstr, g_stringsize);
|
||||||
WideCharToMultiByte(CP_ACP, 0, wstr, g_stringsize, realbuf, g_stringsize, NULL, NULL);
|
WideCharToMultiByte(CP_ACP, 0, wstr, g_stringsize, realbuf, g_stringsize, NULL, NULL);
|
||||||
GlobalFree((HGLOBAL)wstr);
|
GlobalFree((HGLOBAL)wstr);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
case PAT_WSTRING:
|
case PAT_WSTRING:
|
||||||
wstr = *((LPWSTR*)place);
|
wstr = *((LPWSTR*)place);
|
||||||
WideCharToMultiByte(CP_ACP, 0, wstr, g_stringsize, realbuf, g_stringsize, NULL, NULL);
|
#ifdef _UNICODE
|
||||||
|
lstrcpyn(realbuf, wstr, g_stringsize); // note: lstrcpyn always include a null terminator (unlike strncpy)
|
||||||
|
#else
|
||||||
|
WideCharToMultiByte(CP_ACP, 0, wstr, g_stringsize, realbuf, g_stringsize-1, NULL, NULL);
|
||||||
|
realbuf[g_stringsize-1] = _T('\0'); // make sure we have a null terminator
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
case PAT_CALLBACK:
|
case PAT_CALLBACK:
|
||||||
wsprintf(realbuf, _T("%d"), proc->Params[i].Value);
|
wsprintf(realbuf, _T("%d"), proc->Params[i].Value);
|
||||||
|
@ -1002,7 +1063,7 @@ void CallStruct(SystemProc *proc)
|
||||||
if (proc->Params[i].Option < 1)
|
if (proc->Params[i].Option < 1)
|
||||||
structsize += proc->Params[i].Size * 4;
|
structsize += proc->Params[i].Size * 4;
|
||||||
else
|
else
|
||||||
structsize += proc->Params[i].Option-1;
|
structsize += ByteSizeByType[proc->Params[i].Type] * (proc->Params[i].Option - 1);
|
||||||
|
|
||||||
// Struct exists?
|
// Struct exists?
|
||||||
if (proc->Proc == NULL)
|
if (proc->Proc == NULL)
|
||||||
|
@ -1030,7 +1091,7 @@ void CallStruct(SystemProc *proc)
|
||||||
int intmask[4] = {0xFFFFFFFF, 0x000000FF, 0x0000FFFF, 0x00FFFFFF};
|
int intmask[4] = {0xFFFFFFFF, 0x000000FF, 0x0000FFFF, 0x00FFFFFF};
|
||||||
|
|
||||||
// Special
|
// Special
|
||||||
size = proc->Params[i].Option-1;
|
size = (proc->Params[i].Option-1) * ByteSizeByType[proc->Params[i].Type];
|
||||||
|
|
||||||
switch (proc->Params[i].Type)
|
switch (proc->Params[i].Type)
|
||||||
{
|
{
|
||||||
|
|
|
@ -47,6 +47,11 @@
|
||||||
#define PAT_WSTRING 4
|
#define PAT_WSTRING 4
|
||||||
#define PAT_GUID 5
|
#define PAT_GUID 5
|
||||||
#define PAT_CALLBACK 6
|
#define PAT_CALLBACK 6
|
||||||
|
#ifdef _UNICODE
|
||||||
|
#define PAT_TSTRING PAT_WSTRING
|
||||||
|
#else
|
||||||
|
#define PAT_TSTRING PAT_STRING
|
||||||
|
#endif
|
||||||
|
|
||||||
// Input/Output Source/Destination
|
// Input/Output Source/Destination
|
||||||
#define IOT_NONE 0
|
#define IOT_NONE 0
|
||||||
|
|
|
@ -64,7 +64,19 @@ System::Free $0
|
||||||
</pre></blockquote>
|
</pre></blockquote>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<b>StrAlloc</b> <i>SIZE</i>
|
||||||
|
<blockquote>
|
||||||
|
<p>Allocates a string buffer for <i>SIZE</i> <b>TCHARs</b> and returns a memory address on the stack. This is extremely useful if you want to write an NSI script that will work for both ANSI and Unicode NSIS.</p>
|
||||||
|
<h4>Usage Example</h4>
|
||||||
|
<blockquote><pre>
|
||||||
|
System::<b>StrAlloc</b> 64 ; String buffer for 63 characters and \0 termination.
|
||||||
|
Pop $0
|
||||||
|
DetailPrint "A string buffer for 64 characters allocated at $0"
|
||||||
|
System::Free $0
|
||||||
|
</pre></blockquote>
|
||||||
|
</blockquote>
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<b>Copy</b> [/<i>SIZE</i>] <i>DESTINATION</i> <i>SOURCE</i>
|
<b>Copy</b> [/<i>SIZE</i>] <i>DESTINATION</i> <i>SOURCE</i>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
|
@ -283,11 +295,15 @@ DetailPrint $4
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>&t<i>N</i></th>
|
<th>&t<i>N</i></th>
|
||||||
<td><i>N</i> bytes of text (structures only)</td>
|
<td>array of <i>N</i> text characters TCHAR (structures only)</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>&m<i>N</i></th>
|
||||||
|
<td>array of <i>N</i> ANSI characters CHAR (structures only)</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>&w<i>N</i></th>
|
<th>&w<i>N</i></th>
|
||||||
<td><i>N</i> bytes of Unicode text (structures only)</td>
|
<td>array of <i>N</i> Unicode characters WCHAR (structures only)</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>&g<i>N</i></th>
|
<th>&g<i>N</i></th>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue