System plugin: Basic x64 fixes

git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6222 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
anders_k 2012-03-06 23:09:23 +00:00
parent adbdce4c47
commit 8aa67f8987
5 changed files with 68 additions and 54 deletions

View file

@ -13,27 +13,26 @@ struct tagTempStack
}; };
TempStack *tempstack = NULL; TempStack *tempstack = NULL;
PLUGINFUNCTIONSHORT(Alloc) static void AllocWorker(unsigned int mult)
{ {
int size; int size;
if ((size = popint64()) == 0) if ((size = popint()) == 0)
{ {
system_pushint(0); system_pushint(0);
return; return;
} }
system_pushint((int) GlobalAlloc(GPTR, size)); system_pushintptr((INT_PTR) GlobalAlloc(GPTR, size * mult));
}
PLUGINFUNCTIONSHORT(Alloc)
{
AllocWorker(sizeof(unsigned char));
} }
PLUGINFUNCTIONEND PLUGINFUNCTIONEND
PLUGINFUNCTIONSHORT(StrAlloc) PLUGINFUNCTIONSHORT(StrAlloc)
{ {
int size; AllocWorker(sizeof(TCHAR));
if ((size = popint64()) == 0)
{
system_pushint(0);
return;
}
system_pushint((int) GlobalAlloc(GPTR, size * sizeof(TCHAR)));
} }
PLUGINFUNCTIONEND PLUGINFUNCTIONEND
@ -48,19 +47,19 @@ PLUGINFUNCTIONSHORT(Copy)
// Check for size option // Check for size option
if (str[0] == _T('/')) if (str[0] == _T('/'))
{ {
size = (int) myatoi64(str+1); size = (SIZE_T) myatoi(str+1);
dest = (HANDLE) popint64(); dest = (HANDLE) popintptr();
} }
else dest = (HANDLE) myatoi64(str); else dest = (HANDLE) myatoi(str);
source = (HANDLE) popint64(); source = (HANDLE) popintptr();
// Ok, check the size // Ok, check the size
if (size == 0) size = (int) GlobalSize(source); if (size == 0) size = (SIZE_T) GlobalSize(source);
// and the destinantion // and the destinantion
if ((int) dest == 0) if ((int) dest == 0)
{ {
dest = GlobalAlloc((GPTR), size); dest = GlobalAlloc((GPTR), size);
system_pushint((int) dest); system_pushintptr((INT_PTR) dest);
} }
// COPY! // COPY!

View file

@ -134,21 +134,21 @@ void myitoa64(__int64 i, TCHAR *buffer)
*buffer = 0; *buffer = 0;
} }
int popint64() int system_popint()
{ {
int value; int value;
TCHAR *str; TCHAR *str;
if ((str = system_popstring()) == NULL) return -1; if ((str = system_popstring()) == NULL) return -1;
value = (int) myatoi64(str); value = myatoi(str);
GlobalFree(str); GlobalFree(str);
return value; return value;
} }
void system_pushint(int value) void system_pushint(int value)
{ {
TCHAR buffer[1024]; TCHAR buffer[80];
wsprintf(buffer, _T("%d"), value); wsprintf(buffer, _T("%d"), value);
system_pushstring(buffer); system_pushstring(buffer);
} }
void *copymem(void *output, void *input, size_t cbSize) void *copymem(void *output, void *input, size_t cbSize)
@ -164,7 +164,7 @@ void *copymem(void *output, void *input, size_t cbSize)
HANDLE GlobalCopy(HANDLE Old) HANDLE GlobalCopy(HANDLE Old)
{ {
size_t size = GlobalSize(Old); size_t size = GlobalSize(Old);
return copymem(GlobalAlloc(GPTR, size), Old, size); return copymem(GlobalAlloc(GPTR, size), Old, size);
} }

View file

