diff --git a/Contrib/System/Source/Plugin.h b/Contrib/System/Source/Plugin.h index a7a98849..62c31247 100644 --- a/Contrib/System/Source/Plugin.h +++ b/Contrib/System/Source/Plugin.h @@ -15,8 +15,10 @@ #define popintptr system_popintptr #ifdef _WIN64 # define StrToIntPtr(str) ( (INT_PTR)myatoi64((str)) ) +# define IntPtrToStr(p,buf) myitoa64((p),(buf)) #else # define StrToIntPtr(str) ( (INT_PTR)myatoi((str)) ) +# define IntPtrToStr(p,buf) myitoa64((p),(buf)) #endif #define BUGBUG64(brokencast) (brokencast) // Cast that needs fixing on x64 @@ -36,7 +38,8 @@ extern TCHAR *AllocStr(TCHAR *str); extern void myitoa64(__int64 i, TCHAR *buffer); extern TCHAR *AllocString(); -extern TCHAR *system_getuservariable(int varnum); +#define system_getuservariableptr(varnum) ( (g_variables)+(varnum)*(g_stringsize) ) +extern TCHAR *system_getuservariable(int varnum); // NOTE: This dupes with GlobalAlloc! extern TCHAR *system_setuservariable(int varnum, TCHAR *var); extern TCHAR* system_popstring(); // NULL - stack empty extern TCHAR* system_pushstring(TCHAR *str); diff --git a/Contrib/System/Source/System.c b/Contrib/System/Source/System.c index a7c11922..00796dc0 100644 --- a/Contrib/System/Source/System.c +++ b/Contrib/System/Source/System.c @@ -31,24 +31,28 @@ #define PCD_DONE 3 // Just Continue const int PARAMSIZEBYTYPE_PTR = (4==sizeof(void*)) ? 1 : 2; -const int ParamSizeByType[7] = { +static const int ParamSizeByType[8] = { 0, // PAT_VOID (Size will be equal to 1) //BUGBUG64? 1, // PAT_INT 2, // PAT_LONG sizeof(void*) / 4, // PAT_STRING //BUGBUG64? sizeof(void*) / 4, // PAT_WSTRING //BUGBUG64? sizeof(void*) / 4, // PAT_GUID //BUGBUG64? - 0}; // PAT_CALLBACK (Size will be equal to 1) //BUGBUG64? + 0, // PAT_CALLBACK (Size will be equal to 1) //BUGBUG64? + 1 // PAT_REGMEM +}; // Thomas needs to look at this. -static const int ByteSizeByType[7] = { +static const int ByteSizeByType[8] = { 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 + 1, // PAT_CALLBACK + 1 // PAT_REGMEM +}; int LastStackPlace; int LastStackReal; @@ -648,6 +652,7 @@ SystemProc *PrepareProc(BOOL NeedForCall) temp = -1; break; // Pointer parameter option // Types + case _T('@'): temp2 = PAT_REGMEM; break; case _T('v'): case _T('V'): temp2 = PAT_VOID; break; @@ -996,6 +1001,12 @@ void ParamsIn(SystemProc *proc) if (lstrlen(realbuf) > 0) par->Value = (INT_PTR) CreateCallback((SystemProc*) StrToIntPtr(realbuf)); break; + case PAT_REGMEM: + (LPTSTR)place = system_getuservariableptr(par->Input - 1); + par->Value = (INT_PTR) place; + par->Value += sizeof(void*) > 4 ? sizeof(_T("-9223372036854775807")) : sizeof(_T("-2147483647")); + IntPtrToStr(par->Value, (LPTSTR)place); + break; } GlobalFree(realbuf); @@ -1051,9 +1062,15 @@ void ParamsOut(SystemProc *proc) case PAT_VOID: *realbuf = _T('\0'); break; +#ifndef _WIN64 + case PAT_REGMEM: +#endif case PAT_INT: wsprintf(realbuf, _T("%d"), (int)(*((INT_PTR*) place))); break; +#ifdef _WIN64 + case PAT_REGMEM: +#endif case PAT_LONG: myitoa64(*((__int64*) place), realbuf); break; diff --git a/Contrib/System/Source/System.h b/Contrib/System/Source/System.h index 945cbdee..d25769f5 100644 --- a/Contrib/System/Source/System.h +++ b/Contrib/System/Source/System.h @@ -52,6 +52,7 @@ #define PAT_WSTRING 4 #define PAT_GUID 5 #define PAT_CALLBACK 6 +#define PAT_REGMEM 7 #ifdef _UNICODE #define PAT_TSTRING PAT_WSTRING #else diff --git a/Contrib/System/System.html b/Contrib/System/System.html index 29d54b51..e1e325cc 100644 --- a/Contrib/System/System.html +++ b/Contrib/System/System.html @@ -281,6 +281,10 @@ DetailPrint $4 k callback +@ +Direct register memory access (Buffer is limited to (NSIS_MAX_STRLEN - 21) * NSIS_CHAR_SIZE bytes) + + &vN N bytes padding (structures only) @@ -371,6 +375,7 @@ DetailPrint $4 null for source, no output required for destination +

