System plugin
git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@1130 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
parent
1fb8b94a22
commit
88956798f1
15 changed files with 1143 additions and 0 deletions
390
Contrib/System/System.c
Normal file
390
Contrib/System/System.c
Normal file
|
@ -0,0 +1,390 @@
|
|||
// System.cpp : Defines the entry point for the DLL application.
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "Plugin.h"
|
||||
#include "System.h"
|
||||
|
||||
HINSTANCE g_hInstance;
|
||||
|
||||
#define PT_STRING_SIZE 2048
|
||||
#define PARAMOKCHECK(expr) if (expr) { pushint(0); return; }
|
||||
|
||||
PLUGINFUNCTION(PartAddr)
|
||||
char buffer[1024];
|
||||
SystemProc *proc;
|
||||
|
||||
// Retrieve ProcID
|
||||
PARAMOKCHECK(popstring(buffer) == 0);
|
||||
// Try to initialize proc ...
|
||||
proc = ParseProc(buffer);
|
||||
// ... and return it to nsis!
|
||||
pushint((int) proc);
|
||||
PLUGINFUNCTIONEND
|
||||
|
||||
PLUGINFUNCTION(FullAddr)
|
||||
char procid[1024], paramid[1024];
|
||||
SystemProc *proc;
|
||||
|
||||
// Retrieve ProcID and ParamId
|
||||
PARAMOKCHECK((popstring(procid) == 0) || (popstring(paramid) == 0))
|
||||
// Try to initialize proc ...
|
||||
proc = ParseProc(procid);
|
||||
PARAMOKCHECK(proc == NULL)
|
||||
// Try to initialize params ...
|
||||
PARAMOKCHECK(ParseParam(proc, paramid) == FALSE)
|
||||
// ... and return it to nsis!
|
||||
pushint((int) proc);
|
||||
PLUGINFUNCTIONEND
|
||||
|
||||
PLUGINFUNCTION(ShortAddr)
|
||||
char paramid[1024];
|
||||
SystemProc *proc;
|
||||
|
||||
// Retrieve Proc and ParamId
|
||||
PARAMOKCHECK((popint(&((int)proc)) == 0) || (popstring(paramid) == 0))
|
||||
// Try to initialize params ...
|
||||
PARAMOKCHECK(ParseParam(proc, paramid) == FALSE)
|
||||
// ... and return it to nsis!
|
||||
pushint((int) proc);
|
||||
PLUGINFUNCTIONEND
|
||||
|
||||
PLUGINFUNCTION(Call)
|
||||
SystemProc *proc;
|
||||
|
||||
// Retrieve Proc
|
||||
PARAMOKCHECK(popint(&((int)proc)) == 0)
|
||||
|
||||
// Run the proc
|
||||
SystemCall(proc);
|
||||
PLUGINFUNCTIONEND
|
||||
|
||||
PLUGINFUNCTION(ShortCall)
|
||||
char paramid[1024];
|
||||
SystemProc *proc;
|
||||
|
||||
// Retrieve Proc and ParamId
|
||||
PARAMOKCHECK((popint(&((int)proc)) == 0) || (popstring(paramid) == 0))
|
||||
// Try to initialize params ...
|
||||
PARAMOKCHECK(ParseParam(proc, paramid) == FALSE)
|
||||
|
||||
// Run the proc
|
||||
SystemCall(proc);
|
||||
PLUGINFUNCTIONEND
|
||||
|
||||
PLUGINFUNCTION(FullCall)
|
||||
char procid[1024], paramid[1024];
|
||||
SystemProc *proc;
|
||||
|
||||
// Retrieve ProcID and ParamId
|
||||
PARAMOKCHECK((popstring(procid) == 0) || (popstring(paramid) == 0))
|
||||
// Try to initialize proc ...
|
||||
proc = ParseProc(procid);
|
||||
PARAMOKCHECK(proc == NULL)
|
||||
// Try to initialize params ...
|
||||
PARAMOKCHECK(ParseParam(proc, paramid) == FALSE)
|
||||
// ... and return it to nsis!
|
||||
|
||||
// Run the proc
|
||||
SystemCall(proc);
|
||||
|
||||
// We've created it, we've to destroyit
|
||||
GlobalFree(proc);
|
||||
PLUGINFUNCTIONEND
|
||||
|
||||
SystemProc *ParseProc(char *ProcID)
|
||||
{
|
||||
SystemProc *proc;
|
||||
char dllname[1024], procname[256], *p1, *p2;
|
||||
|
||||
// Extract dllname
|
||||
p1 = ProcID;
|
||||
p2 = dllname;
|
||||
while (*p1 && (*p1 != '?')) *(p2++) = *(p1++);
|
||||
*p2 = 0;
|
||||
if ((lstrlen(dllname) == 0) || (*p1 == 0)) return NULL;
|
||||
|
||||
// Extract procname
|
||||
p1++;
|
||||
p2 = procname;
|
||||
while (*p1 && (*p1 != '?')) *(p2++) = *(p1++);
|
||||
*p2 = 0;
|
||||
if ((lstrlen(procname) == 0) || (*p1 == 0)) return NULL;
|
||||
|
||||
// Ok, check If there is at least 1 param
|
||||
p1++;
|
||||
if (*p1 == 0) return NULL;
|
||||
|
||||
// Allocate memory for new Proc
|
||||
proc = (SystemProc*) GlobalAlloc(GPTR, sizeof(SystemProc));
|
||||
|
||||
// Ok, retrieve dll handle
|
||||
proc->dll = GetModuleHandle(dllname);
|
||||
if (proc->dll == NULL)
|
||||
{
|
||||
// Dll is not loaded already
|
||||
proc->dll = LoadLibrary(dllname);
|
||||
if (proc->dll == NULL)
|
||||
{
|
||||
// Dll not found
|
||||
GlobalFree(proc);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Dll succesfully loaded, now we should Get Proc Address
|
||||
proc->proc = GetProcAddress(proc->dll, procname);
|
||||
if (proc->proc == NULL)
|
||||
{
|
||||
// Proc is not loaded succesfully
|
||||
GlobalFree(proc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Allright, lets parse parameters
|
||||
proc->ParamCount = 0;
|
||||
while (*p1 && (*p1 != '?'))
|
||||
{
|
||||
// Memory is initialized to zeros with GlobalAlloc, so we don't need
|
||||
// to set defaults for Parameters
|
||||
|
||||
// We should check for pointer
|
||||
if ((*p1 == 'p') || (*p1 == 'P'))
|
||||
{
|
||||
proc->Params[proc->ParamCount].IsPointer = TRUE;
|
||||
// Check for next character to be valid
|
||||
p1++;
|
||||
if ((*p1 == 0) || (*p1 == '?')) break;
|
||||
}
|
||||
|
||||
switch(*p1)
|
||||
{
|
||||
case 'v':
|
||||
case 'V':
|
||||
proc->Params[proc->ParamCount].Type = PT_VOID;
|
||||
break;
|
||||
case 'i':
|
||||
case 'I':
|
||||
proc->Params[proc->ParamCount].Type = PT_INT;
|
||||
break;
|
||||
case 'l':
|
||||
case 'L':
|
||||
proc->Params[proc->ParamCount].Type = PT_LONG;
|
||||
break;
|
||||
case 's':
|
||||
case 'S':
|
||||
proc->Params[proc->ParamCount].Type = PT_STRING;
|
||||
break;
|
||||
case 'b':
|
||||
case 'B':
|
||||
proc->Params[proc->ParamCount].Type = PT_BOOLEAN;
|
||||
break;
|
||||
};
|
||||
|
||||
// Move to next character
|
||||
proc->ParamCount++;
|
||||
p1++;
|
||||
}
|
||||
return proc;
|
||||
}
|
||||
|
||||
BOOL ParseParam(SystemProc *proc, char *ParamID)
|
||||
{
|
||||
char *p1;
|
||||
ProcParameter *par;
|
||||
|
||||
par = proc->Params + 1;
|
||||
p1 = ParamID;
|
||||
|
||||
// Allright, lets parse input parameters
|
||||
while (*p1 && (*p1 != '?'))
|
||||
{
|
||||
if ((*p1 == 's') || (*p1 == 'S')) par->Input = IOT_STACK;
|
||||
else if ((*p1 == 'n') || (*p1 == 'N')) par->Input = IOT_NONE;
|
||||
else if ((*p1 >= '0') && (*p1 <= '9')) par->Input = (*p1-'0')+1;
|
||||
else if ((*p1 >= 'a') && (*p1 <= 'o')) par->Input = (*p1-'a')+11;
|
||||
else if ((*p1 >= 'A') && (*p1 <= 'O')) par->Input = (*p1-'A')+11;
|
||||
|
||||
// Move to next param & character
|
||||
par++;
|
||||
p1++;
|
||||
}
|
||||
|
||||
if (*p1++ == 0) return TRUE;
|
||||
par = proc->Params;
|
||||
|
||||
// Allright, lets parse output parameters
|
||||
while (*p1)
|
||||
{
|
||||
if ((*p1 == 's') || (*p1 == 'S')) par->Output = IOT_STACK;
|
||||
else if ((*p1 == 'n') || (*p1 == 'N')) par->Output = IOT_NONE;
|
||||
else if ((*p1 >= '0') && (*p1 <= '9')) par->Output = (*p1-'0')+1;
|
||||
else if ((*p1 >= 'a') && (*p1 <= 'o')) par->Output = (*p1-'a')+11;
|
||||
else if ((*p1 >= 'A') && (*p1 <= 'O')) par->Output = (*p1-'A')+11;
|
||||
|
||||
// Move to next param & character
|
||||
par++;
|
||||
p1++;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void ParamsInput(SystemProc *proc)
|
||||
{
|
||||
int i;
|
||||
ProcParameter *par;
|
||||
char buffer[PT_STRING_SIZE], *realbuf;
|
||||
|
||||
par = proc->Params + 1;
|
||||
for (i = 1; i < proc->ParamCount; i++, par++)
|
||||
{
|
||||
// Step 1: retrive value
|
||||
if (par->Input == IOT_STACK) popstring(realbuf = buffer);
|
||||
else if (par->Input > 0) realbuf = getuservariable(par->Input - 1);
|
||||
else *(realbuf = buffer) = 0;
|
||||
|
||||
// Step 2: place it
|
||||
switch (par->Type)
|
||||
{
|
||||
// TODO: PT_VOID input????
|
||||
//case PT_VOID:
|
||||
case PT_INT:
|
||||
{
|
||||
if (par->IsPointer)
|
||||
{
|
||||
par->Value = (int) GlobalAlloc(GPTR, sizeof(int));
|
||||
*((int*) par->Value) = myatoi(realbuf);
|
||||
} else par->Value = myatoi(realbuf);
|
||||
}
|
||||
break;
|
||||
case PT_LONG:
|
||||
{
|
||||
if (par->IsPointer)
|
||||
{
|
||||
par->Value = (int) GlobalAlloc(GPTR, sizeof(ULARGE_INTEGER));
|
||||
((ULARGE_INTEGER*) par->Value)->LowPart = myatoi(realbuf);
|
||||
((ULARGE_INTEGER*) par->Value)->HighPart = 0; // TODO: 64 bit atoi conversion
|
||||
} else; // TODO: PT_LONG direct input????
|
||||
}
|
||||
break;
|
||||
case PT_STRING:
|
||||
{
|
||||
if (par->IsPointer)
|
||||
{
|
||||
par->Value = (int) GlobalAlloc(GPTR, sizeof(int));
|
||||
*((int*)par->Value) = GlobalAlloc(GPTR, PT_STRING_SIZE);
|
||||
lstrcpy(*((LPCSTR*) par->Value), realbuf);
|
||||
} else
|
||||
{
|
||||
par->Value = (int) GlobalAlloc(GPTR, PT_STRING_SIZE);
|
||||
lstrcpy(par->Value, realbuf);
|
||||
}
|
||||
}
|
||||
break;
|
||||
// TODO: PT_BOOLEAN support ???
|
||||
//case PT_BOLEAN: ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ParamsOutput(SystemProc *proc)
|
||||
{
|
||||
int i;
|
||||
ProcParameter *par;
|
||||
char buffer[PT_STRING_SIZE];
|
||||
|
||||
par = proc->Params;
|
||||
for (i = 0; i < proc->ParamCount; i++, par++)
|
||||
{
|
||||
// Step 1: retrieve value
|
||||
switch (par->Type)
|
||||
{
|
||||
case PT_VOID:
|
||||
{
|
||||
if (par->IsPointer); // TODO: Pointer To Void Output
|
||||
else *buffer = 0;
|
||||
}
|
||||
break;
|
||||
case PT_INT:
|
||||
{
|
||||
if (par->IsPointer)
|
||||
{
|
||||
wsprintf(buffer, "%d", *((int*) par->Value));
|
||||
GlobalFree(par->Value);
|
||||
} else wsprintf(buffer, "%d", par->Value);
|
||||
}
|
||||
break;
|
||||
case PT_LONG:
|
||||
{
|
||||
if (par->IsPointer)
|
||||
{
|
||||
wsprintf(buffer, "%ld", *((ULARGE_INTEGER*) par->Value));
|
||||
GlobalFree(par->Value);
|
||||
} else; // TODO: PT_LONG direct output????
|
||||
}
|
||||
break;
|
||||
case PT_STRING:
|
||||
{
|
||||
if (par->IsPointer)
|
||||
{
|
||||
lstrcpy(buffer, *((LPCSTR*) par->Value));
|
||||
GlobalFree(*((int*)par->Value));
|
||||
GlobalFree(par->Value);
|
||||
} else
|
||||
{
|
||||
lstrcpy(buffer, par->Value);
|
||||
GlobalFree((HANDLE) par->Value);
|
||||
}
|
||||
}
|
||||
break;
|
||||
// TODO: PT_BOOLEAN support ???
|
||||
//case PT_BOLEAN: ;
|
||||
}
|
||||
|
||||
// Step 2: place it
|
||||
if (par->Output == IOT_STACK) pushstring(buffer);
|
||||
else if (par->Output > 0) setuservariable(par->Output - 1, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
void SystemCall(SystemProc *proc)
|
||||
{
|
||||
int z;
|
||||
ProcParameter *par;
|
||||
|
||||
// Prepare input arguments
|
||||
ParamsInput(proc);
|
||||
|
||||
// Push arguments to stack
|
||||
par = proc->Params+proc->ParamCount-1;
|
||||
while (par > proc->Params)
|
||||
{
|
||||
z = par->Value;
|
||||
_asm
|
||||
{
|
||||
push z
|
||||
}
|
||||
par--;
|
||||
}
|
||||
|
||||
// Call the proc and save return
|
||||
z = proc->proc;
|
||||
_asm
|
||||
{
|
||||
call z
|
||||
mov z, eax
|
||||
}
|
||||
proc->Params[0].Value = z;
|
||||
|
||||
// Prepare output parameters
|
||||
ParamsOutput(proc);
|
||||
}
|
||||
|
||||
BOOL WINAPI _DllMainCRTStartup(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
|
||||
{
|
||||
g_hInstance=hInst;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue