NSIS GetVolumeInformation Results

0

Ok I found this code from another question asked and I'm a newbie for NSIS. Question Below

!define FILE_SUPPORTS_ENCRYPTION 0x00020000
!define FILE_READ_ONLY_VOLUME 0x00080000
!define FILE_VOLUME_QUOTAS 0x00000020

!macro MakeBitFlagYesNo flags bit outvar
IntOp ${outvar} ${flags} & ${bit}
${IfThen} ${outvar} <> 0 ${|} StrCpy ${outvar} "Yes" ${|}
${IfThen} ${outvar} == 0 ${|} StrCpy ${outvar} "No" ${|}
!macroend

StrCpy $0 "c:\"
System::Call 'Kernel32::GetVolumeInformation(t "$0",t,i ${NSIS_MAX_STRLEN},*i,*i,*i.r1,t,i ${NSIS_MAX_STRLEN})i.r0'
${If} $0 <> 0
    !insertmacro MakeBitFlagYesNo $1 ${FILE_SUPPORTS_ENCRYPTION} $2
    !insertmacro MakeBitFlagYesNo $1 ${FILE_READ_ONLY_VOLUME} $3
    !insertmacro MakeBitFlagYesNo $1 ${FILE_VOLUME_QUOTAS} $4
    MessageBox mb_ok "flags=$1 $\nFILE_SUPPORTS_ENCRYPTION=$2$\nFILE_READ_ONLY_VOLUME=$3$\nFILE_VOLUME_QUOTAS=$4"
${EndIf}

Here is what I need to get:

Drive Volume Label:

File System: (Fat32, NTFS, exFat, ...)

Disk Capacity: (7.27TB, 5.59TB, ...)

Free Space: (4.62TB , 632GB, ...)

Allocation Unit Size: (4096b, 16kb, 32kb, ...)

and then I need to use that info in a if then statement Just not sure how to turn the above code and results into code list below.

I have tried searching google about NSIS and GetVolumeInformation, and with the GetVolumeInformation I could not find out how to get and read results anywhere.

${If} $File_System <> "NTFS"
${EndIf}

${If} $Disk_Capacity < "1.86TB"
${EndIf}

${If} $Free_Space < "1.25TB"
${EndIf}

${If} $Allocation_Unit_Size <> "4096 bytes"
${EndIf}

MessageBox mb_ok "$Drive_Volume_Label$\n$File_System$\n$Disk_Capacity$\n$Free_Space$\n$Allocation_Unit_Size"

And if you could post the answer code for me and then point me where you got the info (the explanation of the) code. This help me learn the code faster if I know what its doing for what I need.

Thanks, Albert

nsis
ntfs
asked on Stack Overflow Oct 8, 2017 by Albert Mulder • edited Oct 8, 2017 by Albert Mulder

1 Answer

0

The code in the answer you found does actually return the name of the file system and then it goes on to tell you that that is probably not the best way to do things. You should use the file system flags if possible. Case in point, Microsofts new file system ReFS supports some of the NTFS features and adds some new reliability features.

!include LogicLib.nsh
StrCpy $9 "c:\"
System::Call 'Kernel32::GetVolumeInformation(t "$9",t.r3,i ${NSIS_MAX_STRLEN},*i,*i,*i.r1,t.r2,i ${NSIS_MAX_STRLEN})i.r0'
${If} $0 <> 0
    IntFmt $1 "%#.8x" $1
    MessageBox MB_OK " FileSystemFlags=$1 $\n FileSystemName=$2 $\n VolumeName=$3"

    ${If} $2 == "NTFS"
        MessageBox MB_OK "$9 is NTFS"
    ${Else}
        MessageBox MB_OK "$9 is $2 and not NTFS but hopefully you don't care"
    ${EndIf}
${EndIf}

Your other properties are not exposed by this function which would be obvious if you looked at its documentation on MSDN.

!include LogicLib.nsh
StrCpy $9 "c:\"
System::Call 'Kernel32::GetDiskFreeSpaceEx(t "$9", *l.r1, *l.r2, *l.r3)i.r0' ; This function does not work on Windows 95
${If} $0 <> 0
    MessageBox MB_OK " FreeBytesAvailable=$1 $\n TotalNumberOfBytes=$2 $\n TotalNumberOfFreeBytes=$3"

    System::Call 'ShLwApi::StrFormatByteSizeW(l $1, w.r4, i ${NSIS_MAX_STRLEN})'
    MessageBox MB_OK "Friendly FreeBytesAvailable: $4" ; For display in UI only!

    !define /math MYSIZE 0x100000 * 666 ; 666 MiB
    ${If} $1 L>= ${MYSIZE}
        MessageBox MB_OK "Disk quota on $9 allows you to write at least ${MYSIZE} bytes on this volume"
    ${Else}
        MessageBox MB_OK|MB_ICONSTOP "Not enough space on volume, ${MYSIZE} bytes required!"
        Quit
    ${EndIf}
${EndIf}

NSIS already provides a directory page that checks the disk space, use that if possible. Note: You cannot compare numbers of different scales (TB vs GB etc.), you must compare a 64-bit count of bytes.

By allocation unit I assume you are talking about the cluster size?

!include LogicLib.nsh
StrCpy $9 "c:\"
System::Call 'Kernel32::GetDiskFreeSpace(t "$9", *i.r1, *i.r2, *i, *i)i.r0'
${If} $0 <> 0
    IntOp $1 $1 * $2
    System::Call 'ShLwApi::StrFormatByteSizeW(l $1, w.r3, i ${NSIS_MAX_STRLEN})'
    MessageBox MB_OK "Cluster size: $3 ($1 bytes)"

    ${If} 4096 <> $1
      ; ...
    ${EndIf}
${EndIf}

(The reported cluster size is probably the logical size, not the physical size)

answered on Stack Overflow Oct 8, 2017 by Anders • edited Oct 8, 2017 by Anders

User contributions licensed under CC BY-SA 3.0