@ -3,6 +3,22 @@
#include <nsis/pluginapi.h> // nsis plugin #include <nsis/pluginapi.h> // nsis plugin
// Always use system* functions to keep the size down
#define pushstring error(use system_pushstring)
#define pushint error(use system_pushint)
#define popint system_popint
#define myatoi(str) ( (int) myatoi64(str) )
#ifdef _WIN64
# error TODO
#else
# define system_pushintptr system_pushint
# define popintptr popint
# define StrToIntPtr(str) ( (INT_PTR)myatoi((str)) )
#endif
#define BUGBUG64(brokencast) (brokencast) // Cast that needs fixing on x64
#define PLUGINFUNCTION(name) \ #define PLUGINFUNCTION(name) \
void __declspec(dllexport) name( \ void __declspec(dllexport) name( \
HWND hwndParent, int string_size, TCHAR *variables, stack_t **stacktop, extra_parameters *extra) { \ HWND hwndParent, int string_size, TCHAR *variables, stack_t **stacktop, extra_parameters *extra) { \
@ -23,7 +39,7 @@ extern TCHAR *system_setuservariable(int varnum, TCHAR *var);
extern TCHAR* system_popstring(); // NULL - stack empty extern TCHAR* system_popstring(); // NULL - stack empty
extern TCHAR* system_pushstring(TCHAR *str); extern TCHAR* system_pushstring(TCHAR *str);
extern __int64 myatoi64(TCHAR *s); extern __int64 myatoi64(TCHAR *s);
extern int popint64(); // -1 -> stack empty extern int system_popint(); // -1 -> stack empty
extern void system_pushint(int value); extern void system_pushint(int value);
extern HANDLE GlobalCopy(HANDLE Old); extern HANDLE GlobalCopy(HANDLE Old);

View file

@ -17,8 +17,7 @@
#endif /* __GNUC__ */ #endif /* __GNUC__ */
#include <objbase.h> #include <objbase.h>
// Type conversion macro
#define INT_TO_POINTER(i) ((void *) (int) (i))
// Parse Section Type // Parse Section Type
#define PST_PROC 0 #define PST_PROC 0
@ -205,7 +204,7 @@ void * NSISGetProcAddress(HMODULE dllHandle, TCHAR* funcName)
PLUGINFUNCTIONSHORT(Free) PLUGINFUNCTIONSHORT(Free)
{ {
HANDLE memtofree = (HANDLE)popint64(); HANDLE memtofree = (HANDLE)popintptr();
if (CallbackThunkListHead) if (CallbackThunkListHead)
{ {
@ -251,7 +250,7 @@ PLUGINFUNCTION(Get)
if ((proc->Options & POPT_ALWRETURN) != 0) if ((proc->Options & POPT_ALWRETURN) != 0)
{ {
// Always return flag set -> return separate proc and result // Always return flag set -> return separate proc and result
system_pushint((int) proc); system_pushintptr((INT_PTR) proc);
GlobalFree(system_pushstring(GetResultStr(proc))); GlobalFree(system_pushstring(GetResultStr(proc)));
} else } else
{ {
@ -264,7 +263,7 @@ PLUGINFUNCTION(Get)
GlobalFree((HANDLE) proc); // No, free it GlobalFree((HANDLE) proc); // No, free it
} }
else // Ok result, return proc else // Ok result, return proc
system_pushint((int) proc); system_pushintptr((INT_PTR) proc);
} }
} PLUGINFUNCTIONEND } PLUGINFUNCTIONEND
@ -317,7 +316,7 @@ PLUGINFUNCTION(Call)
pp = proc->Params[0]; pp = proc->Params[0];
// Return result instead of return value // Return result instead of return value
proc->Params[0].Value = (int) GetResultStr(proc); proc->Params[0].Value = BUGBUG64(int) GetResultStr(proc);
proc->Params[0].Type = PAT_TSTRING; proc->Params[0].Type = PAT_TSTRING;
// Return all params // Return all params
ParamsOut(proc); ParamsOut(proc);
@ -486,7 +485,7 @@ SystemProc *PrepareProc(BOOL NeedForCall)
if (proc != NULL) GlobalFree(proc); if (proc != NULL) GlobalFree(proc);
// Get already defined proc // Get already defined proc
proc = (SystemProc *) INT_TO_POINTER(myatoi64(cbuf)); proc = (SystemProc *) StrToIntPtr(cbuf);
if (!proc) break; if (!proc) break;
// Find the last clone at proc queue // Find the last clone at proc queue
@ -640,8 +639,8 @@ SystemProc *PrepareProc(BOOL NeedForCall)
if (temp3 == 0) if (temp3 == 0)
{ {
ib--; ib--;
// It's stupid, I know, but I'm too laze to do another thing // It's stupid, I know, but I'm too lazy to do another thing
myitoa64(GetIntFromString(&(ib)),(TCHAR *)(temp4 = (int) AllocString())); myitoa64(GetIntFromString(&(ib)),(TCHAR *)(temp4 = BUGBUG64(int) AllocString()));
} }
break; break;
@ -658,7 +657,7 @@ SystemProc *PrepareProc(BOOL NeedForCall)
} }
// finish and save // finish and save
*cb = 0; *cb = 0;
temp4 = (int) AllocStr(cbuf); temp4 = BUGBUG64(int) AllocStr(cbuf);
} }
break; break;
@ -776,7 +775,7 @@ SystemProc *PrepareProc(BOOL NeedForCall)
// Use direct system proc address // Use direct system proc address
int addr; int addr;
proc->Dll = (HMODULE) INT_TO_POINTER(myatoi64(proc->DllName)); proc->Dll = (HMODULE) StrToIntPtr(proc->DllName);
if (proc->Dll == 0) if (proc->Dll == 0)
{ {
@ -788,16 +787,16 @@ SystemProc *PrepareProc(BOOL NeedForCall)
// fake-real parameter: for COM interfaces first param is Interface Pointer // fake-real parameter: for COM interfaces first param is Interface Pointer
proc->Params[1].Output = IOT_NONE; proc->Params[1].Output = IOT_NONE;
proc->Params[1].Input = (int) AllocStr(proc->DllName); proc->Params[1].Input = BUGBUG64(int) AllocStr(proc->DllName);
proc->Params[1].Size = 1; proc->Params[1].Size = 1;
proc->Params[1].Type = PAT_INT; proc->Params[1].Type = PAT_INT;
proc->Params[1].Option = 0; proc->Params[1].Option = 0;
// addr - pointer to interface vtable // addr - pointer to interface vtable
addr = *((int *)addr); addr = *(BUGBUG64(int *)addr);
// now addr contains the pointer to first item at VTABLE // now addr contains the pointer to first item at VTABLE
// add the index of proc // add the index of proc
addr = addr + (int)(myatoi64(proc->ProcName)*4); addr = addr + (int)(myatoi64(proc->ProcName)*4); //BUGBUG: sizeof(void*) on x64?
proc->Proc = *((HANDLE*)addr); proc->Proc = *((HANDLE*)addr);
} }
break; break;
@ -805,7 +804,7 @@ SystemProc *PrepareProc(BOOL NeedForCall)
if (*proc->DllName == 0) if (*proc->DllName == 0)
{ {
// Use direct system proc address // Use direct system proc address
if ((proc->Proc = (HANDLE) INT_TO_POINTER(myatoi64(proc->ProcName))) == 0) if ((proc->Proc = (HANDLE) StrToIntPtr(proc->ProcName)) == 0)
proc->ProcResult = PR_ERROR; proc->ProcResult = PR_ERROR;
} else } else
{ {
@ -836,7 +835,7 @@ SystemProc *PrepareProc(BOOL NeedForCall)
} }
break; break;
case PT_STRUCT: case PT_STRUCT:
if (*(proc->ProcName) != 0) proc->Proc = (HANDLE) INT_TO_POINTER(myatoi64(proc->ProcName)); if (*(proc->ProcName) != 0) proc->Proc = (HANDLE) StrToIntPtr(proc->ProcName);
break; break;
} }
} }
@ -851,7 +850,7 @@ void ParamAllocate(SystemProc *proc)
for (i = 0; i <= proc->ParamCount; i++) for (i = 0; i <= proc->ParamCount; i++)
if (((HANDLE) proc->Params[i].Value == NULL) && (proc->Params[i].Option == -1)) if (((HANDLE) proc->Params[i].Value == NULL) && (proc->Params[i].Option == -1))
{ {
proc->Params[i].Value = (int) GlobalAlloc(GPTR, 4*ParamSizeByType[proc->Params[i].Type]); proc->Params[i].Value = BUGBUG64(int) GlobalAlloc(GPTR, 4*ParamSizeByType[proc->Params[i].Type]);
} }
} }
@ -895,7 +894,7 @@ 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 = myatoi(realbuf);
break; break;
case PAT_LONG: case PAT_LONG:
*(__int64*)place = myatoi64(realbuf); *(__int64*)place = myatoi64(realbuf);
@ -932,14 +931,14 @@ void ParamsIn(SystemProc *proc)
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)
par->Value = (int) CreateCallback((SystemProc*) INT_TO_POINTER(myatoi64(realbuf))); par->Value = BUGBUG64(int) CreateCallback((SystemProc*) StrToIntPtr(realbuf));
break; break;
} }
GlobalFree(realbuf); GlobalFree(realbuf);
#ifdef SYSTEM_LOG_DEBUG #ifdef SYSTEM_LOG_DEBUG
{ {
TCHAR buf[1024]; TCHAR buf[666];
wsprintf(buf, _T("\t\t\tParam In %d: type %d value 0x%08X value2 0x%08X"), i, wsprintf(buf, _T("\t\t\tParam In %d: type %d value 0x%08X value2 0x%08X"), i,
par->Type, par->Value, par->_value); par->Type, par->Value, par->_value);
SYSTEM_LOG_ADD(buf); SYSTEM_LOG_ADD(buf);
@ -975,8 +974,8 @@ void ParamsOut(SystemProc *proc)
do do
{ {
// Retreive pointer to place // Retreive pointer to place
if (proc->Params[i].Option == -1) place = (int*) proc->Params[i].Value; if (proc->Params[i].Option == -1) place = BUGBUG64(int*) proc->Params[i].Value;
else place = (int*) &(proc->Params[i].Value); else place = BUGBUG64(int*) &(proc->Params[i].Value);
realbuf = AllocString(); realbuf = AllocString();
@ -1114,7 +1113,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; //BUGBUG: Does this have to be sizeof(void*)?
else else
structsize += ByteSizeByType[proc->Params[i].Type] * (proc->Params[i].Option - 1); structsize += ByteSizeByType[proc->Params[i].Type] * (proc->Params[i].Option - 1);
} }
@ -1145,7 +1144,7 @@ void CallStruct(SystemProc *proc)
if (proc->Params[i].Option < 1) if (proc->Params[i].Option < 1)
{ {
// Normal // Normal
size = proc->Params[i].Size*4; size = proc->Params[i].Size*4; //BUGBUG: sizeof(void*) on x64?
ptr = (char*) &(proc->Params[i].Value); ptr = (char*) &(proc->Params[i].Value);
} }
else else

View file

@ -49,9 +49,9 @@
#define PAT_CALLBACK 6 #define PAT_CALLBACK 6
#ifdef _UNICODE #ifdef _UNICODE
#define PAT_TSTRING PAT_WSTRING #define PAT_TSTRING PAT_WSTRING
#else #else
#define PAT_TSTRING PAT_STRING #define PAT_TSTRING PAT_STRING
#endif #endif
// Input/Output Source/Destination // Input/Output Source/Destination
#define IOT_NONE 0 #define IOT_NONE 0
@ -75,10 +75,10 @@ typedef struct
{ {
int Type; int Type;
int Option; // -1 -> Pointer, 1-... -> Special+1 int Option; // -1 -> Pointer, 1-... -> Special+1
int Value; // it can hold any 4 byte value int Value; // it can hold any 4 byte value BUGBUG: What about pointers on Win64?
int _value; // value buffer for structures > 4 bytes (I hope 8 bytes will be enough) int _value; // value buffer for structures > 4 bytes (I hope 8 bytes will be enough)
int Size; // Value real size (should be either 1 or 2 (the number of pushes)) int Size; // Value real size (should be either 1 or 2 (the number of pushes))
int Input; int Input; //BUGBUG: What about pointers on Win64?
int Output; int Output;
HGLOBAL allocatedBlock; // block allocated for passing string, wstring or guid param HGLOBAL allocatedBlock; // block allocated for passing string, wstring or guid param
} ProcParameter; } ProcParameter;