From: <and...@us...> - 2022-12-04 18:52:21
|
Revision: 7372 http://sourceforge.net/p/nsis/code/7372 Author: anders_k Date: 2022-12-04 18:52:18 +0000 (Sun, 04 Dec 2022) Log Message: ----------- Further !uninstfinalize big uninstaller fixes (bug #1279) Modified Paths: -------------- NSIS/trunk/Docs/src/history.but NSIS/trunk/Source/build.cpp NSIS/trunk/Source/build.h NSIS/trunk/Source/mmap.cpp NSIS/trunk/Source/mmap.h NSIS/trunk/Source/script.cpp NSIS/trunk/Source/util.cpp NSIS/trunk/Source/util.h Modified: NSIS/trunk/Docs/src/history.but =================================================================== --- NSIS/trunk/Docs/src/history.but 2022-10-24 15:55:02 UTC (rev 7371) +++ NSIS/trunk/Docs/src/history.but 2022-12-04 18:52:18 UTC (rev 7372) @@ -14,7 +14,7 @@ \b Added \R{assert}{!assert} -\b Fixed \cw{!uninstfinalize} bug on large uninstallers +\b Fixed \cw{!uninstfinalize} bug on large uninstallers (\W{http://sf.net/p/nsis/bugs/1279}{bug #1279}) \b Fixed creation of missing special folders on old Windows versions where SHGetFolderPath is not available. Modified: NSIS/trunk/Source/build.cpp =================================================================== --- NSIS/trunk/Source/build.cpp 2022-10-24 15:55:02 UTC (rev 7371) +++ NSIS/trunk/Source/build.cpp 2022-12-04 18:52:18 UTC (rev 7372) @@ -228,7 +228,7 @@ uninstall_mode=0; uninstall_size_full=0; - uninstall_size=-1; + uninstall_size=UINT_MAX; memset(&build_uninst,-1,sizeof(build_uninst)); @@ -2664,7 +2664,7 @@ build_optimize_datablock=0; - int data_block_size_before_uninst = build_datablock.getlen(); + UINT data_block_size_before_uninst = build_datablock.getlen(); RET_UNLESS_OK( uninstall_generate() ); @@ -2880,7 +2880,7 @@ unsigned int dbsize; UINT64 dbsizeu; dbsize = build_datablock.getlen(); - if (uninstall_size>0) dbsize -= uninstall_size; + if (uninstall_size > 0 && uninstall_size < UINT_MAX) dbsize -= uninstall_size; if (build_compress_whole) { dbsizeu = dbsize; @@ -2893,17 +2893,17 @@ INFO_MSG(_T("Install data: %10u%") NPRIs _T(" / %u%") NPRIs _T("\n"), cs.UInt(),cs.Scale(),us.UInt(),us.Scale()); // "123 / 456 bytes" or "123 KiB / 456 MiB" } - UINT future = (build_crcchk ? sizeof(int) : 0) + (uninstall_size > 0 ? uninstall_size_full : 0); + UINT future = (build_crcchk ? sizeof(int) : 0) + (uninstall_size > 0 && uninstall_size < UINT_MAX ? uninstall_size_full : 0); UINT maxsize = (~(UINT)0) - (total_usize + future), totsizadd = dbsizeu < maxsize ? (UINT)dbsizeu : maxsize; total_usize += totsizadd; // Might not be accurate, it is more important to not overflow the additions coming up } - if (uninstall_size>=0) + if (uninstall_size < UINT_MAX) { if (build_compress_whole) - INFO_MSG(_T("Uninstall code+data: (%d bytes)\n"),uninstall_size_full); + INFO_MSG(_T("Uninstall code+data: (%u bytes)\n"),uninstall_size_full); else - INFO_MSG(_T("Uninstall code+data: %6d / %d bytes\n"),uninstall_size,uninstall_size_full); + INFO_MSG(_T("Uninstall code+data: %10u / %u bytes\n"),uninstall_size,uninstall_size_full); total_usize += uninstall_size_full; } @@ -3300,38 +3300,46 @@ if (start_offset) { TCHAR* fpath; - unsigned long in_len; if (!(fpath = create_tempfile_path())) { ERROR_MSG(_T("Error: can't get temporary path\n")); return PS_ERROR; } - size_t ret_size = write_octets_to_file(fpath, (unsigned char*)udata.get(0, udata.getlen()), udata.getlen()); - udata.release(); - if ((size_t)udata.getlen() != ret_size) + MANAGE_WITH(fpath, free); + FILE *hfile = FOPEN(fpath, ("wb")); + if (!hfile) { + ERROR_MSG(_T("Error: failed opening file \"%") NPRIs _T("\"\n"), fpath); + return PS_ERROR; + } + int succ = udata.write_to_external_file(hfile); + fclose(hfile); + if (!succ) + { ERROR_MSG(_T("Error: can't write %d bytes to output\n"), udata.getlen()); - free(fpath); return PS_ERROR; } + udata.clear(); + if (PS_OK != run_postbuild_cmds(postubuild_cmds, fpath, _T("UninstFinalize"))) { - free(fpath); return PS_ERROR; } - BYTE* in_buf = alloc_and_read_file(fpath, in_len); - _tremove(fpath); - free(fpath); - if (!in_buf) + + MMapFile udata_in; + UINT64 udata_size; + if (!(udata_size = udata_in.setfile(fpath))) { - ERROR_MSG(_T("Error: can't read %d bytes from input\n"), in_len); + ERROR_MSG(_T("Error: failed creating mmap of \"%") NPRIs _T("\"\n"), fpath); return PS_ERROR; } - int tmp_offset = add_db_data((char*) in_buf, truncate_cast(int,in_len)); - free(in_buf); - if (tmp_offset < 0) + if (add_db_data(&udata_in) < 0) return PS_ERROR; - uninstall_size_full = in_len; + + assert(NSIS_MAX_EXEFILESIZE <= ~(UINT32)0); + uninstall_size_full = (UINT32) udata_size; + udata_in.clear(); + _tremove(fpath); } else { @@ -3342,11 +3350,8 @@ uninstall_size_full = fh.length_of_all_following_data+(int)m_unicon_size; } - udata.clear(); - // compressed size uninstall_size=build_datablock.getlen()-uninstdata_offset; - SCRIPT_MSG(_T("Done!\n")); } #endif Modified: NSIS/trunk/Source/build.h =================================================================== --- NSIS/trunk/Source/build.h 2022-10-24 15:55:02 UTC (rev 7371) +++ NSIS/trunk/Source/build.h 2022-12-04 18:52:18 UTC (rev 7372) @@ -619,7 +619,7 @@ header build_header, build_uninst, *cur_header; int uninstall_mode; // Are we in uninstall mode? Acts like a bool. - int uninstall_size,uninstall_size_full; + UINT32 uninstall_size,uninstall_size_full; int uninstaller_writes_used; TCHAR build_output_filename[1024]; Modified: NSIS/trunk/Source/mmap.cpp =================================================================== --- NSIS/trunk/Source/mmap.cpp 2022-10-24 15:55:02 UTC (rev 7371) +++ NSIS/trunk/Source/mmap.cpp 2022-12-04 18:52:18 UTC (rev 7372) @@ -28,6 +28,32 @@ #endif #include "util.h" + +// ===== +// IMMap +// ===== + +bool IMMap::write_to_external_file(FILE*file, UINT64 size) +{ + if (~(size&0) == size) size = getsize(); + if (getmaxoffset() < size) + return false; + + UINT64 left = size, written = 0; + int offset = 0; // TODO: this will be removed after converting the mapping code to 64bit. + while (left > 0 && offset >= 0) + { + size_t chunksize = (size_t) STD_MIN(left, (UINT64) 1 << 20); + void *view = getmore(offset, chunksize); + written += fwrite(view, 1, chunksize, file); + release(view, chunksize); + left -= chunksize; + offset += (int)chunksize; + } + return written == size; +} + + // ======== // MMapFile // ======== @@ -34,6 +60,12 @@ int MMapFile::m_iAllocationGranularity = 0; +MMapFile::maxfilesizetype MMapFile::getmaxfilesize() +{ + assert((~(maxfilesizetype)0) > 0); + return (maxfilesizetype) STD_MIN((UINT64) (~(maxfilesizetype)0), (UINT64) Platform_GetMaxFileSize()); +} + MMapFile::MMapFile() { #ifdef _WIN32 @@ -91,10 +123,11 @@ m_bReadOnly = bRO; } +// TODO: Convert to UINT64. Right now the mapping is still limited to 31 bits. #ifdef _WIN32 -int MMapFile::setfile(HANDLE hFile, DWORD dwSize) +int MMapFile::internalsetfile(HANDLE hFile, DWORD dwSize) #else -int MMapFile::setfile(int hFile, DWORD dwSize) +int MMapFile::internalsetfile(int hFile, DWORD dwSize) #endif { clear(); @@ -227,17 +260,82 @@ } } +#ifdef _WIN32 +bool MMapFile::setfile(HANDLE hFile, UINT64 size) +{ + maxfilesizetype maxsize = getmaxfilesize(); + return size <= maxsize && internalsetfile(hFile, (maxfilesizetype) size); +} + +HANDLE MMapFile::openfilehelper(const TCHAR*fpath, UINT64 &size) +{ + HANDLE hFile = CreateFile(fpath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN, NULL); + if (hFile != INVALID_HANDLE_VALUE) + { + ULARGE_INTEGER size64; + if (GetFileSize64(hFile, size64)) + size = size64.QuadPart; + else + CloseHandle(hFile), hFile = INVALID_HANDLE_VALUE; + } + return hFile; +} +#else +bool MMapFile::setfile(FILE*hFile, UINT64 size) +{ + maxfilesizetype maxsize = getmaxfilesize(); + return size <= maxsize && internalsetfile(fileno(hFile), (maxfilesizetype) size); +} + +FILE* MMapFile::openfilehelper(const TCHAR*fpath, UINT64 &size) +{ + FILE *hFile = FOPEN(fpath, ("rb")); + if (hFile) + { + UINT64 size64 = get_file_size64(hFile); + if (size64 != invalid_file_size64) + size = size64; + else + fclose(hFile), hFile = 0; + } + return hFile; +} +#endif + +UINT64 MMapFile::setfile(const TCHAR*fpath) +{ + UINT64 size = 0; +#ifdef _WIN32 + HANDLE hFile = openfilehelper(fpath, size); + if (hFile != INVALID_HANDLE_VALUE) + { + if (!setfile(hFile, size)) size = 0; + CloseHandle(hFile); + } +#else + FILE *hFile = openfilehelper(fpath, size); + if (hFile) + { + if (!setfile(hFile, size)) size = 0; + // NOTE: mmap() requires the file to stay open for get(), otherwise + // get() will fail with errno code EBADFD (bad file descriptor). + //fclose(hFile); + } +#endif + return size; +} + int MMapFile::getsize() const { return m_iSize; } -void *MMapFile::get(int offset, int size) const +void *MMapFile::get(int offset, size_t size) const { return get(offset, &size); } -void *MMapFile::get(int offset, int *sizep) const +void *MMapFile::get(int offset, size_t *sizep) const { if (!sizep) return NULL; @@ -244,9 +342,9 @@ assert(!m_pView); - int size = *sizep; + size_t size = *sizep; - if (!m_iSize || offset + size > m_iSize) + if (!m_iSize || offset + (int)size > m_iSize) // TODO: once m_iSize and offset is converted to unsigned 64bit, this typecast will disappear { extern void quit(); extern int g_display_errors; if (g_display_errors) @@ -284,7 +382,7 @@ return (void *)((char *)m_pView + offset - alignedoffset); } -void *MMapFile::getmore(int offset, int size) const +void *MMapFile::getmore(int offset, size_t size) const { void *pView; void *pViewBackup = m_pView; @@ -313,7 +411,7 @@ m_pView = NULL; } -void MMapFile::release(void *pView, int size) +void MMapFile::release(void *pView, size_t size) { if (!pView) return; @@ -328,7 +426,7 @@ #endif } -void MMapFile::flush(int num) +void MMapFile::flush(size_t num) { if (m_pView) #ifdef _WIN32 @@ -359,19 +457,19 @@ return m_iSize; } -void *MMapFake::get(int offset, int size) const +void *MMapFake::get(int offset, size_t size) const { return get(offset, &size); } -void *MMapFake::get(int offset, int *size) const +void *MMapFake::get(int offset, size_t *size) const { - if (!size || (offset + *size > m_iSize)) + if (!size || (offset + (int)*size > m_iSize)) // TODO: once m_iSize and offset is converted to unsigned 64bit, this typecast will disappear return NULL; return (void *)(m_pMem + offset); } -void *MMapFake::getmore(int offset, int size) const +void *MMapFake::getmore(int offset, size_t size) const { return get(offset, size); } @@ -378,10 +476,10 @@ void MMapFake::resize(int n) {} void MMapFake::release() {} -void MMapFake::release(void *p, int size) {} +void MMapFake::release(void *p, size_t size) {} void MMapFake::clear() {} void MMapFake::setro(BOOL b) {} -void MMapFake::flush(BOOL b) {} +void MMapFake::flush(size_t b) {} // ======= // MMapBuf @@ -458,15 +556,15 @@ return get(0, m_alloc); } -void *MMapBuf::get(int offset, int *sizep) const +void *MMapBuf::get(int offset, size_t *sizep) const { if (!sizep) return NULL; - int size = *sizep; + size_t size = *sizep; return get(offset, size); } -void *MMapBuf::get(int offset, int size) const +void *MMapBuf::get(int offset, size_t size) const { if (m_gb_u) return m_fm.get(offset, size); @@ -473,7 +571,7 @@ return (void *) ((char *) m_gb.get() + offset); } -void *MMapBuf::getmore(int offset, int size) const +void *MMapBuf::getmore(int offset, size_t size) const { if (m_gb_u) return m_fm.getmore(offset, size); @@ -486,7 +584,7 @@ m_fm.release(); } -void MMapBuf::release(void *pView, int size) +void MMapBuf::release(void *pView, size_t size) { if (m_gb_u) m_fm.release(pView, size); @@ -498,7 +596,7 @@ m_fm.clear(); } -void MMapBuf::flush(int num) +void MMapBuf::flush(size_t num) { if (m_gb_u) m_fm.flush(num); Modified: NSIS/trunk/Source/mmap.h =================================================================== --- NSIS/trunk/Source/mmap.h 2022-10-24 15:55:02 UTC (rev 7371) +++ NSIS/trunk/Source/mmap.h 2022-12-04 18:52:18 UTC (rev 7372) @@ -21,6 +21,7 @@ #include "Platform.h" #include "growbuf.h" +#include "tchar.h" #ifndef _WIN32 #include <cstdio> // for FILE* @@ -30,17 +31,22 @@ class IMMap { public: + typedef DWORD maxfilesizetype; // TODO: Change to UINT64 + static inline UINT64 getmaxoffset() { return INT_MAX; } // NSIS offset limit is 31 bits right now + virtual void resize(int newlen)=0; virtual int getsize() const=0; - virtual void *get(int offset, int size) const=0; - virtual void *get(int offset, int *size) const=0; - virtual void *getmore(int offset, int size) const=0; + virtual void *get(int offset, size_t size) const=0; + virtual void *get(int offset, size_t *size) const=0; + virtual void *getmore(int offset, size_t size) const=0; virtual void release()=0; - virtual void release(void *view, int size)=0; + virtual void release(void *view, size_t size)=0; virtual void clear()=0; virtual void setro(BOOL bRO)=0; - virtual void flush(int num)=0; + virtual void flush(size_t num)=0; virtual ~IMMap() {} + + virtual bool write_to_external_file(FILE*file, UINT64 size = ~(UINT64)0); }; class MMapFile : public IMMap @@ -50,6 +56,8 @@ void operator=(const MMapFile&); public: + static DWORD getmaxfilesize(); + MMapFile(); virtual ~MMapFile(); @@ -68,7 +76,7 @@ * Creates the memory mapping object of the file with a mapping size. * * @param hFile The handle to the opened file. - * @param dwSize The size of the memory mapped object. You cannot set + * @param size The size of the memory mapped object. You cannot set * this value to zero like with CreateFileMapping() because it will * immediately return. Most likely, you want to set it to the size * of the file unless you want to only map a part of the file on @@ -76,11 +84,24 @@ * @return Returns 1 on success, 0 on failure. */ #ifdef _WIN32 - int setfile(HANDLE hFile, DWORD dwSize); + bool setfile(HANDLE hFile, UINT64 size); +private: + int internalsetfile(HANDLE hFile, DWORD dwSize); #else - int setfile(int hFile, DWORD dwSize); + bool setfile(FILE*hFile, UINT64 size); +private: + int internalsetfile(int hFile, DWORD dwSize); #endif +public: + UINT64 setfile(const TCHAR*fpath); + +#ifdef _WIN32 + static HANDLE openfilehelper(const TCHAR*fpath, UINT64 &size); +#else + static FILE* openfilehelper(const TCHAR*fpath, UINT64 &size); +#endif + /** * Resize the memory mapping of the file. Used when the filesize has * changed. When setfile has not been called previously, then it will @@ -104,7 +125,7 @@ * @param offset The offset from the beginning of the file. * @param size The size of the memory map window. */ - void *get(int offset, int size) const; + void *get(int offset, size_t size) const; /** * Set the memory map to a particular offset in the file and return the @@ -115,7 +136,7 @@ * @param sizep [in/out] The size of the memory map window. (In non-Win32 * systems, the new size is written back out.) */ - void *get(int offset, int *sizep) const; + void *get(int offset, size_t *sizep) const; /** * This function sets memory map and just hands you the pointer and @@ -128,7 +149,7 @@ * @param offset The offset from the beginning of the file. * @param size The size of the memory map window. */ - void *getmore(int offset, int size) const; + void *getmore(int offset, size_t size) const; /** * Releases the memory map currently being used. Calls UnMapViewOfFile(). @@ -147,7 +168,7 @@ * @param pView The pointer to somewhere in a MemMapped object. * @param size The size of the object. Used only in non-Win32 systems. */ - void release(void *pView, int size); + void release(void *pView, size_t size); /** * Flushes the contents of the current memory map to disk. Set size to 0 @@ -155,7 +176,7 @@ * * @param num The number of bytes to flush. 0 for everything. */ - void flush(int num); + void flush(size_t num); private: #ifdef _WIN32 @@ -183,16 +204,16 @@ void set(const char *pMem, int iSize); int getsize() const; - void *get(int offset, int size) const; - void *get(int offset, int *size) const; - void *getmore(int offset, int size) const; + void *get(int offset, size_t size) const; + void *get(int offset, size_t *size) const; + void *getmore(int offset, size_t size) const; void resize(int n); void release(); - void release(void *p, int size); + void release(void *p, size_t size); void clear(); void setro(BOOL b); - void flush(BOOL b); + void flush(size_t b); private: const char *m_pMem; @@ -224,13 +245,13 @@ int getsize() const; int getlen() const; void *get() const; - void *get(int offset, int *sizep) const; - void *get(int offset, int size) const; - void *getmore(int offset, int size) const; + void *get(int offset, size_t *sizep) const; + void *get(int offset, size_t size) const; + void *getmore(int offset, size_t size) const; void release(); - void release(void *pView, int size); + void release(void *pView, size_t size); void clear(); - void flush(int num); + void flush(size_t num); protected: static inline int getmodethreshold() { return 16 << 20; } Modified: NSIS/trunk/Source/script.cpp =================================================================== --- NSIS/trunk/Source/script.cpp 2022-10-24 15:55:02 UTC (rev 7371) +++ NSIS/trunk/Source/script.cpp 2022-12-04 18:52:18 UTC (rev 7372) @@ -5302,18 +5302,10 @@ const TCHAR *newfn = newfn_s.c_str(); const TCHAR *filename = file.c_str(); MMapFile mmap; - DWORD len; + UINT64 filesize; #ifdef _WIN32 - HANDLE hFile = CreateFile( - newfn, - GENERIC_READ, - FILE_SHARE_READ, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, - NULL - ); + HANDLE hFile = mmap.openfilehelper(newfn, filesize); if (hFile == INVALID_HANDLE_VALUE) { ERROR_MSG(_T("%") NPRIs _T("File: failed opening file \"%") NPRIs _T("\"\n"),generatecode?_T(""):_T("Reserve"),newfn); @@ -5320,34 +5312,23 @@ return PS_ERROR; } MANAGE_WITH(hFile, CloseHandle); - - len = GetFileSize(hFile, NULL); - if (len && !mmap.setfile(hFile, len)) +#else + FILE *hFile = mmap.openfilehelper(newfn, filesize); + if (!hFile) { - ERROR_MSG(_T("%") NPRIs _T("File: failed creating mmap of \"%") NPRIs _T("\"\n"),generatecode?_T(""):_T("Reserve"),newfn); - return PS_ERROR; - } -#else // !_WIN32 - int fd = OPEN(newfn, O_RDONLY); - if (fd == -1) - { ERROR_MSG(_T("%") NPRIs _T("File: failed opening file \"%") NPRIs _T("\"\n"),generatecode?_T(""):_T("Reserve"),newfn); return PS_ERROR; } - MANAGE_WITH(fd, close); // Will auto-close(2) fd - - struct stat s; - if (fstat(fd, &s)) { - ERROR_MSG(_T("%") NPRIs _T("File: failed stating file \"%") NPRIs _T("\"\n"),generatecode?_T(""):_T("Reserve"),newfn); - return PS_ERROR; - } - len = (DWORD) s.st_size; - if (len && !mmap.setfile(fd, len)) + MANAGE_WITH(hFile, fclose); + const int fd = fileno(hFile); +#endif + if (!mmap.setfile(hFile, filesize)) { ERROR_MSG(_T("%") NPRIs _T("File: failed creating mmap of \"%") NPRIs _T("\"\n"),generatecode?_T(""):_T("Reserve"),newfn); return PS_ERROR; } -#endif // ~_WIN32 + DWORD len = (DWORD) filesize; + if (len != filesize) len = 0xffffffffUL; if (generatecode&1) section_add_size_kb((len+1023)/1024); @@ -5402,9 +5383,9 @@ DWORD s=getcurdbsize()-last_build_datablock_used; if (s) s-=4; if (s != len) - SCRIPT_MSG(_T(" %d/%d bytes\n"),s,len); + SCRIPT_MSG(_T(" %u/%u bytes\n"),s,len); else - SCRIPT_MSG(_T(" %d bytes\n"),len); + SCRIPT_MSG(_T(" %u bytes\n"),len); } if (generatecode) Modified: NSIS/trunk/Source/util.cpp =================================================================== --- NSIS/trunk/Source/util.cpp 2022-10-24 15:55:02 UTC (rev 7371) +++ NSIS/trunk/Source/util.cpp 2022-12-04 18:52:18 UTC (rev 7372) @@ -61,7 +61,6 @@ #ifdef _WIN32 -bool GetFileSize64(HANDLE hFile, ULARGE_INTEGER &uli); static char* CreateMappedFileView(LPCTSTR Path, DWORD FAccess, DWORD FShare, DWORD FMode, DWORD PProtect, DWORD MAccess, size_t &FSize) { char *pView = NULL, restoreGLE = false, validSize; @@ -641,28 +640,24 @@ return f; } +#include <sys/types.h> +#include <sys/stat.h> #if (defined(_MSC_VER) && (_MSC_VER >= 1200)) || defined(__MINGW32__) #include <io.h> -static UINT64 get_file_size64(FILE *f) +UINT64 get_file_size64(FILE *f) { 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) +#else +UINT64 get_file_size64(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 + UINT64 result = invalid_file_size64; + // 32bit plaforms require _FILE_OFFSET_BITS = 64 to correctly return the size +#if _XOPEN_SOURCE >= 500 || _POSIX_C_SOURCE >= 200112L struct stat st; - if (0 == fstat(fileno(f), &st) && st.st_size <= (sizeof(st.st_size) >= 8 ? (off_t)0xffffffffUL : LONG_MAX)) - result = (UINT32) st.st_size; + if (0 == fstat(fileno(f), &st) && st.st_size <= (sizeof(st.st_size) >= 8 ? (off_t)0x7fffffffffffffffLL : LONG_MAX)) + result = (UINT64) st.st_size; #else long cb, restoreseek = true; fpos_t orgpos; @@ -674,7 +669,42 @@ #endif return result; } +#endif +UINT32 get_file_size32(FILE *f) +{ + UINT32 result = invalid_file_size32; +#if _XOPEN_SOURCE >= 500 || _POSIX_C_SOURCE >= 200112L + struct stat st; + if (0 == fstat(fileno(f), &st) && st.st_size <= (sizeof(st.st_size) >= 8 ? (off_t)0xffffffffUL : LONG_MAX)) + result = (UINT32) st.st_size; +#else + UINT64 size64 = get_file_size64(f); + if (size64 <= 0xffffffffUL && invalid_file_size64 != size64) + result = (UINT32) size64; +#endif + return result; +} + +UINT64 Platform_GetMaxFileSize() +{ +#ifdef _WIN32 + return ~(UINT64)0; +#elif _XOPEN_SOURCE >= 500 || _POSIX_C_SOURCE >= 200112L + struct stat st; + if (sizeof(st.st_size) >= 8) + { +#ifdef LLONG_MAX + return (UINT64)(off_t)LLONG_MAX; +#endif + const UINT64 sixthree = (~(UINT64)0) >> 1; + return (off_t)sixthree > 0 ? sixthree : (UINT32)(off_t)0xffffffffUL; + } + return (UINT64)(off_t)LONG_MAX; +#endif + return (UINT)INT_MAX; +} + BYTE* alloc_and_read_file(FILE *f, unsigned long &size) { BYTE *result = 0, *mem = 0; Modified: NSIS/trunk/Source/util.h =================================================================== --- NSIS/trunk/Source/util.h 2022-10-24 15:55:02 UTC (rev 7371) +++ NSIS/trunk/Source/util.h 2022-12-04 18:52:18 UTC (rev 7372) @@ -317,6 +317,7 @@ #define OPEN(a, b) my_open(a, b) #else // _WIN32 +bool GetFileSize64(HANDLE hFile, ULARGE_INTEGER &uli); #define my_convert(x) (x) #define my_convert_free(x) @@ -328,9 +329,11 @@ FILE* my_fopen(const TCHAR *path, const char *mode); #define FOPEN(a, b) my_fopen((a), (b)) +UINT64 Platform_GetMaxFileSize(); const UINT32 invalid_file_size32 = ~ (UINT32) 0; UINT32 get_file_size32(FILE *f); const UINT64 invalid_file_size64 = ~ (UINT64) 0; +UINT64 get_file_size64(FILE *f); 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. |