From: <f0...@us...> - 2016-09-06 18:48:33
|
Revision: 6783 http://sourceforge.net/p/nsis/code/6783 Author: f0rt Date: 2016-09-06 18:48:32 +0000 (Tue, 06 Sep 2016) Log Message: ----------- Make WinWStrDupFromWC endian agnostic (Patch #273) Modified Paths: -------------- NSIS/trunk/Source/Tests/winchar.cpp NSIS/trunk/Source/winchar.cpp Modified: NSIS/trunk/Source/Tests/winchar.cpp =================================================================== --- NSIS/trunk/Source/Tests/winchar.cpp 2016-08-22 19:22:45 UTC (rev 6782) +++ NSIS/trunk/Source/Tests/winchar.cpp 2016-09-06 18:48:32 UTC (rev 6783) @@ -35,15 +35,15 @@ WINWCHAR test[] = { _x('t'), _x('e'), _x('s'), _x('t'), 0 }; WINWCHAR *dyn = WinWStrDupFromTChar(_T("test")); - CPPUNIT_ASSERT_EQUAL( 0, memcmp(test, dyn, 5) ); + CPPUNIT_ASSERT_EQUAL( 0, memcmp(test, dyn, sizeof(test)) ); free(dyn); dyn = WinWStrDupFromChar("test"); - CPPUNIT_ASSERT_EQUAL( 0, memcmp(test, dyn, 5) ); + CPPUNIT_ASSERT_EQUAL( 0, memcmp(test, dyn, sizeof(test)) ); free(dyn); dyn = WinWStrDupFromWC(L"test"); - CPPUNIT_ASSERT_EQUAL( 0, memcmp(test, dyn, 5) ); + CPPUNIT_ASSERT_EQUAL( 0, memcmp(test, dyn, sizeof(test)) ); free(dyn); } Modified: NSIS/trunk/Source/winchar.cpp =================================================================== --- NSIS/trunk/Source/winchar.cpp 2016-08-22 19:22:45 UTC (rev 6782) +++ NSIS/trunk/Source/winchar.cpp 2016-09-06 18:48:32 UTC (rev 6783) @@ -111,7 +111,7 @@ // NOTE: Anything outside the ASCII range will not convert correctly! size_t cch = wcslen(s); WINWCHAR* p = (WINWCHAR*) malloc(++cch * 2); - if (p) for (size_t i = 0; i < cch; ++i) p[i] = (unsigned char) s[i]; + if (p) for (size_t i = 0; i < cch; ++i) p[i] = FIX_ENDIAN_INT16(s[i]); return p; #endif } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <and...@us...> - 2016-10-11 19:47:23
|
Revision: 6789 http://sourceforge.net/p/nsis/code/6789 Author: anders_k Date: 2016-10-11 19:47:21 +0000 (Tue, 11 Oct 2016) Log Message: ----------- LockWindow Off should always enable painting Modified Paths: -------------- NSIS/trunk/Source/exehead/Ui.c NSIS/trunk/Source/exehead/exec.c NSIS/trunk/Source/script.cpp Modified: NSIS/trunk/Source/exehead/Ui.c =================================================================== --- NSIS/trunk/Source/exehead/Ui.c 2016-10-11 19:36:06 UTC (rev 6788) +++ NSIS/trunk/Source/exehead/Ui.c 2016-10-11 19:47:21 UTC (rev 6789) @@ -637,7 +637,7 @@ if (!ui_dlg_visible && m_curwnd) { - ShowWindow(hwndDlg, SW_SHOWDEFAULT); + ShowWindow(hwndDlg, SW_SHOWDEFAULT); // BUGBUG: Why is this here, it does not seem to be required? ui_dlg_visible = 1; } Modified: NSIS/trunk/Source/exehead/exec.c =================================================================== --- NSIS/trunk/Source/exehead/exec.c 2016-10-11 19:36:06 UTC (rev 6788) +++ NSIS/trunk/Source/exehead/exec.c 2016-10-11 19:47:21 UTC (rev 6789) @@ -1702,10 +1702,10 @@ #ifdef NSIS_LOCKWINDOW_SUPPORT case EW_LOCKWINDOW: { - // ui_dlg_visible is 1 or 0, so is parm0 - SendMessage(g_hwnd, WM_SETREDRAW, parm0 & ui_dlg_visible, 0); - if ( parm0 ) - InvalidateRect(g_hwnd, NULL, FALSE); + // Not using ui_dlg_visible because it is not always in sync and we don't want to risk not painting. + // See http://forums.winamp.com/showthread.php?t=397781 for details. + SendMessage(g_hwnd, WM_SETREDRAW, parm0, 0); + if (parm0) InvalidateRect(g_hwnd, NULL, FALSE); break; } #endif //NSIS_LOCKWINDOW_SUPPORT Modified: NSIS/trunk/Source/script.cpp =================================================================== --- NSIS/trunk/Source/script.cpp 2016-10-11 19:36:06 UTC (rev 6788) +++ NSIS/trunk/Source/script.cpp 2016-10-11 19:47:21 UTC (rev 6789) @@ -6297,9 +6297,7 @@ case TOK_PLUGINDIR: case TOK__PLUGINCOMMAND: case TOK_INITPLUGINSDIR: - { ERROR_MSG(_T("Error: %") NPRIs _T(" specified, NSIS_CONFIG_PLUGIN_SUPPORT not defined.\n"),line.gettoken_str(0)); - } return PS_ERROR; #endif// NSIS_CONFIG_PLUGIN_SUPPORT @@ -6308,8 +6306,7 @@ SCRIPT_MSG(_T("LockWindow: lock state=%d\n"),line.gettoken_str(1)); ent.which=EW_LOCKWINDOW; ent.offsets[0]=line.gettoken_enum(1,_T("on\0off\0")); - if (ent.offsets[0] == -1) - PRINTHELP(); + if (ent.offsets[0] == -1) PRINTHELP(); return add_entry(&ent); #else case TOK_LOCKWINDOW: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <and...@us...> - 2017-04-13 14:42:48
|
Revision: 6846 http://sourceforge.net/p/nsis/code/6846 Author: anders_k Date: 2017-04-13 14:42:47 +0000 (Thu, 13 Apr 2017) Log Message: ----------- Fix POSIX error Modified Paths: -------------- NSIS/trunk/Source/Platform.h NSIS/trunk/Source/script.cpp NSIS/trunk/Source/util.h Modified: NSIS/trunk/Source/Platform.h =================================================================== --- NSIS/trunk/Source/Platform.h 2017-04-06 18:07:29 UTC (rev 6845) +++ NSIS/trunk/Source/Platform.h 2017-04-13 14:42:47 UTC (rev 6846) @@ -492,6 +492,12 @@ # define SHACF_FILESYSTEM 1 #endif +#ifndef SEE_MASK_NOCLOSEPROCESS +#define SEE_MASK_NOCLOSEPROCESS 0x00000040 +#define SEE_MASK_FLAG_NO_UI 0x00000400 +#define SEE_MASK_FLAG_DDEWAIT 0x00000100 +#endif + // other stuff #ifndef CP_ACP Modified: NSIS/trunk/Source/script.cpp =================================================================== --- NSIS/trunk/Source/script.cpp 2017-04-06 18:07:29 UTC (rev 6845) +++ NSIS/trunk/Source/script.cpp 2017-04-13 14:42:47 UTC (rev 6846) @@ -3257,7 +3257,7 @@ ret=RunChildProcessRedirected(exec, forceutf8 ? true : false); else #endif //~ _WIN32 - ret=sane_system(exec); + ret=sane_system(exec), (void)forceutf8; // forceutf8 is not used on POSIX if (comp == 5) { _stprintf(buf,_T("%d"),ret); @@ -5425,7 +5425,7 @@ ERROR_MSG(_T("%") NPRIs _T(": %d bytes of data exceeded\n"),cmdname,sizeof(data)); return PS_ERROR; } - if (multisz && (data_len < 4 || *(UINT32*)(&data[data_len-4]))) PRINTHELPEX(cmdname); + if (multisz && (data_len < 4 || 0 != read_ptr_as<UINT32>(&data[data_len-4]))) PRINTHELPEX(cmdname); // Must end with 4 zero bytes SCRIPT_MSG(_T("%") NPRIs _T(": %") NPRIs _T("\\%") NPRIs _T("\\%") NPRIs _T("=%") NPRIs _T("\n"), cmdname,line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(4)); if (multisz && !build_unicode) for (int p1=0, p2=p1; p1 < data_len; data_len--) data[p1++]=data[p2], p2+=2; // BUGBUG: Should convert each string from UTF-16 to DBCS but only exehead knows the codepage, limited to ASCII for now. Modified: NSIS/trunk/Source/util.h =================================================================== --- NSIS/trunk/Source/util.h 2017-04-06 18:07:29 UTC (rev 6845) +++ NSIS/trunk/Source/util.h 2017-04-13 14:42:47 UTC (rev 6846) @@ -276,6 +276,15 @@ // assumption: T is an int type template <class T> inline T align_to_512(const T x) { return (x+511) & ~511; } +template<class T> inline T read_ptr_as(const void*p) +{ +#if defined(_MSC_VER) && (_MSC_VER-0 < 1400) // TODO: Figure out which versions are able to optimize the memcpy + return *(T*)(p); +#else + T t; memcpy(&t, p, sizeof(T)); return t; +#endif +} + // some values need to be truncated from size_t to [unsigned] int, using this function is better than a plain cast template<class R, class T> inline R internaltruncate_cast(T t) { assert((~((T)0)) > T(0)); // Only unsigned types supported right now This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <and...@us...> - 2017-06-23 12:59:47
|
Revision: 6876 http://sourceforge.net/p/nsis/code/6876 Author: anders_k Date: 2017-06-23 12:59:44 +0000 (Fri, 23 Jun 2017) Log Message: ----------- Logging build now prints EW_SETFLAG changes Modified Paths: -------------- NSIS/trunk/Source/build.cpp NSIS/trunk/Source/exehead/api.h NSIS/trunk/Source/exehead/exec.c Modified: NSIS/trunk/Source/build.cpp =================================================================== --- NSIS/trunk/Source/build.cpp 2017-06-23 01:11:30 UTC (rev 6875) +++ NSIS/trunk/Source/build.cpp 2017-06-23 12:59:44 UTC (rev 6876) @@ -363,7 +363,7 @@ m_ShellConstants.add(_T("NETHOOD"), CSIDL_NETHOOD, CSIDL_NETHOOD); m_ShellConstants.add(_T("FONTS"), CSIDL_FONTS, CSIDL_FONTS); m_ShellConstants.add(_T("TEMPLATES"), CSIDL_TEMPLATES, CSIDL_COMMON_TEMPLATES); - m_ShellConstants.add(_T("APPDATA"), CSIDL_APPDATA, CSIDL_COMMON_APPDATA); + m_ShellConstants.add(_T("APPDATA"), CSIDL_APPDATA, CSIDL_COMMON_APPDATA); // Note: There is no all-users roaming appdata folder. m_ShellConstants.add(_T("LOCALAPPDATA"), CSIDL_LOCAL_APPDATA, CSIDL_COMMON_APPDATA); m_ShellConstants.add(_T("PRINTHOOD"), CSIDL_PRINTHOOD, CSIDL_PRINTHOOD); //m_ShellConstants.add(_T("ALTSTARTUP"), CSIDL_ALTSTARTUP, CSIDL_COMMON_ALTSTARTUP); Modified: NSIS/trunk/Source/exehead/api.h =================================================================== --- NSIS/trunk/Source/exehead/api.h 2017-06-23 01:11:30 UTC (rev 6875) +++ NSIS/trunk/Source/exehead/api.h 2017-06-23 12:59:44 UTC (rev 6876) @@ -40,20 +40,20 @@ // besides the stack, variables and HWND passed on to plug-ins. typedef struct { - int autoclose; - int all_user_var; // SetShellVarContext: User context = 0, Machine context = 1 - int exec_error; // IfErrors - int abort; // IfAbort - int exec_reboot; // NSIS_SUPPORT_REBOOT - int reboot_called; // NSIS_SUPPORT_REBOOT - int XXX_cur_insttype; // Deprecated - int plugin_api_version; // See NSISPIAPIVER_CURR (Note: used to be XXX_insttype_changed) - int silent; // NSIS_CONFIG_SILENT_SUPPORT - int instdir_error; - int rtl; - int errlvl; // SetErrorLevel - int alter_reg_view; // SetRegView: Default View = 0, Alternative View = (sizeof(void*) > 4 ? KEY_WOW64_32KEY : KEY_WOW64_64KEY) - int status_update; // SetDetailsPrint + int autoclose; // SetAutoClose + int all_user_var; // SetShellVarContext: User context = 0, Machine context = 1 + int exec_error; // IfErrors + int abort; // IfAbort + int exec_reboot; // IfRebootFlag (NSIS_SUPPORT_REBOOT) + int reboot_called; // NSIS_SUPPORT_REBOOT + int XXX_cur_insttype; // Deprecated + int plugin_api_version; // Plug-in ABI. See NSISPIAPIVER_CURR (Note: used to be XXX_insttype_changed) + int silent; // IfSilent (NSIS_CONFIG_SILENT_SUPPORT) + int instdir_error; // GetInstDirError + int rtl; // 1 if $LANGUAGE is a RTL language + int errlvl; // SetErrorLevel + int alter_reg_view; // SetRegView: Default View = 0, Alternative View = (sizeof(void*) > 4 ? KEY_WOW64_32KEY : KEY_WOW64_64KEY) + int status_update; // SetDetailsPrint } exec_flags_t; #ifndef NSISCALL Modified: NSIS/trunk/Source/exehead/exec.c =================================================================== --- NSIS/trunk/Source/exehead/exec.c 2017-06-23 01:11:30 UTC (rev 6875) +++ NSIS/trunk/Source/exehead/exec.c 2017-06-23 12:59:44 UTC (rev 6876) @@ -284,7 +284,7 @@ return ExecuteCodeSegment(v,NULL); } case EW_UPDATETEXT: - log_printf2(_T("detailprint: %s"),GetStringFromParm(0x00)); + log_printf2(_T("DetailPrint: %s"),GetStringFromParm(0x00)); update_status_text(parm0,0); break; case EW_SLEEP: @@ -305,6 +305,7 @@ { FIELDN(g_exec_flags_last_used,parm0)=FIELDN(g_exec_flags,parm0); FIELDN(g_exec_flags,parm0)=GetIntFromParm(1); + log_printf3(_T("SetFlag: %d=%d"),parm0,FIELDN(g_exec_flags,parm0)); } else { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ki...@us...> - 2017-07-23 19:53:41
|
Revision: 6880 http://sourceforge.net/p/nsis/code/6880 Author: kichik Date: 2017-07-23 19:53:39 +0000 (Sun, 23 Jul 2017) Log Message: ----------- vc6 build errors Modified Paths: -------------- NSIS/trunk/Source/build.cpp NSIS/trunk/Source/build.h NSIS/trunk/Source/script.cpp Modified: NSIS/trunk/Source/build.cpp =================================================================== --- NSIS/trunk/Source/build.cpp 2017-07-23 19:11:57 UTC (rev 6879) +++ NSIS/trunk/Source/build.cpp 2017-07-23 19:53:39 UTC (rev 6880) @@ -3451,16 +3451,16 @@ return ret; } -void CEXEBuild::DiagState::Push() +void DiagState::Push() { - CEXEBuild::DiagState *p = new DiagState(); + DiagState *p = new DiagState(); p->m_Disabled = m_Disabled; // Copy current state p->m_pStack = m_pStack, m_pStack = p; } -bool CEXEBuild::DiagState::Pop() +bool DiagState::Pop() { if (!m_pStack) return false; - CEXEBuild::DiagState *pPop = m_pStack; + DiagState *pPop = m_pStack; m_pStack = pPop->m_pStack, pPop->m_pStack = 0; m_Disabled.swap(pPop->m_Disabled); delete pPop; Modified: NSIS/trunk/Source/build.h =================================================================== --- NSIS/trunk/Source/build.h 2017-07-23 19:11:57 UTC (rev 6879) +++ NSIS/trunk/Source/build.h 2017-07-23 19:53:39 UTC (rev 6880) @@ -165,6 +165,21 @@ #define FLAG_OFFSET(flag) (FIELD_OFFSET(exec_flags_t, flag)/sizeof(int)) +class DiagState { +public: + DiagState() : m_pStack(0) { assert(DIAGCODE_INTERNAL_LAST <= 0xffff); } + ~DiagState() { delete m_pStack; } + void Enable(DIAGCODE n) { m_Disabled.erase(static_cast<unsigned short>(n)); } + void Disable(DIAGCODE n) { m_Disabled.insert(static_cast<unsigned short>(n)); } + bool IsDisabled(DIAGCODE n) { return m_Disabled.find(static_cast<unsigned short>(n)) != m_Disabled.end(); } + void Push(); + bool Pop(); + static bool IsValidCode(unsigned int n) { return n >= DIAGCODE_INTERNAL_FIRST && n <= DIAGCODE_INTERNAL_LAST; } +protected: + DiagState *m_pStack; + std::set<unsigned short> m_Disabled; +}; + class CEXEBuild { public: CEXEBuild(signed char pponly); @@ -396,20 +411,7 @@ void print_warnings(); void warninghelper(DIAGCODE dc, bool fl, const TCHAR *fmt, va_list args); - class DiagState { - public: - DiagState() : m_pStack(0) { assert(DIAGCODE_INTERNAL_LAST <= 0xffff); } - ~DiagState() { delete m_pStack; } - void Enable(DIAGCODE n) { m_Disabled.erase(static_cast<unsigned short>(n)); } - void Disable(DIAGCODE n) { m_Disabled.insert(static_cast<unsigned short>(n)); } - bool IsDisabled(DIAGCODE n) { return m_Disabled.find(static_cast<unsigned short>(n)) != m_Disabled.end(); } - void Push(); - bool Pop(); - static bool IsValidCode(unsigned int n) { return n >= DIAGCODE_INTERNAL_FIRST && n <= DIAGCODE_INTERNAL_LAST; } - protected: - DiagState *m_pStack; - std::set<unsigned short> m_Disabled; - } diagstate; + DiagState diagstate; /** Are we defining an uninstall version of the code? * @param un Use like a boolean to define whether in uninstall mode. Modified: NSIS/trunk/Source/script.cpp =================================================================== --- NSIS/trunk/Source/script.cpp 2017-07-23 19:11:57 UTC (rev 6879) +++ NSIS/trunk/Source/script.cpp 2017-07-23 19:53:39 UTC (rev 6880) @@ -868,7 +868,7 @@ #endif multiple_entries_instruction=0; - entry ent={}; + entry ent={0,}; switch (which_token) { // macro stuff This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <and...@us...> - 2017-10-04 12:25:38
|
Revision: 6914 http://sourceforge.net/p/nsis/code/6914 Author: anders_k Date: 2017-10-04 12:25:35 +0000 (Wed, 04 Oct 2017) Log Message: ----------- Added POSIX TLB reader functions Added Paths: ----------- NSIS/trunk/Source/BinInterop.cpp NSIS/trunk/Source/BinInterop.h Added: NSIS/trunk/Source/BinInterop.cpp =================================================================== --- NSIS/trunk/Source/BinInterop.cpp (rev 0) +++ NSIS/trunk/Source/BinInterop.cpp 2017-10-04 12:25:35 UTC (rev 6914) @@ -0,0 +1,411 @@ +/* + * BinInterop.cpp + * + * This file is a part of NSIS. + * + * Copyright (C) 2017 Anders Kjersem + * + * Licensed under the zlib/libpng license (the "License"); + * you may not use this file except in compliance with the License. + * + * Licence details can be found in the file COPYING. + * + * This software is provided 'as-is', without any express or implied + * warranty. + * + */ + +#include "BinInterop.h" +#include "ResourceEditor.h" +#include "util.h" +#include <wchar.h> // _tcstoul +#include <stdexcept> + +enum { DEBUGDUMP = 0 }; // Dump debug info on little-endian systems? + +#define MKPTR(cast, base, offset) ( (cast) ( ((char*)(base)) + (offset) ) ) +const size_t invalid_res_id = ~(size_t)0; + +FILE* MSTLB_fopen(const TCHAR*filepath, size_t*pResId) +{ + size_t resid = invalid_res_id; // MSDN:"By default, the type library is extracted from the first resource of type ITypeLib" + FILE*f = FOPEN(filepath, ("rb")); + if (!f) + { + // Retry with the "filename.exe\1234" syntax supported by LoadTypeLib + tstring name = get_file_name(filepath), parent = get_dir_name(filepath); + const TCHAR *pStart; + TCHAR *pEnd; + resid = _tcstoul(pStart = name.c_str(), &pEnd, 10); + if (pEnd != pStart && !*pEnd && (f = FOPEN(parent.c_str(), ("rb")))) + { + USHORT mz, valid = false; + valid = fread(&mz, 1, sizeof(mz), f) == 2 && (mz == 0x4d5a || mz == 0x5a4d); + if (!valid) fclose(f), f = 0; // Only allow the special syntax on executable files + } + } + if (pResId) *pResId = resid; + return f; +} + +#if !defined(_WIN32) || defined(NSIS_GETTLBVERSION_FORCEINTERNAL) + +unsigned long get_file_size32(FILE*f) +{ + unsigned long error = ~(0UL), result = error, cb, restoreseek = false; + fpos_t orgpos; + if (restoreseek ? 0 == fgetpos(f, &orgpos) : true) + if (0 == fseek(f, 0, SEEK_END)) + if ((cb = ftell(f)) != -1L) + if (restoreseek ? 0 == fsetpos(f, &orgpos) : true) + result = cb; + return result; +} + +void* alloc_and_read_file(FILE*f, unsigned long&size) +{ + void *result = 0, *mem = 0; + if (!f) return result; + size = get_file_size32(f); + mem = (~(0UL) != size) ? malloc(size) : 0; + if (mem) + if (0 == fseek(f, 0, SEEK_SET)) + if (fread(mem, 1, size, f) == size) + result = mem, mem = 0; + free(mem); + return result; +} + +/*void* alloc_and_read_file(const TCHAR*filepath, unsigned long&size) +{ + void *result = 0; + FILE*f = FOPEN(filepath, ("rb")); + if (f) + result = alloc_and_read_file(f, size), fclose(f); + return result; +}*/ + +#if 0 +// midl /DOLDTLB=1 /oldtlb /tlb SLTG.tlb test.idl && midl /DNEWTLB=1 /newtlb /tlb MSFT.tlb test.idl +#ifdef NEWTLB +import "unknwn.idl"; +[ + object, uuid(42424242-1111-1111-0001-424242424242), + //oleautomation, //TYPEFLAG_FOLEAUTOMATION? + //dual, //"Specifying dual on an interface implies that the interface is compatible with Automation, and therefore causes both the TYPEFLAG_FDUAL and TYPEFLAG_FOLEAUTOMATION flags to be set" +] +interface IInTeRfAcE1 : IUnknown { HRESULT I1_MeThOd1(); }; + +[ object, uuid(42424242-1111-1111-0002-424242424242) ] +interface IInTeRfAcE2 : IUnknown { [idempotent] HRESULT I2_MeThOd1(); }; +#endif + +[ //msdn.microsoft.com/en-us/library/windows/desktop/aa367069 + uuid(42424242-1234-1234-1234-424242424242), lcid(0x0809), version(666.1337), + helpstring("HeLpStRiNg"), // ICreateTypeInfo::SetDocString? + helpfile("HeLpFiLe"), helpcontext(0xBABEFACE), +#ifdef NEWTLB + helpstringdll("HeLpStRiNgDlL"), helpstringcontext(0xF00DBABE), +#endif + control, /* LIBFLAG_FCONTROL */ hidden, /* LIBFLAG_FHIDDEN */ restricted, /* LIBFLAG_FRESTRICTED */ +] +library LiBnAmE +{ +#ifdef NEWTLB + //importlib("stdole2.tlb"); +#else + importlib("stdole32.tlb"); +#endif + [ uuid(42424242-0000-0000-0000-424242424242), helpstring("CoClAsSHeLpStRiNg") ] + coclass CoClAsS + { +#ifdef NEWTLB + [default] interface IInTeRfAcE1; interface IInTeRfAcE2; +#else + [default] interface IUnknown; +#endif + }; +}; +#endif //~ .IDL + +#pragma pack(1) +typedef struct { + UINT32 Sig; // 'MSFT' + USHORT FmtVerMaj, FmtVerMin; // This is just a guess, always seems to be 2.1? + UINT32 Unknown; + UINT32 UnkLocale; // idl:library:lcid + UINT32 Locale; // idl:library:lcid & ICreateTypeLib::SetLcid? This is the LCID returned in TLIBATTR. + UINT32 FlagsAndSK; // 0x03=tagSYSKIND mask. 0x0010=idl:library:helpfile 0x0100=idl:library:helpstringdll + USHORT VerMaj, VerMin; // ICreateTypeLib::SetVersion? + USHORT LibFlags; // tagLIBFLAGS (TLIBATTR.wLibFlags) + USHORT Unknown2; + UINT32 Unknown3; // Count of? This changes when the number of interfaces in the .idl changes. + UINT32 HelpString; + UINT32 HelpStringContext; + UINT32 HelpContext; + // ...? +} MSTLB_MSFT_MINIHEADER; + +typedef struct { + UINT32 Sig; // 'SLTG' + USHORT Count; // Count of stream descriptors + USHORT CompObjFooterSize, CompObjHeaderSize; + USHORT First; // Index of the first stream (Streams must be enumerated in the correct order!) + char Guid[16]; // DEFINE_OLEGUID(CLSID_?, 0x000204ff, 0, 0) +} MSTLB_SLTG_HEADER; +typedef struct { + BYTE Sig[1+7+1+3+1]; // "\001CompObj\0dir" (Is "dir" part of the signature or is it the offset in one of the stream descriptors?) +} MSTLB_SLTG_COMPOBJ; +typedef struct { + UINT32 Size; // Size of stream + USHORT Unknown; // Offset to something in the COMPOBJ header? + USHORT Next; // Next stream index +} MSTLB_SLTG_SD; +typedef struct { + USHORT Len; // 0xffff if there is no string. +} MSTLB_SLTG_CSHDR; // Counted narrow string without \0 terminator. +typedef struct { + enum { SIG = 0x51cc, CSCOUNT = 3 }; + USHORT Sig; // 'CC51' + USHORT Unknown[2]; + MSTLB_SLTG_CSHDR Strings[CSCOUNT]; // (Unknown, idl:library:helpstring and idl:library:helpfile) +} MSTLB_SLTG_BLOCK_LIBATTR_HEADER; +typedef struct { + UINT32 HelpContext; // idl:library:helpcontext + USHORT SysKind; // tagSYSKIND (All 16-bits returned in TLIBATTR.syskind) + UINT32 Locale; + USHORT BadLocale; // If this is non-zero the returned TLIBATTR LCID is 0. + USHORT LibFlags; // tagLIBFLAGS (TLIBATTR.wLibFlags) + USHORT VerMaj, VerMin; + char LibGuid[16]; // idl:library:uuid + //...? +} MSTLB_SLTG_BLOCK_LIBATTR_FOOTER; +#pragma pack() + +static bool MSTLB_GetVersion_MSFT(const void*pData, size_t cbData, DWORD &high, DWORD &low) +{ + if (cbData >= sizeof(MSTLB_MSFT_MINIHEADER)) + { + const MSTLB_MSFT_MINIHEADER &h = *(MSTLB_MSFT_MINIHEADER*) pData; + if (FIX_ENDIAN_INT32(h.Sig) == 0x5446534D) + { + if (DEBUGDUMP) + { + for (UINT32 i = 0; i <= min(cbData / 4, 20) && DEBUGDUMP > 1; ++i) + _tprintf(_T("%2x=%.8x (%.4x:%.4x)\n"), i * 4, ((UINT32*)&h)[i], ((USHORT*)&h)[(i*2)+0], ((USHORT*)&h)[(i*2)+1]); + } + + if (FIX_ENDIAN_INT16(h.FmtVerMaj) == 2 && FIX_ENDIAN_INT16(h.FmtVerMin) == 1) // Is this always 2.1? + { + if (DEBUGDUMP) + { + UINT32 fask = FIX_ENDIAN_INT32(h.FlagsAndSK), lcid = FIX_ENDIAN_INT32(h.Locale), lf = FIX_ENDIAN_INT16(h.LibFlags); + _tprintf(_T("lcid=%#.8x sk=%#.8x lf=%#.4x hc=%#x\n"), lcid, fask & 0x03, lf | 0x08, FIX_ENDIAN_INT32(h.HelpContext)); // 0x08 for LIBFLAG_FHASDISKIMAGE because it is not stored in the .TLB + } + + // lcid = FIX_ENDIAN_INT32(h.Locale); + // sysk = FIX_ENDIAN_INT32(h.FlagsAndSK) & 0x03; + // libf = FIX_ENDIAN_INT16(h.LibFlags) | 0x08; // 0x08 for LIBFLAG_FHASDISKIMAGE + high = FIX_ENDIAN_INT16(h.VerMaj), low = FIX_ENDIAN_INT16(h.VerMin); + return true; + } + } + } + return false; +} + +static USHORT GetLenLEToHE(const MSTLB_SLTG_CSHDR &s) +{ + USHORT len = FIX_ENDIAN_INT16(s.Len); + return len != 0xffff ? len : 0; +} + +static inline void DebugDumpLE(const MSTLB_SLTG_CSHDR &s, const char *prefix = 0) +{ + if (DEBUGDUMP) + { + USHORT len = GetLenLEToHE(s); + if (len) + { + if (prefix) _tprintf(_T("%") NPRIns _T(": "), prefix); + TCHAR fmt[50]; + _stprintf(fmt, _T("\"%%.%u") NPRIns _T("\"\n"), len); + _tprintf(fmt, MKPTR(char*, &s, sizeof(USHORT))); + } + } +} + +static bool MSTLB_IsSerializedOleGuid(const void*pData, UINT32 Bits1 = 0, UINT32 Mask1 = 0) +{ + bool failed = false; + failed |= (FIX_ENDIAN_INT32(*MKPTR(UINT32*, pData, 4*0)) & Mask1) != Bits1; + failed |= (FIX_ENDIAN_INT32(*MKPTR(UINT32*, pData, 4*1))) != 0x00000000; + failed |= (FIX_ENDIAN_INT32(*MKPTR(UINT32*, pData, 4*2))) != 0x000000C0; + failed |= (FIX_ENDIAN_INT32(*MKPTR(UINT32*, pData, 4*3))) != 0x46000000; + return !failed; // Does it look like a DEFINE_OLEGUID() GUID? +} + +static bool MSTLB_GetVersion_SLTG(const void*pData, size_t cbData, DWORD &high, DWORD &low) +{ + if (cbData >= sizeof(MSTLB_SLTG_HEADER)) + { + size_t eofPtr = MKPTR(size_t, pData, cbData); + const MSTLB_SLTG_HEADER &h = *(MSTLB_SLTG_HEADER*) pData; + if (FIX_ENDIAN_INT32(h.Sig) == 0x047544C53 && MSTLB_IsSerializedOleGuid(h.Guid, 0x00020400, 0xffffff00)) // 0x000204xx for IID_ITypeLib and friends + { + MSTLB_SLTG_SD *pSD = MKPTR(MSTLB_SLTG_SD*, &h, sizeof(MSTLB_SLTG_HEADER)); + UINT32 streamCount = FIX_ENDIAN_INT16(h.Count); + // compobjCount = streamCount >= 1 ? streamCount - 1 : 0, compobjHdrSize = 13; + if (DEBUGDUMP) + { + for (UINT32 i = 0; i <= min(cbData / 4, 100 / 4) && DEBUGDUMP > 1; ++i) + _tprintf(_T("%2x=%.8x (%.4x:%.4x)\n"), i * 4, ((UINT32*)&h)[i], ((USHORT*)&h)[(i*2)+0], ((USHORT*)&h)[(i*2)+1]); + _tprintf(_T("Count=%d First=%d\n"), FIX_ENDIAN_INT16(h.Count), FIX_ENDIAN_INT16(h.First)); + for (UINT32 i = 0, c = streamCount; i < c; ++i) + _tprintf(_T("S%2d: %.8x=%-4u %.4x=%-2u %.4x=%-2u\n"), i, pSD[i].Size, pSD[i].Size, pSD[i].Unknown, pSD[i].Unknown, pSD[i].Next, pSD[i].Next); + } + + // Check the data in each stream until we find the LIBATTR block + void *pFirstStreamData = MKPTR(void*, pSD, (sizeof(MSTLB_SLTG_SD) * streamCount) + FIX_ENDIAN_INT16(h.CompObjHeaderSize) + FIX_ENDIAN_INT16(h.CompObjFooterSize)); + for (UINT32 tries = 0, i = FIX_ENDIAN_INT16(h.First), c = streamCount, o = 0; tries < c && i < c; ++tries) + { + MSTLB_SLTG_BLOCK_LIBATTR_HEADER *pBH = MKPTR(MSTLB_SLTG_BLOCK_LIBATTR_HEADER*, pFirstStreamData, o), *pD1 = pBH; + if (eofPtr < MKPTR(size_t, pBH, sizeof(USHORT))) break; // The stream must at least have a signature + + if (DEBUGDUMP) + { + _tprintf(_T("Sig=%#.4x Size=%#.6x @ %#.6x in stream %u\n"), FIX_ENDIAN_INT16(pBH->Sig), FIX_ENDIAN_INT32(pSD[i].Size), (unsigned int) ((size_t) pBH - (size_t) pData), i); + } + + if (FIX_ENDIAN_INT16(pBH->Sig) == pD1->SIG && eofPtr > MKPTR(size_t, pD1, sizeof(*pD1))) + { + unsigned long o2 = sizeof(USHORT) * 3; // Skip past the initial members + for (UINT32 strIdx = 0; strIdx < pD1->CSCOUNT; ++strIdx) + { + MSTLB_SLTG_CSHDR *pS = MKPTR(MSTLB_SLTG_CSHDR*, pD1, o2); + if (DEBUGDUMP) DebugDumpLE(*pS); + o2 += sizeof(MSTLB_SLTG_CSHDR) + GetLenLEToHE(*pS); // Skip past the embedded counted string + } + + MSTLB_SLTG_BLOCK_LIBATTR_FOOTER *pD2 = MKPTR(MSTLB_SLTG_BLOCK_LIBATTR_FOOTER*, pD1, o2); + if (eofPtr < MKPTR(size_t, pD2, sizeof(*pD2))) break; + + if (DEBUGDUMP) + { + UINT32 sk = FIX_ENDIAN_INT16(pD2->SysKind), lcid = FIX_ENDIAN_INT32(pD2->Locale), lf = FIX_ENDIAN_INT16(pD2->LibFlags); + _tprintf(_T("lcid=%#.8x sk=%#.8x lf=%#.4x hc=%#x\n"), lcid, sk, lf, FIX_ENDIAN_INT32(pD2->HelpContext)); + } + + // lcid = FIX_ENDIAN_INT32(pD2->Locale); + // sysk = FIX_ENDIAN_INT16(pD2->SysKind); + // libf = FIX_ENDIAN_INT16(pD2->LibFlags); + high = FIX_ENDIAN_INT16(pD2->VerMaj), low = FIX_ENDIAN_INT16(pD2->VerMin); + return true; + } + o += FIX_ENDIAN_INT32(pSD[i].Size), i = FIX_ENDIAN_INT16(pSD[i].Next); + } + } + } + return false; +} + +static bool MSTLB_GetVersion(const void*pData, size_t cbData, DWORD &high, DWORD &low) +{ + bool rv = MSTLB_GetVersion_MSFT(pData, cbData, high, low); + if (!rv) rv = MSTLB_GetVersion_SLTG(pData, cbData, high, low); + return rv; +} + +static BYTE* GetResource(CResourceEditor&RE, const TCHAR*RT, int RN, int RL, size_t&cbData) +{ + BYTE *pResData = RE.GetResource(RT, RN, RL); + if (pResData) cbData = RE.GetResourceSize(RT, RN, RL); + return pResData; +} + +static bool GetTLBVersionUsingRE(const void*pPEFile, size_t cbData, size_t resid, DWORD &high, DWORD &low) +{ + bool result = false; + try + { + const TCHAR* rt = _T("TYPELIB"); + int rn = (int) resid, rl = CResourceEditor::ANYLANGID; + CResourceEditor re((BYTE*) pPEFile, (int) cbData); + BYTE *pResData = resid == invalid_res_id ? re.GetFirstResource(rt, cbData) : GetResource(re, rt, rn, rl, cbData); + if (pResData) + { + result = MSTLB_GetVersion(pResData, cbData, high, low); + re.FreeResource(pResData); + } + } + catch (std::exception&) + { + } + return result; +} + +static bool GetTLBVersionInterop(const TCHAR *filepath, DWORD &high, DWORD &low) +{ + unsigned long size; + size_t resid; + FILE *f = MSTLB_fopen(filepath, &resid); + bool result = false, resonly = invalid_res_id != resid; + void *filedata = alloc_and_read_file(f, size); + if (f) fclose(f); + if (filedata) + { + if (!result && !resonly) result = MSTLB_GetVersion(filedata, size, high, low); // A raw TLB file? + if (!result) result = GetTLBVersionUsingRE(filedata, size, resid, high, low); // A resource in a PE file? + // TODO: if (!result) result = GetTLBVersion16(filedata, size, resid, high, low); // A resouce in a 16-bit executable? + free(filedata); + } + // Not supported: if (!result) result = GetTLBVersionFromMoniker(filepath, high, low); + return result; +} +#else //! !_WIN32 +static bool GetTLBVersionUsingAPI(const TCHAR *filepath, DWORD &high, DWORD &low) +{ + bool found = false; + HRESULT hr; + ITypeLib *pTL; + TCHAR fullpath[1024], *p; + if (!GetFullPathName(filepath, COUNTOF(fullpath), fullpath, &p)) return false; + +#ifdef _UNICODE + hr = LoadTypeLib(fullpath, &pTL); +#else + WCHAR *olepath = (WCHAR*) WinWStrDupFromTChar(fullpath); + if (!olepath) return false; + hr = LoadTypeLib(olepath, &pTL); + free(olepath); +#endif //~ _UNICODE + if (SUCCEEDED(hr)) + { + TLIBATTR *tlatt; + hr = pTL->GetLibAttr(&tlatt); + if (SUCCEEDED(hr)) + { + if (DEBUGDUMP) + { + _tprintf(_T("lcid=%#.8x sk=%#.8x lf=%#.4x\n"), tlatt->lcid, tlatt->syskind, tlatt->wLibFlags); + } + + high = tlatt->wMajorVerNum, low = tlatt->wMinorVerNum; + found = true; + } + pTL->Release(); + } + return found; +} +#endif //~ !_WIN32 + +bool GetTLBVersion(const TCHAR *filepath, DWORD &high, DWORD &low) +{ + bool found = false; +#if defined(_WIN32) && !defined(NSIS_GETTLBVERSION_FORCEINTERNAL) + found = GetTLBVersionUsingAPI(filepath, high, low); +#else //! _WIN32 + found = GetTLBVersionInterop(filepath, high, low); +#endif //~ _WIN32 + return found; +} Added: NSIS/trunk/Source/BinInterop.h =================================================================== --- NSIS/trunk/Source/BinInterop.h (rev 0) +++ NSIS/trunk/Source/BinInterop.h 2017-10-04 12:25:35 UTC (rev 6914) @@ -0,0 +1,28 @@ +/* + * BinInterop.h + * + * This file is a part of NSIS. + * + * Copyright (C) 2017 Anders Kjersem + * + * Licensed under the zlib/libpng license (the "License"); + * you may not use this file except in compliance with the License. + * + * Licence details can be found in the file COPYING. + * + * This software is provided 'as-is', without any express or implied + * warranty. + * + */ + +#ifndef NSIS_BININTEROP_H +#define NSIS_BININTEROP_H + +#include "Platform.h" +#include "tchar.h" +#include <stdio.h> // FILE* + +FILE* MSTLB_fopen(const TCHAR*filepath, size_t*pResId = 0); +bool GetTLBVersion(const TCHAR *filepath, DWORD &high, DWORD &low); + +#endif //~ NSIS_BININTEROP_H This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <and...@us...> - 2017-10-04 23:40:47
|
Revision: 6916 http://sourceforge.net/p/nsis/code/6916 Author: anders_k Date: 2017-10-04 23:40:45 +0000 (Wed, 04 Oct 2017) Log Message: ----------- Refactored GetDLLVersion Modified Paths: -------------- NSIS/trunk/Source/BinInterop.cpp NSIS/trunk/Source/BinInterop.h NSIS/trunk/Source/Plugins.cpp NSIS/trunk/Source/ResourceEditor.cpp NSIS/trunk/Source/ResourceEditor.h NSIS/trunk/Source/script.cpp NSIS/trunk/Source/scriptpp.cpp NSIS/trunk/Source/util.cpp NSIS/trunk/Source/util.h Modified: NSIS/trunk/Source/BinInterop.cpp =================================================================== --- NSIS/trunk/Source/BinInterop.cpp 2017-10-04 18:20:55 UTC (rev 6915) +++ NSIS/trunk/Source/BinInterop.cpp 2017-10-04 23:40:45 UTC (rev 6916) @@ -48,55 +48,12 @@ #if !defined(_WIN32) || defined(NSIS_GETTLBVERSION_FORCEINTERNAL) -unsigned long get_file_size32(FILE*f) -{ - unsigned long error = ~(0UL), result = error, restoreseek = false; - long cb; - fpos_t orgpos; - if (restoreseek ? 0 == fgetpos(f, &orgpos) : true) - if (0 == fseek(f, 0, SEEK_END)) - if ((cb = ftell(f)) != -1L) - if (restoreseek ? 0 == fsetpos(f, &orgpos) : true) - result = cb; - return result; -} - -void* alloc_and_read_file(FILE*f, unsigned long&size) -{ - void *result = 0, *mem = 0; - if (!f) return result; - size = get_file_size32(f); - mem = (~(0UL) != size) ? malloc(size) : 0; - if (mem) - if (0 == fseek(f, 0, SEEK_SET)) - if (fread(mem, 1, size, f) == size) - result = mem, mem = 0; - free(mem); - return result; -} - -/*void* alloc_and_read_file(const TCHAR*filepath, unsigned long&size) -{ - void *result = 0; - FILE*f = FOPEN(filepath, ("rb")); - if (f) - result = alloc_and_read_file(f, size), fclose(f); - return result; -}*/ - #if 0 // midl /DOLDTLB=1 /oldtlb /tlb SLTG.tlb test.idl && midl /DNEWTLB=1 /newtlb /tlb MSFT.tlb test.idl #ifdef NEWTLB import "unknwn.idl"; -[ - object, uuid(42424242-1111-1111-0001-424242424242), - //oleautomation, //TYPEFLAG_FOLEAUTOMATION? - //dual, //"Specifying dual on an interface implies that the interface is compatible with Automation, and therefore causes both the TYPEFLAG_FDUAL and TYPEFLAG_FOLEAUTOMATION flags to be set" -] -interface IInTeRfAcE1 : IUnknown { HRESULT I1_MeThOd1(); }; - -[ object, uuid(42424242-1111-1111-0002-424242424242) ] -interface IInTeRfAcE2 : IUnknown { [idempotent] HRESULT I2_MeThOd1(); }; +[ object, uuid(42424242-1111-1111-0001-424242424242) ] interface IInTeRfAcE1 : IUnknown { HRESULT I1_MeThOd1(); }; +[ object, uuid(42424242-1111-1111-0002-424242424242) ] interface IInTeRfAcE2 : IUnknown { [idempotent] HRESULT I2_MeThOd1(); }; #endif [ //msdn.microsoft.com/en-us/library/windows/desktop/aa367069 @@ -186,7 +143,7 @@ if (cbData >= sizeof(MSTLB_MSFT_MINIHEADER)) { const MSTLB_MSFT_MINIHEADER &h = *(MSTLB_MSFT_MINIHEADER*) pData; - if (FIX_ENDIAN_INT32(h.Sig) == 0x5446534D) + if (h.Sig == FIX_ENDIAN_INT32(0x5446534D)) { if (FIX_ENDIAN_INT16(h.FmtVerMaj) == 2 && FIX_ENDIAN_INT16(h.FmtVerMin) == 1) // Is this always 2.1? { @@ -223,7 +180,7 @@ { size_t eofPtr = MKPTR(size_t, pData, cbData); const MSTLB_SLTG_HEADER &h = *(MSTLB_SLTG_HEADER*) pData; - if (FIX_ENDIAN_INT32(h.Sig) == 0x047544C53 && MSTLB_IsSerializedOleGuid(h.Guid, 0x00020400, 0xffffff00)) // 0x000204xx for IID_ITypeLib and friends + if (h.Sig == FIX_ENDIAN_INT32(0x047544C53) && MSTLB_IsSerializedOleGuid(h.Guid, 0x00020400, 0xffffff00)) // 0x000204xx for IID_ITypeLib and friends { MSTLB_SLTG_SD *pSD = MKPTR(MSTLB_SLTG_SD*, &h, sizeof(MSTLB_SLTG_HEADER)); UINT32 streamCount = FIX_ENDIAN_INT16(h.Count); @@ -281,7 +238,7 @@ { const TCHAR* rt = _T("TYPELIB"); int rn = (int) resid, rl = CResourceEditor::ANYLANGID; - CResourceEditor re((BYTE*) pPEFile, (int) cbData); + CResourceEditor re((void*) pPEFile, (int) cbData); BYTE *pResData = resid == invalid_res_id ? re.GetFirstResource(rt, cbData) : GetResource(re, rt, rn, rl, cbData); if (pResData) { @@ -301,19 +258,19 @@ size_t resid; FILE *f = MSTLB_fopen(filepath, &resid); bool result = false, resonly = invalid_res_id != resid; - void *filedata = alloc_and_read_file(f, size); + void *pFileData = alloc_and_read_file(f, size); if (f) fclose(f); - if (filedata) + if (pFileData) { - if (!result && !resonly) result = MSTLB_GetVersion(filedata, size, high, low); // A raw TLB file? - if (!result) result = GetTLBVersionUsingRE(filedata, size, resid, high, low); // A resource in a PE file? - // TODO: if (!result) result = GetTLBVersion16(filedata, size, resid, high, low); // A resouce in a 16-bit executable? - free(filedata); + if (!result && !resonly) result = MSTLB_GetVersion(pFileData, size, high, low); // A raw TLB file? + if (!result) result = GetTLBVersionUsingRE(pFileData, size, resid, high, low); // A resource in a PE file? + // TODO: if (!result) result = GetTLBVersion16(pFileData, size, resid, high, low); // A resouce in a 16-bit executable? + free(pFileData); } // Not supported: if (!result) result = GetTLBVersionFromMoniker(filepath, high, low); return result; } -#else //! !_WIN32 +#else // !_WIN32 static bool GetTLBVersionUsingAPI(const TCHAR *filepath, DWORD &high, DWORD &low) { bool found = false; @@ -355,3 +312,206 @@ #endif //~ _WIN32 return found; } + +static bool GetDLLVersionUsingRE(const TCHAR *filepath, DWORD &high, DWORD &low) +{ + bool found = false; + LANGID anylangid = CResourceEditor::ANYLANGID; + unsigned long fileSize; + void*pFileData = alloc_and_read_file(filepath, fileSize); + if (!pFileData) return false; + try + { + CResourceEditor re(pFileData, fileSize); + LPBYTE resdata = re.GetResource(VS_FILE_INFO, VS_VERSION_INFO, anylangid); + if (resdata) + { + size_t ressize = re.GetResourceSize(VS_FILE_INFO, VS_VERSION_INFO, anylangid); + size_t vsvhdrsize = sizeof(WORD) * 3; + if (ressize > vsvhdrsize) + { + // Locate VS_FIXEDFILEINFO inside VS_VERSIONINFO + WINWCHAR *szKey = (WINWCHAR*)(resdata + vsvhdrsize); + size_t len = vsvhdrsize + (WinWStrLen(szKey) + 1) * sizeof(WINWCHAR); + len = (len + 3) & ~3; // Align on DWORD boundary + VS_FIXEDFILEINFO *verinfo = (VS_FIXEDFILEINFO*)(resdata + len); + if (ressize >= len + sizeof(VS_FIXEDFILEINFO) && verinfo->dwSignature == FIX_ENDIAN_INT32(VS_FFI_SIGNATURE)) + { + high = FIX_ENDIAN_INT32(verinfo->dwFileVersionMS), low = FIX_ENDIAN_INT32(verinfo->dwFileVersionLS); + found = true; + } + } + re.FreeResource(resdata); + } + } + catch (std::exception&) + { + } + free(pFileData); + return found; +} + +static bool GetDLLVersionUsingAPI(const TCHAR *filepath, DWORD &high, DWORD &low) +{ + bool found = false; +#ifdef _WIN32 + TCHAR path[1024], *name; + path[0] = 0; + GetFullPathName(filepath, 1024, path, &name); + + DWORD ignore, verSize = GetFileVersionInfoSize(path, &ignore); + if (verSize) + { + void *buf = malloc(verSize); + if (buf) + { + UINT valSize; + VS_FIXEDFILEINFO *pvsf; + if (GetFileVersionInfo(path, 0, verSize, buf) && VerQueryValue(buf, _T("\\"), (void**) &pvsf, &valSize)) + { + high = pvsf->dwFileVersionMS, low = pvsf->dwFileVersionLS; + found = true; + } + free(buf); + } + } +#endif + return found; +} + +#pragma pack(push, pre_vxd_ver, 1) +typedef struct _VXD_VERSION_RESOURCE { + char cType; + WORD wID; + char cName; + WORD wOrdinal; + WORD wFlags; + DWORD dwResSize; + BYTE bVerData; +} VXD_VERSION_RESOURCE, *PVXD_VERSION_RESOURCE; +#pragma pack(pop, pre_vxd_ver) + +#ifdef _WIN32 +static void* CreateReadOnlyFullMappedView(LPCTSTR szFile, DWORD Access, DWORD Share, DWORD Mode) +{ + void *pView = NULL; + HANDLE hFile = CreateFile(szFile, Access, Share, NULL, Mode, 0, NULL); + if (hFile == INVALID_HANDLE_VALUE) return pView; + HANDLE hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL); + if (hMap != INVALID_HANDLE_VALUE) + { + CloseHandle(hFile); + if ((pView = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0))) + { + CloseHandle(hMap); + } + else + { + DWORD error = GetLastError(); + CloseHandle(hMap); + SetLastError(error); + } + } + else + { + DWORD error = GetLastError(); + CloseHandle(hFile); + SetLastError(error); + } + return pView; +} + +static BOOL GetVxdVersion(LPCTSTR szFile, LPDWORD lpdwLen, LPVOID lpData) +{ + BOOL result = FALSE; + DWORD resSize = 0, outSize = *lpdwLen; + void *pView = CreateReadOnlyFullMappedView(szFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING); + if (!pView) return FALSE; + + PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER) pView; + if (pDosHdr->e_magic == IMAGE_DOS_SIGNATURE) + { + PIMAGE_NT_HEADERS pNtHdr = (PIMAGE_NT_HEADERS) ((ULONG_PTR) pView + pDosHdr->e_lfanew); + if ((DWORD) pNtHdr->Signature == IMAGE_VXD_SIGNATURE) // Is it a little-endian VXD? + { + PIMAGE_VXD_HEADER pLEHdr = (PIMAGE_VXD_HEADER) pNtHdr; + if (pLEHdr->e32_winreslen != 0) + { + PVXD_VERSION_RESOURCE pVerRes; + pVerRes = (VXD_VERSION_RESOURCE*) ((ULONG_PTR) pView + pLEHdr->e32_winresoff); + resSize = pVerRes->dwResSize; + if (lpData && outSize >= resSize) + { + void *pResData = &(pVerRes->bVerData); + ZeroMemory(lpData, outSize); + CopyMemory(lpData, pResData, resSize); + result = TRUE; + } + else + SetLastError(ERROR_INSUFFICIENT_BUFFER); + } + else + SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND); + } + else + SetLastError(ERROR_BAD_FORMAT); + } + else + SetLastError(ERROR_BAD_FORMAT); + + UnmapViewOfFile(pView); + *lpdwLen = resSize; + return result; +} + +static DWORD GetVxdVersionInfoSize(LPCTSTR szFile) +{ + DWORD result = 0; + if (!GetVxdVersion(szFile, &result, NULL)) + { + if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) // Successfully queried the required size? + { + SetLastError(0); + return result; + } + } + return result; +} + +static BOOL GetVxdVersionInfo(LPCTSTR szFile, DWORD dwLen, LPVOID lpData) +{ + return GetVxdVersion(szFile, &dwLen, lpData); +} +#endif //_WIN32 + +static bool GetDLLVersionFromVXD(const TCHAR *filepath, DWORD &high, DWORD &low) +{ + bool found = false; +#ifdef _WIN32 + DWORD verSize = GetVxdVersionInfoSize(filepath); + if (verSize) + { + void *buf = malloc(verSize); + if (buf) + { + UINT valSize; + VS_FIXEDFILEINFO *pvsf; + if (GetVxdVersionInfo(filepath, verSize, buf) && VerQueryValue(buf, _T("\\"), (void**) &pvsf, &valSize)) + { + high = pvsf->dwFileVersionMS, low = pvsf->dwFileVersionLS; + found = true; + } + free(buf); + } + } +#endif + return found; +} + +bool GetDLLVersion(const TCHAR *filepath, DWORD &high, DWORD &low) +{ + bool result = GetDLLVersionUsingAPI(filepath, high, low); + if (!result) result = GetDLLVersionUsingRE(filepath, high, low); + if (!result) result = GetDLLVersionFromVXD(filepath, high, low); + return result; +} Modified: NSIS/trunk/Source/BinInterop.h =================================================================== --- NSIS/trunk/Source/BinInterop.h 2017-10-04 18:20:55 UTC (rev 6915) +++ NSIS/trunk/Source/BinInterop.h 2017-10-04 23:40:45 UTC (rev 6916) @@ -25,4 +25,6 @@ FILE* MSTLB_fopen(const TCHAR*filepath, size_t*pResId = 0); bool GetTLBVersion(const TCHAR *filepath, DWORD &high, DWORD &low); +bool GetDLLVersion(const TCHAR *filepath, DWORD &high, DWORD &low); + #endif //~ NSIS_BININTEROP_H Modified: NSIS/trunk/Source/Plugins.cpp =================================================================== --- NSIS/trunk/Source/Plugins.cpp 2017-10-04 18:20:55 UTC (rev 6915) +++ NSIS/trunk/Source/Plugins.cpp 2017-10-04 23:40:45 UTC (rev 6916) @@ -114,36 +114,16 @@ NSISException(const tstring& msg) : NSISExceptionInner(TtoCString(msg)) {} }; -namespace { -// This function slurps the whole file into the vector. -// Modified so the huge vector isn't returned by value. -void read_file(const tstring& filename, vector<unsigned char>& data) -{ - FILE*file = FOPEN(filename.c_str(), ("rb")); - if (!file) throw NSISException(_T("Can't open file '") + filename + _T("'")); - MANAGE_WITH(file, fclose); - bool succ = false; - - if (!fseek(file, 0, SEEK_END)) - { - const long filesize = ftell(file); - rewind(file); - data.resize(filesize); - size_t cbio = fread(reinterpret_cast<char*>(&data[0]), 1, filesize, file); - succ = cbio == (size_t)filesize; - } - if (!succ) throw NSISException(_T("Couldn't read entire file '") + filename + _T("'")); -} -} - void Plugins::GetExports(const tstring &pathToDll, bool pe64, bool displayInfo) { - vector<unsigned char> dlldata; PIMAGE_NT_HEADERS pNTHdrs; + unsigned long dllsize; + BYTE *dlldata = alloc_and_read_file(pathToDll.c_str(), dllsize); + MANAGE_WITH(dlldata, free); + try { - read_file(pathToDll, dlldata); - if (dlldata.empty()) return; - pNTHdrs = CResourceEditor::GetNTHeaders(&dlldata[0]); + if (!dllsize) return ; + pNTHdrs = CResourceEditor::GetNTHeaders(&dlldata[0]); // This might throw } catch (std::runtime_error&) { return; } Modified: NSIS/trunk/Source/ResourceEditor.cpp =================================================================== --- NSIS/trunk/Source/ResourceEditor.cpp 2017-10-04 18:20:55 UTC (rev 6915) +++ NSIS/trunk/Source/ResourceEditor.cpp 2017-10-04 23:40:45 UTC (rev 6916) @@ -120,9 +120,9 @@ // Construction/Destruction ////////////////////////////////////////////////////////////////////// -CResourceEditor::CResourceEditor(BYTE* pbPE, int iSize, bool bKeepData /*=true*/) { +CResourceEditor::CResourceEditor(void* pbPE, int iSize, bool bKeepData /*=true*/) { // Copy the data pointer - m_pbPE = pbPE; + m_pbPE = (BYTE*) pbPE; m_iSize = iSize; m_bKeepData = bKeepData; Modified: NSIS/trunk/Source/ResourceEditor.h =================================================================== --- NSIS/trunk/Source/ResourceEditor.h 2017-10-04 18:20:55 UTC (rev 6915) +++ NSIS/trunk/Source/ResourceEditor.h 2017-10-04 23:40:45 UTC (rev 6916) @@ -119,7 +119,7 @@ class CResourceEditor { public: - CResourceEditor(BYTE* pbPE, int iSize, bool bKeepData = true); + CResourceEditor(void* pbPE, int iSize, bool bKeepData = true); virtual ~CResourceEditor(); enum { ANYLANGID = 0xffff }; Modified: NSIS/trunk/Source/script.cpp =================================================================== --- NSIS/trunk/Source/script.cpp 2017-10-04 18:20:55 UTC (rev 6915) +++ NSIS/trunk/Source/script.cpp 2017-10-04 23:40:45 UTC (rev 6916) @@ -23,6 +23,7 @@ #include "winchar.h" #include "ResourceEditor.h" #include "DialogTemplate.h" +#include "BinInterop.h" #include "lang.h" #include "dirreader.h" #include <nsis-version.h> Modified: NSIS/trunk/Source/scriptpp.cpp =================================================================== --- NSIS/trunk/Source/scriptpp.cpp 2017-10-04 18:20:55 UTC (rev 6915) +++ NSIS/trunk/Source/scriptpp.cpp 2017-10-04 23:40:45 UTC (rev 6916) @@ -584,7 +584,7 @@ int CEXEBuild::pp_getversionhelper(const TCHAR *cmdname, const TCHAR *path, const TCHAR *basesymname, DWORD high, DWORD low, DWORD flags) { TCHAR *symbuf = m_templinebuf; - DWORD tlb = (flags & PPGVHF_TLB); + DWORD tlb = (flags & PPGVHF_TLB), noerrors = (flags & PPGVHF_NOERRORS); FILE *pF = tlb ? MSTLB_fopen(path) : FOPEN(path, ("rb")); if (pF) fclose(pF); bool vnum = pF && (flags & PPGVHF_VALID); // LibraryLocal users want to detect "file not found" vs "no version info" @@ -594,7 +594,7 @@ if (!pF) { - if (flags & PPGVHF_NOERRORS) return PS_OK; + if (noerrors) return PS_OK; ERROR_MSG(_T("%") NPRIs _T(": error reading version info from \"%") NPRIs _T("\"\n"), cmdname, path); return PS_ERROR; } Modified: NSIS/trunk/Source/util.cpp =================================================================== --- NSIS/trunk/Source/util.cpp 2017-10-04 18:20:55 UTC (rev 6915) +++ NSIS/trunk/Source/util.cpp 2017-10-04 23:40:45 UTC (rev 6916) @@ -75,6 +75,11 @@ return cch; } +size_t my_strftime(TCHAR *s, size_t max, const TCHAR *fmt, const struct tm *tm) +{ + return _tcsftime(s, max, fmt, tm); +} + // Returns 0 if everything is OK // Returns -1 if can't find the file // Returns -2 if the file is an invalid bitmap @@ -604,10 +609,45 @@ return f; } -size_t my_strftime(TCHAR *s, size_t max, const TCHAR *fmt, const struct tm *tm) { - return _tcsftime(s, max, fmt, tm); +unsigned long get_file_size32(FILE *f) +{ + unsigned long error = ~(0UL), result = error; + long cb, restoreseek = true; + fpos_t orgpos; + if (restoreseek ? 0 == fgetpos(f, &orgpos) : true) + if (0 == fseek(f, 0, SEEK_END)) + if ((cb = ftell(f)) != -1L) + if (restoreseek ? 0 == fsetpos(f, &orgpos) : true) + result = cb; + return result; } +BYTE* alloc_and_read_file(FILE *f, unsigned long &size) +{ + BYTE *result = 0, *mem = 0; + if (!f) return result; + size = get_file_size32(f); + mem = (~(0UL) != size) ? (BYTE*) malloc(size) : 0; + if (mem) + if (0 == fseek(f, 0, SEEK_SET)) + if (fread(mem, 1, size, f) == size) + result = mem, mem = 0; + free(mem); + return result; +} + +BYTE* alloc_and_read_file(const TCHAR *filepath, unsigned long &size) +{ + BYTE *result = 0; + FILE*f = FOPEN(filepath, ("rb")); + if (f) + { + result = alloc_and_read_file(f, size); + fclose(f); + } + return result; +} + tstring get_full_path(const tstring &path) { #ifdef _WIN32 TCHAR real_path[1024], *fnpart; @@ -1200,287 +1240,6 @@ #endif } - -static bool GetDLLVersionUsingRE(const TCHAR *filepath, DWORD& high, DWORD & low) -{ - bool found = false; - LANGID anylangid = CResourceEditor::ANYLANGID; - - FILE *fdll = FOPEN(filepath, ("rb")); - if (!fdll) - return 0; - - fseek(fdll, 0, SEEK_END); - unsigned int len = ftell(fdll); - fseek(fdll, 0, SEEK_SET); - - LPBYTE dll = (LPBYTE) malloc(len); - - if (!dll) - { - fclose(fdll); - return 0; - } - - if (fread(dll, 1, len, fdll) != len) - { - fclose(fdll); - free(dll); - return 0; - } - fclose(fdll); - - try - { - CResourceEditor *dllre = new CResourceEditor(dll, len); - LPBYTE ver = dllre->GetResource(VS_FILE_INFO, VS_VERSION_INFO, anylangid); - size_t versize = (size_t) dllre->GetResourceSize(VS_FILE_INFO, VS_VERSION_INFO, anylangid); - - if (ver) - { - if (versize > sizeof(WORD) * 3) - { - // get VS_FIXEDFILEINFO from VS_VERSIONINFO - WINWCHAR *szKey = (WINWCHAR *)(ver + sizeof(WORD) * 3); - size_t len = (WinWStrLen(szKey) + 1) * sizeof(WINWCHAR) + sizeof(WORD) * 3; - len = (len + 3) & ~3; // align on DWORD boundary - VS_FIXEDFILEINFO *verinfo = (VS_FIXEDFILEINFO *)(ver + len); - if (versize > len && verinfo->dwSignature == VS_FFI_SIGNATURE) - { - found = true, low = verinfo->dwFileVersionLS, high = verinfo->dwFileVersionMS; - } - } - dllre->FreeResource(ver); - } - - delete dllre; - } - catch (exception&) - { - } - - return found; -} - -static bool GetDLLVersionUsingAPI(const TCHAR *filepath, DWORD& high, DWORD& low) -{ - bool found = false; - -#ifdef _WIN32 - TCHAR path[1024]; - TCHAR *name; - path[0] = 0; - - GetFullPathName(filepath, 1024, path, &name); - - DWORD d; - DWORD verSize = GetFileVersionInfoSize(path, &d); - if (verSize) - { - void *buf = (void *) GlobalAlloc(GPTR, verSize); - if (buf) - { - UINT uLen; - VS_FIXEDFILEINFO *pvsf; - if (GetFileVersionInfo(path, 0, verSize, buf) && VerQueryValue(buf, _T("\\"), (void**) &pvsf, &uLen)) - { - found = true, low = pvsf->dwFileVersionLS, high = pvsf->dwFileVersionMS; - } - GlobalFree(buf); - } - } -#endif - - return found; -} - -#ifdef _WIN32 - -// the following structure must be byte-aligned. -#pragma pack( push, pre_vxd_ver, 1 ) -typedef struct _VXD_VERSION_RESOURCE { - char cType; // Should not be converted to TCHAR (JP) - WORD wID; - char cName; // Should not be converted to TCHAR (JP) - WORD wOrdinal; - WORD wFlags; - DWORD dwResSize; - BYTE bVerData; -} VXD_VERSION_RESOURCE, *PVXD_VERSION_RESOURCE; -#pragma pack( pop, pre_vxd_ver ) - -static BOOL GetVxdVersion( LPCTSTR szFile, LPDWORD lpdwLen, LPVOID lpData ) -{ - - HANDLE hFile = NULL; - HANDLE hFileMapping = NULL; - void * pView = NULL; - DWORD dwSize = 0; - DWORD dwError = 0; - - PIMAGE_DOS_HEADER pDosExeHdr = NULL; - PIMAGE_NT_HEADERS pNtExeHdr = NULL; - PIMAGE_VXD_HEADER pLEHdr = NULL; - PVXD_VERSION_RESOURCE pVerRes = NULL; - LPVOID pRawRes = NULL; - - // Open the file for shared read access. - hFile = CreateFile( szFile, GENERIC_READ, FILE_SHARE_READ, - NULL, OPEN_EXISTING, 0, NULL ); - if ( hFile == INVALID_HANDLE_VALUE ) - { - return FALSE; - } - - // Create a read-only file mapping object for the file. - hFileMapping = CreateFileMapping( hFile, NULL, - PAGE_READONLY, 0, 0, NULL); - if ( !hFileMapping ) - { - dwError = GetLastError(); - if ( hFile != INVALID_HANDLE_VALUE ) CloseHandle( hFile ); - SetLastError( dwError ); - return FALSE; - } - - // Map a view of the the file. - pView = MapViewOfFile( hFileMapping, FILE_MAP_READ, 0, 0, 0 ); - if ( !pView ) - { - dwError = GetLastError(); - if ( hFileMapping ) CloseHandle( hFileMapping ); - if ( hFile != INVALID_HANDLE_VALUE ) CloseHandle( hFile ); - SetLastError( dwError ); - return FALSE; - } - - // The DOS header begins at byte 0. - pDosExeHdr = (PIMAGE_DOS_HEADER) pView; - - // Check to make sure the file has a DOS EXE header. - if ( pDosExeHdr->e_magic != IMAGE_DOS_SIGNATURE ) - { - if ( pView ) UnmapViewOfFile( pView ); - if ( hFileMapping ) CloseHandle( hFileMapping ); - if ( hFile != INVALID_HANDLE_VALUE ) CloseHandle( hFile ); - SetLastError( ERROR_BAD_FORMAT ); - return FALSE; - } - - // Find the beginning of the NT header at offset e_lfanew. - pNtExeHdr = (PIMAGE_NT_HEADERS) ( (ULONG_PTR) pView + pDosExeHdr->e_lfanew ); - - // Check to make sure the file is a VxD. - if ( (DWORD) pNtExeHdr->Signature != IMAGE_VXD_SIGNATURE ) - { - if ( pView ) UnmapViewOfFile( pView ); - if ( hFileMapping ) CloseHandle( hFileMapping ); - if ( hFile != INVALID_HANDLE_VALUE ) CloseHandle( hFile ); - SetLastError( ERROR_BAD_FORMAT ); - return FALSE; - } - - // The LE header begins at the same place as the NT header. - pLEHdr = (PIMAGE_VXD_HEADER) pNtExeHdr; - - // e32_winreslen contains the size of the VxD's version resource. - if ( pLEHdr->e32_winreslen == 0 ) { - *lpdwLen = 0; - if ( pView ) UnmapViewOfFile( pView ); - if ( hFileMapping ) CloseHandle( hFileMapping ); - if ( hFile != INVALID_HANDLE_VALUE ) CloseHandle( hFile ); - SetLastError( ERROR_RESOURCE_DATA_NOT_FOUND ); - return FALSE; - } - - // e32_winresoff contains the offset of the resource in the VxD. - pVerRes = (VXD_VERSION_RESOURCE *) ( (ULONG_PTR) pView + pLEHdr->e32_winresoff ); - dwSize = pVerRes->dwResSize; - pRawRes = &(pVerRes->bVerData); - - // Make sure the supplied buffer is large enough for the resource. - if ( ( lpData == NULL ) || ( *lpdwLen < dwSize ) ) { - *lpdwLen = dwSize; - if ( pView ) UnmapViewOfFile( pView ); - if ( hFileMapping ) CloseHandle( hFileMapping ); - if ( hFile != INVALID_HANDLE_VALUE ) CloseHandle( hFile ); - SetLastError( ERROR_INSUFFICIENT_BUFFER ); - return FALSE; - } - - // Zero the passed buffer and copy the resource into it. - ZeroMemory( lpData, *lpdwLen ); - CopyMemory( lpData, pRawRes, dwSize ); - *lpdwLen = dwSize; - - // Clean up resources. - if ( pView ) UnmapViewOfFile( pView ); - if ( hFileMapping ) CloseHandle( hFileMapping ); - if ( hFile != INVALID_HANDLE_VALUE ) CloseHandle( hFile ); - SetLastError(0); // Why bother? - return TRUE; -} - -static DWORD GetVxdVersionInfoSize( LPCTSTR szFile ) -{ - DWORD dwResult = 0; - - // Call GetVxdVersion() with NULL for the pointer to the buffer. - if ( !GetVxdVersion( szFile, &dwResult, NULL ) ) - { - DWORD dwError = GetLastError(); - - // GetVxdVersion() will fail with ERROR_INSUFFICIENT_BUFFER and - // the required buffer size will be returned in dwResult. - if ( dwError == ERROR_INSUFFICIENT_BUFFER ) - { - SetLastError( 0 ); - return dwResult; - } - } - - // The following line is never executed. - return 0; -} - -static BOOL GetVxdVersionInfo( LPCTSTR szFile, DWORD dwLen, LPVOID lpData ) -{ - return GetVxdVersion( szFile, &dwLen, lpData ); -} - -#endif //_WIN32 - -static bool GetDLLVersionFromVXD(const TCHAR *filepath, DWORD& high, DWORD& low) -{ - bool found = false; -#ifdef _WIN32 - DWORD verSize = GetVxdVersionInfoSize(filepath); - if (verSize) - { - void *buf = (void *) GlobalAlloc(GPTR, verSize); - if (buf) - { - UINT uLen; - VS_FIXEDFILEINFO *pvsf; - if (GetVxdVersionInfo(filepath, verSize, buf) && VerQueryValue(buf, _T("\\"), (void**) &pvsf, &uLen)) - { - found = true, low = pvsf->dwFileVersionLS, high = pvsf->dwFileVersionMS; - } - GlobalFree(buf); - } - } -#endif - return found; -} - -bool GetDLLVersion(const TCHAR *filepath, DWORD& high, DWORD& low) -{ - if (GetDLLVersionUsingAPI(filepath, high, low)) return true; - if (GetDLLVersionUsingRE(filepath, high, low)) return true; - if (GetDLLVersionFromVXD(filepath, high, low)) return true; - return false; -} - unsigned char Platform_SupportsUTF8Conversion() { static unsigned char cached = 0; Modified: NSIS/trunk/Source/util.h =================================================================== --- NSIS/trunk/Source/util.h 2017-10-04 18:20:55 UTC (rev 6915) +++ NSIS/trunk/Source/util.h 2017-10-04 23:40:45 UTC (rev 6916) @@ -41,8 +41,6 @@ // If width or height are specified it will also make sure the bitmap is in that size int update_bitmap(CResourceEditor* re, WORD id, const TCHAR* filename, int width=0, int height=0, int maxbpp=0); -bool GetDLLVersion(const TCHAR *filepath, DWORD &high, DWORD &low); - tstring get_full_path(const tstring& path); tstring get_dir_name(const tstring& path); tstring get_file_name(const tstring& path); @@ -259,8 +257,8 @@ TCHAR *my_convert(const TCHAR *path); void my_convert_free(TCHAR *converted_path); + int my_open(const TCHAR *pathname, int flags); - #define OPEN(a, b) my_open(a, b) #else // _WIN32 @@ -275,6 +273,10 @@ FILE* my_fopen(const TCHAR *path, const char *mode); #define FOPEN(a, b) my_fopen((a), (b)) +unsigned long get_file_size32(FILE *f); +BYTE* alloc_and_read_file(FILE *f, unsigned long &size); +BYTE* alloc_and_read_file(const TCHAR *filepath, unsigned long &size); + // round a value up to be a multiple of 512 // assumption: T is an int type template <class T> inline T align_to_512(const T x) { return (x+511) & ~511; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <and...@us...> - 2017-10-05 18:11:06
|
Revision: 6917 http://sourceforge.net/p/nsis/code/6917 Author: anders_k Date: 2017-10-05 18:11:03 +0000 (Thu, 05 Oct 2017) Log Message: ----------- Avoid using SEEK_END when possible Modified Paths: -------------- NSIS/trunk/Source/build.cpp NSIS/trunk/Source/script.cpp NSIS/trunk/Source/util.cpp NSIS/trunk/Source/util.h Modified: NSIS/trunk/Source/build.cpp =================================================================== --- NSIS/trunk/Source/build.cpp 2017-10-04 23:40:45 UTC (rev 6916) +++ NSIS/trunk/Source/build.cpp 2017-10-05 18:11:03 UTC (rev 6917) @@ -3974,34 +3974,16 @@ } int CEXEBuild::update_exehead(const tstring& file, size_t *size/*=NULL*/) { - FILE *tmpfile = FOPEN(file.c_str(), ("rb")); - if (!tmpfile) + unsigned long exehead_size; + unsigned char *exehead = alloc_and_read_file(file.c_str(), exehead_size); + if (!exehead) { - ERROR_MSG(_T("Error: opening stub \"%") NPRIs _T("\"\n"), file.c_str()); - return PS_ERROR; - } - - fseek(tmpfile, 0, SEEK_END); - size_t exehead_size = ftell(tmpfile); - - unsigned char *exehead = new unsigned char[exehead_size]; - fseek(tmpfile, 0, SEEK_SET); - if (fread(exehead, 1, exehead_size, tmpfile) != exehead_size) - { ERROR_MSG(_T("Error: reading stub \"%") NPRIs _T("\"\n"), file.c_str()); - fclose(tmpfile); - delete [] exehead; return PS_ERROR; } - fclose(tmpfile); - update_exehead(exehead, exehead_size); - - if (size) - *size = exehead_size; - - delete [] exehead; - + if (size) *size = exehead_size; + free(exehead); return PS_OK; } Modified: NSIS/trunk/Source/script.cpp =================================================================== --- NSIS/trunk/Source/script.cpp 2017-10-04 23:40:45 UTC (rev 6916) +++ NSIS/trunk/Source/script.cpp 2017-10-05 18:11:03 UTC (rev 6917) @@ -721,9 +721,8 @@ } FILE *f=strm.GetHandle(); UINT cbBOMOffset=ftell(f); // We might be positioned after a BOM - fseek(f,0,SEEK_END); - UINT cbFileData=ftell(f)-cbBOMOffset; // Size of file in bytes! - + UINT32 cbFileSize=get_file_size32(f); + UINT cbFileData=(invalid_file_size32 == cbFileSize) ? 0 : cbFileSize - cbBOMOffset; if (!cbFileData) { warning_fl(DW_LICENSE_EMPTY, _T("%") NPRIs _T(": empty license file \"%") NPRIs _T("\"\n"),cmdname,file); @@ -1972,28 +1971,15 @@ int k=line.gettoken_enum(1, _T("all\0IDD_LICENSE\0IDD_DIR\0IDD_SELCOM\0IDD_INST\0IDD_INSTFILES\0IDD_UNINST\0IDD_VERIFY\0IDD_LICENSE_FSRB\0IDD_LICENSE_FSCB\0")); if (k<0) PRINTHELP(); - FILE *fui = FOPEN(line.gettoken_str(2), ("rb")); - if (!fui) { - ERROR_MSG(_T("Error: Can't open \"%") NPRIs _T("\"!\n"), line.gettoken_str(2)); - return PS_ERROR; - } - MANAGE_WITH(fui, fclose); - - fseek(fui, 0, SEEK_END); - unsigned int len = ftell(fui); - fseek(fui, 0, SEEK_SET); - LPBYTE ui = (LPBYTE) malloc(len); - if (!ui) { - ERROR_MSG(_T("Internal compiler error #12345: malloc(%d) failed\n"), len); - extern void quit(); quit(); - } - MANAGE_WITH(ui, free); - if (fread(ui, 1, len, fui) != len) { + unsigned long uifilesize; + BYTE *uifiledata = alloc_and_read_file(line.gettoken_str(2), uifilesize); + if (!uifiledata) { ERROR_MSG(_T("Error: Can't read \"%") NPRIs _T("\"!\n"), line.gettoken_str(2)); return PS_ERROR; } + MANAGE_WITH(uifiledata, free); - CResourceEditor *uire = new CResourceEditor(ui, len); + CResourceEditor *uire = new CResourceEditor(uifiledata, uifilesize); init_res_editor(); // Search for required items Modified: NSIS/trunk/Source/util.cpp =================================================================== --- NSIS/trunk/Source/util.cpp 2017-10-04 23:40:45 UTC (rev 6916) +++ NSIS/trunk/Source/util.cpp 2017-10-05 18:11:03 UTC (rev 6917) @@ -609,16 +609,37 @@ return f; } -unsigned long get_file_size32(FILE *f) +#if (defined(_MSC_VER) && (_MSC_VER >= 1200)) || defined(__MINGW32__) +#include <io.h> +static UINT64 get_file_size64(FILE *f) { - unsigned long error = ~(0UL), result = error; + INT64 s = _filelengthi64(_fileno(f)); // Could also use _get_osfhandle+GetFileSize64 + return (INT64) -1L != s ? s : invalid_file_size64; +} +#endif + +#include <sys/types.h> +#include <sys/stat.h> +UINT32 get_file_size32(FILE *f) +{ + UINT32 result = invalid_file_size32; +#if (defined(_MSC_VER) && (_MSC_VER >= 1200)) || defined(__MINGW32__) + UINT64 size64 = get_file_size64(f); + if (invalid_file_size64 != size64 && size64 <= 0xffffffffUL) + result = (UINT32) size64; +#elif _XOPEN_SOURCE >= 500 || _POSIX_C_SOURCE >= 200112L + struct stat st; + if (0 == fstat(fileno(f), &st) && st.st_size <= (sizeof(st.st_size) >= 8 ? 0xffffffffUL : LONG_MAX)) + result = (UINT32) st.st_size; +#else long cb, restoreseek = true; fpos_t orgpos; - if (restoreseek ? 0 == fgetpos(f, &orgpos) : true) - if (0 == fseek(f, 0, SEEK_END)) - if ((cb = ftell(f)) != -1L) - if (restoreseek ? 0 == fsetpos(f, &orgpos) : true) + if (!restoreseek || 0 == fgetpos(f, &orgpos)) + if (0 == fseek(f, 0, SEEK_END)) // Not fully portable! + if ((cb = ftell(f)) != -1L) // This might not be correct for files in text mode! + if (!restoreseek || 0 == fsetpos(f, &orgpos)) result = cb; +#endif return result; } @@ -626,8 +647,8 @@ { BYTE *result = 0, *mem = 0; if (!f) return result; - size = get_file_size32(f); - mem = (~(0UL) != size) ? (BYTE*) malloc(size) : 0; + UINT32 size32 = get_file_size32(f); + mem = (invalid_file_size32 != size32) ? (BYTE*) malloc(size = size32) : 0; if (mem) if (0 == fseek(f, 0, SEEK_SET)) if (fread(mem, 1, size, f) == size) Modified: NSIS/trunk/Source/util.h =================================================================== --- NSIS/trunk/Source/util.h 2017-10-04 23:40:45 UTC (rev 6916) +++ NSIS/trunk/Source/util.h 2017-10-05 18:11:03 UTC (rev 6917) @@ -273,7 +273,9 @@ FILE* my_fopen(const TCHAR *path, const char *mode); #define FOPEN(a, b) my_fopen((a), (b)) -unsigned long get_file_size32(FILE *f); +const UINT32 invalid_file_size32 = ~ (UINT32) 0; +UINT32 get_file_size32(FILE *f); +const UINT64 invalid_file_size64 = ~ (UINT64) 0; BYTE* alloc_and_read_file(FILE *f, unsigned long &size); BYTE* alloc_and_read_file(const TCHAR *filepath, unsigned long &size); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <and...@us...> - 2017-10-06 14:30:56
|
Revision: 6919 http://sourceforge.net/p/nsis/code/6919 Author: anders_k Date: 2017-10-06 14:30:54 +0000 (Fri, 06 Oct 2017) Log Message: ----------- VIAddVersionKey and SetFont now supports hex numbers in the /LANG= parameter Modified Paths: -------------- NSIS/trunk/Source/lineparse.cpp NSIS/trunk/Source/lineparse.h NSIS/trunk/Source/script.cpp Modified: NSIS/trunk/Source/lineparse.cpp =================================================================== --- NSIS/trunk/Source/lineparse.cpp 2017-10-06 13:21:51 UTC (rev 6918) +++ NSIS/trunk/Source/lineparse.cpp 2017-10-06 14:30:54 UTC (rev 6919) @@ -75,39 +75,23 @@ m_eat++; } -double LineParser::gettoken_float(int token, int *success/*=0*/) const +static unsigned int number_has_base_prefix(const TCHAR *str) { - token+=m_eat; - if (token < 0 || token >= m_nt) + unsigned int hasbase = false; + if (_T('-') == *str || _T('+') == *str) ++str; + if (_T('0') == str[0]) { - if (success) *success=0; - return 0.0; + if (_T('x') == (str[1]|32)) ++hasbase; + if (_T('n') == (str[1]|32)) ++hasbase; + if (_T('b') == (str[1]|32) || _T('y') == (str[1]|32)) ++hasbase; + if (_T('o') == (str[1]|32) || _T('t') == (str[1]|32)) ++hasbase; } - if (success) - { - TCHAR *t=m_tokens[token]; - if (_T('-') == *t || _T('+') == *t) ++t; - *success=*t?1:0; - unsigned int dotcount = 0; - while (*t) - { - if (_T('.') == *t && ++dotcount > 1) *success=0; - if ((*t < _T('0') || *t > _T('9'))&&*t != _T('.')) *success=0; - t++; - } - } - return _tstof(m_tokens[token]); + return hasbase; } -int LineParser::gettoken_int(int token, int *success/*=0*/) const +int LineParser::parse_int(const TCHAR *str, int *success/*=0*/) { - token+=m_eat; - if (token < 0 || token >= m_nt || !m_tokens[token][0]) - { - if (success) *success=0; - return 0; - } - const TCHAR *p=m_tokens[token], *parse=p; + const TCHAR *p=str, *parse=p; TCHAR *end; int neg=0, base=0, num; if (_T('+') == *p) @@ -134,18 +118,56 @@ return num; } +int LineParser::gettoken_int(int token, int *success/*=0*/) const +{ + token+=m_eat; + if (token < 0 || token >= m_nt || !m_tokens[token][0]) + { + if (success) *success=0; + return 0; + } + return parse_int(m_tokens[token], success); +} + +double LineParser::parse_float(const TCHAR *str, int *success/*=0*/) +{ + if (success) + { + const TCHAR *t=str; + if (_T('-') == *t || _T('+') == *t) ++t; + *success=*t ? 1 : 0; + unsigned int dotcount = 0; + while (*t) + { + if (_T('.') == *t && ++dotcount > 1) *success=0; + if ((*t < _T('0') || *t > _T('9')) && *t != _T('.')) *success=0; + t++; + } + } + return _tstof(str); +} + +double LineParser::gettoken_float(int token, int *success/*=0*/) const +{ + token+=m_eat; + if (token < 0 || token >= m_nt) + { + if (success) *success=0; + return 0.0; + } + return parse_float(m_tokens[token], success); +} + +double LineParser::parse_number(const TCHAR *str, int *success/*=0*/) +{ + const unsigned int forceint = number_has_base_prefix(str); + return forceint ? parse_int(str,success) : parse_float(str,success); +} + double LineParser::gettoken_number(int token, int *success/*=0*/) const { const TCHAR*str=gettoken_str(token); - if (_T('-') == *str || _T('+') == *str) ++str; - unsigned int forceint = false; - if (_T('0') == str[0]) - { - if (_T('x') == (str[1]|32)) ++forceint; - if (_T('n') == (str[1]|32)) ++forceint; - if (_T('b') == (str[1]|32) || _T('y') == (str[1]|32)) ++forceint; - if (_T('o') == (str[1]|32) || _T('t') == (str[1]|32)) ++forceint; - } + const unsigned int forceint = number_has_base_prefix(str); return forceint ? gettoken_int(token,success) : gettoken_float(token,success); } Modified: NSIS/trunk/Source/lineparse.h =================================================================== --- NSIS/trunk/Source/lineparse.h 2017-10-06 13:21:51 UTC (rev 6918) +++ NSIS/trunk/Source/lineparse.h 2017-10-06 14:30:54 UTC (rev 6919) @@ -32,13 +32,17 @@ int parse(TCHAR *line, int ignore_escaping=0); // returns -1 on error int getnumtokens(); void eattoken(); + int gettoken_int(int token, int *success=0) const; double gettoken_float(int token, int *success=0) const; - int gettoken_int(int token, int *success=0) const; double gettoken_number(int token, int *success=0) const; int gettoken_binstrdata(int token, char*buffer, int bufcap) const; TCHAR *gettoken_str(int token) const; int gettoken_enum(int token, const TCHAR *strlist); // null separated list + static int parse_int(const TCHAR *str, int *success=0); + static double parse_float(const TCHAR *str, int *success=0); + static double parse_number(const TCHAR *str, int *success=0); + private: void freetokens(); Modified: NSIS/trunk/Source/script.cpp =================================================================== --- NSIS/trunk/Source/script.cpp 2017-10-06 13:21:51 UTC (rev 6918) +++ NSIS/trunk/Source/script.cpp 2017-10-06 14:30:54 UTC (rev 6919) @@ -80,6 +80,13 @@ } #endif //~ NSIS_CONFIG_ENHANCEDUI_SUPPORT +static LANGID ParseLangId(const TCHAR*Str) +{ + const TCHAR *p = Str; + if (_T('+') == *p || _T('-') == *p) ++p; + return _T('0') == p[0] && _T('x') == (p[1]|32) ? LineParser::parse_int(Str) : _ttoi(Str); +} + int CEXEBuild::process_script(NIStream&Strm, const TCHAR *filename) { NStreamLineReader linereader(Strm); @@ -2162,7 +2169,7 @@ unsigned char failed = 0; if (!_tcsnicmp(line.gettoken_str(1), _T("/LANG="), 6)) { - LANGID lang_id = _ttoi(line.gettoken_str(1) + 6); + LANGID lang_id = ParseLangId(line.gettoken_str(1) + 6); LanguageTable *table = GetLangTable(lang_id); const TCHAR*facename = line.gettoken_str(2); table->nlf.m_szFont = _tcsdup(facename); @@ -4815,7 +4822,7 @@ const bool forceneutrallang = !_tcsicmp(line.gettoken_str(a),_T("/LANG=0")); if (!_tcsnicmp(line.gettoken_str(a),_T("/LANG="),6)) - LangID=_ttoi(line.gettoken_str(a++)+6); + LangID=ParseLangId(line.gettoken_str(a++)+6); if (line.getnumtokens()!=a+2) PRINTHELP(); TCHAR *pKey = line.gettoken_str(a); TCHAR *pValue = line.gettoken_str(a+1); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <and...@us...> - 2017-10-19 14:16:12
|
Revision: 6934 http://sourceforge.net/p/nsis/code/6934 Author: anders_k Date: 2017-10-19 14:16:09 +0000 (Thu, 19 Oct 2017) Log Message: ----------- Support named version resource in VxD files so we can handle MSGame.VxD Modified Paths: -------------- NSIS/trunk/Source/BinInterop.cpp NSIS/trunk/Source/util.cpp NSIS/trunk/Source/util.h Modified: NSIS/trunk/Source/BinInterop.cpp =================================================================== --- NSIS/trunk/Source/BinInterop.cpp 2017-10-16 22:08:27 UTC (rev 6933) +++ NSIS/trunk/Source/BinInterop.cpp 2017-10-19 14:16:09 UTC (rev 6934) @@ -18,10 +18,14 @@ #include "BinInterop.h" #include "ResourceEditor.h" #include "util.h" +#include <string.h> // strlen #include <wchar.h> // _tcstoul #include <stdexcept> #define MKPTR(cast, base, offset) ( (cast) ( ((char*)(base)) + (offset) ) ) +#define LE2HE16 FIX_ENDIAN_INT16 // Little-endian 2 Host-endian +#define LE2HE32 FIX_ENDIAN_INT32 +#define HE2LE16 LE2HE16 const size_t invalid_res_id = ~(size_t)0; FILE* MSTLB_fopen(const TCHAR*filepath, size_t*pResId) @@ -379,132 +383,57 @@ return found; } -#pragma pack(push, pre_vxd_ver, 1) -typedef struct _VXD_VERSION_RESOURCE { - char cType; - WORD wID; - char cName; - WORD wOrdinal; - WORD wFlags; - DWORD dwResSize; - BYTE bVerData; -} VXD_VERSION_RESOURCE, *PVXD_VERSION_RESOURCE; -#pragma pack(pop, pre_vxd_ver) +#pragma pack(push, 1) +typedef struct tagMINI_IMAGE_VXD_HEADER { + WORD e32_magic, endian; + BYTE data[180]; + DWORD e32_winresoff, e32_winreslen; + WORD e32_devid, e32_ddkver; +} MINI_IMAGE_VXD_HEADER, *PMINI_IMAGE_VXD_HEADER; +#pragma pack(pop) -#ifdef _WIN32 -static void* CreateReadOnlyFullMappedView(LPCTSTR szFile, DWORD Access, DWORD Share, DWORD Mode) +static bool GetDLLVersionFromVXD(const TCHAR *filepath, DWORD &high, DWORD &low) { - void *pView = NULL; - HANDLE hFile = CreateFile(szFile, Access, Share, NULL, Mode, 0, NULL); - if (hFile == INVALID_HANDLE_VALUE) return pView; - HANDLE hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL); - if (hMap != INVALID_HANDLE_VALUE) + bool found = false; + FILEVIEW map; + char *filedata = create_file_view_readonly(filepath, map); + if (filedata) { - CloseHandle(hFile); - if ((pView = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0))) + PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER) filedata; + if ((pDosHdr->e_magic == 0x5A4D) | (pDosHdr->e_magic == 0x4D5A)) { - CloseHandle(hMap); - } - else - { - DWORD error = GetLastError(); - CloseHandle(hMap); - SetLastError(error); - } - } - else - { - DWORD error = GetLastError(); - CloseHandle(hFile); - SetLastError(error); - } - return pView; -} - -static BOOL GetVxdVersion(LPCTSTR szFile, LPDWORD lpdwLen, LPVOID lpData) -{ - BOOL result = FALSE; - DWORD resSize = 0, outSize = *lpdwLen; - void *pView = CreateReadOnlyFullMappedView(szFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING); - if (!pView) return FALSE; - - PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER) pView; - if (pDosHdr->e_magic == IMAGE_DOS_SIGNATURE) - { - PIMAGE_NT_HEADERS pNtHdr = (PIMAGE_NT_HEADERS) ((ULONG_PTR) pView + pDosHdr->e_lfanew); - if ((DWORD) pNtHdr->Signature == IMAGE_VXD_SIGNATURE) // Is it a little-endian VXD? - { - PIMAGE_VXD_HEADER pLEHdr = (PIMAGE_VXD_HEADER) pNtHdr; - if (pLEHdr->e32_winreslen != 0) + PMINI_IMAGE_VXD_HEADER pVxdHdr = MKPTR(PMINI_IMAGE_VXD_HEADER, pDosHdr, LE2HE32(pDosHdr->e_lfanew)); + if (pVxdHdr->e32_magic == HE2LE16(0x454C) && pVxdHdr->endian == 0) // Is it a little-endian VXD? { - PVXD_VERSION_RESOURCE pVerRes; - pVerRes = (VXD_VERSION_RESOURCE*) ((ULONG_PTR) pView + pLEHdr->e32_winresoff); - resSize = pVerRes->dwResSize; - if (lpData && outSize >= resSize) + UINT minvsvi16 = 2 + 2 + 16, minvsffi = 52, minressecsize = ((1 + 2) + (1 + 2) + 2 + 4) + minvsvi16 + minvsffi; + PMINI_IMAGE_VXD_HEADER pLEHdr = pVxdHdr; + UINT ressecsize = LE2HE32(pLEHdr->e32_winreslen); + if (ressecsize >= minressecsize && pLEHdr->e32_winresoff != 0) { - void *pResData = &(pVerRes->bVerData); - ZeroMemory(lpData, outSize); - CopyMemory(lpData, pResData, resSize); - result = TRUE; + // MSKB201685 just assumes that the first item is the version and we do the same. + char *pRes = MKPTR(char*, pDosHdr, LE2HE32(pLEHdr->e32_winresoff)); + UINT ressize, ofs = 3, succ = *MKPTR(BYTE*, pRes, 0) == 0xff && *MKPTR(WORD*, pRes, 1) == HE2LE16(16); // RT_VERSION + if (succ) succ = *MKPTR(BYTE*, pRes, ofs) == 0xff ? (ofs += (1 + 2) + 2) : (ofs += (strlen(MKPTR(char*, pRes, ofs)) + !0) + 2); // Ordinal or string name + if (succ) succ = ofs + 4 < ressecsize; + if (succ) ressize = LE2HE32(*MKPTR(DWORD*, pRes, ofs)), ofs += 4; + if (succ && ressize >= minvsvi16 + minvsffi && ressize < ressecsize) + { + WORD *pVSVI = MKPTR(WORD*, pRes, ofs); // VS_VERSIONINFO (16-bit/ASCII version) + if (LE2HE16(pVSVI[0]) >= minvsvi16 + minvsffi && LE2HE16(pVSVI[1]) >= minvsffi && !memcmp(&pVSVI[2], "VS_VERSION_INFO", 16)) + { + VS_FIXEDFILEINFO *pFFI = MKPTR(VS_FIXEDFILEINFO*, pVSVI, 2 + 2 + 16); + if (LE2HE32(pFFI->dwSignature) == 0xFEEF04BD) + { + high = LE2HE32(pFFI->dwFileVersionMS), low = LE2HE32(pFFI->dwFileVersionLS); + found = true; + } + } + } } - else - SetLastError(ERROR_INSUFFICIENT_BUFFER); } - else - SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND); } - else - SetLastError(ERROR_BAD_FORMAT); + close_file_view(map); } - else - SetLastError(ERROR_BAD_FORMAT); - - UnmapViewOfFile(pView); - *lpdwLen = resSize; - return result; -} - -static DWORD GetVxdVersionInfoSize(LPCTSTR szFile) -{ - DWORD result = 0; - if (!GetVxdVersion(szFile, &result, NULL)) - { - if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) // Successfully queried the required size? - { - SetLastError(0); - return result; - } - } - return result; -} - -static BOOL GetVxdVersionInfo(LPCTSTR szFile, DWORD dwLen, LPVOID lpData) -{ - return GetVxdVersion(szFile, &dwLen, lpData); -} -#endif //_WIN32 - -static bool GetDLLVersionFromVXD(const TCHAR *filepath, DWORD &high, DWORD &low) -{ - bool found = false; -#ifdef _WIN32 - DWORD verSize = GetVxdVersionInfoSize(filepath); - if (verSize) - { - void *buf = malloc(verSize); - if (buf) - { - UINT valSize; - VS_FIXEDFILEINFO *pvsf; - if (GetVxdVersionInfo(filepath, verSize, buf) && VerQueryValue(buf, _T("\\"), (void**) &pvsf, &valSize)) - { - high = pvsf->dwFileVersionMS, low = pvsf->dwFileVersionLS; - found = true; - } - free(buf); - } - } -#endif return found; } Modified: NSIS/trunk/Source/util.cpp =================================================================== --- NSIS/trunk/Source/util.cpp 2017-10-16 22:08:27 UTC (rev 6933) +++ NSIS/trunk/Source/util.cpp 2017-10-19 14:16:09 UTC (rev 6934) @@ -58,6 +58,38 @@ extern int g_display_errors; extern FILE *g_output, *g_errout; +#ifdef _WIN32 +static char* CreateMappedFileView(LPCTSTR szFile, DWORD FAccess, DWORD FShare, DWORD FMode, DWORD PProtect, DWORD MAccess) +{ + char *pView = NULL, restoreGLE = false; + HANDLE hFile = CreateFile(szFile, FAccess, FShare, NULL, FMode, 0, NULL); + if (hFile == INVALID_HANDLE_VALUE) return pView; + HANDLE hMap = CreateFileMapping(hFile, NULL, PProtect, 0, 0, NULL); + if (hMap != INVALID_HANDLE_VALUE) + { + CloseHandle(hFile); + if ((pView = (char*) MapViewOfFile(hMap, MAccess, 0, 0, 0))) + { + CloseHandle(hMap); + } + else + { + DWORD error = restoreGLE ? GetLastError() : 0; + CloseHandle(hMap); + if (restoreGLE) SetLastError(error); + } + } + else + { + DWORD error = restoreGLE ? GetLastError() : 0; + CloseHandle(hFile); + if (restoreGLE) SetLastError(error); + } + return pView; +} +#endif //~ _WIN32 + + double my_wtof(const wchar_t *str) { char buf[100]; @@ -585,7 +617,7 @@ #endif return result; } -#endif//!_WIN32 +#endif //! _WIN32 FILE* my_fopen(const TCHAR *path, const char *mode) { @@ -669,6 +701,23 @@ return result; } +void close_file_view(FILEVIEW&mmfv) +{ +#ifdef _WIN32 + if (mmfv.base) UnmapViewOfFile(mmfv.base); +#else + // TODO +#endif +} +char* create_file_view_readonly(const TCHAR *filepath, FILEVIEW&mmfv) +{ +#ifdef _WIN32 + return mmfv.base = CreateMappedFileView(filepath, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, PAGE_READONLY, FILE_MAP_READ); +#else + return 0; // TODO +#endif +} + tstring get_full_path(const tstring &path) { #ifdef _WIN32 TCHAR real_path[1024], *fnpart; Modified: NSIS/trunk/Source/util.h =================================================================== --- NSIS/trunk/Source/util.h 2017-10-16 22:08:27 UTC (rev 6933) +++ NSIS/trunk/Source/util.h 2017-10-19 14:16:09 UTC (rev 6934) @@ -268,7 +268,7 @@ #define OPEN(a, b) _topen(a, b) -#endif // ~_WIN32 +#endif //~ _WIN32 FILE* my_fopen(const TCHAR *path, const char *mode); #define FOPEN(a, b) my_fopen((a), (b)) @@ -279,6 +279,10 @@ BYTE* alloc_and_read_file(FILE *f, unsigned long &size); BYTE* alloc_and_read_file(const TCHAR *filepath, unsigned long &size); +typedef struct { char*base; size_t internal; } FILEVIEW; +void close_file_view(FILEVIEW&mmfv); +char* create_file_view_readonly(const TCHAR *filepath, FILEVIEW&mmfv); + // round a value up to be a multiple of 512 // assumption: T is an int type template <class T> inline T align_to_512(const T x) { return (x+511) & ~511; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <and...@us...> - 2017-11-28 18:15:45
|
Revision: 6953 http://sourceforge.net/p/nsis/code/6953 Author: anders_k Date: 2017-11-28 18:15:44 +0000 (Tue, 28 Nov 2017) Log Message: ----------- Force HEASLR DllCharacteristics when ASLR bit is set for 64-bit targets Modified Paths: -------------- NSIS/trunk/Source/Platform.h NSIS/trunk/Source/build.cpp Modified: NSIS/trunk/Source/Platform.h =================================================================== --- NSIS/trunk/Source/Platform.h 2017-11-16 22:55:14 UTC (rev 6952) +++ NSIS/trunk/Source/Platform.h 2017-11-28 18:15:44 UTC (rev 6953) @@ -789,10 +789,10 @@ # define IMAGE_SIZEOF_SHORT_NAME 8 #endif #ifndef IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE -#define IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE 0x0040 +#define IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE 0x0040 // ASLR #endif #ifndef IMAGE_DLLCHARACTERISTICS_NX_COMPAT -#define IMAGE_DLLCHARACTERISTICS_NX_COMPAT 0x0100 +#define IMAGE_DLLCHARACTERISTICS_NX_COMPAT 0x0100 // DEP #endif #ifndef IMAGE_DLLCHARACTERISTICS_NO_SEH #define IMAGE_DLLCHARACTERISTICS_NO_SEH 0x0400 @@ -800,6 +800,9 @@ #ifndef IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE #define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE 0x8000 #endif +#ifndef IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA +#define IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA 0x0020 // HEASLR +#endif // structures Modified: NSIS/trunk/Source/build.cpp =================================================================== --- NSIS/trunk/Source/build.cpp 2017-11-16 22:55:14 UTC (rev 6952) +++ NSIS/trunk/Source/build.cpp 2017-11-28 18:15:44 UTC (rev 6953) @@ -2414,7 +2414,9 @@ *GetCommonMemberFromPEOptHdr(headers->OptionalHeader, MinorSubsystemVersion) = FIX_ENDIAN_INT16(PESubsysVerMin); } // DllCharacteristics - *GetCommonMemberFromPEOptHdr(headers->OptionalHeader, DllCharacteristics) = FIX_ENDIAN_INT16(PEDllCharacteristics); + WORD dc = PEDllCharacteristics; + if ((dc & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) && is_target_64bit()) dc |= IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA; + *GetCommonMemberFromPEOptHdr(headers->OptionalHeader, DllCharacteristics) = FIX_ENDIAN_INT16(dc); } catch (std::runtime_error& err) { ERROR_MSG(_T("Error updating PE headers: %") NPRIs _T("\n"), CtoTStrParam(err.what())); return PS_ERROR; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <and...@us...> - 2018-01-29 14:42:15
|
Revision: 6972 http://sourceforge.net/p/nsis/code/6972 Author: anders_k Date: 2018-01-29 14:42:13 +0000 (Mon, 29 Jan 2018) Log Message: ----------- Attempt to fix VC6 Modified Paths: -------------- NSIS/trunk/Source/build.h NSIS/trunk/Source/util.cpp Modified: NSIS/trunk/Source/build.h =================================================================== --- NSIS/trunk/Source/build.h 2018-01-29 02:46:55 UTC (rev 6971) +++ NSIS/trunk/Source/build.h 2018-01-29 14:42:13 UTC (rev 6972) @@ -171,7 +171,7 @@ template<class C, class K, class V> void insert_or_assign(C&c, const K&k, V val) { typename C::value_type item(k, val); - std::pair<typename C::iterator, bool> ret = c.insert(item); + std::pair<C::iterator, bool> ret = c.insert(item); if (!ret.second) ret.first->second = val; } template<class C, class K> typename mapped_type_helper<C>::type get_paired_value(const C&c, const K&k, typename mapped_type_helper<C>::type defval) const Modified: NSIS/trunk/Source/util.cpp =================================================================== --- NSIS/trunk/Source/util.cpp 2018-01-29 02:46:55 UTC (rev 6971) +++ NSIS/trunk/Source/util.cpp 2018-01-29 14:42:13 UTC (rev 6972) @@ -1021,7 +1021,7 @@ DWORD childec = -1; if (ok) { - bool utf8 = CP_UTF8 == cp, okt; + bool fullbuf = false, utf8 = CP_UTF8 == cp, okt; char iobuf[512]; DWORD cbRead, cbOfs = 0, cchwb = 0; WCHAR wbuf[100], wchbuf[2+1]; // A surrogate pair + \0 @@ -1067,7 +1067,7 @@ if (!cch) continue; wbuf[cchwb++] = wchbuf[0]; if (--cch) wbuf[cchwb++] = wchbuf[1]; - const bool fullbuf = cchwb+cch >= COUNTOF(wbuf)-1; // cch is 1 for surrogate pairs + fullbuf = cchwb+cch >= COUNTOF(wbuf)-1; // cch is 1 for surrogate pairs if (!okr || fullbuf || L'\n' == wchbuf[0]) // Stop on \n so \r\n conversion has enough context (...\r\n vs ...\n) { finalwrite: #ifdef MAKENSIS @@ -1082,7 +1082,7 @@ } if (!okr) { - if (cchwb) goto finalwrite; + if (cchwb) goto finalwrite; // End of stream without a ending newline, write out the remaining data. break; } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <and...@us...> - 2018-05-14 19:07:22
|
Revision: 6993 http://sourceforge.net/p/nsis/code/6993 Author: anders_k Date: 2018-05-14 19:07:17 +0000 (Mon, 14 May 2018) Log Message: ----------- Preliminary support for disableWindowFiltering and gdiScaling manifest elements Modified Paths: -------------- NSIS/trunk/Source/build.cpp NSIS/trunk/Source/build.h NSIS/trunk/Source/manifest.cpp NSIS/trunk/Source/manifest.h NSIS/trunk/Source/script.cpp NSIS/trunk/Source/tokens.cpp NSIS/trunk/Source/tokens.h Modified: NSIS/trunk/Source/build.cpp =================================================================== --- NSIS/trunk/Source/build.cpp 2018-05-03 21:26:10 UTC (rev 6992) +++ NSIS/trunk/Source/build.cpp 2018-05-14 19:07:17 UTC (rev 6993) @@ -281,6 +281,7 @@ PEDllCharacteristics = IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE|IMAGE_DLLCHARACTERISTICS_NO_SEH|IMAGE_DLLCHARACTERISTICS_NX_COMPAT|IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE; //forums.winamp.com/showthread.php?t=344755 PESubsysVerMaj = PESubsysVerMin = (WORD) -1; + manifest_flags = manifest::flags_default; manifest_comctl = manifest::comctl_old; manifest_exec_level = manifest::exec_level_admin; manifest_dpiaware = manifest::dpiaware_notset; @@ -2384,7 +2385,7 @@ try { init_res_editor(); // This should stay ANSI - string manifest = manifest::generate(manifest_comctl, manifest_exec_level, manifest_dpiaware, manifest_dpiawareness.c_str(), manifest_sosl); + string manifest = manifest::generate((manifest::flags)manifest_flags, manifest_comctl, manifest_exec_level, manifest_dpiaware, manifest_dpiawareness.c_str(), manifest_sosl); if (manifest == "") return PS_OK; Modified: NSIS/trunk/Source/build.h =================================================================== --- NSIS/trunk/Source/build.h 2018-05-03 21:26:10 UTC (rev 6992) +++ NSIS/trunk/Source/build.h 2018-05-14 19:07:17 UTC (rev 6993) @@ -674,6 +674,7 @@ #endif WORD PEDllCharacteristics, PESubsysVerMaj, PESubsysVerMin; + unsigned int manifest_flags; manifest::comctl manifest_comctl; manifest::exec_level manifest_exec_level; manifest::dpiaware manifest_dpiaware; Modified: NSIS/trunk/Source/manifest.cpp =================================================================== --- NSIS/trunk/Source/manifest.cpp 2018-05-03 21:26:10 UTC (rev 6992) +++ NSIS/trunk/Source/manifest.cpp 2018-05-14 19:07:17 UTC (rev 6993) @@ -91,7 +91,7 @@ } -string generate(comctl comctl_selection, exec_level exec_level_selection, dpiaware dpia, const TCHAR*dpia2, SupportedOSList& sosl) +string generate(flags featureflags, comctl comctl_selection, exec_level exec_level_selection, dpiaware dpia, const TCHAR*dpia2, SupportedOSList& sosl) { bool default_or_empty_sosl = sosl.isdefaultlist() || !sosl.getcount(); if (comctl_selection == comctl_old && exec_level_selection == exec_level_none && default_or_empty_sosl && dpiaware_notset == dpia) @@ -149,21 +149,35 @@ xml += "</application></compatibility>"; } - if (dpiaware_notset != dpia || *dpia2) + string xml_aws = ""; // <application><windowsSettings> + if (featureflags & disablewindowfiltering) { + xml_aws += "<disableWindowFiltering xmlns=\"http://schemas.microsoft.com/SMI/2011/WindowsSettings\">"; + xml_aws += "true"; + xml_aws += "</disableWindowFiltering>"; + } + if (featureflags & gdiscaling) + { + xml_aws += "<gdiScaling xmlns=\"http://schemas.microsoft.com/SMI/2017/WindowsSettings\">"; + xml_aws += "true"; + xml_aws += "</gdiScaling>"; + } + if (dpiaware_notset != dpia) + { + xml_aws += "<dpiAware xmlns=\"http://schemas.microsoft.com/SMI/2005/WindowsSettings\">"; + xml_aws += dpia >= dpiaware_permonitor ? "True/PM" : dpiaware_false != dpia ? "true" : "false"; + xml_aws += "</dpiAware>"; + } + if (*dpia2) + { + xml_aws += "<dpiAwareness xmlns=\"http://schemas.microsoft.com/SMI/2016/WindowsSettings\">"; + xml_aws += TtoCString(dpia2); + xml_aws += "</dpiAwareness>"; + } + if (!xml_aws.empty()) + { xml += "<application xmlns=\"urn:schemas-microsoft-com:asm.v3\"><windowsSettings>"; - if (dpiaware_notset != dpia) - { - xml += "<dpiAware xmlns=\"http://schemas.microsoft.com/SMI/2005/WindowsSettings\">"; - xml += dpia >= dpiaware_permonitor ? "True/PM" : dpiaware_false != dpia ? "true" : "false"; - xml += "</dpiAware>"; - } - if (*dpia2) - { - xml += "<dpiAwareness xmlns=\"http://schemas.microsoft.com/SMI/2016/WindowsSettings\">"; - xml += TtoCString(dpia2); - xml += "</dpiAwareness>"; - } + xml += xml_aws; xml += "</windowsSettings></application>"; } Modified: NSIS/trunk/Source/manifest.h =================================================================== --- NSIS/trunk/Source/manifest.h 2018-05-03 21:26:10 UTC (rev 6992) +++ NSIS/trunk/Source/manifest.h 2018-05-14 19:07:17 UTC (rev 6993) @@ -24,13 +24,20 @@ namespace manifest { - enum comctl + enum flags { + disablewindowfiltering = 0x01, // Win8+ + gdiscaling = 0x02, // Win10FU1703+ + flags_default = 0 + }; + + enum comctl // WinXP+ + { comctl_old, comctl_xp }; - enum exec_level + enum exec_level // WinVista+ { exec_level_none, exec_level_user, @@ -38,7 +45,7 @@ exec_level_admin }; - enum dpiaware + enum dpiaware // WinVista+ { dpiaware_notset, dpiaware_false, @@ -46,7 +53,7 @@ dpiaware_permonitor // System DPI on Vista/7/8, PerMonitor on 8.1+ }; - class SupportedOSList + class SupportedOSList // Win7+ { StringList m_list; bool m_isdefaultlist; @@ -79,7 +86,7 @@ } }; - std::string generate(comctl, exec_level, dpiaware, const TCHAR*, SupportedOSList&); + std::string generate(flags, comctl, exec_level, dpiaware, const TCHAR*, SupportedOSList&); }; Modified: NSIS/trunk/Source/script.cpp =================================================================== --- NSIS/trunk/Source/script.cpp 2018-05-03 21:26:10 UTC (rev 6992) +++ NSIS/trunk/Source/script.cpp 2018-05-14 19:07:17 UTC (rev 6993) @@ -2293,6 +2293,24 @@ } } return PS_OK; + case TOK_MANIFEST_DISABLEWINDOWFILTERING: + switch(line.gettoken_enum(1,_T("notset\0false\0true"))) + { + case 0: + case 1: manifest_flags &= ~manifest::disablewindowfiltering; break; + case 2: manifest_flags |= manifest::disablewindowfiltering; break; + default: PRINTHELP(); + } + return PS_OK; + case TOK_MANIFEST_GDISCALING: + switch(line.gettoken_enum(1,_T("notset\0false\0true"))) + { + case 0: + case 1: manifest_flags &= ~manifest::gdiscaling; break; + case 2: manifest_flags |= manifest::gdiscaling; break; + default: PRINTHELP(); + } + return PS_OK; #ifdef _UNICODE case TOK_TARGET: Modified: NSIS/trunk/Source/tokens.cpp =================================================================== --- NSIS/trunk/Source/tokens.cpp 2018-05-03 21:26:10 UTC (rev 6992) +++ NSIS/trunk/Source/tokens.cpp 2018-05-14 19:07:17 UTC (rev 6993) @@ -256,6 +256,8 @@ {TOK_MANIFEST_DPIAWARE,_T("ManifestDPIAware"),1,0,_T("notset|true|false"),TP_GLOBAL}, {TOK_MANIFEST_DPIAWARENESS,_T("ManifestDPIAwareness"),1,0,_T("comma_separated_string"),TP_GLOBAL}, {TOK_MANIFEST_SUPPORTEDOS,_T("ManifestSupportedOS"),1,-1,_T("none|all|WinVista|Win7|Win8|Win8.1|Win10|{GUID} [...]"),TP_GLOBAL}, +{TOK_MANIFEST_DISABLEWINDOWFILTERING,_T("ManifestDisableWindowFiltering"),1,0,_T("notset|true"),TP_GLOBAL}, +{TOK_MANIFEST_GDISCALING,_T("ManifestGdiScaling"),1,0,_T("notset|true"),TP_GLOBAL}, {TOK_P_PACKEXEHEADER,_T("!packhdr"),2,0,_T("temp_file_name command_line_to_compress_that_temp_file"),TP_ALL}, {TOK_P_FINALIZE,_T("!finalize"),1,2,_T("command_with_%1 [<OP retval>]"),TP_ALL}, {TOK_P_SYSTEMEXEC,_T("!system"),1,2,_T("command [<OP retval> | <retvalsymbol>]\n OP=(< > <> =)"),TP_ALL}, Modified: NSIS/trunk/Source/tokens.h =================================================================== --- NSIS/trunk/Source/tokens.h 2018-05-03 21:26:10 UTC (rev 6992) +++ NSIS/trunk/Source/tokens.h 2018-05-14 19:07:17 UTC (rev 6993) @@ -66,6 +66,8 @@ TOK_MANIFEST_DPIAWARE, TOK_MANIFEST_DPIAWARENESS, TOK_MANIFEST_SUPPORTEDOS, + TOK_MANIFEST_DISABLEWINDOWFILTERING, + TOK_MANIFEST_GDISCALING, TOK_CHANGEUI, TOK_ADDBRANDINGIMAGE, TOK_SETFONT, This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <and...@us...> - 2018-06-02 00:38:49
|
Revision: 7000 http://sourceforge.net/p/nsis/code/7000 Author: anders_k Date: 2018-06-02 00:38:45 +0000 (Sat, 02 Jun 2018) Log Message: ----------- throw() is deprecated in C++17 Modified Paths: -------------- NSIS/trunk/Source/Platform.h NSIS/trunk/Source/scriptpp.cpp NSIS/trunk/Source/util.cpp Modified: NSIS/trunk/Source/Platform.h =================================================================== --- NSIS/trunk/Source/Platform.h 2018-06-01 22:08:04 UTC (rev 6999) +++ NSIS/trunk/Source/Platform.h 2018-06-02 00:38:45 UTC (rev 7000) @@ -1037,10 +1037,15 @@ #if defined(__clang__) && defined(__cplusplus) && __cplusplus < 201103L -#define NSIS_CXX_THROWSPEC(throwspec) throw(throwspec) // Use exception specifications to avoid operator new missing-exception-spec warning +# define NSIS_CXX_THROWSPEC(throwspec) throw(throwspec) // Use exception specifications to avoid operator new missing-exception-spec warning #else -#define NSIS_CXX_THROWSPEC(ignoredthrowspec) // Ignore c++ exception specifications +# define NSIS_CXX_THROWSPEC(ignoredthrowspec) // Ignore c++ exception specifications #endif +#if defined(__cplusplus) && __cplusplus >= 201103L +# define NSIS_CXX_NOEXCEPT() noexcept(true) +#else +# define NSIS_CXX_NOEXCEPT() throw() // Can't specialize __declspec(nothrow) because MSVC requires it before the function name +#endif #define BUGBUG64TRUNCATE(cast,xpr) ( (cast) (xpr) ) /* @@ -1048,7 +1053,7 @@ Always use our NPRI* (NsisPRInt*[Narrow|Wide]) defines in format strings when calling functions from tchar.h (Similar to the way <inttypes.h> works) -Example: _tprintf(_T("Hello %") NPRIs _T("\n"), _T("World")); +Example: _tprintf(_T("%") NPRIs _T(" %") NPRIws _T("\n"), _T("Hello"), L"World"); */ #ifdef _WIN32 # define NPRIs _T("s") Modified: NSIS/trunk/Source/scriptpp.cpp =================================================================== --- NSIS/trunk/Source/scriptpp.cpp 2018-06-01 22:08:04 UTC (rev 6999) +++ NSIS/trunk/Source/scriptpp.cpp 2018-06-02 00:38:45 UTC (rev 7000) @@ -235,11 +235,11 @@ TCHAR* CEXEBuild::GetMacro(const TCHAR *macroname, TCHAR**macroend /*= 0*/) { TCHAR *t = (TCHAR*)m_macros.get(), *mbeg, *mbufbeg = t; - size_t cbAll = m_macros.getlen(), cchAll = cbAll / sizeof(TCHAR); + size_t cbAll = m_macros.getlen(); for (; t && *t; ++t) { mbeg = t; - if (t-mbufbeg >= cchAll) break; + if ((size_t)t - (size_t)mbufbeg >= cbAll) break; const bool foundit = !_tcsicmp(mbeg, macroname); t += _tcslen(t) + 1; // advance over macro name Modified: NSIS/trunk/Source/util.cpp =================================================================== --- NSIS/trunk/Source/util.cpp 2018-06-01 22:08:04 UTC (rev 6999) +++ NSIS/trunk/Source/util.cpp 2018-06-02 00:38:45 UTC (rev 7000) @@ -1354,5 +1354,5 @@ { return operator new(size); } -void operator delete(void *p) throw() { if (p) free(p); } -void operator delete [](void *p) throw() { if (p) free(p); } +void operator delete(void *p) NSIS_CXX_NOEXCEPT() { if (p) free(p); } +void operator delete [](void *p) NSIS_CXX_NOEXCEPT() { if (p) free(p); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <and...@us...> - 2018-06-14 22:13:27
|
Revision: 7008 http://sourceforge.net/p/nsis/code/7008 Author: anders_k Date: 2018-06-14 22:13:23 +0000 (Thu, 14 Jun 2018) Log Message: ----------- Stricter !delfile error/warning handling Modified Paths: -------------- NSIS/trunk/Source/build.h NSIS/trunk/Source/scriptpp.cpp Modified: NSIS/trunk/Source/build.h =================================================================== --- NSIS/trunk/Source/build.h 2018-06-14 20:46:23 UTC (rev 7007) +++ NSIS/trunk/Source/build.h 2018-06-14 22:13:23 UTC (rev 7008) @@ -91,6 +91,8 @@ DW_PLUGIN_NOUNLOAD_PLACEMENT = 6080, // reserved ..6099 DW_PP_PRAGMA_UNKNOWN = 6100, // reserved ..6199 DW_PP_PRAGMA_INVALID = 6101, + DW_PP_DELFILE_DELERROR = 6149, + DW_PP_DELFILE_NOMATCH = DW_PP_DELFILE_DELERROR, DW_PP_VERBOSE_POP_EMPTY_STACK = 6150, //DW_PP_VERBOSE_BAD_LEVEL = 6151?, // 2.x failed to issue a warning. 3.x currently aborts with hard error. DW_INCLUDE_NONFATAL_NOT_FOUND = 7000, // reserved ..7009 Modified: NSIS/trunk/Source/scriptpp.cpp =================================================================== --- NSIS/trunk/Source/scriptpp.cpp 2018-06-14 20:46:23 UTC (rev 7007) +++ NSIS/trunk/Source/scriptpp.cpp 2018-06-14 22:13:23 UTC (rev 7008) @@ -491,9 +491,8 @@ int CEXEBuild::pp_delfile(LineParser&line) { - int fatal = 1; - int a = 1; - TCHAR *fc = line.gettoken_str(a); + UINT fatal = true, a = 1, matchcount = 0; + const TCHAR *fc = line.gettoken_str(a); if (line.getnumtokens()==3) { if (!_tcsicmp(fc,_T("/nonfatal"))) @@ -502,7 +501,8 @@ PRINTHELP(); } - SCRIPT_MSG(_T("!delfile: \"%") NPRIs _T("\"\n"), line.gettoken_str(a)); + SCRIPT_MSG(_T("!delfile: \"%") NPRIs _T("\"\n"), fc); + const TCHAR *fmt = _T("!delfile: \"%") NPRIs _T("\" couldn't be deleted.\n"); tstring dir = get_dir_name(fc), spec = get_file_name(fc); tstring basedir = dir + PLATFORM_PATH_SEPARATOR_STR; @@ -510,25 +510,33 @@ boost::scoped_ptr<dir_reader> dr( new_dir_reader() ); dr->read(dir); // BUGBUG: PATH_CONVERT? - - for (dir_reader::iterator files_itr = dr->files().begin(); - files_itr != dr->files().end(); - files_itr++) + dir_reader::iterator files_itr = dr->files().begin(); + for (; files_itr != dr->files().end(); files_itr++) { if (!dir_reader::matches(*files_itr, spec)) continue; + ++matchcount; tstring file = basedir + *files_itr; // BUGBUG: PATH_CONVERT? - - int result = _tunlink(file.c_str()); - if (result == -1) + fc = file.c_str(); + if (-1 == _tunlink(fc)) { - ERROR_MSG(_T("!delfile: \"%") NPRIs _T("\" couldn't be deleted.\n"), file.c_str()); - if (fatal) return PS_ERROR; + if (fatal) + return (ERROR_MSG(fmt, fc), PS_ERROR); + else + warning_fl(DW_PP_DELFILE_DELERROR, fmt, fc); } else - SCRIPT_MSG(_T("!delfile: deleted \"%") NPRIs _T("\"\n"), file.c_str()); + SCRIPT_MSG(_T("!delfile: deleted \"%") NPRIs _T("\"\n"), fc); } + + if (!matchcount) + { + if (fatal) + return (ERROR_MSG(fmt, fc), PS_ERROR); + else + warning_fl(DW_PP_DELFILE_NOMATCH, fmt, fc); + } return PS_OK; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <and...@us...> - 2018-06-25 21:33:36
|
Revision: 7011 http://sourceforge.net/p/nsis/code/7011 Author: anders_k Date: 2018-06-25 21:33:30 +0000 (Mon, 25 Jun 2018) Log Message: ----------- List plug-in directories when plug-in call fails Modified Paths: -------------- NSIS/trunk/Source/Platform.h NSIS/trunk/Source/Plugins.cpp NSIS/trunk/Source/Plugins.h NSIS/trunk/Source/build.h NSIS/trunk/Source/exehead/fileform.h NSIS/trunk/Source/script.cpp NSIS/trunk/Source/util.cpp Modified: NSIS/trunk/Source/Platform.h =================================================================== --- NSIS/trunk/Source/Platform.h 2018-06-17 21:20:05 UTC (rev 7010) +++ NSIS/trunk/Source/Platform.h 2018-06-25 21:33:30 UTC (rev 7011) @@ -1046,6 +1046,11 @@ #else # define NSIS_CXX_NOEXCEPT() throw() // Can't specialize __declspec(nothrow) because MSVC requires it before the function name #endif +#if defined(_MSC_VER) && _MSC_VER <= 1200 +# define NSIS_CXX_TYPENAME // VC6 can't handle typename in some places but GCC requires it +#else +# define NSIS_CXX_TYPENAME typename +#endif #define BUGBUG64TRUNCATE(cast,xpr) ( (cast) (xpr) ) /* @@ -1090,4 +1095,12 @@ #endif //~ _MSC_VER >= 1500 #endif //~ _MSC_VER + +#ifdef __cplusplus +namespace STLHelpers +{ + template<class M> struct mapped_type_helper { typedef typename M::value_type::second_type type; }; // VC6 uses referent_type and not mapped_type +} +#endif //~ __cplusplus + #endif // EOF Modified: NSIS/trunk/Source/Plugins.cpp =================================================================== --- NSIS/trunk/Source/Plugins.cpp 2018-06-17 21:20:05 UTC (rev 7010) +++ NSIS/trunk/Source/Plugins.cpp 2018-06-25 21:33:30 UTC (rev 7011) @@ -76,6 +76,16 @@ } +static tstring GetDllPath(const tstring&fullpath) +{ + tstring::size_type platsep = fullpath.rfind(PLATFORM_PATH_SEPARATOR_STR); + tstring::size_type unixsep = platsep; + if (PLATFORM_PATH_SEPARATOR_C != _T('/')) unixsep = fullpath.rfind(_T("/")); // Ideally get_dir_name would do this for us + tstring::size_type lastsep = platsep != string::npos && unixsep != string::npos ? STD_MAX(platsep, unixsep) : STD_MIN(platsep, unixsep); + if (lastsep == string::npos) return _T(""); + return fullpath.substr(0, lastsep); +} + static inline tstring GetDllName(const tstring&command) { return get_string_prefix(command, _T("::")); @@ -253,4 +263,28 @@ return dllname.length() + 2 < token.length(); } +struct PrintPluginDirsHelper { + template<class C> static void print(const C&c, const char*indent = "") + { + std::/*unordered_*/set<typename STLHelpers::mapped_type_helper<C>::type +#ifdef _WIN32 + , Plugins::strnocasecmp #endif + > seen; + for (NSIS_CXX_TYPENAME C::const_iterator it = c.begin(); it != c.end(); ++it) + { + const tstring path = GetDllPath(it->second); + if (contains(seen, path)) continue; + seen.insert(path); + _ftprintf(g_output, _T("%") NPRIns _T("%") NPRIs _T("\n"), indent, path.c_str()); + } + } +}; + +void Plugins::PrintPluginDirs() +{ + _ftprintf(g_output, _T("Plugin directories:\n")); + PrintPluginDirsHelper::print(m_dllname_to_path, " "); +} + +#endif Modified: NSIS/trunk/Source/Plugins.h =================================================================== --- NSIS/trunk/Source/Plugins.h 2018-06-17 21:20:05 UTC (rev 7010) +++ NSIS/trunk/Source/Plugins.h 2018-06-25 21:33:30 UTC (rev 7011) @@ -57,6 +57,7 @@ int GetDllDataHandle(bool uninst, const tstring& command) const; void SetDllDataHandle(bool uninst, tstring&canoniccmd, int dataHandle); static bool IsPluginCallSyntax(const tstring& token); + void PrintPluginDirs(); private: // methods void GetExports(const tstring &pathToDll, bool pe64, bool displayInfo); Modified: NSIS/trunk/Source/build.h =================================================================== --- NSIS/trunk/Source/build.h 2018-06-17 21:20:05 UTC (rev 7010) +++ NSIS/trunk/Source/build.h 2018-06-25 21:33:30 UTC (rev 7011) @@ -169,15 +169,11 @@ #define FLAG_OFFSET(flag) (FIELD_OFFSET(exec_flags_t, flag)/sizeof(int)) class DiagState { - template<class M> struct mapped_type_helper { typedef typename M::value_type::second_type type; }; // VC6 uses referent_type and not mapped_type + template<class M> struct mapped_type_helper { typedef typename STLHelpers::mapped_type_helper<M>::type type; }; template<class C, class K, class V> void insert_or_assign(C&c, const K&k, V val) { typename C::value_type item(k, val); -#if defined(_MSC_VER) && _MSC_VER <= 1200 - std::pair<C::iterator, bool> ret = c.insert(item); -#else - std::pair<typename C::iterator, bool> ret = c.insert(item); -#endif + std::pair<NSIS_CXX_TYPENAME C::iterator, bool> ret = c.insert(item); if (!ret.second) ret.first->second = val; } template<class C, class K> typename mapped_type_helper<C>::type get_paired_value(const C&c, const K&k, typename mapped_type_helper<C>::type defval) const Modified: NSIS/trunk/Source/exehead/fileform.h =================================================================== --- NSIS/trunk/Source/exehead/fileform.h 2018-06-17 21:20:05 UTC (rev 7010) +++ NSIS/trunk/Source/exehead/fileform.h 2018-06-25 21:33:30 UTC (rev 7011) @@ -516,7 +516,7 @@ #define REGROOTVIEW32 0x40000000 #define REGROOTVIEW64 0x20000000 -#define REGROOTVIEWTOSAMVIEW(rv) ( ((UINT_PTR)(rv)&(REGROOTVIEW32|REGROOTVIEW64)) >> 21 ) // REGROOTVIEWxx to KEY_WOW64_xxKEY +#define REGROOTVIEWTOSAMVIEW(rv) ( (UINT)(((UINT_PTR)(rv)&(REGROOTVIEW32|REGROOTVIEW64)) >> 21) ) // REGROOTVIEWxx to KEY_WOW64_xxKEY #define IsRegRootkeyForcedView(hKey) ( ((UINT_PTR) (hKey) & (REGROOTVIEW32|REGROOTVIEW64)) ) #define MAKEREGROOTVIEW(r, fv) ( (HKEY) ((UINT_PTR)(r) | (fv)) ) #define HKSHCTX ( (HKEY) 0 ) // Converted to HKCU or HKLM by GetRegRootKey Modified: NSIS/trunk/Source/script.cpp =================================================================== --- NSIS/trunk/Source/script.cpp 2018-06-17 21:20:05 UTC (rev 7010) +++ NSIS/trunk/Source/script.cpp 2018-06-25 21:33:30 UTC (rev 7011) @@ -297,7 +297,10 @@ { #ifdef NSIS_CONFIG_PLUGIN_SUPPORT if (Plugins::IsPluginCallSyntax(tokstr0)) + { + if (m_pPlugins && display_warnings) m_pPlugins->PrintPluginDirs(); ERROR_MSG(_T("Plugin%") NPRIs _T(" not found, cannot call %") NPRIs _T("\n"),m_pPlugins && m_pPlugins->IsKnownPlugin(tokstr0) ? _T(" function") : _T(""),tokstr0); + } else #endif ERROR_MSG(_T("Invalid command: \"%") NPRIs _T("\"\n"),tokstr0); Modified: NSIS/trunk/Source/util.cpp =================================================================== --- NSIS/trunk/Source/util.cpp 2018-06-17 21:20:05 UTC (rev 7010) +++ NSIS/trunk/Source/util.cpp 2018-06-25 21:33:30 UTC (rev 7011) @@ -1023,7 +1023,7 @@ { bool fullbuf = false, utf8 = CP_UTF8 == cp, okt; char iobuf[512]; - DWORD cbRead, cbOfs = 0, cchwb = 0; + DWORD cbRead, cbOfs = 0, cchwb = 0, i; WCHAR wbuf[100], wchbuf[2+1]; // A surrogate pair + \0 for(;;) { @@ -1030,7 +1030,7 @@ BOOL okr = ReadFile(hSORd, iobuf+cbOfs, sizeof(iobuf)-cbOfs, &cbRead, 0); cbRead += cbOfs, cbOfs = 0; unsigned char cbTrail, cch; - for(DWORD i = 0; i < cbRead;) + for(i = 0; i < cbRead;) { cch = 0; if (utf8) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <and...@us...> - 2018-10-24 19:01:03
|
Revision: 7025 http://sourceforge.net/p/nsis/code/7025 Author: anders_k Date: 2018-10-24 19:01:00 +0000 (Wed, 24 Oct 2018) Log Message: ----------- Refactored postbuild_cmd and !tempfile handling to help patch #280 Modified Paths: -------------- NSIS/trunk/Source/build.cpp NSIS/trunk/Source/build.h NSIS/trunk/Source/scriptpp.cpp NSIS/trunk/Source/tstring.cpp NSIS/trunk/Source/util.cpp NSIS/trunk/Source/util.h Modified: NSIS/trunk/Source/build.cpp =================================================================== --- NSIS/trunk/Source/build.cpp 2018-10-21 12:28:10 UTC (rev 7024) +++ NSIS/trunk/Source/build.cpp 2018-10-24 19:01:00 UTC (rev 7025) @@ -96,16 +96,11 @@ int nlt = lang_tables.getlen() / sizeof(LanguageTable); LanguageTable *nla = (LanguageTable*)lang_tables.get(); - for (int i = 0; i < nlt; i++) { + for (int i = 0; i < nlt; i++) DeleteLangTable(nla+i); - } - for (;postbuild_cmds;) - { - struct postbuild_cmd * tmp = postbuild_cmds; - postbuild_cmds = postbuild_cmds->next; - delete [] tmp; - } + if (postbuild_cmds) + postbuild_cmds->delete_all(); } CEXEBuild::CEXEBuild(signed char pponly, bool warnaserror) : @@ -3006,40 +3001,7 @@ fileend,total_usize,pc/10,pc%10); } fclose(fp); - if (postbuild_cmds) - { - for (struct postbuild_cmd *cmd=postbuild_cmds; cmd; cmd = cmd->next) - { - TCHAR *cmdstr = cmd->cmd, *cmdstrbuf = NULL; - TCHAR *arg = _tcsstr(cmdstr, _T("%1")); - if (arg) // if found, replace %1 by build_output_filename - { - const size_t cchbldoutfile = _tcslen(build_output_filename); - cmdstrbuf = (TCHAR*) malloc( (_tcslen(cmdstr) + cchbldoutfile + 1)*sizeof(TCHAR) ); - if (!cmdstrbuf) - { - ERROR_MSG(_T("Error: can't allocate memory for finalize command\n")); - return PS_ERROR; - } - arg -= ((UINT_PTR)cmdstr)/sizeof(TCHAR), arg += ((UINT_PTR)cmdstrbuf)/sizeof(TCHAR); - _tcscpy(cmdstrbuf,cmdstr); - cmdstr = cmdstrbuf; - memmove(arg+cchbldoutfile, arg+2, (_tcslen(arg+2)+1)*sizeof(TCHAR)); - memmove(arg, build_output_filename, cchbldoutfile*sizeof(TCHAR)); - //BUGBUG: Should we call PathConvertWinToPosix on build_output_filename? - } - - SCRIPT_MSG(_T("\nFinalize command: %") NPRIs _T("\n"),cmdstr); - int ret = sane_system(cmdstr); - if (!check_external_exitcode(ret, cmd->cmpop, cmd->cmpval)) - { - ERROR_MSG(_T("%") NPRIs _T(" %d, aborting\n"), _T("Finalize command returned"), ret); - return PS_ERROR; - } - if (ret != 0) INFO_MSG(_T("%") NPRIs _T(" %d\n"), _T("Finalize command returned"), ret); - free(cmdstrbuf); - } - } + RET_UNLESS_OK(run_postbuild_cmds(postbuild_cmds, build_output_filename, _T("Finalize"))); print_warnings(); return PS_OK; } @@ -4029,6 +3991,57 @@ } } +void CEXEBuild::postbuild_cmd::delete_all() +{ + for (struct postbuild_cmd *p = this, *tmp; p;) + { + tmp = p, p = p->next; + delete [] tmp; + } +} + +CEXEBuild::postbuild_cmd* CEXEBuild::postbuild_cmd::make(const TCHAR *cmdstr, int cmpop, int cmpval) +{ + postbuild_cmd *p = (postbuild_cmd*) (new BYTE[FIELD_OFFSET(postbuild_cmd, cmd[_tcsclen(cmdstr)+!0])]); + p->next = NULL, _tcscpy(p->cmd, cmdstr); + p->cmpop = cmpop, p->cmpval = cmpval; + return p; +} + +int CEXEBuild::run_postbuild_cmds(const postbuild_cmd *cmds, const TCHAR *templatearg_pc1, const TCHAR* commandname) +{ + for (const postbuild_cmd *cmd = cmds; cmd; cmd = cmd->next) + { + const TCHAR *cmdstr = cmd->cmd; + TCHAR *arg = _tcsstr(const_cast<TCHAR*>(cmdstr), _T("%1")), *cmdstrbuf = NULL; + if (arg) // If found, replace %1 with templatearg_pc1 + { + const size_t cchtpc1 = _tcslen(templatearg_pc1); + cmdstrbuf = (TCHAR*) malloc((_tcslen(cmdstr) + cchtpc1 + 1) * sizeof(TCHAR)); + if (!cmdstrbuf) + { + ERROR_MSG(_T("Error: Can't allocate memory for %") NPRIs _T(" command\n"), commandname); + return PS_ERROR; + } + arg -= ((UINT_PTR)cmdstr)/sizeof(TCHAR), arg += ((UINT_PTR)cmdstrbuf)/sizeof(TCHAR); + _tcscpy(cmdstrbuf, cmdstr), cmdstr = cmdstrbuf; + memmove(arg+cchtpc1, arg+2, (_tcslen(arg+2)+1)*sizeof(TCHAR)); + memmove(arg, templatearg_pc1, cchtpc1*sizeof(TCHAR)); + //BUGBUG: Should we call PathConvertWinToPosix on templatearg_pc1? + } + SCRIPT_MSG(_T("\n%") NPRIs _T(" command: %") NPRIs _T("\n"), commandname, cmdstr); + int ret = sane_system(cmdstr); + if (!check_external_exitcode(ret, cmd->cmpop, cmd->cmpval)) + { + ERROR_MSG(_T("%") NPRIs _T(" command returned %d, aborting\n"), commandname, ret); + return PS_ERROR; + } + if (ret != 0) INFO_MSG(_T("%") NPRIs _T(" command returned %d\n"), commandname, ret); + free(cmdstrbuf); + } + return PS_OK; +} + int CEXEBuild::check_external_exitcode(int exitcode, int op, int val) { switch(op) Modified: NSIS/trunk/Source/build.h =================================================================== --- NSIS/trunk/Source/build.h 2018-10-21 12:28:10 UTC (rev 7024) +++ NSIS/trunk/Source/build.h 2018-10-24 19:01:00 UTC (rev 7025) @@ -583,7 +583,10 @@ struct postbuild_cmd*next; int cmpop, cmpval; TCHAR cmd[1]; + void delete_all(); + static postbuild_cmd* make(const TCHAR *cmdstr, int cmpop, int cmpval); } *postbuild_cmds; + int run_postbuild_cmds(const postbuild_cmd *cmds, const TCHAR *templatearg_pc1, const TCHAR* commandname); int check_external_exitcode(int exitcode, int op, int val); TCHAR build_packname[1024], build_packcmd[1024]; Modified: NSIS/trunk/Source/scriptpp.cpp =================================================================== --- NSIS/trunk/Source/scriptpp.cpp 2018-10-21 12:28:10 UTC (rev 7024) +++ NSIS/trunk/Source/scriptpp.cpp 2018-10-24 19:01:00 UTC (rev 7025) @@ -449,43 +449,19 @@ int CEXEBuild::pp_tempfile(LineParser&line) { TCHAR *symbol = line.gettoken_str(1); - const TCHAR *fpath; -#ifdef _WIN32 - TCHAR buf[MAX_PATH], buf2[MAX_PATH]; - GetTempPath(MAX_PATH, buf); - if (!GetTempFileName(buf, _T("nst"), 0, buf2)) + TCHAR *tfpath = create_tempfile_path(); + if (!tfpath) { - ERROR_MSG(_T("!tempfile: unable to create temporary file.\n")); + ERROR_MSG(_T("!tempfile: Unable to create temporary file!\n")); return PS_ERROR; } - fpath = buf2; -#else // !_WIN32 - char t[] = ("/tmp/makensisXXXXXX"); - const mode_t old_umask = umask(0077); - int fd = mkstemp(t); - umask(old_umask); - if (fd == -1) - { L_tok_p_tempfile_oom: - ERROR_MSG(_T("!tempfile: unable to create temporary file.\n")); - return PS_ERROR; - } - close(fd); -#ifdef _UNICODE - if (!(fpath = NSISRT_mbtowc(t))) goto L_tok_p_tempfile_oom; -#else - fpath = t; -#endif -#endif // ~_WIN32 - - if (definedlist.add(symbol, fpath)) + int symexisted = definedlist.add(symbol, tfpath); + free(tfpath); + if (symexisted) { ERROR_MSG(_T("!tempfile: \"%") NPRIs _T("\" already defined!\n"), symbol); return PS_ERROR; } - SCRIPT_MSG(_T("!tempfile: \"%") NPRIs _T("\"=\"%") NPRIs _T("\"\n"), symbol, fpath); -#if !defined(_WIN32) && defined(_UNICODE) - NSISRT_free(fpath); -#endif return PS_OK; } @@ -1054,21 +1030,24 @@ return bufOf ? PS_ERROR : PS_OK; } +template<class T> void slist_append(T&list, T&item) +{ + T prev; + for (prev = list; prev && prev->next;) + prev = prev->next; + (prev ? prev->next : list) = item; +} + int CEXEBuild::pp_finalize(LineParser&line) { TCHAR* cmdstr = line.gettoken_str(1); int validparams = false; - struct postbuild_cmd *newcmd, *prevcmd; - newcmd = (struct postbuild_cmd*) (new BYTE[FIELD_OFFSET(struct postbuild_cmd, cmd[_tcsclen(cmdstr)+1])]); - newcmd->next = NULL, _tcscpy(newcmd->cmd, cmdstr); - newcmd->cmpop = line.gettoken_enum(2, _T("<\0>\0<>\0=\0ignore\0")), newcmd->cmpval = line.gettoken_int(3, &validparams); + postbuild_cmd *newcmd = postbuild_cmd::make(cmdstr, line.gettoken_enum(2, _T("<\0>\0<>\0=\0ignore\0")), line.gettoken_int(3, &validparams)); if (line.getnumtokens() == 1+1) - newcmd->cmpop = 4, validparams = true; // just a command, ignore the exit code + newcmd->cmpop = 4, validparams = true; // Just a command, ignore the exit code if (newcmd->cmpop == -1 || !validparams) PRINTHELP(); - for (prevcmd = postbuild_cmds; prevcmd && prevcmd->next;) - prevcmd = prevcmd->next; - if (prevcmd) prevcmd->next = newcmd; else postbuild_cmds = newcmd; + slist_append(postbuild_cmds, newcmd); SCRIPT_MSG(_T("!finalize: \"%") NPRIs _T("\"\n"), cmdstr); return PS_OK; } Modified: NSIS/trunk/Source/tstring.cpp =================================================================== --- NSIS/trunk/Source/tstring.cpp 2018-10-21 12:28:10 UTC (rev 7024) +++ NSIS/trunk/Source/tstring.cpp 2018-10-24 19:01:00 UTC (rev 7025) @@ -24,6 +24,7 @@ #if defined(_UNICODE) && !defined(_WIN32) if (CP_ACP == cp) { + assert(NSISRT_free_is_STDC_free()); m_wStr = NSISRT_mbtowc(str); // Should be faster than iconv return ; } @@ -45,6 +46,7 @@ void TtoCString::Init(const wchar_t* str) { #if defined(_UNICODE) && !defined(_WIN32) + assert(NSISRT_free_is_STDC_free()); m_cStr = NSISRT_wctomb(str); // Should be faster than iconv return ; #endif Modified: NSIS/trunk/Source/util.cpp =================================================================== --- NSIS/trunk/Source/util.cpp 2018-10-21 12:28:10 UTC (rev 7024) +++ NSIS/trunk/Source/util.cpp 2018-10-24 19:01:00 UTC (rev 7025) @@ -740,6 +740,33 @@ #endif } +TCHAR* create_tempfile_path() +{ + TCHAR *tfpath = NULL; +#ifdef _WIN32 + TCHAR buftmpdir[MAX_PATH], buf[MAX_PATH]; + DWORD cch = GetTempPath(COUNTOF(buftmpdir), buftmpdir); + if (cch && cch < COUNTOF(buftmpdir) && GetTempFileName(buftmpdir, _T("nst"), 0, buf)) + tfpath = _tcsdup(buf); +#else //! _WIN32 + char narrowpath[] = ("/tmp/makensisXXXXXX"); + const mode_t org_umask = umask(0077); + int fd = mkstemp(narrowpath); + umask(org_umask); + if (fd != -1) + { +#ifdef _UNICODE + assert(NSISRT_free_is_STDC_free()); + tfpath = NSISRT_mbtowc(narrowpath); +#else + tfpath = _tcsdup(narrowpath); +#endif + close(fd); + } +#endif //~ _WIN32 + return tfpath; +} + tstring get_full_path(const tstring &path) { #ifdef _WIN32 TCHAR real_path[1024], *fnpart; @@ -1156,12 +1183,6 @@ uli.LowPart = GetFileSize(hFile, &uli.HighPart); return INVALID_FILE_SIZE != uli.LowPart || !GetLastError(); } -static HANDLE NSISRT_GetConsoleScreenHandle() -{ - DWORD cm; - HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE); - return GetConsoleMode(hCon, &cm) ? hCon : GetStdHandle(STD_ERROR_HANDLE); -} #endif //~ _WIN32 #if defined(_WIN32) && defined(_UNICODE) && defined(MAKENSIS) #include <io.h> // for _get_osfhandle @@ -1272,6 +1293,12 @@ #elif defined(_WIN32) #define NSISRT_FastGetConsoleScreenHandle NSISRT_GetConsoleScreenHandle bool NSISRT_Initialize() { return true; } // Init function for non-MakeNSIS Win32 (NSISRT_DEFINEGLOBALS sets g_output and g_errout) +static HANDLE NSISRT_GetConsoleScreenHandle() +{ + DWORD cm; + HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE); + return GetConsoleMode(hCon, &cm) ? hCon : GetStdHandle(STD_ERROR_HANDLE); +} #endif void PrintColorFmtErrMsg(const TCHAR *fmtstr, va_list args) Modified: NSIS/trunk/Source/util.h =================================================================== --- NSIS/trunk/Source/util.h 2018-10-21 12:28:10 UTC (rev 7024) +++ NSIS/trunk/Source/util.h 2018-10-24 19:01:00 UTC (rev 7025) @@ -41,6 +41,7 @@ // If width or height are specified it will also make sure the bitmap is in that size int update_bitmap(CResourceEditor* re, WORD id, const TCHAR* filename, int width=0, int height=0, int maxbpp=0); +TCHAR* create_tempfile_path(); tstring get_full_path(const tstring& path); tstring get_dir_name(const tstring& path); tstring get_file_name(const tstring& path); @@ -237,6 +238,7 @@ #else #define CharNext CharNextA #endif +#define NSISRT_free_is_STDC_free() 1 // NSISRT_free == free #define NSISRT_free(p) ( free((void*)(p)) ) wchar_t* NSISRT_mbtowc(const char *Str); char* NSISRT_wctomb(const wchar_t *Str); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <and...@us...> - 2018-11-01 23:09:10
|
Revision: 7036 http://sourceforge.net/p/nsis/code/7036 Author: anders_k Date: 2018-11-01 23:09:07 +0000 (Thu, 01 Nov 2018) Log Message: ----------- Moved POSIX dialog unit calcilation function stubs Modified Paths: -------------- NSIS/trunk/Source/DialogTemplate.cpp NSIS/trunk/Source/DialogTemplate.h Modified: NSIS/trunk/Source/DialogTemplate.cpp =================================================================== --- NSIS/trunk/Source/DialogTemplate.cpp 2018-11-01 22:47:52 UTC (rev 7035) +++ NSIS/trunk/Source/DialogTemplate.cpp 2018-11-01 23:09:07 UTC (rev 7036) @@ -430,7 +430,11 @@ item->sWidth = short(size.cx); item->sHeight = short(size.cy); } -#endif +#else //! WIN32 +void CDialogTemplate::PixelsToDlgUnits(short& x, short& y) { assert(0); } +void CDialogTemplate::PixelsToDlgUnits(SIZE& siz) { assert(0); } +void CDialogTemplate::DlgUnitsToPixels(short& x, short& y) { assert(0); } +#endif //~ WIN32 // Moves every item right and gives it the WS_EX_RIGHT extended style void CDialogTemplate::ConvertToRTL() { Modified: NSIS/trunk/Source/DialogTemplate.h =================================================================== --- NSIS/trunk/Source/DialogTemplate.h 2018-11-01 22:47:52 UTC (rev 7035) +++ NSIS/trunk/Source/DialogTemplate.h 2018-11-01 23:09:07 UTC (rev 7036) @@ -123,11 +123,11 @@ #endif void MoveAll(short x, short y); void Resize(short x, short y); -#ifdef _WIN32 - static inline bool SupportsDialogUnitComputation() { return true; } void PixelsToDlgUnits(short& x, short& y); void PixelsToDlgUnits(SIZE& siz); void DlgUnitsToPixels(short& x, short& y); +#ifdef _WIN32 + static inline bool SupportsDialogUnitComputation() { return true; } SIZE GetStringSize(WORD id, TCHAR *str); void RTrimToString(WORD id, TCHAR *str, int margins); void LTrimToString(WORD id, TCHAR *str, int margins); @@ -134,8 +134,6 @@ void CTrimToString(WORD id, TCHAR *str, int margins); #else static inline bool SupportsDialogUnitComputation() { return false; } - inline void PixelsToDlgUnits(short& x, short& y) { assert(0); } - inline void DlgUnitsToPixels(short& x, short& y) { assert(0); } #endif void ConvertToRTL(); BYTE* Save(DWORD& dwSize); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <and...@us...> - 2018-11-01 23:38:40
|
Revision: 7037 http://sourceforge.net/p/nsis/code/7037 Author: anders_k Date: 2018-11-01 23:38:37 +0000 (Thu, 01 Nov 2018) Log Message: ----------- POSIX does not have SIZE type but that is OK because we never call that overload Modified Paths: -------------- NSIS/trunk/Source/DialogTemplate.cpp NSIS/trunk/Source/DialogTemplate.h Modified: NSIS/trunk/Source/DialogTemplate.cpp =================================================================== --- NSIS/trunk/Source/DialogTemplate.cpp 2018-11-01 23:09:07 UTC (rev 7036) +++ NSIS/trunk/Source/DialogTemplate.cpp 2018-11-01 23:38:37 UTC (rev 7037) @@ -432,7 +432,6 @@ } #else //! WIN32 void CDialogTemplate::PixelsToDlgUnits(short& x, short& y) { assert(0); } -void CDialogTemplate::PixelsToDlgUnits(SIZE& siz) { assert(0); } void CDialogTemplate::DlgUnitsToPixels(short& x, short& y) { assert(0); } #endif //~ WIN32 Modified: NSIS/trunk/Source/DialogTemplate.h =================================================================== --- NSIS/trunk/Source/DialogTemplate.h 2018-11-01 23:09:07 UTC (rev 7036) +++ NSIS/trunk/Source/DialogTemplate.h 2018-11-01 23:38:37 UTC (rev 7037) @@ -124,10 +124,10 @@ void MoveAll(short x, short y); void Resize(short x, short y); void PixelsToDlgUnits(short& x, short& y); - void PixelsToDlgUnits(SIZE& siz); void DlgUnitsToPixels(short& x, short& y); #ifdef _WIN32 static inline bool SupportsDialogUnitComputation() { return true; } + void PixelsToDlgUnits(SIZE& siz); SIZE GetStringSize(WORD id, TCHAR *str); void RTrimToString(WORD id, TCHAR *str, int margins); void LTrimToString(WORD id, TCHAR *str, int margins); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <and...@us...> - 2019-02-02 20:25:11
|
Revision: 7077 http://sourceforge.net/p/nsis/code/7077 Author: anders_k Date: 2019-02-02 20:25:07 +0000 (Sat, 02 Feb 2019) Log Message: ----------- Print "ANSI targets are deprecated" warning if Unicode/Target attributes are never used. Modified Paths: -------------- NSIS/trunk/Source/build.cpp NSIS/trunk/Source/build.h Modified: NSIS/trunk/Source/build.cpp =================================================================== --- NSIS/trunk/Source/build.cpp 2019-01-29 23:15:37 UTC (rev 7076) +++ NSIS/trunk/Source/build.cpp 2019-02-02 20:25:07 UTC (rev 7077) @@ -416,6 +416,7 @@ tstring uninst = stubs_dir + PLATFORM_PATH_SEPARATOR_STR + _T("uninst"); uninstaller_icon = load_icon_file(uninst.c_str()); + changed_target = false; } @@ -2568,6 +2569,8 @@ RET_UNLESS_OK( check_write_output_errors() ); has_called_write_output=true; + if (!changed_target && !build_unicode) + warning(DW_GENERIC_DEPRECATED, _T("ANSI targets are deprecated")); #ifdef NSIS_CONFIG_PLUGIN_SUPPORT RET_UNLESS_OK( add_plugins_dir_initializer() ); @@ -3898,6 +3901,7 @@ #ifdef NSIS_CONFIG_PLUGIN_SUPPORT if (PS_OK == ec) ec = initialize_default_plugins(true); #endif + changed_target = true; return ec; } Modified: NSIS/trunk/Source/build.h =================================================================== --- NSIS/trunk/Source/build.h 2019-01-29 23:15:37 UTC (rev 7076) +++ NSIS/trunk/Source/build.h 2019-02-02 20:25:07 UTC (rev 7077) @@ -108,6 +108,7 @@ DW_ATTRIBUTE_OVERLONGSTRING = 7060, DW_PARSE_BADNUMBER = 7070, DW_PARSE_LNK_HK = 7075, + DW_GENERIC_DEPRECATED = 7998, DW_PARSE_REGPATHPREFIX = 7999, DW_INSTFILESPAGE_NOT_USED = 8000, // reserved ..8019 DW_COMP_FINAL = 8020, // reserved ..8059 @@ -441,6 +442,7 @@ void print_warnings(); void warninghelper(DIAGCODE dc, bool fl, const TCHAR *fmt, va_list args); DiagState diagstate; + bool changed_target; /** Are we defining an uninstall version of the code? * @param un Use like a boolean to define whether in uninstall mode. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <and...@us...> - 2019-02-11 20:32:45
|
Revision: 7082 http://sourceforge.net/p/nsis/code/7082 Author: anders_k Date: 2019-02-11 20:32:42 +0000 (Mon, 11 Feb 2019) Log Message: ----------- Cast away MAKEINTRESOURCE wchar_t* vs WORD* issue we don't care about Modified Paths: -------------- NSIS/trunk/Source/Platform.h NSIS/trunk/Source/ResourceEditor.cpp Modified: NSIS/trunk/Source/Platform.h =================================================================== --- NSIS/trunk/Source/Platform.h 2019-02-11 17:45:47 UTC (rev 7081) +++ NSIS/trunk/Source/Platform.h 2019-02-11 20:32:42 UTC (rev 7082) @@ -226,13 +226,13 @@ # define FIELD_OFFSET(t,f) ((UINT_PTR)&(((t*)0)->f)) # endif # ifndef MAKEINTRESOURCEA -# define MAKEINTRESOURCEA(i) ((LPSTR)((ULONG_PTR)((WORD)(i)))) +# define MAKEINTRESOURCEA(i) ((LPSTR)((ULONG_PTR)((WORD)(ULONG_PTR)(i)))) # endif # ifndef MAKEINTRESOURCEW -# define MAKEINTRESOURCEW(i) ((LPWSTR)((ULONG_PTR)((WORD)(i)))) +# define MAKEINTRESOURCEW(i) ((LPWSTR)((ULONG_PTR)((WORD)(ULONG_PTR)(i)))) # endif # ifndef MAKEINTRESOURCE -# ifdef UNICODE +# ifdef _UNICODE # define MAKEINTRESOURCE MAKEINTRESOURCEW # else # define MAKEINTRESOURCE MAKEINTRESOURCEA Modified: NSIS/trunk/Source/ResourceEditor.cpp =================================================================== --- NSIS/trunk/Source/ResourceEditor.cpp 2019-02-11 17:45:47 UTC (rev 7081) +++ NSIS/trunk/Source/ResourceEditor.cpp 2019-02-11 20:32:42 UTC (rev 7082) @@ -412,7 +412,7 @@ return UpdateResourceT(szType, szName, wLanguage, 0, 0, Manip); assert(!EditorSupportsStringNames() && sizeof(szName)); - const TCHAR*name = MAKEINTRESOURCE(szName); + const TCHAR *name = (const TCHAR*) MAKEINTRESOURCE(szName); unsigned int deleted = 0; for (;; ++deleted) { CResourceDirectoryEntry*pDir = FindResourceLanguageDirEntryT(szType, name, ANYLANGID); @@ -461,8 +461,9 @@ bool CResourceEditor::ResourceExistsT(const TCHAR* szType, WORD szName, LANGID wLanguage, LANGID*pFoundLanguage) { assert(!EditorSupportsStringNames() && sizeof(szName)); + const TCHAR *name = (const TCHAR*) MAKEINTRESOURCE(szName); if (wLanguage == ALLLANGID) wLanguage = ANYLANGID; - CResourceDirectoryEntry *pRDE = FindResourceLanguageDirEntryT(szType, MAKEINTRESOURCE(szName), wLanguage); + CResourceDirectoryEntry *pRDE = FindResourceLanguageDirEntryT(szType, name, wLanguage); if (pFoundLanguage) *pFoundLanguage = pRDE ? pRDE->GetId() : INVALIDLANGID; return pRDE != 0; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <and...@us...> - 2019-02-14 23:06:36
|
Revision: 7085 http://sourceforge.net/p/nsis/code/7085 Author: anders_k Date: 2019-02-14 23:06:33 +0000 (Thu, 14 Feb 2019) Log Message: ----------- LR_CREATEDIBSECTION breaks modern.bmp so we must disallow TopDown CheckBitmaps Modified Paths: -------------- NSIS/trunk/Source/exehead/Ui.c NSIS/trunk/Source/util.cpp Modified: NSIS/trunk/Source/exehead/Ui.c =================================================================== --- NSIS/trunk/Source/exehead/Ui.c 2019-02-14 22:59:08 UTC (rev 7084) +++ NSIS/trunk/Source/exehead/Ui.c 2019-02-14 23:06:33 UTC (rev 7085) @@ -1342,7 +1342,7 @@ hTreeItems=(HTREEITEM*)GlobalAlloc(GPTR,sizeof(HTREEITEM)*num_sections); - hBMcheck1=LoadImage(g_hInstance, MAKEINTRESOURCE(IDB_BITMAP1), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION); // LR_CREATEDIBSECTION required to load TopDown bitmaps + hBMcheck1=LoadImage(g_hInstance, MAKEINTRESOURCE(IDB_BITMAP1), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR); // LR_CREATEDIBSECTION required to load TopDown bitmaps but that breaks modern.bmp last_selected_tree_item=-1; oldTreeWndProc=(WNDPROC)SetWindowLongPtr(hwndTree1,GWLP_WNDPROC,(LONG_PTR)newTreeWndProc); Modified: NSIS/trunk/Source/util.cpp =================================================================== --- NSIS/trunk/Source/util.cpp 2019-02-14 22:59:08 UTC (rev 7084) +++ NSIS/trunk/Source/util.cpp 2019-02-14 23:06:33 UTC (rev 7085) @@ -146,7 +146,7 @@ signed char hdr[14+124], retval = -2; size_t size = fread(hdr, 1, sizeof(hdr), f); GENERICIMAGEINFO info; - if (IsBMPFile(hdr, size, &info) && 0 == fseek(f, 0, SEEK_SET)) + if (IsBMPFile(hdr, size, &info) && 0 == fseek(f, 0, SEEK_SET) && info.Height == info.RawHeight) { if ((width && width != (int) info.Width) || (height && height != (int) info.Height)) retval = -3; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <and...@us...> - 2019-08-18 22:54:29
|
Revision: 7116 http://sourceforge.net/p/nsis/code/7116 Author: anders_k Date: 2019-08-18 22:54:26 +0000 (Sun, 18 Aug 2019) Log Message: ----------- BITMAPCOREHEADER bitmaps cannot be top-down bitmaps Modified Paths: -------------- NSIS/trunk/Source/BinInterop.cpp NSIS/trunk/Source/BinInterop.h Modified: NSIS/trunk/Source/BinInterop.cpp =================================================================== --- NSIS/trunk/Source/BinInterop.cpp 2019-08-18 22:15:53 UTC (rev 7115) +++ NSIS/trunk/Source/BinInterop.cpp 2019-08-18 22:54:26 UTC (rev 7116) @@ -455,7 +455,8 @@ DWORD size = LE2HE32(p32[0]); if (size == 12) // BITMAPCOREHEADER { - Info.Width = LE2HE16(p16[2]), Info.Height = (INT32) (SHORT) LE2HE16(p16[3]); + Info.Width = LE2HE16(p16[2]), Info.RawHeight = (INT32) (SHORT) LE2HE16(p16[3]); + Info.Height = Info.RawHeight; // BITMAPCOREHEADER bitmaps cannot be top-down bitmaps (docs.microsoft.com/en-us/windows/win32/gdi/bitmap-header-types) Info.Planes = LE2HE16(p16[4]), Info.BPP = LE2HE16(p16[5]); return size; } Modified: NSIS/trunk/Source/BinInterop.h =================================================================== --- NSIS/trunk/Source/BinInterop.h 2019-08-18 22:15:53 UTC (rev 7115) +++ NSIS/trunk/Source/BinInterop.h 2019-08-18 22:54:26 UTC (rev 7116) @@ -27,11 +27,12 @@ bool GetDLLVersion(const TCHAR *filepath, DWORD &high, DWORD &low); -typedef struct { +typedef struct GENERICIMAGEINFO { UINT32 Width, Height; INT32 RawHeight; WORD BPP, Planes; - bool IsTopDownBitmap() const { return Height != (UINT32) RawHeight; } + GENERICIMAGEINFO() : RawHeight(0) {} + bool IsTopDownBitmap() const { return Height != (UINT32) RawHeight && RawHeight; } } GENERICIMAGEINFO; DWORD GetDIBHeaderInfo(const void*pData, size_t DataSize, GENERICIMAGEINFO&Info); @@ -47,7 +48,7 @@ } inline WORD IsICOCURFile(const void*pData, size_t DataSize) { - return DataSize >= 6 ? IsICOCURFile(pData) : 0; + return DataSize > 6 ? IsICOCURFile(pData) : 0; } #endif //~ NSIS_BININTEROP_H This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ki...@us...> - 2020-07-31 21:38:44
|
Revision: 7198 http://sourceforge.net/p/nsis/code/7198 Author: kichik Date: 2020-07-31 21:38:42 +0000 (Fri, 31 Jul 2020) Log Message: ----------- vc6 build fixes Modified Paths: -------------- NSIS/trunk/Source/build.cpp NSIS/trunk/Source/manifest.cpp Modified: NSIS/trunk/Source/build.cpp =================================================================== --- NSIS/trunk/Source/build.cpp 2020-07-31 21:06:25 UTC (rev 7197) +++ NSIS/trunk/Source/build.cpp 2020-07-31 21:38:42 UTC (rev 7198) @@ -3650,7 +3650,7 @@ if (Msg == WM_COPYDATA && pCDS->cbData > sizeof(TCHAR) && pCDS->cbData <= io[2] * sizeof(TCHAR)) { _tcscpy((TCHAR*) io[1], (TCHAR*) ((COPYDATASTRUCT*)lParam)->lpData); - return (io[0] = (pCDS->dwData == PROMPT_FILEPATH)); + return (io[0] = (pCDS->dwData == MakensisAPI::PROMPT_FILEPATH)); } return false; } Modified: NSIS/trunk/Source/manifest.cpp =================================================================== --- NSIS/trunk/Source/manifest.cpp 2020-07-31 21:06:25 UTC (rev 7197) +++ NSIS/trunk/Source/manifest.cpp 2020-07-31 21:38:42 UTC (rev 7198) @@ -127,7 +127,7 @@ bool any = false; int i = isvalidappendpath(path); if (i >= 0) - for (std::size_t j = 0; j < g_appendstrings[i].size(); ++j) + for (size_t j = 0; j < g_appendstrings[i].size(); ++j) { if (!any && prefix) xml += prefix, any = true; xml += g_appendstrings[i][j]; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <and...@us...> - 2021-09-18 20:24:43
|
Revision: 7328 http://sourceforge.net/p/nsis/code/7328 Author: anders_k Date: 2021-09-18 20:24:41 +0000 (Sat, 18 Sep 2021) Log Message: ----------- Icon now supports the res:// protocol Modified Paths: -------------- NSIS/trunk/Source/ResourceEditor.cpp NSIS/trunk/Source/ResourceEditor.h NSIS/trunk/Source/icon.cpp NSIS/trunk/Source/icon.h NSIS/trunk/Source/script.cpp NSIS/trunk/Source/util.h Modified: NSIS/trunk/Source/ResourceEditor.cpp =================================================================== --- NSIS/trunk/Source/ResourceEditor.cpp 2021-09-17 18:13:17 UTC (rev 7327) +++ NSIS/trunk/Source/ResourceEditor.cpp 2021-09-18 20:24:41 UTC (rev 7328) @@ -30,6 +30,7 @@ // Utilities ////////////////////////////////////////////////////////////////////// +#define FIRSTRESDIRSTRADDRESS ( (WINWCHAR*)(~(size_t)0) ) #define WCHARPTR2WINWCHARPTR(s) ( (WINWCHAR*) (s) ) // Only for WinSDK structs like IMAGE_RESOURCE_DIR_STRING_U where we cannot change the WCHAR type! #define RALIGN(dwToAlign, dwAlignOn) ((dwToAlign%dwAlignOn == 0) ? dwToAlign : dwToAlign - (dwToAlign%dwAlignOn) + dwAlignOn) #define ALIGN(dwToAlign, dwAlignOn) dwToAlign = RALIGN((dwToAlign), (dwAlignOn)) @@ -37,6 +38,31 @@ static inline DWORD ConvertEndianness(DWORD d) { return FIX_ENDIAN_INT32(d); } static inline WORD ConvertEndianness(WORD w) { return FIX_ENDIAN_INT16(w); } +#if !(defined(_WIN32) && defined(_UNICODE)) +static void FreeUnicodeResString(WINWCHAR* s) { + if (!IS_INTRESOURCE(s) && FIRSTRESDIRSTRADDRESS != (WINWCHAR*) s) + free(s); +} +static WINWCHAR* ResStringToUnicode(const char *s) { + if (IS_INTRESOURCE(s)) return MAKEINTRESOURCEWINW((ULONG_PTR)s); + if (FIRSTRESDIRSTRADDRESS == (WINWCHAR*) s) return (WINWCHAR*) s; + WINWCHAR *ws = WinWStrDupFromTChar(s); + if (!ws) throw std::runtime_error("Unicode conversion failed"); + return ws; +} +#endif //~ !(_WIN32 && _UNICODE) + +struct UTF16LEResString { + WINWCHAR *m_s; + operator WINWCHAR*() const { return m_s; } +#if defined(_WIN32) && defined(_UNICODE) + UTF16LEResString(const TCHAR*tstr) : m_s((WINWCHAR*) tstr) {} +#else + UTF16LEResString(const TCHAR*tstr) : m_s(ResStringToUnicode(tstr)) { } + ~UTF16LEResString() { FreeUnicodeResString(m_s); } +#endif +}; + PIMAGE_NT_HEADERS CResourceEditor::GetNTHeaders(BYTE* pbPE) { // Get dos header PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER) pbPE; @@ -140,12 +166,13 @@ #include "exehead/resource.h" // IDI_ICON2 #include "exehead/config.h" // NSIS_DEFAULT_LANG -const TCHAR* CResourceEditor::ParseResourceNameString(const TCHAR*Str) { +const TCHAR* CResourceEditor::ParseResourceNameString(const TCHAR*Str, bool AllowFirst) { if (Str[0] == _T('#')) { ++Str; if (!_tcsicmp(Str, _T("Version"))) return (TCHAR*) MAKEINTRESOURCE(1); if (!_tcsicmp(Str, _T("Icon"))) return (TCHAR*) MAKEINTRESOURCE(IDI_ICON2); + if (AllowFirst && Str[0] == '?' && !Str[1]) return (TCHAR*) FIRSTRESDIRSTRADDRESS; int succ, num = ParseSimpleInt(Str, &succ); return succ && IS_INTRESOURCE(num) ? (TCHAR*) MAKEINTRESOURCE(num) : NULL; } @@ -161,19 +188,26 @@ return succ ? num : INVALIDLANGID; } -LANGID CResourceEditor::ParseResourceTypeNameLangString(const TCHAR**Type, const TCHAR**Name, const TCHAR*Lang) { +LANGID CResourceEditor::ParseResourceTypeNameLangString(const TCHAR**Type, const TCHAR**Name, const TCHAR*Lang, bool AllowFirst) { if (!(*Type = ParseResourceTypeString(*Type))) return INVALIDLANGID; - if (!(*Name = ParseResourceNameString(*Name))) return INVALIDLANGID; + if (!(*Name = ParseResourceNameString(*Name, AllowFirst))) return INVALIDLANGID; return ParseResourceLangString(Lang); } +UINT CResourceEditor::IsResProtocol(const TCHAR*Url) +{ + if ('r' == S7ChLwr(Url[0]) && 'e' == S7ChLwr(Url[1]) && 's' == S7ChLwr(Url[2])) + if (':' == Url[3] && '/' == Url[4] && '/' == Url[5]) + return 6; + return 0; +} + static TCHAR* ParseResProtocolAlloc(const TCHAR*Url, const TCHAR*&Type, const TCHAR*&Name, LANGID&Lang) { //msdn.microsoft.com/library/aa767740#res Protocol - TCHAR proto[42], *path = 0, *buf = 0, *pD, ch; - UINT prefix = 6, mswin = Platform_IsWindows(), bad = false, pipe = 0, skip = 0; - my_strncpy(proto, Url, prefix+!0); + TCHAR *path = 0, *buf = 0, *pD, ch; + UINT prefix, mswin = Platform_IsWindows(), bad = false, pipe = 0, skip = 0; size_t typestart = 0, namestart = 0, i, cch; - if (lowercase(tstring(proto)).compare(_T("res://")) != 0) + if (!(prefix = CResourceEditor::IsResProtocol(Url))) return path; for (Url += prefix, i = 0; Url[i]; ++i) if (Url[i] == '/') @@ -201,7 +235,7 @@ } if (!(*pD = (mswin && ch == '/') ? '\\' : ch)) break; // Convert path if needed and stop at the end. } - Lang = CResourceEditor::ParseResourceTypeNameLangString(&rt, &rn, rl); + Lang = CResourceEditor::ParseResourceTypeNameLangString(&rt, &rn, rl, true); if (!bad && Lang != CResourceEditor::INVALIDLANGID) path = buf, Type = rt, Name = rn; } @@ -275,28 +309,46 @@ // Methods ////////////////////////////////////////////////////////////////////// -#define FINDRESOURCE_NAME_FIRSTITEM ( (WINWCHAR*)(~(size_t)0) ) +bool CResourceEditor::CanOpen(const void*Data, size_t Size) +{ + return 'P' == GetExeType(Data, Size); // We only understand PE, not NE/LE +} -CResourceDirectoryEntry* CResourceEditor::FindResourceLanguageDirEntryW(const WINWCHAR* Type, const WINWCHAR* Name, LANGID Language) { - int i = m_cResDir->Find(Type); - if (-1 != i) { - CResourceDirectory* pND = m_cResDir->GetEntry(i)->GetSubDirectory(); - i = FINDRESOURCE_NAME_FIRSTITEM == Name ? 0 : pND->Find(Name); - if (-1 != i) { - CResourceDirectory* pLD = pND->GetEntry(i)->GetSubDirectory(); - i = ANYLANGID == Language ? 0 : pLD->Find(Language); - if (-1 != i) - return pLD->GetEntry(i); +CResourceDataEntry* CResourceEditor::FindResourceW(const WINWCHAR*RT, const WINWCHAR*RN, LANGID RL, CResourceDirectoryEntry**ppTE, CResourceDirectoryEntry**ppNE, CResourceDirectoryEntry**ppLE) const { + int i = m_cResDir->Find(RT); + CResourceDirectoryEntry*pTDE = -1 != i ? m_cResDir->GetEntry(i) : 0, *pNDE, *pLDE; + if (pTDE) { + CResourceDirectory *pND = pTDE->GetSubDirectory(); + i = FIRSTRESDIRSTRADDRESS == RN ? 0 : pND->Find(RN); + if ((pNDE = (-1 != i) ? pND->GetEntry(i) : 0)) { + CResourceDirectory *pLD = pNDE->GetSubDirectory(); + i = ANYLANGID == RL ? 0 : pLD->Find(RL); + if ((pLDE = (-1 != i) ? pLD->GetEntry(i) : 0)) { + if (ppTE) *ppTE = pTDE; + if (ppNE) *ppNE = pNDE; + if (ppLE) *ppLE = pLDE; + return pLDE->GetDataEntry(); + } } } return 0; } -CResourceDataEntry* CResourceEditor::FindResource(const WINWCHAR* Type, const WINWCHAR* Name, LANGID Language) { - CResourceDirectoryEntry*pRDE = FindResourceLanguageDirEntryW(Type, Name, Language); - return pRDE ? pRDE->GetDataEntry() : 0; +CResourceDataEntry* CResourceEditor::FindResourceT(const TCHAR*RT, const TCHAR*RN, LANGID RL, CResourceDirectoryEntry**ppTE, CResourceDirectoryEntry**ppNE, CResourceDirectoryEntry**ppLE) const { + return FindResourceW(UTF16LEResString(RT), UTF16LEResString(RN), RL, ppTE, ppNE, ppLE); } +CResourceDirectoryEntry* CResourceEditor::FindResourceLanguageDirEntryW(const WINWCHAR* RT, const WINWCHAR* RN, LANGID RL) const { + CResourceDirectoryEntry*pLDE = 0; + FindResourceW(RT, RN, RL, 0, 0, &pLDE); + return pLDE; +} + +CResourceDataEntry* CResourceEditor::FindResource(const WINWCHAR* RT, const WINWCHAR* RN, LANGID RL) const { + CResourceDirectoryEntry*pDE = FindResourceLanguageDirEntryW(RT, RN, RL); + return pDE ? pDE->GetDataEntry() : 0; +} + template<class T> static void UpdateManipulationType(CResourceEditor::TYPEMANIPULATION &Manip, const T* szType, const void*Data, size_t Size) { WORD dependenttype = GetDependentType(szType); if (Manip == CResourceEditor::TM_AUTO) @@ -408,37 +460,13 @@ return success; } -#ifndef _UNICODE -static WINWCHAR* ResStringToUnicode(const char *szString) { - if (IS_INTRESOURCE(szString)) return MAKEINTRESOURCEWINW((ULONG_PTR)szString); - WINWCHAR *s = WinWStrDupFromTChar(szString); - if (!s) throw std::bad_alloc(); - return s; -} -static void FreeUnicodeResString(WINWCHAR* szwString) { - if (!IS_INTRESOURCE(szwString)) free(szwString); -} -#else -#ifndef _WIN32 -static WINWCHAR* ResStringToUnicode(const TCHAR *s) { - if (IS_INTRESOURCE(s)) return MAKEINTRESOURCEWINW((ULONG_PTR)s); - WCToUTF16LEHlpr cnv; - if (!cnv.Create(s)) throw std::runtime_error("Unicode conversion failed"); - return (WINWCHAR*) cnv.Detach(); -} -static void FreeUnicodeResString(WINWCHAR* s) { - if (!IS_INTRESOURCE(s)) free(s); -} -#endif // ~_WIN32 -#endif // ~_UNICODE - -CResourceDirectoryEntry* CResourceEditor::FindResourceLanguageDirEntryT(const TCHAR* Type, const TCHAR* Name, LANGID Language) { - assert(!EditorSupportsStringNames() && sizeof(Name)); +CResourceDirectoryEntry* CResourceEditor::FindResourceLanguageDirEntryT(const TCHAR* RT, const TCHAR* RN, LANGID RL) const { + assert(!EditorSupportsStringNames() && sizeof(RN)); #if defined(_WIN32) && defined(_UNICODE) - return FindResourceLanguageDirEntryW((WINWCHAR*)Type, (WINWCHAR*)Name, Language); + return FindResourceLanguageDirEntryW((WINWCHAR*)RT, (WINWCHAR*)RN, RL); #else - WINWCHAR* szwType = ResStringToUnicode(Type); - CResourceDirectoryEntry* result = FindResourceLanguageDirEntryW(szwType, (WINWCHAR*)Name, Language); + WINWCHAR* szwType = ResStringToUnicode(RT); + CResourceDirectoryEntry* result = FindResourceLanguageDirEntryW(szwType, (WINWCHAR*)RN, RL); FreeUnicodeResString(szwType); return result; #endif @@ -550,7 +578,7 @@ // Returns a copy of the resource data from the first resource of a specific type BYTE* CResourceEditor::GetFirstResourceW(const WINWCHAR* szType, size_t&cbData) { - CResourceDataEntry *pDE = FindResource(szType, FINDRESOURCE_NAME_FIRSTITEM, ANYLANGID); + CResourceDataEntry *pDE = FindResource(szType, FIRSTRESDIRSTRADDRESS, ANYLANGID); if (pDE) { cbData = pDE->GetSize(); @@ -863,17 +891,28 @@ return !failed; } -bool CResourceEditor::UpdateResourceFromExternalT(const TCHAR* Type, WORD Name, LANGID Lang, const TCHAR*File, TYPEMANIPULATION Manip) -{ - bool success = false; - const TCHAR *srctype, *srcname; - LANGID srclang = 0; - TCHAR *resproto = ParseResProtocolAlloc(File, srctype, srcname, srclang); +template<class C, class P> static bool Contains(C&Map, P*p) { + return p && (SIZE_T) Map.base <= (SIZE_T) p && (SIZE_T) Map.base + Map.size > (SIZE_T) p; +} + +void CResourceEditor::FreeExternal(EXTERNAL&X) { + assert(sizeof(FILEVIEW) <= sizeof(X.Map)); + if (X.Data) { + FILEVIEW &map = *(FILEVIEW*) &X.Map; + if (!Contains(map, X.Data)) free(X.Data); + close_file_view(map); + free(X.FreeThis); // ParseResProtocolAlloc + } +} + +// Maps a file into memory and locates a resource inside it, a manipulated from a resource inside it or the file itself. Free with FreeExternal. +const TCHAR* CResourceEditor::MapExternal(const TCHAR*File, TYPEMANIPULATION Manip, EXTERNAL&X) { + TCHAR *resproto = ParseResProtocolAlloc(File, X.RT, X.RN, X.RL); if (resproto) { File = resproto; } - FILEVIEW map; + FILEVIEW &map = *(FILEVIEW*) &X.Map; size_t datasize; char *filedata = create_file_view_readonly(File, map), *data = 0, *dataalloc = 0; if (filedata) { @@ -881,15 +920,17 @@ signed char exetype = GetExeType(filedata, map.size); if (exetype == 'P') { CResourceEditor re(filedata, (int) map.size); - WORD ordsrcname = (WORD)(size_t) srcname; - if (!re.EditorSupportsStringNames() && !IS_INTRESOURCE(srcname)) { - assert(!"Unsupported name"); - srclang = INVALIDLANGID; + DWORD ofs, siz = 0, firstname = X.RN == (TCHAR*) FIRSTRESDIRSTRADDRESS; + CResourceDirectoryEntry*pNRDE, *pLRDE; + CResourceDataEntry*pRE = re.FindResourceT(X.RT, X.RN, X.RL, 0, &pNRDE, &pLRDE); + if (pRE) { + const WINWCHAR *wrn = pNRDE->GetNameOrId(); + if (firstname) X.RN = IS_INTRESOURCE(wrn) ? MAKEINTRESOURCE((size_t) wrn) : _T(""); + X.RL = pLRDE->GetId(); + ofs = pRE->GetOffset(), siz = pRE->GetSize(); } - DWORD ofs = re.GetResourceOffset(srctype, ordsrcname, srclang); - DWORD siz = re.GetResourceSize(srctype, ordsrcname, srclang); - if (IsIcoCurGroupType(srctype) && (Manip == TM_AUTO || (Manip & TM_ICON))) { // Must create a fake .ico file - data = dataalloc = (char*) re.ExtractIcoCur(srctype, ordsrcname, srclang, datasize), siz = 0; + if (siz && IsIcoCurGroupType(X.RT) && (Manip == TM_AUTO || (Manip & TM_ICON))) { // Must create a fake .ico file + data = dataalloc = (char*) re.ExtractIcoCur(*pRE, X.RL, datasize), siz = 0; } if (siz && siz != DWORD(-1)) { data = filedata + ofs, datasize = siz; // Raw resource data @@ -899,26 +940,43 @@ else { data = filedata, datasize = map.size; // Just a normal file } - if (data && (DWORD) datasize == datasize) { - success = this->UpdateResource(Type, Name, Lang, (BYTE*) data, (DWORD) datasize, Manip); + } + X.Data = (BYTE*) data, X.cbData = datasize; + X.FreeThis = resproto; + if (data) return File; + FreeExternal(X); + return 0; +} + +bool CResourceEditor::UpdateResourceFromExternalT(const TCHAR* Type, WORD Name, LANGID Lang, const TCHAR*File, TYPEMANIPULATION Manip) { + EXTERNAL x; + size_t &datasize = x.cbData; + bool success = false; + const TCHAR *parsedpath = MapExternal(File, Manip, x); + if (parsedpath) { + if ((DWORD) datasize == datasize) { + success = this->UpdateResource(Type, Name, Lang, (BYTE*) x.Data, (DWORD) datasize, Manip); } - close_file_view(map); + FreeExternal(x); } - free(dataalloc); - free(resproto); return success; } -CResourceDataEntry* CResourceEditor::FindIcoCurDataEntry(WORD Type, WORD Id, LANGID PrefLang) { +CResourceDataEntry* CResourceEditor::FindIcoCurDataEntry(WORD Type, WORD Id, LANGID PrefLang) const { CResourceDataEntry*pRDE = FindResource(MAKEINTRESOURCEWINW(Type), MAKEINTRESOURCEWINW(Id), PrefLang); return pRDE ? pRDE : FindResource(MAKEINTRESOURCEWINW(Type), MAKEINTRESOURCEWINW(Id), ANYLANGID); } -BYTE* CResourceEditor::ExtractIcoCurW(const WINWCHAR* szType, WINWCHAR* szName, LANGID wLanguage, size_t&cbData) { +BYTE* CResourceEditor::ExtractIcoCurW(const WINWCHAR* szType, const WINWCHAR* szName, LANGID wLanguage, size_t&cbData) const { CResourceDirectoryEntry*pLangDir = FindResourceLanguageDirEntryW(szType, szName, wLanguage); if (!pLangDir) return 0; CResourceDataEntry*pRDE = pLangDir->GetDataEntry(); + return ExtractIcoCur(*pRDE, pLangDir->GetId(), cbData); // Uses the "real" LANGID +} + +BYTE* CResourceEditor::ExtractIcoCur(const CResourceDataEntry&rde, LANGID ChildLang, size_t&cbData) const { + const CResourceDataEntry*pRDE = &rde; BYTE*pSH = pRDE->GetData(), cbRGE = 14, cbFGE = 16, *pResData; DWORD i, cbRes, failed = false; if (pRDE->GetSize() < 6) // Must at least have a ICO file header @@ -932,7 +990,7 @@ // Get the size of all images for (i = 0, pRGE = pFirstRGE; i < count; ++i, pRGE += cbRGE / sizeof(*pRGE)) { - pRDE = FindIcoCurDataEntry(imgResType, ((RSRCICOGROUPENTRY*)pRGE)->Id, wLanguage); + pRDE = FindIcoCurDataEntry(imgResType, ((RSRCICOGROUPENTRY*)pRGE)->Id, ChildLang); if (pRDE && pRDE->GetData()) cbImages += FIX_ENDIAN_INT32(((FILEICOGROUPENTRY*)pRGE)->Size); else count = 0; } // Build the .ICO file @@ -940,7 +998,7 @@ if (count && (pDH = (WORD*) malloc(cbTot += cbImages))) { pDH[0] = 0x0000, pDH[1] = FIX_ENDIAN_INT16(isCursor ? 2 : 1), pDH[2] = FIX_ENDIAN_INT16(count); for (i = 0, pRGE = pFirstRGE; i < count; ++i, pRGE += cbRGE / sizeof(*pRGE)) { - pRDE = FindIcoCurDataEntry(imgResType, ((RSRCICOGROUPENTRY*)pRGE)->Id, wLanguage); + pRDE = FindIcoCurDataEntry(imgResType, ((RSRCICOGROUPENTRY*)pRGE)->Id, ChildLang); pResData = pRDE->GetData(), cbRes = pRDE->GetSize(); FILEICOGROUPENTRY*pFGE = (FILEICOGROUPENTRY*) ((char*)pDH + grpsOfs); memcpy(pFGE, pRGE, cbRGE), pFGE->Offset = FIX_ENDIAN_INT32(imgsOfs); // Initialize ICO group entry @@ -972,7 +1030,7 @@ return (BYTE*) pDH; } -BYTE* CResourceEditor::ExtractIcoCurT(const TCHAR* szType, WORD szName, LANGID wLanguage, size_t&cbData) { +BYTE* CResourceEditor::ExtractIcoCurT(const TCHAR* szType, WORD szName, LANGID wLanguage, size_t&cbData) const { assert(!EditorSupportsStringNames() && sizeof(szName)); #if defined(_WIN32) && defined(_UNICODE) return ExtractIcoCurW((WINWCHAR*)szType, MAKEINTRESOURCEWINW(szName), wLanguage, cbData); @@ -1454,7 +1512,7 @@ // To save memory this function doesn't give you a copy of the data // Don't mess with the data returned from this function! -BYTE* CResourceDataEntry::GetData() { +BYTE* CResourceDataEntry::GetData() const { return m_pbData; } @@ -1471,14 +1529,14 @@ m_dwOffset = DWORD(-1); // unset } -DWORD CResourceDataEntry::GetSize() { +DWORD CResourceDataEntry::GetSize() const { return m_dwSize; } -DWORD CResourceDataEntry::GetCodePage() { +DWORD CResourceDataEntry::GetCodePage() const { return m_dwCodePage; } -DWORD CResourceDataEntry::GetOffset() { +DWORD CResourceDataEntry::GetOffset() const { return m_dwOffset; } Modified: NSIS/trunk/Source/ResourceEditor.h =================================================================== --- NSIS/trunk/Source/ResourceEditor.h 2021-09-17 18:13:17 UTC (rev 7327) +++ NSIS/trunk/Source/ResourceEditor.h 2021-09-18 20:24:41 UTC (rev 7328) @@ -180,6 +180,7 @@ return ExtractIcoCurT((const TCHAR*) Type, Name, Lang, cbData); } + CResourceDataEntry* FindResourceT(const TCHAR*RT, const TCHAR*RN, LANGID RL, CResourceDirectoryEntry**pTE, CResourceDirectoryEntry**pNE, CResourceDirectoryEntry**pLE) const; bool UpdateResourceFromExternalT(const TCHAR* Type, WORD Name, LANGID Lang, const TCHAR*File, TYPEMANIPULATION Manip = TM_AUTO); bool UpdateResourceT (const TCHAR* szType, WORD szName, LANGID wLanguage, BYTE* lpData, DWORD dwSize, TYPEMANIPULATION Manip = TM_RAW); bool UpdateResourceT (const TCHAR* szType, WORD szName, LANGID wLanguage, FILE*Data, TYPEMANIPULATION Manip = TM_AUTO); @@ -189,7 +190,8 @@ DWORD GetResourceOffsetT(const TCHAR* szType, WORD szName, LANGID wLanguage); bool ResourceExistsT (const TCHAR* szType, WORD szName, LANGID wLanguage, LANGID*pFoundLanguage = 0); BYTE* GetFirstResourceT (const TCHAR* szType, size_t&cbData); - BYTE* ExtractIcoCurT (const TCHAR* szType, WORD szName, LANGID wLanguage, size_t&cbData); + BYTE* ExtractIcoCurT (const TCHAR* szType, WORD szName, LANGID wLanguage, size_t&cbData) const; + BYTE* ExtractIcoCur(const CResourceDataEntry&rde, LANGID ChildLang, size_t&cbData) const; void FreeResource(BYTE* pbResource); // The section name must be in ASCII. @@ -208,9 +210,14 @@ ); static const TCHAR* ParseResourceTypeString(const TCHAR*String); - static const TCHAR* ParseResourceNameString(const TCHAR*String); + static const TCHAR* ParseResourceNameString(const TCHAR*String, bool AllowFirst = false); static LANGID ParseResourceLangString(const TCHAR*String); - static LANGID ParseResourceTypeNameLangString(const TCHAR**Type, const TCHAR**Name, const TCHAR*Lang); + static LANGID ParseResourceTypeNameLangString(const TCHAR**Type, const TCHAR**Name, const TCHAR*Lang, bool AllowFirst = false); + static bool CanOpen(const void*Data, size_t Size); + static UINT IsResProtocol(const TCHAR*Url); + typedef struct { BYTE*Data; size_t cbData, Map[2]; void*FreeThis; const TCHAR*RT, *RN; LANGID RL; } EXTERNAL; + static void FreeExternal(EXTERNAL&External); + static const TCHAR* MapExternal(const TCHAR*File, TYPEMANIPULATION Manip, EXTERNAL&External); static bool EditorSupportsStringNames() { return false; } // UpdateResource/GetResource do not support string names (yet) static bool EditorSupportsCursorPng() { return false; } @@ -220,14 +227,15 @@ int GetResourceSizeW (const WINWCHAR* szType, WINWCHAR* szName, LANGID wLanguage); DWORD GetResourceOffsetW(const WINWCHAR* szType, WINWCHAR* szName, LANGID wLanguage); BYTE* GetFirstResourceW (const WINWCHAR* szType, size_t&cbData); - BYTE* ExtractIcoCurW (const WINWCHAR* szType, WINWCHAR* szName, LANGID wLanguage, size_t&cbData); - CResourceDataEntry* FindResource(const WINWCHAR* Type, const WINWCHAR* Name, LANGID Language); - CResourceDirectoryEntry* FindResourceLanguageDirEntryW(const WINWCHAR* Type, const WINWCHAR* Name, LANGID Language); - CResourceDirectoryEntry* FindResourceLanguageDirEntryT(const TCHAR* Type, const TCHAR* Name, LANGID Language); + BYTE* ExtractIcoCurW (const WINWCHAR* szType, const WINWCHAR* szName, LANGID wLanguage, size_t&cbData) const; + CResourceDataEntry* FindResource(const WINWCHAR*RT, const WINWCHAR*RN, LANGID RL) const; + CResourceDataEntry* FindResourceW(const WINWCHAR*RT, const WINWCHAR*RN, LANGID RL, CResourceDirectoryEntry**ppTE, CResourceDirectoryEntry**ppNE, CResourceDirectoryEntry**ppLE) const; + CResourceDirectoryEntry* FindResourceLanguageDirEntryW(const WINWCHAR* RT, const WINWCHAR* RN, LANGID RL) const; + CResourceDirectoryEntry* FindResourceLanguageDirEntryT(const TCHAR* RT, const TCHAR* RN, LANGID RL) const; bool DeleteIconImages(const CResourceDirectoryEntry& LangDir); bool DeleteIconImagesW(const WINWCHAR* OwnerType, WINWCHAR* Name, LANGID LangId); bool AddExtraIconFromFile(const WINWCHAR* Type, WINWCHAR* Name, LANGID LangId, BYTE* Data, DWORD Size); - CResourceDataEntry* FindIcoCurDataEntry(WORD Type, WORD Id, LANGID PrefLang); + CResourceDataEntry* FindIcoCurDataEntry(WORD Type, WORD Id, LANGID PrefLang) const; BYTE* DupData(CResourceDataEntry*pDE); // Free with FreeResource CResourceDirectory* ScanDirectory(PRESOURCE_DIRECTORY rdRoot, PRESOURCE_DIRECTORY rdToScan); @@ -279,6 +287,7 @@ CResourceDirectoryEntry(const WINWCHAR* szName, CResourceDataEntry* rdeData); virtual ~CResourceDirectoryEntry(); + const WINWCHAR* GetNameOrId() const { return HasName() ? GetName() : (WINWCHAR*)(size_t) GetId(); } bool HasName() const; const WINWCHAR* GetName() const; int GetNameLength() const; @@ -306,13 +315,13 @@ CResourceDataEntry(BYTE* pbData, DWORD dwSize, DWORD dwCodePage = 0, DWORD dwOffset = DWORD(-1)); ~CResourceDataEntry(); - BYTE* GetData(); + BYTE* GetData() const; void SetData(BYTE* pbData, DWORD dwSize); void SetData(BYTE* pbData, DWORD dwSize, DWORD dwCodePage); - DWORD GetSize(); - DWORD GetCodePage(); - DWORD GetOffset(); + DWORD GetSize() const; + DWORD GetCodePage() const; + DWORD GetOffset() const; ULONG_PTR m_ulWrittenAt; Modified: NSIS/trunk/Source/icon.cpp =================================================================== --- NSIS/trunk/Source/icon.cpp 2021-09-17 18:13:17 UTC (rev 7327) +++ NSIS/trunk/Source/icon.cpp 2021-09-18 20:24:41 UTC (rev 7328) @@ -43,13 +43,9 @@ return FIX_ENDIAN_INT16(pGH->wCount) != 0; } -static FILE * open_icon(const TCHAR* filename, IconGroupHeader& igh) +template<class S> static WORD read_icon_header(S*f, IconGroupHeader& igh) { - FILE* f = FOPEN(filename, ("rb")); - if (!f) - throw runtime_error("can't open file"); - - if (!fread(&igh, sizeof(IconGroupHeader), 1, f)) + if (!freadall(&igh, sizeof(IconGroupHeader), f)) { fclose(f); throw runtime_error("unable to read header from file"); @@ -57,6 +53,7 @@ if (!is_valid_header(&igh)) { + igh.wType = igh.wCount = 0; fclose(f); throw runtime_error("invalid icon file"); } @@ -64,30 +61,31 @@ FIX_ENDIAN_INT16_INPLACE(igh.wReserved); FIX_ENDIAN_INT16_INPLACE(igh.wType); FIX_ENDIAN_INT16_INPLACE(igh.wCount); - return f; + return igh.wCount; } -void free_loaded_icon(IconGroup icon) +void free_loaded_icon(IconGroup&icon) { for (IconGroup::size_type i = 0; i < icon.size(); i++) - { delete [] icon[i].data; - } + icon.clear(); } -IconGroup load_icon_res(CResourceEditor* re, WORD id) +IconGroup load_icon_res(CResourceEditor* re, const TCHAR*RT, WORD RN, LANGID RL) { IconGroupHeader* header; IconGroup result; - LPBYTE group = re->GetResource( - RT_GROUP_ICON, id, NSIS_DEFAULT_LANG); - + LPBYTE group = re->GetResource(RT, RN, RL); if (!group) throw runtime_error("can't find icon group"); header = (IconGroupHeader*) group; + // Note: To handle cursors, use CResourceEditor::ExtractIcoCur + if (MAKEINTRESOURCE((size_t) RT) != RT_GROUP_ICON) + throw runtime_error("unsupported type"); + for (WORD i = 0; i < FIX_ENDIAN_INT16(header->wCount); i++) { Icon icon; @@ -99,9 +97,7 @@ memcpy(&icon.meta, &entry->header, sizeof(IconGroupEntry)); WORD rsrc_id = FIX_ENDIAN_INT16(entry->wRsrcId); - - icon.data = re->GetResource(RT_ICON, rsrc_id, NSIS_DEFAULT_LANG); - + icon.data = re->GetResource(RT_ICON, rsrc_id, RL); if (!icon.data) { free_loaded_icon(result); @@ -115,14 +111,15 @@ return result; } -IconGroup load_icon_file(const TCHAR* filename) +IconGroup load_icon_res(CResourceEditor* re, WORD id) { - IconGroupHeader iconHeader; + return load_icon_res(re, RT_GROUP_ICON, id, NSIS_DEFAULT_LANG); +} + +template<class S> static IconGroup load_iconimages_from_stream(const IconGroupHeader&iconHeader, S&file) +{ IconGroup result; - FILE *file = open_icon(filename, iconHeader); - MANAGE_WITH(file, fclose); - for (WORD i = 0; i < iconHeader.wCount; i++) { Icon icon; @@ -129,7 +126,7 @@ icon.index = i; icon.data = NULL; - if (!fread(&icon.meta, sizeof(IconGroupEntry), 1, file)) + if (!freadall(&icon.meta, sizeof(IconGroupEntry), file)) { free_loaded_icon(result); throw runtime_error("unable to read entry from file"); @@ -143,8 +140,7 @@ } DWORD iconOffset; - - if (!fread(&iconOffset, sizeof(DWORD), 1, file)) + if (!freadall(&iconOffset, sizeof(DWORD), file)) { free_loaded_icon(result); throw runtime_error("unable to read offset from file"); @@ -154,7 +150,6 @@ fpos_t pos; fgetpos(file, &pos); - if (fseek(file, iconOffset, SEEK_SET)) { free_loaded_icon(result); @@ -162,14 +157,14 @@ } icon.data = new BYTE[size]; - - if (!fread(icon.data, size, 1, file)) + if (!freadall(icon.data, size, file)) die: { free_loaded_icon(result); throw runtime_error("unable to read icon from file"); } - fsetpos(file, &pos); + if (fsetpos(file, &pos)) + goto die; result.push_back(icon); } @@ -177,6 +172,39 @@ return result; } +template<class S> static IconGroup load_icon_from_stream(S*file) +{ + IconGroupHeader iconHeader; + read_icon_header(file, iconHeader); + return load_iconimages_from_stream(iconHeader, file); +} + +IconGroup load_icon_file(const TCHAR* filename) +{ + FILE* f = FOPEN(filename, ("rb")); + if (!f) + throw runtime_error("can't open file"); + + MANAGE_WITH(f, fclose); + return load_icon_from_stream(f); +} + +IconGroup load_icon(const TCHAR* filename) +{ + if (CResourceEditor::IsResProtocol(filename)) // Try opening embedded resource + { + CResourceEditor::EXTERNAL x; + if (CResourceEditor::MapExternal(filename, CResourceEditor::TM_ICON, x)) + { + CStdFileStreamOnMemory stream(x.Data, x.cbData); + IconGroup icon = load_icon_from_stream(&stream); + CResourceEditor::FreeExternal(x); + return icon; + } + } + return load_icon_file(filename); +} + typedef struct { unsigned index1; Modified: NSIS/trunk/Source/icon.h =================================================================== --- NSIS/trunk/Source/icon.h 2021-09-17 18:13:17 UTC (rev 7327) +++ NSIS/trunk/Source/icon.h 2021-09-18 20:24:41 UTC (rev 7328) @@ -62,9 +62,10 @@ typedef std::vector<Icon> IconGroup; +IconGroup load_icon(const TCHAR* filename); IconGroup load_icon_file(const TCHAR* filename); IconGroup load_icon_res(CResourceEditor* re, WORD id); -void free_loaded_icon(IconGroup icon); +void free_loaded_icon(IconGroup&icon); void set_main_icon(CResourceEditor* re, WORD wIconId, IconGroup icon1, IconGroup icon2); Modified: NSIS/trunk/Source/script.cpp =================================================================== --- NSIS/trunk/Source/script.cpp 2021-09-17 18:13:17 UTC (rev 7327) +++ NSIS/trunk/Source/script.cpp 2021-09-18 20:24:41 UTC (rev 7328) @@ -1333,7 +1333,7 @@ SCRIPT_MSG(_T("Icon: \"%") NPRIs _T("\"\n"),line.gettoken_str(1)); try { free_loaded_icon(installer_icon); - installer_icon = load_icon_file(line.gettoken_str(1)); + installer_icon = load_icon(line.gettoken_str(1)); } catch (exception& err) { ERROR_MSG(_T("Error while loading icon from \"%") NPRIs _T("\": %") NPRIs _T("\n"), line.gettoken_str(1), CtoTStrParam(err.what())); @@ -2593,7 +2593,7 @@ SCRIPT_MSG(_T("UninstallIcon: \"%") NPRIs _T("\"\n"),line.gettoken_str(1)); try { free_loaded_icon(uninstaller_icon); - uninstaller_icon = load_icon_file(line.gettoken_str(1)); + uninstaller_icon = load_icon(line.gettoken_str(1)); } catch (exception& err) { ERROR_MSG(_T("Error while loading icon from \"%") NPRIs _T("\": %") NPRIs _T("\n"), line.gettoken_str(1), CtoTStrParam(err.what())); Modified: NSIS/trunk/Source/util.h =================================================================== --- NSIS/trunk/Source/util.h 2021-09-17 18:13:17 UTC (rev 7327) +++ NSIS/trunk/Source/util.h 2021-09-18 20:24:41 UTC (rev 7328) @@ -29,8 +29,8 @@ # include <stdio.h> # include <unistd.h> #endif - #include <stdarg.h> +#include <stdio.h> extern double my_wtof(const wchar_t *str); extern size_t my_strncpy(TCHAR*Dest, const TCHAR*Src, size_t cchMax); @@ -109,6 +109,49 @@ int sane_system(const TCHAR *command); +template<class S> static size_t freadall(void*b, size_t cb, S*s) { return cb == fread(b, 1, cb, s) ? cb : 0; } +template<class T, class S> static inline size_t freadpod(T&b, S*s) { return freadall(b, sizeof(T), s); } + +struct CStdFileStreamOnMemory +{ + typedef CStdFileStreamOnMemory S_t; + BYTE*m_Base; + size_t m_cb, m_pos; + template<class T> CStdFileStreamOnMemory(T*p, size_t cb) : m_Base((BYTE*)p), m_cb(cb), m_pos(0) {} + template<class V> static inline bool assignfp(fpos_t*p, V v) + { + if (sizeof(p) >= sizeof(v)) return (*(V*)p = v, true); + UINT t = (UINT) v; + return t == v && sizeof(p) >= sizeof(t) && assignfp(p, t); + } + template<class V> static inline void readfp(V&v, const fpos_t*p) { v = sizeof(p) >= sizeof(v) ? *(V*)p : *(UINT*)p; } + friend inline size_t fclose(S_t*s) { return 0; } + friend int fgetpos(S_t*s, fpos_t*pos) { return assignfp(pos, s->m_pos) ? 0 : 1; } + friend int fsetpos(S_t*s, const fpos_t*pos) { size_t v; readfp(v, pos); return v < s->m_cb ? (s->m_pos = v, 0) : 1; } + friend int fseek(S_t*s, long int offset, int origin) + { + if ((unsigned long) offset != (size_t) offset) return 1; // long int will usually fit in our size_t + size_t newpos, invalid = 0; + switch(origin) + { + case SEEK_SET: newpos = (size_t) offset, invalid = offset < 0; break; + case SEEK_CUR: newpos = s->m_pos + offset; break; + case SEEK_END: newpos = s->m_cb + offset; break; + default: ++invalid; + } + if (!(invalid += s->m_cb <= newpos)) s->m_pos = newpos; + return (int) invalid; + } + friend size_t fread(void*b, size_t e, size_t c, S_t*s) + { + size_t cb = e * c, endpos = s->m_pos + cb; + if (endpos < s->m_pos || cb < c) return 0; // EOF/Overflow + if (s->m_cb < endpos) cb = s->m_cb - s->m_pos; // EOF + memcpy(b, s->m_Base + s->m_pos, cb); + return (s->m_pos += cb, cb); + } +}; + #define NSISRT_DEFINEGLOBALS() int g_display_errors=1; FILE *g_output=stdout, *g_errout=stderr void PrintColorFmtErrMsg(const TCHAR *fmtstr, va_list args); void PrintColorFmtMsg(unsigned int type, const TCHAR *fmtstr, va_list args); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |