From 0a1b4aa83c7ac9dafcb07a9bec23b6f2665d60bd Mon Sep 17 00:00:00 2001 From: joostverburg Date: Thu, 31 Oct 2002 14:41:46 +0000 Subject: [PATCH] version 2 final git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@1511 212acab6-be3b-0410-9dea-997c60f758d6 --- Contrib/System/Buffers.c | 85 +++++--- Contrib/System/Buffers.h | 2 - Contrib/System/Example.nsi | 42 ---- Contrib/System/New System.txt | 120 ------------ Contrib/System/Plugin.c | 31 ++- Contrib/System/Plugin.h | 6 +- Contrib/System/SysFunc.nsh | 283 --------------------------- Contrib/System/System.c | 107 +++++++---- Contrib/System/System.h | 7 +- Contrib/System/System.nsh | 353 ---------------------------------- Contrib/System/System.vcproj | 2 +- Plugins/System.dll | Bin 8704 -> 9216 bytes 12 files changed, 159 insertions(+), 879 deletions(-) delete mode 100644 Contrib/System/Example.nsi delete mode 100644 Contrib/System/New System.txt delete mode 100644 Contrib/System/SysFunc.nsh delete mode 100644 Contrib/System/System.nsh diff --git a/Contrib/System/Buffers.c b/Contrib/System/Buffers.c index 6ae37d0f..41014838 100644 --- a/Contrib/System/Buffers.c +++ b/Contrib/System/Buffers.c @@ -3,6 +3,14 @@ #include "System.h" #include "Buffers.h" +typedef struct tagTempStack TempStack; +typedef struct tagTempStack +{ + TempStack *Next; + char Data[0]; +} TempStack; +TempStack *tempstack = NULL; + PLUGINFUNCTIONSHORT(Alloc) { int size; @@ -27,10 +35,10 @@ PLUGINFUNCTIONSHORT(Copy) if (str[0] == '/') { size = (int) myatoi(str+1); - dest = popint(); + dest = (HANDLE) popint(); } else dest = (HANDLE) myatoi(str+1); - source = popint(); + source = (HANDLE) popint(); // Ok, check the size if (size == 0) size = (int) GlobalSize(source); @@ -46,36 +54,53 @@ PLUGINFUNCTIONEND PLUGINFUNCTIONSHORT(Free) { - char *str; - // Get the string - if ((str = popstring()) == NULL) return; - // Check for callback clear - if (lstrcmpi(str,"/callback") == 0) - { - SystemProc *proc, *next; - next = (SystemProc*) popint(); - // Clear all the clone queue of callback - while ((proc = next) != NULL) - { - next = proc->Clone; - GlobalFree((HANDLE)proc); - } - } - else - GlobalFree((HANDLE) myatoi(str)); - GlobalFree(str); + GlobalFree((HANDLE) popint()); } PLUGINFUNCTIONEND -char *copymem(char *output, char *input, int size) +PLUGINFUNCTION(Store) { - char *out = output; - while (size-- > 0) *(out++) = *(input++); - return output; -} + TempStack *tmp; + int size = ((INST_R9+1)*g_stringsize); -HANDLE GlobalCopy(HANDLE Old) -{ - SIZE_T size = GlobalSize(Old); - return copymem(GlobalAlloc(GPTR, size), Old, (int) size); -} \ No newline at end of file + char *command, *cmd = command = popstring(); + while (*cmd != 0) + { + switch (*(cmd++)) + { + case 's': + case 'S': + // Store the whole variables range + tmp = (TempStack*) GlobalAlloc(GPTR, sizeof(TempStack)+size); + tmp->Next = tempstack; + tempstack = tmp; + + // Fill with data + copymem(tempstack->Data, g_variables, size); + break; + case 'l': + case 'L': + // Fill with data + copymem(g_variables, tempstack->Data, size); + + // Restore stack + tmp = tempstack->Next; + GlobalFree((HANDLE) tempstack); + tempstack = tmp; + break; + case 'P': + *cmd += 10; + case 'p': + GlobalFree((HANDLE) pushstring(getuservariable(*(cmd++)-'0'))); + break; + case 'R': + *cmd += 10; + case 'r': + GlobalFree((HANDLE) setuservariable(*(cmd++)-'0', popstring())); + break; + } + } + + GlobalFree((HANDLE) command); +} +PLUGINFUNCTIONEND \ No newline at end of file diff --git a/Contrib/System/Buffers.h b/Contrib/System/Buffers.h index ae12263f..3f59c932 100644 --- a/Contrib/System/Buffers.h +++ b/Contrib/System/Buffers.h @@ -1,4 +1,2 @@ #pragma once -extern HANDLE GlobalCopy(HANDLE Old); -extern char *copymem(char *output, char *input, int size); \ No newline at end of file diff --git a/Contrib/System/Example.nsi b/Contrib/System/Example.nsi deleted file mode 100644 index 6507d716..00000000 --- a/Contrib/System/Example.nsi +++ /dev/null @@ -1,42 +0,0 @@ -Name "System.dll Test" - -OutFile "System.dll Test.exe" - -Section - ; Memory for paths - System::Alloc 1024 - Pop $1 - ; Get drives - System::Call 'kernel32::GetLogicalDriveStringsA(i 1024, i r1) i' - enumok: - ; One more drive? - System::Call 'kernel32::lstrlenA(i r1) i.r2' - IntCmp $2 0 enumex - - ; Drive space - System::Call 'kernel32::GetDiskFreeSpaceExA(i r1, *l .r3, *l .r4, *l .r5) i' - - ; Pretty KBs - System::Int64Op $3 / 1024 - Pop $3 - System::Int64Op $4 / 1024 - Pop $4 - System::Int64Op $5 / 1024 - Pop $5 - - ; Get pretty drive path string - System::Call '*$1(&t1024 .r6)' - ; Message box - System::Call 'user32::MessageBoxA(i $HWNDPARENT, t "Path: `$6`, Free for Caller: $3 kb, Free for All: $5 kb, Disk Size: $4 kb$\r$\nMore?", t "Disk spaces example", i 33) i.r0' - ; User cancel? - IntCmp $0 2 enumex - - ; Next drive path - IntOp $1 $1 + $2 - IntOp $1 $1 + 1 - goto enumok - - enumex: ; End of drives or user cancel - ; Free memory for paths - System::Free $1 -SectionEnd \ No newline at end of file diff --git a/Contrib/System/New System.txt b/Contrib/System/New System.txt deleted file mode 100644 index a24ac620..00000000 --- a/Contrib/System/New System.txt +++ /dev/null @@ -1,120 +0,0 @@ -Additional notes: -1. if you are using callbacks you should set SetPluginUnload -to alwaysoff. -2. If you are using inline input syntax, you shouldn't use the same quotes for -quoting inlines and the whole defenition. Use \ as escape character (for ex.: -\" will be replaced with "). - ------------ Main functions ----------- - -RESULT/PROC System::Get "Proc" -RESULT/RETURN System::Call "Proc" StackArgs... - -These functions return error RESULTs or PROC/RETURN in OK case. -Error result is "error" and callback results are "callbackN", where N is -callback index. - ------------ Additional functions ----------- - -System::Int64Op ARG1 OP1 -System::Int64Op ARG1 OP2 ARG2 - Performs operation on ARG1 and ARG2 (or on ARG1 only at single argument -operator cases) and returns result on stack. Here are the OP2s: +, -, *, / DIV, -% MOD, | OR, & AND, ^ XOR, || LOGIC-OR, && LOGIC-AND, < BELOW, > ABOVE, = EQUAL. -There are only 2 OP1s: ~ (BITWISE-NOT) and ! (LOGIC-NOT). - -System::Alloc SIZE - Allocates SIZE bytes and returns the pointer on stack. - -System::Copy 0 SOURCE -System::Copy DESTINATION SOURCE -System::Copy /SIZE 0 SOURCE -System::Copy /SIZE DESTINATION SOURCE - Copys data from source to destination, if /SIZE option and SIZE itself -are undefined uses GlobalSize to determine source size. If destination is equal -to 0, allocates the new memory block. - -System::Free ADDR -System::Free /callback ADDR - Frees memory used by object at ADDR. If /callback option is specified, -then ADDR is considered to be the addr of CALLBACK proc, and will be cleared -accordingly (must be used!). - ------------ Get/Call syntaxis ----------- - -Syntax: - "Proc(Params)Return?Options#Proc(Params)Return?Options..." - -Proc: - dll::proc -> Proc from DLL - ::addr -> Handle to system proc (memory address) - *addr -> Structure - * -> New structure - nothing -> Dup proc, usually callback or for future defenition - - proc -> Ready proc specification for use or redefinition - - - If in System::Call proc specification points to already existing proc, -the existing proc will be adapted and executed, otherwise the new proc will be -created, executed and deleted. - -Params syntax: (Param1, Param2, Param3...), the number of params of proc is set -to number of params at last Params section (so params cutting may ocur). If you -need to save previous Param defenition use '_' after last param at Params -section - no param cutting will ocur for it (section). -Syntax of single param: "Type Source Destination", type can be omitted (previous -or void will be used), each of Source and Destination can be replaced with -'.' placeholder. Any parameter can be omitted at all - previous or default -values will be used (example: "(i1,,i2)", 2nd arg omitted). - - Return section is like single param defenition, but the Source defenition is -never used, beside callback cases. - -Params & Return - Type: - v - void (generaly for return) - i - int (includes char, byte, short, handles, pointers and so on) - l - long & large integer (know as int64) - t - text, string (LPCSTR, pointer to first character) - b - boolean (needs/returns 'true':'false') - by the fact this type is - senseless -> usual integer can be used ('0':'1') - k - callback. See Callback section. - - * - pointer specifier -> the proc needs the pointer to type, affects - next char (parameter) [ex: '*i' - pointer to int] - -For structures: & - additional meaning specificator. - &v - padding, &vN - pad for N bytes - &i - smaller types: &i4, &i2 (short), &i1 (byte) - &t - structure contains plain text, &tN - lenght == N bytes. - -Params & Return - Source / Destination: - . - makes no change to source - 0..9 - starts numeric inline input (accepts 0..9, x, |) - " / ' / ` - starts / ends string inline input, use \ to escape chars - Registers $0-$9 -> r(0..9) - Registers $R0-$R9 -> 'r(10..19)' or 'R(0..9)' - Additional regs -> c(Cmdline) d(instDir) o(Outdir) e(Exedir) a(lAng) - Stack -> s (you could pass arguments from Call line, see examples) - None -> n (0 (null) for input / specifies no output is required) - -Options (any option can be turned off (returned to default value) by specifing -'!' where needed, for example _stdcall cc can be turned on by '!c'): - c - _cdecl calling convention (the stack restored by caller). By default -stdcall calling convention is used (the stack restored by callee). - r - always return (for GET means you should pop result and proc, -for CALL means you should pop result (at least)). By default result is returned -for errors only (for GET you will pop either error result or right -proc, and for CALL you will get either your return or result at defined -return place. - n - no redefine. Whenever this proc will be used it will never be -redefined either by GET or CALL. This options is never inherited to childs. - s - use general Stack. Whenever the first callback defined the system -starts using the temporary stacks for function calls. - -Callback: you should check for callbacked return after every function call -which can use your callback. Genereal scheme is: - 1. Check result for callback or normal return - 2. Input arguments defined for callback are at places. - 3. Place output and return arguments - 4. Call System::Call using callback proc handle \ No newline at end of file diff --git a/Contrib/System/Plugin.c b/Contrib/System/Plugin.c index c18631b8..3e5a732b 100644 --- a/Contrib/System/Plugin.c +++ b/Contrib/System/Plugin.c @@ -1,5 +1,6 @@ #include "stdafx.h" #include "Plugin.h" +#include "Buffers.h" #include "System.h" HWND g_hwndParent; @@ -50,12 +51,12 @@ char *getuservariable(int varnum) return AllocStr(g_variables+varnum*g_stringsize); } -void setuservariable(int varnum, char *var) +char *setuservariable(int varnum, char *var) { if (var != NULL && varnum >= 0 && varnum < __INST_LAST) { lstrcpy (g_variables + varnum*g_stringsize, var); - } + return var; } // Updated for int64 and simple bitwise operations @@ -121,12 +122,16 @@ void myitoa64(__int64 i, char *buffer) *(buffer++) = '-'; i = -i; } - while (i > 0) + if (i == 0) *(buffer++) = '0'; + else { - *(b++) = '0' + ((char) (i%10)); - i /= 10; + while (i > 0) + { + *(b++) = '0' + ((char) (i%10)); + i /= 10; + } + while (b > buf) *(buffer++) = *(--b); } - while (b > buf) *(buffer++) = *(--b); *buffer = 0; } @@ -147,6 +152,20 @@ void pushint(int value) pushstring(buffer); } +char *copymem(char *output, char *input, int size) +{ + char *out = output; + if ((input != NULL) && (output != NULL)) + while (size-- > 0) *(out++) = *(input++); + return output; +} + +HANDLE GlobalCopy(HANDLE Old) +{ + SIZE_T size = GlobalSize(Old); + return copymem(GlobalAlloc(GPTR, size), Old, (int) size); +} + #ifdef _DEBUG void main() { diff --git a/Contrib/System/Plugin.h b/Contrib/System/Plugin.h index 956302cd..e6a2df28 100644 --- a/Contrib/System/Plugin.h +++ b/Contrib/System/Plugin.h @@ -45,19 +45,21 @@ __INST_LAST #define PLUGINFUNCTIONSHORT(name) void __declspec(dllexport) name(HWND hwndParent, int string_size, char *variables, stack_t **stacktop) { \ g_stringsize=string_size; \ g_stacktop=stacktop; -#define PLUGINFUNCTIONEND } extern char *AllocStr(char *str); extern void myitoa64(__int64 i, char *buffer); extern char *AllocString(); extern char *getuservariable(int varnum); -extern void setuservariable(int varnum, char *var); +extern char *setuservariable(int varnum, char *var); extern char* popstring(); // NULL - stack empty extern char* pushstring(char *str); extern __int64 myatoi(char *s); extern int popint(); // -1 -> stack empty extern void pushint(int value); +extern HANDLE GlobalCopy(HANDLE Old); +extern char *copymem(char *output, char *input, int size); + extern HWND g_hwndParent; extern int g_stringsize; extern stack_t **g_stacktop; diff --git a/Contrib/System/SysFunc.nsh b/Contrib/System/SysFunc.nsh deleted file mode 100644 index f3590eca..00000000 --- a/Contrib/System/SysFunc.nsh +++ /dev/null @@ -1,283 +0,0 @@ -; Some useful functions based on System plugin -; -; (c) brainsucker, 2002 -; (r) BSForce - -!include "${NSISDIR}\Contrib\System\System.nsh" -!include "${NSISDIR}\Examples\WinMessages.nsh" - -!define ssName $9 -!define ssDelay $8 -!define ssInstance $7 -!define ssImage $6 -!define ssWnd $5 -!define ssResult $4 -!define ssCallback $3 - -Function _systemSplashWndCB - ; Callback receives 4 values ( - Pop $R2 ; hwnd - Pop $R5 ; umsg - Pop $R0 ; wparam - Pop $R1 ; lparam - - ; Save globals and use them - Push $R6 - Push $R7 - Push $R8 - Push $R9 - Push $2 - Push $5 - Push $7 - Push $9 - StrCpy $2 $R2 - StrCpy $5 $R5 - StrCpy $7 $R0 - StrCpy $9 $R1 - -; MessageBox MB_OK "Got: $2 $5 $7 $9" - - ; Message branching - IntCmp $5 ${WM_CLOSE} m_Close - IntCmp $5 ${WM_TIMER} m_Timer - IntCmp $5 ${WM_LBUTTONDOWN} m_Lbtn - IntCmp $5 ${WM_CREATE} m_Create - IntCmp $5 ${WM_PAINT} m_Paint - goto default - -m_Create: - - ; Create structures - System::Call "*${sysRECT} (_) .R8" - System::Call "*${sysBITMAP} (_) .R9" - - ; Get bitmap info - System::Call "${sysGetObject} (r6, ${sysBITMAP_SIZE}, R9)" - - ; Get desktop info - System::Call "${sysSystemParametersInfo} (${SPI_GETWORKAREA}, 0, R8, 0)" - - ; Style (callbacked) - System::Call "${sysSetWindowLong} (r2, ${GWL_STYLE}, 0) .s" - !insertmacro SINGLE_CALLBACK 5 $R7 1 _systemSplashWndCB - - ; Calculate and set window pos - - ; Get bmWidth(R2) and bmHeight(R3) - System::Call "*$R9${sysBITMAP} (,.R2,.R3)" - ; Get left(R4), top(R5), right(R6), bottom(R7) - System::Call "*$R8${sysRECT} (.R4,.R5,.R6,.R7)" - - ; Left pos - IntOp $R0 $R6 - $R4 - IntOp $R0 $R0 - $R2 - IntOp $R0 $R0 / 2 - IntOp $R0 $R0 + $R4 - - ; Top pos - IntOp $R1 $R7 - $R5 - IntOp $R1 $R1 - $R3 - IntOp $R1 $R1 / 2 - IntOp $R1 $R1 + $R5 - - System::Call "${sysSetWindowPos} (r2, 0, R0, R1, R2, R3, ${SWP_NOZORDER}) .s" - !insertmacro SINGLE_CALLBACK 6 $R7 1 _systemSplashWndCB - - ; Show window - System::Call "${sysShowWindow} (r2, ${SW_SHOW}) .s" - !insertmacro SINGLE_CALLBACK 7 $R7 1 _systemSplashWndCB - - ; Set Timer - System::Call "${sysSetTimer} (r2, 1, r8,)" - - ; Free used memory - System::Free $R8 - System::Free $R9 - - StrCpy $R0 0 - goto exit - -m_Paint: - - ; Create structures - System::Call "*${sysRECT} (_) .R8" - System::Call "*${sysPAINTSTRUCT} (_) .R9" - - ; Begin Paint - System::Call "${sysBeginPaint} (r2, R9) .R7" - - ; CreateCompatibleDC - System::Call "${sysCreateCompatibleDC} (R7) .R6" - - ; GetClientRect - System::Call "${sysGetClientRect} (r2, R8)" - - ; Select new bitmap - System::Call "${sysSelectObject} (R6, r6) .R5" - - ; Get left(R0), top(R1), right(R2), bottom(R3) - System::Call "*$R8${sysRECT} (.R0,.R1,.R2,.R3)" - - ; width=right-left - IntOp $R2 $R2 - $R0 - ; height=bottom-top - IntOp $R3 $R3 - $R1 - - System::Call "${sysBitBlt} (R7, R0, R1, R2, R3, R6, 0, 0, ${SRCCOPY})" - - ; Select old bitmap - System::Call "${sysSelectObject} (R6, R5)" - - ; Delete compatible DC - System::Call "${sysDeleteDC} (R6)" - - ; End Paint - System::Call "${sysEndPaint} (r2, R9)" - - ; Free used memory - System::Free $R8 - System::Free $R9 - - StrCpy $R0 0 - goto exit - -m_Timer: -m_Lbtn: - StrCpy ${ssResult} 0 - IntCmp $5 ${WM_TIMER} destroy - StrCpy ${ssResult} 1 - -destroy: - System::Call "${sysDestroyWindow} (r2) .s" - !insertmacro SINGLE_CALLBACK 12 $R4 1 _systemSplashWndCB - -default: - ; Default - System::Call "${sysDefWindowProc} (r2, r5, r7, r9) .s" - !insertmacro SINGLE_CALLBACK 14 $R0 1 _systemSplashWndCB - goto exit - -m_Close: - StrCpy $R0 0 - goto exit - -exit: - ; Restore globals - Pop $9 - Pop $7 - Pop $5 - Pop $2 - Pop $R9 - Pop $R8 - Pop $R7 - Pop $R6 - - ; Return from callback - System::Call "${ssCallback}" $R0 -FunctionEnd - -Function systemSplash - Pop $R8 - Pop $R9 - - ; Save global register - Push $9 - Push $8 - Push $7 - Push $6 - Push $5 - Push $4 - Push $3 - - StrCpy ${ssName} $R9 - StrCpy ${ssDelay} $R8 - - ; Get module instance - System::Call "${sysGetModuleHandle} (i) .r7" - ; Pop ${ssInstance} - - ; Get arrow cursor - System::Call "${sysLoadCursor} (0, i ${IDC_ARROW}) .R9" - ; Pop $R9 - - ; Get callback - System::Get "${sysWNDPROC}" - Pop ${ssCallback} - - ; Create window class - System::Call "*${sysWNDCLASS} (,r3,,,r7,,R9,,,s) .R9" "_sp" - ; Pop $R9 - - ; Register window class - System::Call "${sysRegisterClass} (R9) .R9" - IntCmp $R9 0 errorexit ; Class registered ok? - - ; Load Image (LR_CREATEDIBSECTION|LR_LOADFROMFILE = 0x2010) - System::Call '${sysLoadImage} (, s, ${IMAGE_BITMAP}, 0, 0, ${LR_CREATEDIBSECTION}|${LR_LOADFROMFILE}) .r6' "${ssName}.bmp" - ; Pop ${ssImage} - IntCmp ${ssImage} 0 errorexit ; Image loaded ok? - - ; Start the sound (SND_ASYNC|SND_FILENAME|SND_NODEFAULT = 0x20003) - System::Call "${sysPlaySound} (s,,${SND_ASYNC}|${SND_FILENAME}|${SND_NODEFAULT})" "${ssName}.wav" - - ; Create window - System::Call "${sysCreateWindowEx} (${WS_EX_TOOLWINDOW}, s, s,,,,,, $HWNDPARENT,,r7,) .s" "_sp" "_sp" - ; Pop ${ssWnd} -> SINGLE_CALLBACK will do that - !insertmacro SINGLE_CALLBACK 1 ${ssWnd} 1 _systemSplashWndCB - - ; Create MSG struct - System::Call "*${sysMSG} (_) i.R9" - ; Pop $R9 - - ; ------------------------- -repeat: - ; Check for window - System::Call "${sysIsWindow} (r5) .s" - !insertmacro SINGLE_CALLBACK 2 $R8 1 _systemSplashWndCB - IntCmp $R8 0 finish - - ; Get message - System::Call "${sysGetMessage} (R9, r5,_) .s" - !insertmacro SINGLE_CALLBACK 3 $R8 1 _systemSplashWndCB - IntCmp $R8 0 finish - - ; Dispatch message - System::Call "${sysDispatchMessage} (R9) .s" - !insertmacro SINGLE_CALLBACK 4 $R8 1 _systemSplashWndCB - - ; Repeat dispatch cycle - goto repeat - ; ------------------------- - -finish: - ; Stop the sound - System::Call "${sysPlaySound}" - - ; Delete bitmap object - System::Call "${sysDeleteObject} (r6)" - - ; Delete the callback queue - System::Free /CALLBACK ${ssCallback} - - ; Dialog return - StrCpy $R0 ${ssResult} - goto exit - -; Exit in case of error -errorexit: - StrCpy $R0 -1 - goto exit - -exit: - ; Restore globals - Pop $3 - Pop $4 - Pop $5 - Pop $6 - Pop $7 - Pop $8 - Pop $9 - - ; Return - Push $R0 -FunctionEnd \ No newline at end of file diff --git a/Contrib/System/System.c b/Contrib/System/System.c index fbe9a9cc..90ed75ee 100644 --- a/Contrib/System/System.c +++ b/Contrib/System/System.c @@ -48,7 +48,7 @@ char *GetResultStr(SystemProc *proc) PLUGINFUNCTION(Get) { - SystemProc *proc = PrepareProc(); + SystemProc *proc = PrepareProc(FALSE); if ((proc->Options & POPT_ALWRETURN) != 0) { // Always return flag set -> return separate proc and result @@ -72,7 +72,7 @@ PLUGINFUNCTION(Get) PLUGINFUNCTION(Call) { // Prepare input - SystemProc *proc = PrepareProc(); + SystemProc *proc = PrepareProc(TRUE); if (proc->ProcResult != PR_CALLBACK) ParamAllocate(proc); ParamsIn(proc); @@ -184,7 +184,7 @@ __int64 GetIntFromString(char **p) return myatoi(buffer); } -SystemProc *PrepareProc() +SystemProc *PrepareProc(BOOL NeedForCall) { int SectionType = PST_PROC, // First section is always proc spec ProcType = PT_NOTHING, // Default proc spec @@ -242,12 +242,18 @@ SystemProc *PrepareProc() // Is it previous proc or just unknown proc? if (cb != cbuf) { + // Previous proc (for clear up) + SystemProc *pr = NULL; + if (proc != NULL) GlobalFree(proc); // Get already defined proc proc = (SystemProc *) myatoi(cbuf); // Find the last clone at proc queue - while (proc->Clone != NULL) proc = proc->Clone; + while (proc->Clone != NULL) proc = (pr = proc)->Clone; + + // Clear parents record for child callback proc + if (pr != NULL) pr->Clone = NULL; // Never Redefine? if ((proc->Options & POPT_NEVERREDEF) != 0) @@ -364,15 +370,17 @@ SystemProc *PrepareProc() } break; - case '\"': case '\'': case '\`': + case '\"': case '\'': case '`': // Character inline { char start = *ib; cb = cbuf; // copy inline - while ((*(++ib) != start) && (*ib)) - if (*ib == '\\') *(cb++) = *(++ib); - else *(cb++) = *(ib); + while (!((*(++ib) == start) && (*(ib+1) != start)) && (*ib)) + { + if ((*ib) == start) ++ib; + *(cb++) = *(ib); + } // finish and save *cb = 0; temp4 = (int) AllocStr(cbuf); @@ -400,7 +408,7 @@ SystemProc *PrepareProc() proc->Params[ParamIndex].Size = // If pointer, then 1, else by type (temp == -1)?(1):((ParamSizeByType[temp2]>0)?(ParamSizeByType[temp2]):(1)); // Get the parameter real special option value - if (temp == 1) temp = (int) GetIntFromString(&ib); + if (temp == 1) temp = ((int) GetIntFromString(&ib)) + 1; proc->Params[ParamIndex].Option = temp; proc->Params[ParamIndex].Value = 0; proc->Params[ParamIndex].Input = IOT_NONE; @@ -516,7 +524,9 @@ void ParamAllocate(SystemProc *proc) for (i = 0; i <= proc->ParamCount; i++) if (((HANDLE) proc->Params[i].Value == NULL) && (proc->Params[i].Option == -1)) + { proc->Params[i].Value = (int) GlobalAlloc(GPTR, ParamSizeByType[proc->Params[i].Type]); + } } void ParamsIn(SystemProc *proc) @@ -528,14 +538,16 @@ void ParamsIn(SystemProc *proc) do { // Step 1: retrive value - if (proc->Params[i].Input == IOT_NONE) realbuf = AllocStr(""); + if ((proc->Params[i].Input == IOT_NONE) || (proc->Params[i].Input == IOT_INLINE)) + realbuf = AllocStr(""); else if (proc->Params[i].Input == IOT_STACK) realbuf = popstring(); - else if ((proc->Params[i].Input > 0) && (proc->Params[i].Input <= __INST_LAST)) realbuf = getuservariable(proc->Params[i].Input - 1); + else if ((proc->Params[i].Input > 0) && (proc->Params[i].Input <= __INST_LAST)) + realbuf = getuservariable(proc->Params[i].Input - 1); else { // Inline input, will be freed as realbuf realbuf = (char*) proc->Params[i].Input; - proc->Params[i].Input = 0; + proc->Params[i].Input = IOT_INLINE; } // Retreive pointer to place @@ -580,7 +592,13 @@ void ParamsDeAllocate(SystemProc *proc) for (i = proc->ParamCount; i >= 0; i--) if (((HANDLE) proc->Params[i].Value != NULL) && (proc->Params[i].Option == -1)) - GlobalFree((HANDLE) proc->Params[i].Value); + { +#ifndef _DEBUG + // I see no point for error debug version gives here + GlobalFree((HANDLE) (proc->Params[i].Value)); +#endif + proc->Params[i].Value = (int) NULL; + } } void ParamsOut(SystemProc *proc) @@ -782,16 +800,11 @@ SystemProc __declspec(naked) *RealCallBack() } // Find last unused clone - while ((proc->ProcResult != PR_OK) && (proc->Clone != NULL)) proc = proc->Clone; - // Unused? - if (proc->ProcResult != PR_OK) - { - // Callback already used, create new - // 2. Create new clone - proc = (proc->Clone = GlobalCopy(proc)); - // 3. Set clone option - proc->Options |= POPT_CLONE; - } + while ((proc->Clone != NULL)) proc = proc->Clone; + // 2. Create new clone + proc = (proc->Clone = GlobalCopy(proc)); + // 3. Set clone option + proc->Options |= POPT_CLONE; // Read arguments proc->ArgsSize = 0; @@ -863,6 +876,9 @@ SystemProc __declspec(naked) *CallBack(SystemProc *proc) // Right return statement address retaddr = (HANDLE) retexpr; + // Remove unneeded callback proc + GlobalFree((HANDLE) proc); + _asm { // Prepare return @@ -919,22 +935,22 @@ HANDLE CreateCallback(SystemProc *cbproc) void CallStruct(SystemProc *proc) { - int i, size = 0; + int i, structsize = 0, size = 0; char *st, *ptr; + // Calculate the structure size + for (i = 1; i <= proc->ParamCount; i++) + if (proc->Params[i].Option < 1) + structsize += proc->Params[i].Size * 4; + else + structsize += proc->Params[i].Option-1; + // Struct exists? if (proc->Proc == NULL) - { - // No. Calculate the size and create - for (i = 1; i <= proc->ParamCount; i++) - if (proc->Params[i].Option < 1) - size += proc->Params[i].Size * 4; - else - size += proc->Params[i].Option; - - // Allocate struct memory - proc->Proc = (HANDLE) GlobalAlloc(GPTR, size); - } + // No. Allocate struct memory + proc->Proc = (HANDLE) GlobalAlloc(GPTR, structsize); + else // In case of zero size defined structure use mapped size + if (structsize == 0) structsize = (int) GlobalSize((HANDLE) proc->Proc); // Pointer to current data st = (char*) proc->Proc; @@ -950,12 +966,29 @@ void CallStruct(SystemProc *proc) } else { + int intmask[4] = {0xFFFFFFFF, 0x000000FF, 0x0000FFFF, 0x00FFFFFF}; + // Special - size = proc->Params[i].Option; + size = proc->Params[i].Option-1; + switch (proc->Params[i].Type) { case PAT_VOID: ptr = NULL; break; - case PAT_INT: ptr = (char*) &(proc->Params[i].Value); break; + case PAT_INT: + // clear unused value bits + proc->Params[i].Value &= intmask[((size >= 0) && (size < 4))?(size):(0)]; + // pointer + ptr = (char*) &(proc->Params[i].Value); + break; + case PAT_LONG: + // real structure size + proc->Params[i].Value = structsize; + proc->Params[i]._value = 0; + // clear unused value bits + proc->Params[i].Value &= intmask[((size >= 0) && (size < 4))?(size):(0)]; + // pointer + ptr = (char*) &(proc->Params[i].Value); + break; case PAT_STRING: ptr = (char*) proc->Params[i].Value; break; } } diff --git a/Contrib/System/System.h b/Contrib/System/System.h index 7d3c6634..0676f84c 100644 --- a/Contrib/System/System.h +++ b/Contrib/System/System.h @@ -33,9 +33,10 @@ #define PAT_CALLBACK 5 // Input/Output Source/Destination -#define IOT_NONE 0 +#define IOT_NONE 0 #define IOT_STACK -1 #define IOT_REG 1 +#define IOT_INLINE (__INST_LAST+1) // should replace pointer to inline input // #define INLINE_INPUT -> any other value, will contain pointer to input string // Options @@ -50,7 +51,7 @@ typedef struct { int Type; - int Option; // -1 -> Pointer, 1-... -> Special + int Option; // -1 -> Pointer, 1-... -> Special+1 int Value; // it can hold any 4 byte value 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)) @@ -83,7 +84,7 @@ typedef struct tag_SystemProc extern int ParamSizeByType[]; // Size of every parameter type (*4 bytes) extern HANDLE CreateCallback(SystemProc *cbproc); -extern SystemProc *PrepareProc(); +extern SystemProc *PrepareProc(BOOL NeedForCall); extern void ParamAllocate(SystemProc *proc); extern void ParamsDeAllocate(SystemProc *proc); extern void ParamsIn(SystemProc *proc); diff --git a/Contrib/System/System.nsh b/Contrib/System/System.nsh deleted file mode 100644 index b4eae5b0..00000000 --- a/Contrib/System/System.nsh +++ /dev/null @@ -1,353 +0,0 @@ -; Some useful functions, structures, constants -; -; (c) brainsucker, 2002 -; (r) BSForce - -; Check for double includes -!ifndef System.NSH.Included - -!define System.NSH.Included - -; ------------- Functions -------------- - -; LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); -!define sysWNDPROC "(i.s, i.s, i.s, i.s) iss" - -; LRESULT DefWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); -!define sysDefWindowProc "user32::DefWindowProcA(i, i, i, i) i" - -!define sysMessageBox "user32::MessageBoxA(i, t, t, i) i" - -; int wsprintf(LPTSTR lpOut, LPCTSTR lpFmt, ...); -!define syswsprintf "user32::wsprintfA(t, t) i ? c" - -; HMODULE GetModuleHandle(LPCTSTR lpModuleName); -!define sysGetModuleHandle "kernel32::GetModuleHandleA(t) i" - -; HCURSOR LoadCursor(HINSTANCE hInstance, LPCTSTR lpCursorName); -!define sysLoadCursor "user32::LoadCursorA(i, t) i" - -; ATOM RegisterClass(CONST WNDCLASS *lpWndClass); -!define sysRegisterClass "user32::RegisterClassA(i) i" - -; HANDLE LoadImage(HINSTANCE hinst, LPCTSTR lpszName, UINT uType, -; int cxDesired, int cyDesired, UINT fuLoad); -!define sysLoadImage "user32::LoadImageA(i, t, i, i, i, i) i" - -; BOOL PlaySound(LPCSTR pszSound, HMODULE hmod, DWORD fdwSound); -!define sysPlaySound "winmm.dll::PlaySoundA(t, i, i) i" - -; HWND CreateWindowEx(DWORD dwExStyle, LPCTSTR lpClassName, LPCTSTR lpWindowName, -; DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, -; HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam); -!define sysCreateWindowEx "user32::CreateWindowExA(i, t, t, i, i, i, i, i, i, i, i, i) i" - -; BOOL IsWindow(HWND hWnd); -!define sysIsWindow "user32::IsWindow(i) i" - -; LONG SetWindowLong(HWND hWnd, int nIndex, LONG dwNewLong); -!define sysSetWindowLong "user32::SetWindowLongA(i, i, i) i" - -; BOOL SetWindowPos(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags); -!define sysSetWindowPos "user32::SetWindowPos(i, i, i, i, i, i, i) i" - -; BOOL ShowWindow(HWND hWnd, int nCmdShow); -!define sysShowWindow "user32::ShowWindow(i, i) i" - -; BOOL DestroyWindow(HWND hWnd); -!define sysDestroyWindow "user32::DestroyWindow(i) i" - -; BOOL GetClientRect(HWND hWnd, LPRECT lpRect); -!define sysGetClientRect "user32::GetClientRect(i, i) i" - -; BOOL GetMessage(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax); -!define sysGetMessage "user32::GetMessageA(i, i, i, i) i" - -; LRESULT DispatchMessage(CONST MSG *lpmsg); -!define sysDispatchMessage "user32::DispatchMessageA(i) i" - -; BOOL DeleteObject(HGDIOBJ hObject); -!define sysDeleteObject "gdi32::DeleteObject(i) i" - -; int GetObject(HGDIOBJ hgdiobj, int cbBuffer, LPVOID lpvObject); -!define sysGetObject "gdi32::GetObjectA(i, i, i) i" - -; HGDIOBJ SelectObject(HDC hdc, HGDIOBJ hgdiobj); -!define sysSelectObject "gdi32::SelectObject(i, i) i" - -; HDC CreateCompatibleDC(HDC hdc); -!define sysCreateCompatibleDC "gdi32::CreateCompatibleDC(i) i" - -; BOOL DeleteDC(HDC hdc); -!define sysDeleteDC "gdi32::DeleteDC(i) i" - -; BOOL BitBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, -; HDC hdcSrc, int nXSrc, int nYSrc, DWORD dwRop); -!define sysBitBlt "gdi32::BitBlt(i, i, i, i, i, i, i, i, i) i" - -; HDC BeginPaint(HWND hwnd, LPPAINTSTRUCT lpPaint); -!define sysBeginPaint "user32::BeginPaint(i, i) i" - -; BOOL EndPaint(HWND hWnd, CONST PAINTSTRUCT *lpPaint); -!define sysEndPaint "user32::EndPaint(i, i) i" - -; BOOL SystemParametersInfo(UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni); -!define sysSystemParametersInfo "user32::SystemParametersInfoA(i, i, i, i) i" - -; UINT_PTR SetTimer(HWND hWnd, UINT_PTR nIDEvent, UINT uElapse, TIMERPROC lpTimerFunc); -!define sysSetTimer "user32::SetTimer(i, i, i, k) i" - - -; ------------- Structures -------------- - -; typedef struct _WNDCLASS { -; UINT style; -; WNDPROC lpfnWndProc; -; int cbClsExtra; -; int cbWndExtra; -; HINSTANCE hInstance; -; HICON hIcon; -; HCURSOR hCursor; -; HBRUSH hbrBackground; -; LPCTSTR lpszMenuName; -; LPCTSTR lpszClassName; -; } WNDCLASS, *PWNDCLASS; -!define sysWNDCLASS "(i, k, i, i, i, i, i, i, t, t) i" - -; typedef struct tagMSG { -; HWND hwnd; -; UINT message; -; WPARAM wParam; -; LPARAM lParam; -; DWORD time; -; POINT pt; -> will be presented as two separate px and py -; } MSG, *PMSG; -!define sysMSG "(i, i, i, i, i, i, i) i" - -; typedef struct tagBITMAP { -; LONG bmType; -; LONG bmWidth; -; LONG bmHeight; -; LONG bmWidthBytes; -; WORD bmPlanes; -; WORD bmBitsPixel; -; LPVOID bmBits; -; } BITMAP, *PBITMAP; -!define sysBITMAP "(i, i, i, i, i, i, i) i" -!define sysBITMAP_SIZE 28 - -; typedef struct _RECT { -; LONG left; -; LONG top; -; LONG right; -; LONG bottom; -; } RECT, *PRECT; -!define sysRECT "(i, i, i, i) i" - -; typedef struct tagPAINTSTRUCT { -; HDC hdc; -; BOOL fErase; -; RECT rcPaint; (rcl, rct, rcr, rcb) -; BOOL fRestore; -; BOOL fIncUpdate; -; BYTE rgbReserved[32]; -; } PAINTSTRUCT, *PPAINTSTRUCT; -!define sysPAINTSTRUCT "(i, i, i, i, i, i, i, i, &v32) i" - -; ------------- Constants -------------- - -; == Cursors == - -!define IDC_ARROW 32512 -!define IDC_IBEAM 32513 -!define IDC_WAIT 32514 -!define IDC_CROSS 32515 -!define IDC_UPARROW 32516 -!define IDC_SIZE 32640 -!define IDC_ICON 32641 -!define IDC_SIZENWSE 32642 -!define IDC_SIZENESW 32643 -!define IDC_SIZEWE 32644 -!define IDC_SIZENS 32645 -!define IDC_SIZEALL 32646 -!define IDC_NO 32648 -!define IDC_HAND 32649 -!define IDC_APPSTARTING 32650 -!define IDC_HELP 32651 - -; == Images == - -!define IMAGE_BITMAP 0 -!define IMAGE_ICON 1 -!define IMAGE_CURSOR 2 -!define IMAGE_ENHMETAFILE 3 - -!define LR_DEFAULTCOLOR 0x0000 -!define LR_MONOCHROME 0x0001 -!define LR_COLOR 0x0002 -!define LR_COPYRETURNORG 0x0004 -!define LR_COPYDELETEORG 0x0008 -!define LR_LOADFROMFILE 0x0010 -!define LR_LOADTRANSPARENT 0x0020 -!define LR_DEFAULTSIZE 0x0040 -!define LR_VGACOLOR 0x0080 -!define LR_LOADMAP3DCOLORS 0x1000 -!define LR_CREATEDIBSECTION 0x2000 -!define LR_COPYFROMRESOURCE 0x4000 -!define LR_SHARED 0x8000 - -; == Sounds == - -!define SND_SYNC 0x0000 -!define SND_ASYNC 0x0001 -!define SND_NODEFAULT 0x0002 -!define SND_MEMORY 0x0004 -!define SND_LOOP 0x0008 -!define SND_NOSTOP 0x0010 - -!define SND_NOWAIT 0x00002000 -!define SND_ALIAS 0x00010000 -!define SND_ALIAS_ID 0x00110000 -!define SND_FILENAME 0x00020000 -!define SND_RESOURCE 0x00040004 -!define SND_PURGE 0x0040 -!define SND_APPLICATION 0x0080 - -; == Windows == - -!define WS_OVERLAPPED 0x00000000 -!define WS_POPUP 0x80000000 -!define WS_CHILD 0x40000000 -!define WS_MINIMIZE 0x20000000 -!define WS_VISIBLE 0x10000000 -!define WS_DISABLED 0x08000000 -!define WS_CLIPSIBLINGS 0x04000000 -!define WS_CLIPCHILDREN 0x02000000 -!define WS_MAXIMIZE 0x01000000 -!define WS_CAPTION 0x00C00000 -!define WS_BORDER 0x00800000 -!define WS_DLGFRAME 0x00400000 -!define WS_VSCROLL 0x00200000 -!define WS_HSCROLL 0x00100000 -!define WS_SYSMENU 0x00080000 -!define WS_THICKFRAME 0x00040000 -!define WS_GROUP 0x00020000 -!define WS_TABSTOP 0x00010000 -!define WS_MINIMIZEBOX 0x00020000 -!define WS_MAXIMIZEBOX 0x00010000 -!define WS_TILED ${WS_OVERLAPPED} -!define WS_ICONIC ${WS_MINIMIZE} -!define WS_SIZEBOX ${WS_THICKFRAME} -!define WS_OVERLAPPEDWINDOW 0x00CF0000 -!define WS_TILEDWINDOW ${WS_OVERLAPPEDWINDOW} -!define WS_POPUPWINDOW 0x80880000 -!define WS_CHILDWINDOW ${WS_CHILD} -!define WS_EX_DLGMODALFRAME 0x00000001 -!define WS_EX_NOPARENTNOTIFY 0x00000004 -!define WS_EX_TOPMOST 0x00000008 -!define WS_EX_ACCEPTFILES 0x00000010 -!define WS_EX_TRANSPARENT 0x00000020 -!define WS_EX_MDICHILD 0x00000040 -!define WS_EX_TOOLWINDOW 0x00000080 -!define WS_EX_WINDOWEDGE 0x00000100 -!define WS_EX_CLIENTEDGE 0x00000200 -!define WS_EX_CONTEXTHELP 0x00000400 -!define WS_EX_RIGHT 0x00001000 -!define WS_EX_LEFT 0x00000000 -!define WS_EX_RTLREADING 0x00002000 -!define WS_EX_LTRREADING 0x00000000 -!define WS_EX_LEFTSCROLLBAR 0x00004000 -!define WS_EX_RIGHTSCROLLBAR 0x00000000 -!define WS_EX_CONTROLPARENT 0x00010000 -!define WS_EX_STATICEDGE 0x00020000 -!define WS_EX_APPWINDOW 0x00040000 -!define WS_EX_OVERLAPPEDWINDOW 0x00000300 -!define WS_EX_PALETTEWINDOW 0x00000188 -!define WS_EX_LAYERED 0x00080000 -!define WS_EX_NOINHERITLAYOUT 0x00100000 -!define WS_EX_LAYOUTRTL 0x00400000 -!define WS_EX_COMPOSITED 0x02000000 -!define WS_EX_NOACTIVATE 0x08000000 - - -; == System Parameters Info == - -!define SPI_GETWORKAREA 0x0030 - -; == Window Long Offsets == - -!define GWL_WNDPROC -4 -!define GWL_HINSTANCE -6 -!define GWL_HWNDPARENT -8 -!define GWL_STYLE -16 -!define GWL_EXSTYLE -20 -!define GWL_USERDATA -21 -!define GWL_ID -12 - -; == Show Window == - -!define SW_HIDE 0 -!define SW_SHOWNORMAL 1 -!define SW_NORMAL 1 -!define SW_SHOWMINIMIZED 2 -!define SW_SHOWMAXIMIZED 3 -!define SW_MAXIMIZE 3 -!define SW_SHOWNOACTIVATE 4 -!define SW_SHOW 5 -!define SW_MINIMIZE 6 -!define SW_SHOWMINNOACTIVE 7 -!define SW_SHOWNA 8 -!define SW_RESTORE 9 -!define SW_SHOWDEFAULT 10 -!define SW_FORCEMINIMIZE 11 -!define SW_MAX 11 - -; == Window swap == - -!define SWP_NOSIZE 0x0001 -!define SWP_NOMOVE 0x0002 -!define SWP_NOZORDER 0x0004 -!define SWP_NOREDRAW 0x0008 -!define SWP_NOACTIVATE 0x0010 -!define SWP_FRAMECHANGED 0x0020 -!define SWP_SHOWWINDOW 0x0040 -!define SWP_HIDEWINDOW 0x0080 -!define SWP_NOCOPYBITS 0x0100 -!define SWP_NOOWNERZORDER 0x0200 -!define SWP_NOSENDCHANGING 0x0400 - -!define SWP_DRAWFRAME ${SWP_FRAMECHANGED} -!define SWP_NOREPOSITION ${SWP_NOOWNERZORDER} -!define SWP_DEFERERASE 0x2000 -!define SWP_ASYNCWINDOWPOS 0x4000 - -; == Bit Copy == - -!define SRCCOPY 0x00CC0020 -!define SRCPAINT 0x00EE0086 -!define SRCAND 0x008800C6 -!define SRCINVERT 0x00660046 -!define SRCERASE 0x00440328 -!define NOTSRCCOPY 0x00330008 -!define NOTSRCERASE 0x001100A6 -!define MERGECOPY 0x00C000CA -!define MERGEPAINT 0x00BB0226 -!define PATCOPY 0x00F00021 -!define PATPAINT 0x00FB0A09 -!define PATINVERT 0x005A0049 -!define DSTINVERT 0x00550009 -!define BLACKNESS 0x00000042 -!define WHITENESS 0x00FF0062 - -; == Callbacks == - -!macro SINGLE_CALLBACK CHKN RES INDEX FUNC -CheckCB_${CHKN}: - Pop ${RES} - StrCmp ${RES} "callback${INDEX}" 0 ExitCB_${CHKN} - Call ${FUNC} - Goto CheckCB_${CHKN} -ExitCB_${CHKN}: -!macroend - -!endif \ No newline at end of file diff --git a/Contrib/System/System.vcproj b/Contrib/System/System.vcproj index 2ce19646..f4033b4d 100644 --- a/Contrib/System/System.vcproj +++ b/Contrib/System/System.vcproj @@ -87,7 +87,7 @@ OutputFile="$(OutDir)/System.dll" LinkIncremental="1" IgnoreAllDefaultLibraries="TRUE" - GenerateDebugInformation="TRUE" + GenerateDebugInformation="FALSE" GenerateMapFile="TRUE" MapExports="TRUE" SubSystem="2" diff --git a/Plugins/System.dll b/Plugins/System.dll index ffc4c7ee06dff6ad274ba9f3c17e5a20bb548e25..37e7e6864852633539ee9921edab9a02aebf0cef 100644 GIT binary patch delta 4358 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 nGxsIV($uAc;nOdS(E<@TE6y6 delta 3936 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