* Basic System::Call support when compiling with 64-bit MinGW/GCC toolchain

* Win64 fixes


git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6607 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
anders_k 2015-09-17 14:30:07 +00:00
parent 757d16f937
commit 286edd20c4
41 changed files with 335 additions and 232 deletions

View file

@ -139,9 +139,7 @@ typedef DWORDLONG ULONGLONG,*PULONGLONG;
#endif
#endif
#ifdef _countof
#define COUNTOF _countof
#else
#ifndef COUNTOF
#define COUNTOF(a) (sizeof(a)/sizeof(a[0]))
#endif
@ -1020,22 +1018,22 @@ typedef struct tagVS_FIXEDFILEINFO {
/*
_tprintf on Windows/MSVCRT treats %s as TCHAR* and on POSIX %s is always char*!
Always use our NPRI* (NsisPRInt[Narrow|Wide]*) defines in format strings when calling
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"));
*/
#ifdef _WIN32
# define NPRIs _T("s")
# define NPRINs _T("hs")
# define NPRIWs _T("ls") // ws also works, not sure which is most compatible
# define NPRIns _T("hs")
# define NPRIws _T("ls") // ws also works, not sure which is most compatible
# ifndef _WIN64
# define NPRIp _T(".8x")
# define NPRINp ".8x"
# define NPRIpN ".8x"
# endif
#else // !_WIN32
# define NPRINs _T("s")
# define NPRIWs _T("ls")
# define NPRIns _T("s")
# define NPRIws _T("ls")
# ifdef _UNICODE
# define NPRIs _T("ls")
# else // !_UNICODE
@ -1044,7 +1042,7 @@ Example: _tprintf(_T("Hello %") NPRIs _T("\n"), _T("World"));
#endif // ~_WIN32
#ifndef NPRIp
# define NPRIp _T("p")
# define NPRINp "p"
# define NPRIpN "p"
#endif
#endif // EOF

View file

@ -849,7 +849,7 @@ void CResourceDirectory::RemoveEntry(int i) {
}
unsigned int CResourceDirectory::CountEntries() {
return BUGBUG64TRUNCATE(unsigned int,m_vEntries.size());
return truncate_cast(unsigned int,m_vEntries.size());
}
// Returns the index of a directory entry with the specified name

View file

@ -448,7 +448,7 @@ void CEXEBuild::init_shellconstantvalues()
// see Source\exehead\util.c for implementation details
// basically, it knows it needs to get folders from the registry when the 0x80 is on
const char* msg = "Internal compiler error: too many strings added to strings block before adding shell constants!";
ERROR_MSG(_T("%") NPRINs, msg);
ERROR_MSG(_T("%") NPRIns, msg);
throw out_of_range(msg);
}
@ -469,7 +469,7 @@ void CEXEBuild::init_shellconstantvalues()
|| uncf64_def != cf64_def)
{
const char* msg = "Internal compiler error: installer's shell constants are different than uninstallers!";
ERROR_MSG(_T("%") NPRINs, msg);
ERROR_MSG(_T("%") NPRIns, msg);
throw out_of_range(msg);
}
}
@ -602,7 +602,7 @@ int CEXEBuild::preprocess_string(TCHAR *out, const TCHAR *in, WORD codepage/*=CP
{
// starts with a $ but not $$.
bool bProceced=false;
if ( *p )
if (*p)
{
const TCHAR *pUserVarName = p;
while (isSimpleChar(*pUserVarName))
@ -610,10 +610,10 @@ int CEXEBuild::preprocess_string(TCHAR *out, const TCHAR *in, WORD codepage/*=CP
while (pUserVarName > p)
{
if (m_ShellConstants.get(p, BUGBUG64TRUNCATE(int, pUserVarName-p)) >= 0)
if (m_ShellConstants.get(p, truncate_cast(int, (size_t)(pUserVarName - p))) >= 0)
break; // Woops it's a shell constant
int idxUserVar = m_UserVarNames.get(p, BUGBUG64TRUNCATE(int, pUserVarName-p));
int idxUserVar = m_UserVarNames.get(p, truncate_cast(int, (size_t)(pUserVarName - p)));
if (idxUserVar >= 0)
{
// Well, using variables inside string formating doens't mean
@ -641,7 +641,7 @@ int CEXEBuild::preprocess_string(TCHAR *out, const TCHAR *in, WORD codepage/*=CP
while (pShellConstName > p)
{
// Look for the identifier in the shell constants list of strings.
int idxConst = m_ShellConstants.get((TCHAR*)p, BUGBUG64TRUNCATE(int, pShellConstName - p));
int idxConst = m_ShellConstants.get((TCHAR*)p, truncate_cast(int, (size_t)(pShellConstName - p)));
// If found...
if (idxConst >= 0)
@ -857,6 +857,14 @@ int CEXEBuild::add_db_data(IMMap *mmap) // returns offset
bufferlen = INT_MAX-st-sizeof(int); // so maximize compressor room and hope the file compresses well
db->resize(st + bufferlen + sizeof(int));
#if defined(NSIS_CONFIG_COMPRESSION_SUPPORT) && defined(__GNUC__) && defined(_WIN64) // There is another one of these, remove both when fixed
// BUGBUG: zlib is currently broken on 64-bit MinGW
if (compressor == &zlib_compressor)
{
ERROR_MSG(_T("\nError: ZLib is currently broken on this platform!\n"));
return -1;
}
#endif
int n = compressor->Init(build_compress_level, build_compress_dict_size);
if (n != C_OK)
{
@ -1123,8 +1131,7 @@ int CEXEBuild::add_function(const TCHAR *funname)
// ns_func contains all the function names defined.
int addr=ns_func.add(funname,0);
int x;
int n=cur_functions->getlen()/sizeof(section);
int n=cur_functions->getlen()/sizeof(section), x;
section *tmp=(section*)cur_functions->get();
for (x = 0; x < n; x ++)
{
@ -2566,6 +2573,15 @@ int CEXEBuild::write_output(void)
RET_UNLESS_OK( check_write_output_errors() );
#if defined(NSIS_CONFIG_COMPRESSION_SUPPORT) && defined(__GNUC__) && defined(_WIN64) // There is another one of these, remove both when fixed
// BUGBUG: zlib is currently broken on 64-bit MinGW
if (compressor == &zlib_compressor)
{
ERROR_MSG(_T("\nError: ZLib is currently broken on this platform!\n"));
return PS_ERROR;
}
#endif
has_called_write_output=true;
#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
@ -3198,7 +3214,7 @@ int CEXEBuild::uninstall_generate()
compressor->Compress(0);
if (compressor->GetNextOut() - obuf > 0)
{
udata.add(obuf, BUGBUG64TRUNCATE(int, compressor->GetNextOut() - obuf));
udata.add(obuf, truncate_cast(int, (size_t)(compressor->GetNextOut() - obuf)));
}
}
@ -3215,7 +3231,7 @@ int CEXEBuild::uninstall_generate()
compressor->SetNextOut(obuf, sizeof(obuf));
compressor->Compress(0);
if (compressor->GetNextOut() - obuf > 0)
udata.add(obuf, BUGBUG64TRUNCATE(int, compressor->GetNextOut() - obuf));
udata.add(obuf, truncate_cast(int, (size_t)(compressor->GetNextOut() - obuf)));
}
ubuild_datablock.release();
@ -3229,7 +3245,7 @@ int CEXEBuild::uninstall_generate()
compressor->SetNextOut(obuf, sizeof(obuf));
compressor->Compress(C_FINISH);
if (compressor->GetNextOut() - obuf > 0)
udata.add(obuf, BUGBUG64TRUNCATE(int, compressor->GetNextOut() - obuf));
udata.add(obuf, truncate_cast(int, (size_t)(compressor->GetNextOut() - obuf)));
else break;
}
compressor->End();

View file

@ -19,10 +19,11 @@
#include "Platform.h"
#include "crc32.h"
#include "exehead/config.h"
#ifdef NSIS_CONFIG_CRC_SUPPORT
// this is based on the (slow,small) CRC32 implementation from zlib.
crc32_t NSISCALL CRC32(crc32_t crc, const unsigned char *buf, unsigned int len)
crc32_t NSISCALL CRC32(crc32_t crc, const unsigned char *buf, size_t len)
{
static crc32_t crc_table[256];

View file

@ -16,16 +16,17 @@
* Reviewed for Unicode support by Jim Park -- 08/24/2007
*/
#include "Platform.h"
#ifndef ___CRC32__H___
#define ___CRC32__H___
#include "Platform.h"
#include <stddef.h> // size_t
typedef UINT32 crc32_t;
#ifdef __cplusplus
extern "C"
#endif
crc32_t NSISCALL CRC32(crc32_t crc, const unsigned char *buf, unsigned int len);
crc32_t NSISCALL CRC32(crc32_t crc, const unsigned char *buf, size_t len);
#endif//!___CRC32__H___

View file

@ -290,7 +290,7 @@ FORCE_INLINE int NSISCALL ui_doinstall(void)
if (header->install_reg_key_ptr)
{
myRegGetStr(
(HKEY)header->install_reg_rootkey,
(HKEY)(UINT_PTR)header->install_reg_rootkey,
GetNSISStringNP(header->install_reg_key_ptr),
GetNSISStringNP(header->install_reg_value_ptr),
ps_tmpbuf,

View file

@ -77,7 +77,7 @@ LRESULT CALLBACK BG_WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
if (header->bg_textcolor != -1)
{
HFONT newFont = CreateFontIndirect((LOGFONT *) header->blocks[NB_BGFONT].offset);
HFONT newFont = CreateFontIndirect((LOGFONT*) header->blocks[NB_BGFONT].offset);
if (newFont)
{
HFONT oldFont;

View file

@ -189,10 +189,10 @@ static LONG NSISCALL myRegDeleteKeyEx(HKEY thiskey, LPCTSTR lpSubKey, int onlyif
static HKEY NSISCALL GetRegRootKey(int hRootKey)
{
if (hRootKey)
return (HKEY) hRootKey;
return (HKEY) (UINT_PTR) hRootKey;
// HKEY_LOCAL_MACHINE - HKEY_CURRENT_USER == 1
return (HKEY) ((int) HKEY_CURRENT_USER + g_exec_flags.all_user_var);
return (HKEY) ((UINT_PTR) HKEY_CURRENT_USER + g_exec_flags.all_user_var);
}
static HKEY NSISCALL myRegOpenKey(REGSAM samDesired)
@ -870,7 +870,7 @@ static int NSISCALL ExecuteEntry(entry *entry_)
TCHAR *buf2=GetStringFromParm(0x22);
GetStringFromParm(0x15); // For update_status_text_buf1
update_status_text_buf1(LANG_EXECSHELL);
x=(int)ShellExecute(g_hwnd,buf0[0]?buf0:NULL,buf3,buf2[0]?buf2:NULL,state_output_directory,parm3);
x=(int)(INT_PTR)ShellExecute(g_hwnd,buf0[0]?buf0:NULL,buf3,buf2[0]?buf2:NULL,state_output_directory,parm3);
if (x < 33)
{
log_printf5(_T("ExecShell: warning: error (\"%s\": file:\"%s\" params:\"%s\")=%d"),buf0,buf3,buf2,x);

View file

@ -17,6 +17,10 @@
*/
#include "../Platform.h"
#if defined(__cplusplus) && defined(truncate_cast)
#undef BUGBUG64TRUNCATE
#define BUGBUG64TRUNCATE truncate_cast
#endif
#include "fileform.h"
#include "util.h"
#include "state.h"
@ -327,7 +331,13 @@ const TCHAR * NSISCALL loadHeaders(int cl_flags)
// set offsets to real memory offsets rather than installer's header offset
left = BLOCKS_NUM;
while (left--)
header->blocks[left].offset += (int)data;
{
#ifdef DEBUG
if (h.length_of_header < header->blocks[left].offset)
return _LANG_GENERIC_ERROR; // Should never happen
#endif
header->blocks[left].offset += BUGBUG64TRUNCATE(UINT, (UINT_PTR) data);
}
#ifdef NSIS_COMPRESS_WHOLE
header->blocks[NB_DATA].offset = dbd_pos;
@ -398,7 +408,7 @@ int NSISCALL _dodecomp(int offset, HANDLE hFileOut, unsigned char *outbuf, int o
if (err<0) return -4;
u=BUGBUG64TRUNCATE(int, (char*)g_inflate_stream.next_out - outbuffer);
u=BUGBUG64TRUNCATE(int, (size_t)((char*)g_inflate_stream.next_out - outbuffer));
tc=GetTickCount();
if (g_exec_flags.status_update & 1 && (tc - ltc > 200 || !input_len))
@ -501,7 +511,7 @@ static int NSISCALL __ensuredata(int amount)
{
return -3;
}
r=(DWORD)g_inflate_stream.next_out-(DWORD)_outbuffer;
r=BUGBUG64TRUNCATE(DWORD,(UINT_PTR)g_inflate_stream.next_out)-BUGBUG64TRUNCATE(DWORD,(UINT_PTR)_outbuffer);
if (r)
{
if (!WriteFile(dbd_hFile,_outbuffer,r,&t,NULL) || r != t)

View file

@ -258,7 +258,7 @@ typedef struct
// nsis blocks
struct block_header {
int offset;
/*UINT_PTR*/ int offset; // BUGBUG: This should probably be UINT_PTR but that currently crashes :(
int num;
};
@ -554,10 +554,10 @@ extern int g_flags;
extern int g_filehdrsize;
extern int g_is_uninstaller;
#define g_pages ((page*)g_blocks[NB_PAGES].offset)
#define g_sections ((section*)g_blocks[NB_SECTIONS].offset)
#define num_sections (g_blocks[NB_SECTIONS].num)
#define g_entries ((entry*)g_blocks[NB_ENTRIES].offset)
#define g_pages ( (page*) g_blocks[NB_PAGES].offset )
#define g_sections ( (section*) g_blocks[NB_SECTIONS].offset )
#define num_sections ( g_blocks[NB_SECTIONS].num )
#define g_entries ( (entry*) g_blocks[NB_ENTRIES].offset )
#endif
#endif //_FILEFORM_H_

View file

@ -567,7 +567,9 @@ void RenameViaWininit(const TCHAR* prevName, const TCHAR* newName)
*/
void NSISCALL MoveFileOnReboot(LPCTSTR pszExisting, LPCTSTR pszNew)
{
BOOL fOk = 0;
#ifndef _WIN64 // Shut up GCC unused warning
BOOL fOk = FALSE;
#endif
typedef BOOL (WINAPI *mfea_t)(LPCTSTR lpExistingFileName,LPCTSTR lpNewFileName,DWORD dwFlags);
mfea_t mfea;
#ifdef _WIN64
@ -577,7 +579,10 @@ void NSISCALL MoveFileOnReboot(LPCTSTR pszExisting, LPCTSTR pszNew)
if (mfea)
#endif
{
fOk=mfea(pszExisting, pszNew, MOVEFILE_DELAY_UNTIL_REBOOT|MOVEFILE_REPLACE_EXISTING);
#ifndef _WIN64 // Shut up GCC unused warning
fOk=
#endif
mfea(pszExisting, pszNew, MOVEFILE_DELAY_UNTIL_REBOOT|MOVEFILE_REPLACE_EXISTING);
}
#ifndef _WIN64
if (!fOk)

View file

@ -30,36 +30,37 @@
using namespace std;
// Default constructor
GrowBuf::GrowBuf() { m_alloc=m_used=m_zero=0; m_s=NULL; m_bs=32768; }
GrowBuf::GrowBuf() { m_alloc=m_used=0, m_zero=false, m_s=NULL, m_bs=32768; }
// Destructor
GrowBuf::~GrowBuf() { free(m_s); }
void GrowBuf::set_zeroing(int zero) { m_zero=zero; }
void GrowBuf::set_zeroing(bool zero) { m_zero=zero; }
int GrowBuf::add(const void *data, int len)
GrowBuf::size_type GrowBuf::add(const void *data, GrowBuf::size_type len)
{
if (len<=0) return 0;
if (len<=0) return 0; // BUGBUG: Why is this returning 0? It should return m_used?
resize(m_used+len);
memcpy((BYTE*)m_s+m_used-len,data,len);
return m_used-len;
}
void GrowBuf::resize(int newlen)
void GrowBuf::resize(GrowBuf::size_type newlen)
{
int os=m_alloc; // old size
int ou=m_used; // old used
const size_type orgalloc=m_alloc;
const size_type orgused=m_used;
m_used=newlen;
if (newlen > m_alloc)
{
void *n;
void *newstor;
// Jim Park: Not sure why we don't just add m_bs. Multiplying by 2
// makes m_bs meaningless after a few resizes. So TinyGrowBuf
// isn't very tiny.
m_alloc = newlen*2 + m_bs;
n = realloc(m_s, m_alloc);
if (!n)
newstor = realloc(m_s, m_alloc);
if (!newstor)
{
extern int g_display_errors;
if (g_display_errors)
@ -67,8 +68,8 @@ void GrowBuf::resize(int newlen)
PrintColorFmtMsg_ERR(_T("\nack! realloc(%d) failed, trying malloc(%d)!\n"),m_alloc,newlen);
}
m_alloc=newlen; // try to malloc the minimum needed
n=malloc(m_alloc);
if (!n)
newstor=malloc(m_alloc);
if (!newstor)
{
extern void quit();
if (g_display_errors)
@ -77,15 +78,15 @@ void GrowBuf::resize(int newlen)
}
quit();
}
memcpy(n,m_s,min(newlen,os));
memcpy(newstor,m_s,min(newlen,orgalloc));
free(m_s);
}
m_s=n;
m_s=newstor;
}
// Zero out the new buffer area
if (m_zero && m_used > ou)
memset((BYTE*)m_s + ou, 0, m_used - ou);
if (m_zero && m_used > orgused)
memset((BYTE*)m_s + orgused, 0, m_used - orgused);
if (!m_used && m_alloc > 2*m_bs) // only free if you resize to 0 and we're > 64k or
// 2K in the case of TinyGrowBuf
@ -96,7 +97,7 @@ void GrowBuf::resize(int newlen)
}
}
int GrowBuf::getlen() const { return m_used; }
GrowBuf::size_type GrowBuf::getlen() const { return m_used; }
void *GrowBuf::get() const { return m_s; }
void GrowBuf::swap(GrowBuf&other)

View file

@ -26,6 +26,7 @@
class IGrowBuf
{
public:
typedef int size_type; // Hopefully we can change this at some point
virtual ~IGrowBuf() {}
/**
@ -34,19 +35,19 @@ class IGrowBuf
* @param len Size of the data in bytes.
* @return the previous logical size in bytes before the addition.
*/
virtual int add(const void *data, int len)=0;
virtual size_type add(const void *data, size_type len)=0;
/**
* Resizes the buffer to hold the number of bytes specified.
* @param newlen the desired logical size of the buffer.
*/
virtual void resize(int newlen)=0;
virtual void resize(size_type newlen)=0;
/**
* Get the length of the logical buffer in bytes.
* @return the length in bytes
*/
virtual int getlen() const=0;
virtual size_type getlen() const=0;
/**
* Get the buffer itself.
@ -72,7 +73,7 @@ class GrowBuf : public IGrowBuf
* Set whether to zero out buffer
* @param zero A boolean value.
*/
void set_zeroing(int zero);
void set_zeroing(bool zero);
/**
* Add data to the buffer.
@ -80,22 +81,21 @@ class GrowBuf : public IGrowBuf
* @param len Size of the data in bytes.
* @return the previous logical size in bytes before the addition.
*/
int add(const void *data, int len);
size_type add(const void *data, size_type len);
/**
* Resizes the buffer to hold the number of bytes specified.
* Setting the newlen to 0 will cause the buffer to be at most
* 2*m_bs bytes long. (It will free the buffer if > 2*m_bs.)
* @param newlen the desired logical size of the buffer.
*/
void resize(int newlen);
void resize(size_type newlen);
/**
* Get the length of the logical buffer in bytes.
* Setting the newlen to 0 will cause the buffer to be at most
* 2*m_bs bytes long. (It will free the buffer if > 2*m_bs.)
*
* @return the length in bytes
*/
int getlen() const;
size_type getlen() const;
/**
* Get the buffer itself.
@ -107,12 +107,12 @@ class GrowBuf : public IGrowBuf
private:
void *m_s; /* the storage buffer */
int m_alloc; /* allocated bytes */
int m_used; /* how many bytes of the buffer is used? */
int m_zero; /* should storage be zeroed out? */
size_type m_alloc; /* allocated bytes */
size_type m_used; /* how many bytes of the buffer is used? */
bool m_zero; /* should storage be zeroed out? */
protected:
int m_bs; // byte-size to grow by
unsigned short m_bs; // byte-size to grow by
};
/**

View file

@ -228,7 +228,7 @@ static IconPairs get_icon_order(IconGroup icon1, IconGroup icon2)
FIX_ENDIAN_INT32(sorted_icons1[i].meta.dwRawSize),
FIX_ENDIAN_INT32(sorted_icons2[i].meta.dwRawSize)
);
pair.size_index = BUGBUG64TRUNCATE(unsigned int,i);
pair.size_index = truncate_cast(unsigned int,i);
result.push_back(pair);
}
@ -242,7 +242,7 @@ static IconPairs get_icon_order(IconGroup icon1, IconGroup icon2)
pair.index1 = sorted_icons1[i].index;
pair.index2 = 0xffff;
pair.size = FIX_ENDIAN_INT32(sorted_icons1[i].meta.dwRawSize);
pair.size_index = BUGBUG64TRUNCATE(unsigned int,i);
pair.size_index = truncate_cast(unsigned int,i);
}
if (i < sorted_icons2.size())
@ -250,7 +250,7 @@ static IconPairs get_icon_order(IconGroup icon1, IconGroup icon2)
pair.index2 = sorted_icons2[i].index;
pair.index1 = 0xffff;
pair.size = FIX_ENDIAN_INT32(sorted_icons2[i].meta.dwRawSize);
pair.size_index = BUGBUG64TRUNCATE(unsigned int,i);
pair.size_index = truncate_cast(unsigned int,i);
}
result.push_back(pair);

View file

@ -118,8 +118,11 @@ static void init_signals(HWND notify_hwnd)
#ifdef _WIN32
DWORD id;
HANDLE hThread = CreateThread(NULL, 0, sigint_event_msg_handler, (LPVOID)notify_hwnd, 0, &id);
SetThreadPriority(hThread, THREAD_PRIORITY_HIGHEST);
if (hThread) CloseHandle(hThread);
if (hThread)
{
SetThreadPriority(hThread, THREAD_PRIORITY_HIGHEST);
CloseHandle(hThread);
}
#endif
}
@ -326,7 +329,7 @@ static inline int makensismain(int argc, TCHAR **argv)
{
initialparsefail=!HasReqParam(argv,++argpos,argc,true);
if (initialparsefail) break;
hostnotifyhandle=(HWND)_ttol(argv[argpos]);
hostnotifyhandle=(HWND)(INT_PTR) _ttol(argv[argpos]); // MSDN says we should sign extend HWNDs: msdn.microsoft.com/en-us/library/aa384203
#ifdef _WIN32
if (!IsWindow(hostnotifyhandle)) hostnotifyhandle=0;
#endif
@ -394,7 +397,7 @@ static inline int makensismain(int argc, TCHAR **argv)
// The host can override the output format if they want to
LPARAM lp=MAKELONG(outputenc.GetCodepage(),outputbom);
LRESULT mr=SendMessage(hostnotifyhandle,MakensisAPI::QUERYHOST,MakensisAPI::QH_OUTPUTCHARSET,lp);
if (mr) outputenc.SetCodepage((WORD)--mr), outputbom = -1;
if (mr) outputenc.SetCodepage((WORD)(--mr)), outputbom = -1;
}
if (!WinStdIO_OStreamInit(g_osdata_stdout,g_output,outputenc.GetCodepage(),outputbom))

View file

@ -52,6 +52,8 @@ using namespace std;
#define MAX_INCLUDEDEPTH 10
#define REGROOTKEYTOINT(hk) ( (INT) (((INT_PTR)(hk)) & 0xffffffff) ) // Masking off non-existing top bits to make GCC happy
static UINT read_line_helper(NStreamLineReader&lr, TCHAR*buf, UINT cch)
{
// Helper function for reading lines from text files. buf MUST be valid and cch MUST be > 1!
@ -662,7 +664,7 @@ void CEXEBuild::ps_addtoline(const TCHAR *str, GrowBuf &linedata, StringList &hi
if (t-in > 1) // handle multibyte chars (no escape)
{
linedata.add((void*)in,BUGBUG64TRUNCATE(int,(t-in)*sizeof(TCHAR)));
linedata.add((void*)in,truncate_cast(int, (size_t)((t-in)*sizeof(TCHAR))));
in=t;
continue;
}
@ -1213,7 +1215,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
TCHAR *mbufb=(TCHAR*)m_macros.get();
const size_t mcb=((mend)-mbeg)*sizeof(TCHAR), mbufcb=m_macros.getlen();
memmove(mbeg,mend,mbufcb-(((mbeg-mbufb)*sizeof(TCHAR))+mcb));
m_macros.resize(BUGBUG64TRUNCATE(int,mbufcb-mcb));
m_macros.resize(truncate_cast(int,(size_t)(mbufcb-mcb)));
SCRIPT_MSG(_T("!macroundef: %") NPRIs _T("\n"),mname);
}
return PS_OK;
@ -2293,7 +2295,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
int k=line.gettoken_enum(1,rootkeys[0]);
if (k == -1) k=line.gettoken_enum(1,rootkeys[1]);
if (k == -1) PRINTHELP()
build_header.install_reg_rootkey=(INT)rootkey_tab[k];
build_header.install_reg_rootkey=REGROOTKEYTOINT(rootkey_tab[k]);
if (!build_header.install_reg_rootkey) PRINTHELP() // SHCTX is invalid here
build_header.install_reg_key_ptr = add_string(line.gettoken_str(2),0);
if (line.gettoken_str(2)[0] == _T('\\'))
@ -5339,7 +5341,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
int k=line.gettoken_enum(2,rootkeys[0]);
if (k == -1) k=line.gettoken_enum(2,rootkeys[1]);
if (ent.offsets[0] == -1 || k == -1) PRINTHELP()
ent.offsets[1]=(INT)rootkey_tab[k];
ent.offsets[1]=REGROOTKEYTOINT(rootkey_tab[k]);
ent.offsets[2]=add_string(line.gettoken_str(3));
ent.offsets[3]=add_string(line.gettoken_str(4));
if (which_token == TOK_READREGDWORD) ent.offsets[4]=1;
@ -5371,7 +5373,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
if (k == -1) k=line.gettoken_enum(a,rootkeys[1]);
if (k == -1) PRINTHELP()
ent.which=EW_DELREG;
ent.offsets[1]=(INT)rootkey_tab[k];
ent.offsets[1]=REGROOTKEYTOINT(rootkey_tab[k]);
ent.offsets[2]=add_string(line.gettoken_str(a+1));
ent.offsets[3]=(which_token==TOK_DELETEREGKEY)?0:add_string(line.gettoken_str(a+2));
if (line.gettoken_str(a+1)[0] == _T('\\'))
@ -5391,7 +5393,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
if (k == -1) k=line.gettoken_enum(1,rootkeys[1]);
if (k == -1) PRINTHELP()
ent.which=EW_WRITEREG;
ent.offsets[0]=(INT)rootkey_tab[k];
ent.offsets[0]=REGROOTKEYTOINT(rootkey_tab[k]);
ent.offsets[1]=add_string(line.gettoken_str(2));
if (line.gettoken_str(2)[0] == _T('\\'))
warning_fl(_T("%") NPRIs _T(": registry path name begins with \'\\\', may cause problems"),line.gettoken_str(0));
@ -5458,7 +5460,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
int k=line.gettoken_enum(2,rootkeys[0]);
if (k == -1) k=line.gettoken_enum(2,rootkeys[1]);
if (ent.offsets[0] == -1 || k == -1) PRINTHELP()
ent.offsets[1]=(INT)rootkey_tab[k];
ent.offsets[1]=REGROOTKEYTOINT(rootkey_tab[k]);
ent.offsets[2]=add_string(line.gettoken_str(3));
ent.offsets[3]=add_string(line.gettoken_str(4));
ent.offsets[4]=which_token == TOK_ENUMREGKEY;

View file

@ -124,7 +124,7 @@ unsigned int ExeHeadStringList::find(const void *ptr, unsigned int cchF, WORD co
#ifndef NDEBUG
if (!cbMB)
{
const TCHAR *fmt = _T("Unable to convert%")NPRINs _T(" string \"%")NPRIs _T("\" to codepage %u\n");
const TCHAR *fmt = _T("Unable to convert%")NPRIns _T(" string \"%")NPRIs _T("\" to codepage %u\n");
PrintColorFmtMsg_ERR(fmt,(processed ? " processed" : ""),find,codepage);
}
#endif
@ -160,7 +160,8 @@ unsigned int ExeHeadStringList::find(const void *ptr, unsigned int cchF, WORD co
else
delete[] bufMB;
}
return BUGBUG64TRUNCATE(unsigned int, retval);
// -1 is a valid magic return value but we must avoid the truncation check in truncate_cast
return retval != (size_t)(-1) ? truncate_cast(unsigned int,retval) : (unsigned int) retval;
}
int ExeHeadStringList::add(const TCHAR *str, WORD codepage, bool processed)
@ -203,7 +204,7 @@ int StringList::add(const TCHAR *str, int case_sensitive)
{
int a=find(str,case_sensitive);
if (a >= 0 && case_sensitive!=-1) return a;
return m_gr.add(str,BUGBUG64TRUNCATE(int, (_tcslen(str)+1)*sizeof(TCHAR)))/sizeof(TCHAR);
return m_gr.add(str,truncate_cast(int,(_tcslen(str)+1)*sizeof(TCHAR)))/sizeof(TCHAR);
}
// use 2 for case sensitive end-of-string matches too
@ -233,9 +234,9 @@ int StringList::find(const TCHAR *str, int case_sensitive, int *idx/*=NULL*/) co
str_slen < offs_slen && // check for end of string
!_tcscmp(s + offs + offs_slen - str_slen,str))
{
return BUGBUG64TRUNCATE(int, offs + offs_slen - str_slen);
return truncate_cast(int,offs + offs_slen - str_slen);
}
offs += BUGBUG64TRUNCATE(int, offs_slen + 1);
offs += truncate_cast(int,offs_slen + 1);
if (idx) (*idx)++;
}
@ -316,7 +317,7 @@ int DefineList::addn(const TCHAR *name, size_t maxvallen, const TCHAR *value)
extern void quit();
if (g_display_errors)
{
PrintColorFmtMsg_ERR(_T("\nInternal compiler error #12345: DefineList malloc(%lu) failed.\n"), BUGBUG64TRUNCATE(unsigned long,cbVal));
PrintColorFmtMsg_ERR(_T("\nInternal compiler error #12345: DefineList malloc(%lu) failed.\n"), truncate_cast(unsigned long,cbVal));
}
quit();
}

View file

@ -456,8 +456,8 @@ void create_code_page_string(TCHAR *buf, size_t len, UINT code_page)
if (!g_nrt_iconv_narrowloc) NSISRT_Initialize(); // For winchar.cpp unit test
switch(code_page)
{
case CP_ACP: _sntprintf(buf, len, _T("%") NPRINs, iconv_ACP); return;
case CP_OEMCP: _sntprintf(buf, len, _T("%") NPRINs, iconv_OEM); return;
case CP_ACP: _sntprintf(buf, len, _T("%") NPRIns, iconv_ACP); return;
case CP_OEMCP: _sntprintf(buf, len, _T("%") NPRIns, iconv_OEM); return;
case CP_UTF8: _sntprintf(buf, len, _T("UTF-8")); return;
case 1200: // UTF16LE
case 1201: // UTF16BE

View file

@ -140,7 +140,7 @@ int WinStdIO_wprintf(const wchar_t*Fmt, ...);
#define _vftprintf WinStdIO_vfwprintf
#endif // ~MAKENSIS
#else
int RunChildProcessRedirected(LPCWSTR cmd);
int RunChildProcessRedirected(LPCSTR cmd);
#endif // ~_UNICODE
#define ResetPrintColor() FlushOutputAndResetPrintColor() // For reset ONLY, use PrintColorFmtMsg(0,NULL ...
#define SetPrintColorWARN() PrintColorFmtMsg(1|0x10, NULL, (va_list)NULL)
@ -274,10 +274,28 @@ FILE* my_fopen(const TCHAR *path, const char *mode);
// 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;
template <class T> inline T align_to_512(const T x) { return (x+511) & ~511; }
// 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
if (sizeof(T) > sizeof(R)) assert(t <= (T)(~((R)0))); // BUGBUG: What if R is a signed type?
return (R) t;
}
template<class R, class T> inline R debugtruncate_cast(T t,const char*f,unsigned int l) {
#ifdef MAKENSIS
if (sizeof(T) > sizeof(R) && !( (t <= (T)(~((R)0))) )) {
_tprintf(_T("unsafe truncate_cast: %") NPRIns _T(":%u\n"),f,l);
if (sizeof(T) <= sizeof(void*)) _tprintf(_T("\t0x%p > %0xp\n"),(void*)(UINT_PTR)(t),(void*)(UINT_PTR)(~((R)0)));
}
#endif
return internaltruncate_cast<R>(t);
}
#if defined(DEBUG) || defined(_WIN64) // Always enabled for experimental 64-bit builds
#define truncate_cast(ret_t,input) debugtruncate_cast<ret_t>((input),__FILE__,__LINE__)
#else
#define truncate_cast(ret_t,input) internaltruncate_cast<ret_t>((input))
#endif
// ================
// ResourceManagers

View file

@ -96,9 +96,28 @@ void writer_sink::write_growbuf(const IGrowBuf *b)
write_data(b->get(), b->getlen());
}
namespace hlp {
template<class T> static inline bool issigned() { return T(-1) < T(0); }
template<class T> static inline bool issigned(const T&t) { return issigned<T>(); }
}
void growbuf_writer_sink::write_data(const void *data, const size_t size)
{
m_buf->add(data, BUGBUG64TRUNCATE(int, size));
// TODO: Replace all of this with a simple call when GrowBuf is changed to use size_t
if (sizeof(size) == sizeof(sink_type::size_type) && hlp::issigned(size) == hlp::issigned<sink_type::size_type>())
{
m_buf->add(data, truncate_cast(sink_type::size_type, size));
}
else
{
size_t left = size;
sink_type::size_type cbmaxadd = INT_MAX, cb;
for (char *p = (char *) data; left; p += cb, left -= cb)
{
cb = left >= (size_t) cbmaxadd ? cbmaxadd : (sink_type::size_type) left;
m_buf->add(p, cb);
}
}
}
void file_writer_sink::write_data(const void *data, const size_t size)
@ -114,6 +133,6 @@ void file_writer_sink::write_data(const void *data, const size_t size)
void crc_writer_sink::write_data(const void *data, const size_t size)
{
*m_crc = CRC32(*m_crc, (const unsigned char *) data, BUGBUG64TRUNCATE(unsigned int, size));
*m_crc = CRC32(*m_crc, (const unsigned char *) data, size);
}
#endif

View file

@ -55,12 +55,13 @@ protected:
class growbuf_writer_sink : public writer_sink {
public:
growbuf_writer_sink(IGrowBuf *buf, bool build_unicode) : m_buf(buf) { m_build_unicode=build_unicode; }
typedef IGrowBuf sink_type;
growbuf_writer_sink(sink_type *buf, bool build_unicode) : m_buf(buf) { m_build_unicode=build_unicode; }
virtual void write_data(const void *data, const size_t size);
private:
IGrowBuf *m_buf;
sink_type *m_buf;
};