From 52d67824471613b3209f6bec284842068a75f2e0 Mon Sep 17 00:00:00 2001 From: anders_k Date: Sun, 29 Aug 2021 18:39:07 +0000 Subject: [PATCH] Added GetWinVer instruction git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@7309 212acab6-be3b-0410-9dea-997c60f758d6 --- Docs/src/generalpurpose.but | 8 +++++ Docs/src/history.but | 2 ++ Include/WinVer.nsh | 70 ++++++++++++++++++++++++++++++++++++- Source/Tests/winver.nsi | 65 ++++++++++++++++++++++++++++------ Source/exehead/Main.c | 40 ++++++++++++++++++--- Source/exehead/exec.c | 19 +++++++--- Source/exehead/exec.h | 3 -- Source/exehead/fileform.h | 12 +++++++ Source/exehead/state.h | 17 ++++++++- Source/exehead/util.c | 5 ++- Source/exehead/util.h | 11 +++--- Source/script.cpp | 32 ++++++++++++++++- Source/tokens.cpp | 2 ++ Source/tokens.h | 2 ++ 14 files changed, 257 insertions(+), 31 deletions(-) diff --git a/Docs/src/generalpurpose.but b/Docs/src/generalpurpose.but index 2621b5ef..5917eb97 100644 --- a/Docs/src/generalpurpose.but +++ b/Docs/src/generalpurpose.but @@ -51,6 +51,14 @@ The error flag is set if the shortcut cannot be created (i.e. either of the path \c "some command line parameters" "$INSTDIR\My Program.exe" 2 SW_SHOWNORMAL \ \c ALT|CONTROL|SHIFT|F5 "a description" +\S2{getwinver} GetWinVer + +\c user_var(output) Major|Minor|Build|ServicePack + +Gets the Windows version as reported by GetVersionEx. WinVer.nsh is the preferred method for performing Windows version checks. + +\c GetWinVer $1 Build + \S2{getdllversion} GetDLLVersion \c filename user_var(high dword output) user_var(low dword output) diff --git a/Docs/src/history.but b/Docs/src/history.but index bb4d51b3..93ad4ec3 100644 --- a/Docs/src/history.but +++ b/Docs/src/history.but @@ -18,6 +18,8 @@ Released on ???? ??th, 20?? \b Added \cw{$USER..} and \cw{$COMMON..} alias constants +\b Added \R{getwinver}{GetWinVer} instruction + \b Disallow start maximized mode \b Added /LAUNCH compiler switch diff --git a/Include/WinVer.nsh b/Include/WinVer.nsh index ea41ff89..babe4aa7 100644 --- a/Include/WinVer.nsh +++ b/Include/WinVer.nsh @@ -202,6 +202,54 @@ # lazy initialization macro +!define /IfNDef __WinVer_GWV GetWinVer + +!macro __WinVer_InitVars_NEW + !insertmacro __WinVer_DeclareVars + + # only calculate version once + StrCmp $__WINVERV "" _winver_noveryet + Return + _winver_noveryet: + + Push $0 + ${__WinVer_GWV} $0 Product + ${__WinVer_GWV} $__WINVERV NTDDIMajMin + IntOp $__WINVERV $__WINVERV << 16 ; _WINVER_MASKVMAJ & _WINVER_MASKVMIN + IntOp $__WINVERSP $0 & 2 + IntOp $__WINVERSP $__WINVERSP << 29 ; _WINVER_NTSRVBIT & _WINVER_NTDCBIT + + ${If} $__WINVERSP <> 0 ; Server? + ${If} $__WINVERV U>= 0x06000000 + ${AndIf} $__WINVERV U< 0x09000000 + IntOp $__WINVERV $__WINVERV | ${_WINVER_VERXBIT} ; Extra bit so Server 2008 comes after Vista SP1 that has the same minor version, same for Win7 vs 2008R2 + ${EndIf} + ${Else} + ${If} $__WINVERV = 0x05020000 + StrCpy $__WINVERV 0x05010000 ; Change XP 64-bit from 5.2 to 5.1 so it's still XP + ${EndIf} + ${EndIf} ;~ Server + + ${If} $0 <> 0 ; WNT? +!if "${NSIS_PTR_SIZE}" <= 4 +!ifdef WINVER_NT4_OVER_W95 + ${If} $__WINVERV = 0x04000000 + IntOp $__WINVERV $__WINVERV | ${_WINVER_VERXBIT} ; change NT 4.0.reserved.0 to 4.0.reserved.1 + ${EndIf} +!endif +!endif + IntOp $__WINVERSP $__WINVERSP | ${_WINVER_NTBIT} ; _WINVER_NTBIT + IntOp $__WINVERV $__WINVERV | ${_WINVER_NTBIT} ; _WINVER_NTBIT + ${EndIf} ;~ WNT + + ${__WinVer_GWV} $0 Build + IntOp $__WINVERSP $__WINVERSP | $0 ; _WINVER_MASKVBLD + ${__WinVer_GWV} $0 ServicePack + IntOp $0 $0 << 16 + IntOp $__WINVERSP $__WINVERSP | $0 ; _WINVER_MASKSP + Pop $0 +!macroend + !ifmacrondef __WinVer_Call_GetVersionEx !macro __WinVer_Call_GetVersionEx STRUCT_SIZE @@ -213,7 +261,7 @@ !endif -!macro __WinVer_InitVars +!macro __WinVer_InitVars_OLD # variables !insertmacro __WinVer_DeclareVars @@ -389,6 +437,14 @@ !macroend +!macro __WinVer_InitVars + !ifndef WinVer_v3_7 + !insertmacro __WinVer_InitVars_NEW + !else + !insertmacro __WinVer_InitVars_OLD + !endif +!macroend + # version comparison LogicLib macros !macro _WinVerAtLeast _a _b _t _f @@ -452,9 +508,13 @@ # service pack macros !macro _WinVer_GetServicePackLevel OUTVAR + !ifndef WinVer_v3_7 + ${__WinVer_GWV} ${OUTVAR} ServicePack + !else ${CallArtificialFunction} __WinVer_InitVars IntOp ${OUTVAR} $__WINVERSP & ${_WINVER_MASKSP} IntOp ${OUTVAR} ${OUTVAR} >> 16 + !endif !macroend !define WinVerGetServicePackLevel '!insertmacro _WinVer_GetServicePackLevel ' @@ -492,6 +552,7 @@ !define IsStarterEdition `${SM_STARTER} WinVer_SysMetricCheck ""` !define OSHasMediaCenter `${SM_MEDIACENTER} WinVer_SysMetricCheck ""` !define OSHasTabletSupport `${SM_TABLETPC} WinVer_SysMetricCheck ""` +!define IsSafeBootMode `67 WinVer_SysMetricCheck ""` # version retrieval macros @@ -509,7 +570,14 @@ !define WinVerGetMajor '!insertmacro __WinVer_GetVer $__WINVERV 24 ${_WINVER_MASKVMAJ}' !define WinVerGetMinor '!insertmacro __WinVer_GetVer $__WINVERV 16 ${_WINVER_MASKVMIN}' +!ifndef WinVer_v3_7 +!macro __WinVer_GetVerBuild outvar + ${__WinVer_GWV} ${outvar} Build +!macroend +!define WinVerGetBuild '!insertmacro __WinVer_GetVerBuild ' +!else !define WinVerGetBuild '!insertmacro __WinVer_GetVer $__WINVERSP "" ${_WINVER_MASKVBLD}' +!endif !macro _WinVer_BuildNumCheck op num _t _f !insertmacro _LOGICLIB_TEMP diff --git a/Source/Tests/winver.nsi b/Source/Tests/winver.nsi index 84b40bc5..d8004c3b 100644 --- a/Source/Tests/winver.nsi +++ b/Source/Tests/winver.nsi @@ -71,10 +71,7 @@ # SUCCESS Windows 95 OSR B # SUCCESS Windows 98 # SUCCESS Windows ME -# Server detection failed for Windows NT4 SP1 -# Expected: server -# Got: client -# FAILURE Windows NT4 SP1 +# SUCCESS Windows NT4 SP1 # SUCCESS Windows NT4 SP6 # SUCCESS Windows 2000 # SUCCESS Windows 2000 SP4 @@ -85,12 +82,6 @@ # SUCCESS Windows Server 2008 # Completed # -# FAILURES -# -# * On NT4 below SP6, the registry has to be checked to figure out if it's -# a server or not. WinVer doesn't do that yet. -# -# #### Name winver @@ -110,6 +101,59 @@ Var OSVERSIONINFOEX_INIT Var WVSTATS_TESTS Var WVSTATS_FAILS +!define __WinVer_GWV '!insertmacro __WinVerTest_GWV ' + +!include Util.nsh +!macro __WinVerTest_GWV_Imp ; This macro simulates the GetWinVer instruction + System::Store S + System::Call '*(&i999)p.r0' + Push $OSVERSIONINFO_CSD + System::Call '*$0($OSVERSIONINFO_INIT)' + ${If} $OSVERSIONINFOEX_RES <> 0 + Push $OSVERSIONINFOEX_CSD + System::Call '*$0($OSVERSIONINFOEX_INIT)' + ${EndIf} + Pop $8 + ${If} $8 == Product + System::Call '*$0(i,i,i,i,i.r1,&t128,&i2,&i2,&i2,&i1.r2)' + StrCpy $9 0 ; W9x + ${If} $1 U>= 2 + StrCpy $9 $2 + ${IfThen} $9 = 0 ${|} StrCpy $9 4 ${|} + ${EndIf} + ${ElseIf} $8 == NTDDIMajMin + System::Call '*$0(i,i.r1,i.r2)' + IntOp $9 $1 << 8 + IntOp $9 $9 | $2 + ${ElseIf} $8 == Build + System::Call '*$0(i,i,i,i.r9)' + ${ElseIf} $8 == ServicePack + System::Call '*$0(i,i,i,i,i,&t128.r1,&i2.r9,&i2,&i2,&i1)' + StrCpy $2 $1 1 + ${If} $9 = 0 + ${AndIf} $2 != "" + StrCpy $9 $1 "" 13 + ${If} $2 != "S" + StrCpy $2 $1 1 1 + StrCmp $2 "" +3 + IntFmt $2 "%#x" 0x$2 + IntOp $9 $2 - 9 ; W9x + ${EndIf} + ${EndIf} + ${Else} + MessageBox mb_iconstop "Unknown: $8" + Quit + ${EndIf} + System::Free $0 + Push $9 + System::Store L +!macroend +!macro __WinVerTest_GWV outvar field + Push "${field}" + ${CallArtificialFunction} __WinVerTest_GWV_Imp + Pop ${outvar} +!macroend + !macro __WinVer_Call_GetVersionEx STRUCT_SIZE !if ${STRUCT_SIZE} == ${OSVERSIONINFO_SIZE} @@ -412,6 +456,7 @@ Section # 940000000400000000000000650500000200000053657276696365205061636b2031000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 !insertmacro TestWinVer "Windows NT4 SP1" NT4 1 client nt ; Server can only be detected by reading the registry, cannot be performed in test environment. + DetailPrint "NOTE: NT4 SP1 client/server test is inaccurate" #### WINDOWS NT4 SP6 Server diff --git a/Source/exehead/Main.c b/Source/exehead/Main.c index 672fac1f..93826c40 100644 --- a/Source/exehead/Main.c +++ b/Source/exehead/Main.c @@ -96,18 +96,50 @@ EXTERN_C void NSISWinMainNOCRT() TCHAR *realcmds; TCHAR seekchar=_T(' '); TCHAR *cmdline; + OSVERSIONINFOEX ovi; SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS); - g_WinVer = GetVersion() & ~(NSIS_WINVER_WOW64FLAG); // We store a private flag in the build number bits + + // Get the version as reported by Windows + if (sizeof(void*) < 8) + { + *((UINT32*)&ovi.szCSDVersion[0]) = 0; // Zero out SP + *((UINT64*)&ovi.wServicePackMajor) = 0; // wServicePackMajor, wSuiteMask and wProductType + } + ovi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + if (!GetVersionEx((OSVERSIONINFO*) &ovi) && sizeof(void*) < 8) + { + ovi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx((OSVERSIONINFO*) &ovi); + if (sizeof(TCHAR) == 2 || ovi.dwPlatformId == VER_PLATFORM_WIN32_NT) + { + ovi.wProductType = 4; // TODO: For < NT4SP6, look it up in the registry. 4 means not W9x and not VER_NT_* + ovi.wServicePackMajor = ovi.szCSDVersion[0] == 'S' ? ovi.szCSDVersion[13] - '0' : 0; + } + } + if (sizeof(TCHAR) == 1 && ovi.dwPlatformId < VER_PLATFORM_WIN32_NT) + { + ovi.wProductType = 0; + ovi.wServicePackMajor = ovi.szCSDVersion[1] >= 'A' ? ovi.szCSDVersion[1] - ('A'-1) : 0; // A, B or C + } + if (sizeof(void*) < 8 && ovi.dwMajorVersion < 10) // Ideally (sizeof(TCHAR) == 1 && ovi.dwMajorVersion < 5) but the compatibility tab emulates this bug + { + ovi.dwBuildNumber &= 0xffff; // Remove W9x garbage + } + // Save the packed version information + { + UINT32 *p = &g_osinfo.WVBuild; + p[0] = ovi.dwBuildNumber; + p[1] = MAKELONG(MAKEWORD(ovi.wProductType, ovi.wServicePackMajor), MAKEWORD(ovi.dwMinorVersion, ovi.dwMajorVersion)); + } { // bug #1125: Don't load modules from the application nor current directory. // SetDefaultDllDirectories() allows us to restrict implicitly loaded and // dynamically loaded modules to just %windir%\System32 and directories // added with AddDllDirectory(). This prevents DLL search order attacks (CAPEC-471). - DWORD winver = g_WinVer; // CoCreateInstance(CLSID_ShellLink, ...) fails on Vista if SetDefaultDllDirectories is called - BOOL avoidwinbug = LOWORD(winver) == MAKEWORD(6, 0); + BOOL avoidwinbug = IsWinVista(); if (!avoidwinbug) { FARPROC fp = myGetProcAddress(MGA_SetDefaultDllDirectories); @@ -160,7 +192,7 @@ EXTERN_C void NSISWinMainNOCRT() // accessing a unsupported view and RegKey* takes care of that by looking at the WOW64 flag. FARPROC fp = myGetProcAddress(MGA_IsOS); enum { os_wow6432 = 30 }; - if (fp && ((BOOL(WINAPI*)(UINT))fp)(os_wow6432)) g_WinVer |= NSIS_WINVER_WOW64FLAG; + if (fp && ((BOOL(WINAPI*)(UINT))fp)(os_wow6432)) g_osinfo.WVProd |= NSIS_OSINFO_PROD_WOW64FLAG; } #endif diff --git a/Source/exehead/exec.c b/Source/exehead/exec.c index 7fc8e739..4b48da74 100644 --- a/Source/exehead/exec.c +++ b/Source/exehead/exec.c @@ -45,8 +45,9 @@ typedef struct _stack_t { static stack_t *g_st; #endif -exec_flags_t g_exec_flags; + exec_flags_t g_exec_flags_last_used; +execflags_and_osinfo g_execflags_and_osinfo; extra_parameters plugin_extra_parameters = { &g_exec_flags, @@ -1721,10 +1722,10 @@ static int NSISCALL ExecuteEntry(entry *entry_) case EW_GETOSINFO: { - //switch(parm0) + switch(parm3) { #ifdef NSIS_SUPPORT_FNUTIL - //case 0: + case GETOSINFO_KNOWNFOLDER: { TCHAR *outstr = var1; IID kfid; @@ -1740,8 +1741,18 @@ static int NSISCALL ExecuteEntry(entry *entry_) if (!succ) exec_error++, *outstr = _T('\0'); } - //break; + break; #endif + case GETOSINFO_READMEMORY: + { + TCHAR *outstr = var1; + SIZE_T addr = GetIntPtrFromParm(2), spec = GetIntPtrFromParm(4), value = 0; + UINT cb = LOBYTE(spec), offset = (UINT)(spec) >> 24; + if (addr == ABI_OSINFOADDRESS) addr = (SIZE_T) (&g_execflags_and_osinfo); + mini_memcpy(&value, ((char*) addr) + offset, cb); + iptrtostr(outstr, value); + } + break; } } break; diff --git a/Source/exehead/exec.h b/Source/exehead/exec.h index 0ffc3b8d..039bdaca 100644 --- a/Source/exehead/exec.h +++ b/Source/exehead/exec.h @@ -21,9 +21,6 @@ #include "api.h" -extern exec_flags_t g_exec_flags; -extern exec_flags_t g_exec_flags_last_used; - int NSISCALL ExecuteCodeSegment(int pos, HWND hwndProgress); // returns 0 on success int NSISCALL ExecuteCallbackFunction(int num); // returns 0 on success diff --git a/Source/exehead/fileform.h b/Source/exehead/fileform.h index 3b48a6eb..012fd9dc 100644 --- a/Source/exehead/fileform.h +++ b/Source/exehead/fileform.h @@ -568,6 +568,18 @@ typedef struct { #endif +#define GETOSINFO_KNOWNFOLDER 0 +#define GETOSINFO_READMEMORY 1 +typedef struct { + UINT32 WVBuild; + BYTE WVProd; // W9x: 0, WNT:AnyServer: & 2, WNT:DC: & 7 == 3 + BYTE WVSP; + BYTE WVMin; + BYTE WVMaj; +} osinfo; +#define ABI_OSINFOOFFSET ( sizeof(exec_flags_t) ) +#define ABI_OSINFOADDRESS ( 0 ) + // special escape characters used in strings: (we use control codes in order to minimize conflicts with normal characters) #define NS_LANG_CODE _T('\x01') // for a langstring #define NS_SHELL_CODE _T('\x02') // for a shell folder path diff --git a/Source/exehead/state.h b/Source/exehead/state.h index 890ef7e0..c6b42888 100644 --- a/Source/exehead/state.h +++ b/Source/exehead/state.h @@ -1,5 +1,5 @@ /* - * fileform.h + * state.h * * This file is a part of NSIS. * @@ -16,7 +16,10 @@ * Unicode support by Jim Park -- 08/22/2007 */ +#ifndef NSIS_EXEHEAD_STATE_H +#define NSIS_EXEHEAD_STATE_H #include "fileform.h" +#include "api.h" #ifdef __GNUC__ // GCC warns about array bounds when accessing g_usrvarssection[2] because it is only [1] at compile time, @@ -50,3 +53,15 @@ extern HWND insthwnd,insthwndbutton; #define g_hwnd 0 #define g_hInstance 0 #endif//NSIS_CONFIG_VISIBLE_SUPPORT + + +typedef struct { + exec_flags_t exec_flags; + osinfo osi; +} execflags_and_osinfo; + +extern execflags_and_osinfo g_execflags_and_osinfo; +#define g_exec_flags (g_execflags_and_osinfo.exec_flags) +#define g_osinfo (g_execflags_and_osinfo.osi) + +#endif //~ Include guard diff --git a/Source/exehead/util.c b/Source/exehead/util.c index 994af432..fc2edf64 100644 --- a/Source/exehead/util.c +++ b/Source/exehead/util.c @@ -851,7 +851,7 @@ TCHAR * NSISCALL GetNSISString(TCHAR *outbuf, int strtab) LPITEMIDLIST idl; int x = 2; - DWORD ver = sizeof(void*) > 4 ? MAKEWORD(5, 2) : g_WinVer; // We only care about 95/98 vs ME/NT4+ + BOOL isWin9598 = IsWin9598(); /* SHGetFolderPath as provided by shfolder.dll is used to get special folders unless the installer is running on Windows 95/98. For 95/98 shfolder.dll is @@ -869,8 +869,7 @@ TCHAR * NSISCALL GetNSISString(TCHAR *outbuf, int strtab) */ BOOL use_shfolder = // Use shfolder if not on 95/98 - !((ver & 0x80000000) && (LOWORD(ver) != MAKEWORD(4,90))) || - + !isWin9598 || // Unless the Application Data or Documents folder is requested ( (fldrs[3] == CSIDL_COMMON_APPDATA) || diff --git a/Source/exehead/util.h b/Source/exehead/util.h index f4522b58..fe4643f1 100644 --- a/Source/exehead/util.h +++ b/Source/exehead/util.h @@ -68,10 +68,13 @@ LONG NSISCALL RegKeyCreate(HKEY hBase, LPCTSTR SubKey, REGSAM RS, HKEY*phKey); void NSISCALL myRegGetStr(HKEY root, const TCHAR *sub, const TCHAR *name, TCHAR *out, UINT altview); -extern DWORD g_WinVer; // GetVersion() -#define IsWin95NT4() ( sizeof(void*) == 4 && LOWORD(g_WinVer) == 0x0004 ) -#define NSIS_WINVER_WOW64FLAG ( sizeof(void*) > 4 ? ( 0 ) : ( 0x40000000 ) ) -#define IsWow64() ( sizeof(void*) > 4 ? ( FALSE ) : ( g_WinVer & NSIS_WINVER_WOW64FLAG ) ) +#define GetWinVerNTDDIMajMin() ( *(UINT16*)(&g_osinfo.WVMin) ) +#define IsWin95NT4() ( sizeof(void*) == 4 && GetWinVerNTDDIMajMin() == 0x0400 ) +#define IsWin9598ME() ( sizeof(TCHAR) == 1 && g_osinfo.WVProd == 0 ) +#define IsWin9598() ( IsWin9598ME() && GetWinVerNTDDIMajMin() < MAKEWORD(90, 4) ) +#define IsWinVista() ( GetWinVerNTDDIMajMin() == 0x0600 ) +#define NSIS_OSINFO_PROD_WOW64FLAG ( sizeof(void*) > 4 ? ( 0 ) : ( 0x80 ) ) +#define IsWow64() ( sizeof(void*) > 4 ? ( FALSE ) : ( (signed char) g_osinfo.WVProd < 0 ) ) // NSIS_OSINFO_PROD_WOW64FLAG #define SystemSupportsAltRegView() ( sizeof(void*) > 4 ? ( TRUE ) : ( IsWow64() ) ) diff --git a/Source/script.cpp b/Source/script.cpp index b27e32f7..004069a7 100644 --- a/Source/script.cpp +++ b/Source/script.cpp @@ -4183,9 +4183,39 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) return add_entry(&ent); case TOK_GETKNOWNFOLDERPATH: ent.which=EW_GETOSINFO; - ent.offsets[0]=0; // Operation ent.offsets[1]=GetUserVarIndex(line, 1); ent.offsets[2]=add_string(line.gettoken_str(2)); + ent.offsets[3]=GETOSINFO_KNOWNFOLDER; + SCRIPT_MSG(_T("%") NPRIs _T(": %") NPRIs _T("->%") NPRIs _T("\n"), get_commandtoken_name(which_token), line.gettoken_str(2), line.gettoken_str(1)); + return add_entry(&ent); + case TOK_GETWINVER: + { + int k = line.gettoken_enum(2, _T("major\0minor\0build\0servicepack\0product\0ntddimajmin")), cb = 0, ofs = 0; + switch(k) + { + case 0: cb = 1, ofs = ABI_OSINFOOFFSET + FIELD_OFFSET(osinfo, WVMaj); break; + case 1: cb = 1, ofs = ABI_OSINFOOFFSET + FIELD_OFFSET(osinfo, WVMin); break; + case 2: cb = 4, ofs = ABI_OSINFOOFFSET + FIELD_OFFSET(osinfo, WVBuild); break; + case 3: cb = 1, ofs = ABI_OSINFOOFFSET + FIELD_OFFSET(osinfo, WVSP); break; + case 4: cb = 1, ofs = ABI_OSINFOOFFSET + FIELD_OFFSET(osinfo, WVProd); break; + case 5: cb = 2, ofs = ABI_OSINFOOFFSET + FIELD_OFFSET(osinfo, WVMin); break; + default: PRINTHELP(); + } + ent.which=EW_GETOSINFO; + ent.offsets[1]=GetUserVarIndex(line, 1); + ent.offsets[2]=add_intstring(ABI_OSINFOADDRESS); + ent.offsets[3]=GETOSINFO_READMEMORY; + ent.offsets[4]=add_intstring((cb << 0) | (ofs << 24)); + SCRIPT_MSG(_T("%") NPRIs _T(": %") NPRIs _T("=%") NPRIs _T("\n"), get_commandtoken_name(which_token), line.gettoken_str(1), line.gettoken_str(2)); + } + return add_entry(&ent); + case TOK_READMEMORY: + ent.which=EW_GETOSINFO; + ent.offsets[1]=GetUserVarIndex(line, 1); + ent.offsets[2]=add_string(line.gettoken_str(2)); + ent.offsets[3]=GETOSINFO_READMEMORY; + ent.offsets[4]=add_string(line.gettoken_str(3)); + SCRIPT_MSG(_T("%") NPRIs _T(": %") NPRIs _T("=*%") NPRIs _T("\n"), get_commandtoken_name(which_token), line.gettoken_str(1), line.gettoken_str(2)); return add_entry(&ent); case TOK_SEARCHPATH: ent.which=EW_SEARCHPATH; diff --git a/Source/tokens.cpp b/Source/tokens.cpp index 78a039d5..a20fd41d 100644 --- a/Source/tokens.cpp +++ b/Source/tokens.cpp @@ -111,6 +111,8 @@ static tokenType tokenlist[TOK__LAST] = {TOK_GETFULLPATHNAME,_T("GetFullPathName"),2,1,_T("[/SHORT] $(user_var: result) path_or_file"),TP_CODE}, {TOK_GETTEMPFILENAME,_T("GetTempFileName"),1,1,_T("$(user_var: name output) [base_dir]"),TP_CODE}, {TOK_GETKNOWNFOLDERPATH,_T("GetKnownFolderPath"),2,0,_T("$(user_var: result) knownfolderid"),TP_CODE}, +{TOK_GETWINVER,_T("GetWinVer"),2,0,_T("$(user_var: result) field\n field=MAJOR|MINOR|BUILD|SERVICEPACK"),TP_CODE}, +{TOK_READMEMORY,_T("ReadMemory"),3,0,_T("$(user_var: result) address size"),TP_CODE}, {TOK_HIDEWINDOW,_T("HideWindow"),0,0,_T(""),TP_CODE}, {TOK_ICON,_T("Icon"),1,0,_T("local_icon.ico"),TP_GLOBAL}, {TOK_IFABORT,_T("IfAbort"),1,1,_T("label_to_goto_if_abort [label_to_goto_if_no_abort]"),TP_CODE}, diff --git a/Source/tokens.h b/Source/tokens.h index c0978370..954286ff 100644 --- a/Source/tokens.h +++ b/Source/tokens.h @@ -283,6 +283,8 @@ enum TOK_FILESEEK, TOK_GETFULLPATHNAME, TOK_GETKNOWNFOLDERPATH, + TOK_GETWINVER, + TOK_READMEMORY, TOK_REBOOT, TOK_IFREBOOTFLAG, TOK_SETREBOOTFLAG,