Menu

#1115 Invalid disk space size available over 4TB

3.0 Alpha Series
closed-fixed
nobody
None
6
2015-05-14
2015-04-08
No

On the modern UI directory page it reports disk space needed and available can report wrong at times

My installer needs 42GB to install and the hard drive i am installing to has over 4TB free

It is reporting that i have 5.6GB free and will not let me click install as the space is to small

I bloated my hard drive by copying over some data just to have less than 4TB free and then it reported that i had 3950GB free and i could continue.

From what i can tell this is due to the usage of a 32bit int for the disk space calculation here. Hopefully there is a way to make this use 64bit address space so we can report larger drives or change the math to use MB or GB instead of KB to get more bits to use.

There are some drive space calculation plugin's that use system::Int64Op to find drive size so maybe similar methods can be used here?

Discussion

  • Mathew Saunders

    Mathew Saunders - 2015-04-08

    Similar issue was reported in 2.44

    https://sourceforge.net/p/nsis/bugs/896/

     
  • Anders

    Anders - 2015-04-09

    The free space is read as a 64-bit number but is then right shifted by 10 to convert to KB and then stored in a 32-bit variable.

    CHAR buf1[100], buf2[100];
    UINT64 bignums[] = { 0x300ffffffffULL, 0x3FFffffffffULL, 0x40000000000ULL, 0x40000000999ULL, 0x40000001025ULL, 0x400ffffffffULL };
    for (UINT i = 0; i < ARRAYSIZE(bignums); ++i)
    {
        UINT64 big = bignums[i];
        UINT32 n32 = (int)(big >> 10);
        StrFormatByteSize64A(big, buf1, ARRAYSIZE(buf1));
        StrFormatByteSize64A(((UINT64)n32) << 10, buf2, ARRAYSIZE(buf2));
        printf("64: %13I64u bytes (%hs) -> 32: %10u KiB (%hs)\n", big, buf1, n32, buf2);
    }
    

    This prints

    64: 3302829850623 bytes (3,00 TB) -> 32: 3225419775 KiB (3,00 TB)
    64: 4398046511103 bytes (3,99 TB) -> 32: 4294967295 KiB (3,99 TB)
    64: 4398046511104 bytes (4,00 TB) -> 32:          0 KiB (0 bytes)
    64: 4398046513561 bytes (4,00 TB) -> 32:          2 KiB (2,00 KB)
    64: 4398046515237 bytes (4,00 TB) -> 32:          4 KiB (4,00 KB)
    64: 4402341478399 bytes (4,00 TB) -> 32:    4194303 KiB (3,99 GB)
    

    I guess when NSIS was originally written even having gigabytes of free space was a luxury. All jokes aside, doing 64-bit math and then displaying the result on Win95 without using the CRT is not fun which is probably why it was designed like this.

     
  • Mathew Saunders

    Mathew Saunders - 2015-04-09

    Thank you for looking in to this, Can this be fixed then? 6TB drives are not that expensive at this point, seems like large drives are becoming more and more normal. I think it could become a bigger problem for other people.

     
  • Jason

    Jason - 2015-04-17

    We could leave the 64 bit value as is, and then when we do the formatting for MB, GB, etc, we do a compare for this 32 bit overflow, and bit shift it to convert to KB, MB, or whatever. So something like this (my bit shifting and limits are probably wrong):

    UINT64 space64 = GetFreeSpace();
    UINT64 32limits64[] = { 0x3ffffffffffULL, 0x7ffffffffffULL, 0xbffffffffffULL, 0xfffffffffffULL, 0x3fffffffffffULL, 0x7fffffffffffULL};
    UINT8 shiftbits[] = { 10, 20, 30, 40, 50, 60 };
    TCHAR unit[] = { 'K', 'M', 'G', 'T', 'P', 'E' };
    int i = 0;

    while (i < ARRAYSIZE(32limits64))
    {
    if (32limits64[i] > space64)
    {
    break;
    }
    i++;
    }
    wsprintf(somebuffer, _T("%u %sB"), (UINT32)(space64 >> shiftbits[i]), unit[i]);

    This counts up so the bigger the free space the longer it takes. The logic can be swapped too, so the bigger the free space the less time it takes.

     

    Last edit: Jason 2015-04-17
    • Anders

      Anders - 2015-05-14

      The size texts are in the language files and we currently don't have texts for anything beyond GiB. For smaller sizes with also want to maintain the "floating point" calculation...

       
  • Anders

    Anders - 2015-05-14
    • status: unread --> closed-fixed
     
  • Anders

    Anders - 2015-05-14

    It now uses the full 64 bits for the size check while the display code is limited to 4194303 TiB and will display the wrong value if you have more free space than that.

     

Log in to post a comment.