Source is required when using the @ type and must be a register. When the call returns the source register already contains the memory address in string form so using destination is usually not necessary.

Callbacks

@@ -492,16 +497,23 @@ DetailPrint "Return value - $2"
 System::Alloc 4
 Pop $0
-System::Call "*$0(i 5)"
-System::Call "*$0(i .r1)"
+System::Call "*$0(i 5)" ; Write
+System::Call "*$0(i .r1)" ; Read
+System::Free $0
 DetailPrint $1
 
 System::Call "*(i 5) p .r0"
 System::Call "*$0(i .r1)"
+System::Free $0
 DetailPrint $1
 
+System::Call "user32::GetClientRect(p $hwndparent, @ r0)"
+System::Call "*$0(i,i,i.r1,i.r2)"
+DetailPrint ClientRect=$1x$2
+
+
 # defines
 !define CLSCTX_INPROC_SERVER 1
 !define CLSID_ActiveDesktop {75048700-EF1F-11D0-9888-006097DEACF9}
diff --git a/Contrib/nsDialogs/nsDialogs.nsh b/Contrib/nsDialogs/nsDialogs.nsh
index ac528574..6dfd55b5 100644
--- a/Contrib/nsDialogs/nsDialogs.nsh
+++ b/Contrib/nsDialogs/nsDialogs.nsh
@@ -543,29 +543,19 @@ Header file for creating custom installer pages with nsDialogs
 !macro __NSD_SetStretchedImage CONTROL IMAGE HANDLE
 
 	Push $0
-	Push $1
-	Push $2
 	Push $R0
 
+	Push "${IMAGE}" # in case ${IMAGE} is $0 or $R0
 	StrCpy $R0 ${CONTROL} # in case ${CONTROL} is $0
 
-	# Allocate a RECT in $0 and initialize $1 and $2 to 0
-	System::Call '*(i0r1, i0r2, i, i)p.r0'
-	${If} $0 <> 0
-		System::Call 'user32::GetClientRect(pR0, pr0)'
-		System::Call '*$0(i, i, i .s, i .s)'
-		System::Free $0
-		Pop $1
-		Pop $2
-	${EndIf}
+	System::Call 'user32::GetClientRect(pR0,@r0)'
+	System::Call '*$0(i,i,i.r0,i.s)'
+	Exch # swap so stack contains ImagePath and then ControlHeight
 
-	System::Call 'user32::LoadImage(p0, ts, i ${IMAGE_BITMAP}, ir1, ir2, i${LR_LOADFROMFILE}) p.s' "${IMAGE}"
-	Pop $0
+	System::Call 'user32::LoadImage(p0, ts, i${IMAGE_BITMAP}, ir0, is, i${LR_LOADFROMFILE}) p.r0'
 	SendMessage $R0 ${STM_SETIMAGE} ${IMAGE_BITMAP} $0
 
 	Pop $R0
-	Pop $2
-	Pop $1
 	Exch $0
 
 	Pop ${HANDLE}
diff --git a/Docs/src/history.but b/Docs/src/history.but
index e6adab83..958e2b05 100644
--- a/Docs/src/history.but
+++ b/Docs/src/history.but
@@ -16,6 +16,8 @@ Released on ?, 2014
 
 \S2{} Minor Changes
 
+\b Added System::Call direct register memory access type. (\W{http://sf.net/p/nsis/patches/249}{patch #249})
+
 \b Fixed POSIX !searchparse bug (\W{http://sf.net/p/nsis/patches/251}{patch #251})
 
 \S2{} Translations