例子:获取硬盘和分区列表
优质
小牛编辑
137浏览
2023-12-01
引用 DriveList.nsi 的内容:
!include MUI2.nsh !include FileFunc.nsh !include WordFunc.nsh Name "DriveList" OutFile "DriveList.exe" Var DISK_LIST Var PART_LIST Var REFRESHBTN1 Var REFRESHBTN2 Var PriPtNumber Var ExtPtNumber !define PropertyStandardQuery 0 !define StorageDeviceProperty 0 !define OPEN_EXISTING 3 !define MAX_DISKS 24 !define MAX_PATH 260 !define GENERIC_READ 0x80000000 !define FILE_SHARE_READ 0x00000001 !define FILE_SHARE_WRITE 0x00000002 !define FILE_FLAG_NO_BUFFERING 0x20000000 !define FILE_FLAG_WRITE_THROUGH 0x80000000 !define IOCTL_STORAGE_QUERY_PROPERTY 0x002D1400 !define IOCTL_DISK_GET_DRIVE_GEOMETRY 0x00070000 !define IOCTL_DISK_GET_DRIVE_LAYOUT 0x0007400C Page custom PageInit !insertmacro MUI_LANGUAGE "SimpChinese" Section -Main SectionEnd Function PageInit !insertmacro MUI_HEADER_TEXT "磁盘分区浏览" "请先选择磁盘,然后可在分区列表中查看该磁盘的所有分区。" nsDialogs::Create 1018 Pop $0 ${If} $0 == error Abort ${EndIf} ${NSD_CreateLabel} 0u 0u 300u 8u "磁盘列表:" Pop $0 ${NSD_CreateDroplist} 0u 13u 230u 70u "" Pop $DISK_LIST ${NSD_OnChange} $DISK_LIST EnumParts ${NSD_CreateButton} 240u 11u 60u 16u "刷新" Pop $REFRESHBTN1 ${NSD_OnClick} $REFRESHBTN1 EnumDisks ${NSD_CreateLabel} 0u 40u 300u 8u "分区列表:" Pop $0 ${NSD_CreateDroplist} 0u 53u 230u 70u "" Pop $PART_LIST ${NSD_CreateButton} 240u 51u 60u 16u "刷新" Pop $REFRESHBTN2 ${NSD_OnClick} $REFRESHBTN2 EnumParts Call EnumDisks nsDialogs::Show FunctionEnd Function EnumDisks SendMessage $DISK_LIST ${CB_RESETCONTENT} 0 0 SendMessage $PART_LIST ${CB_RESETCONTENT} 0 0 ${For} $1 0 ${MAX_DISKS} StrCpy $R0 "\\.\PhysicalDrive$1" Call CheckDisk ${If} $R1 != "" SendMessage $DISK_LIST ${CB_ADDSTRING} 0 "STR:hd$1:$R1" ${EndIf} ${Next} FunctionEnd Function CheckDisk StrCpy $R1 "" System::Call "kernel32::CreateFile(tR0,i0,i${FILE_SHARE_READ}|${FILE_SHARE_WRITE},i0,i${OPEN_EXISTING},i0,i0)i.R2" ${If} $R2 > 0 System::Alloc 24 Pop $R3 System::Call "kernel32::DeviceIoControl(iR2,i${IOCTL_DISK_GET_DRIVE_GEOMETRY},i0,i0,iR3,i24,*i.R5,i0)i.R4" ${If} $R4 == 0 Return ${EndIf} System::Call "*$R3(&i8.R4,i.R5,i.R6,i.R7,i.R8)" System::Free $R3 IntOp $R6 $R6 * $R7 IntOp $R6 $R6 * $R8 System::Int64Op $R4 * $R6 Pop $R4 System::Call 'shlwapi::StrFormatByteSize64(lR4,t.R4,t${NSIS_MAX_STRLEN})' StrCpy $R8 $R4 System::Call "*(i${StorageDeviceProperty},i${PropertyStandardQuery},i0)i.s" Pop $R3 System::Alloc 1024 Pop $R4 System::Call "kernel32::DeviceIoControl(iR2,i${IOCTL_STORAGE_QUERY_PROPERTY},iR3,i12,iR4,i1024,*i.R5,i0)i.." ${If} $R5 > 0 IntOp $R5 $R4 + 28 System::Call "*$R5(i.R6)" ${Select} $R6 ${Case} "1" StrCpy $R6 "SCSI" ${Case} "3" StrCpy $R6 "ATA" ${Case} "4" StrCpy $R6 "1394" ${Case} "5" StrCpy $R6 "SSA" ${Case} "6" StrCpy $R6 "FIBRE" ${Case} "7" StrCpy $R6 "USB" ${Case} "8" StrCpy $R6 "RAID" ${Case} "9" StrCpy $R6 "iSCSI" ${Case} "10" StrCpy $R6 "SAS" ${Case} "11" StrCpy $R6 "SATA" ${Case} "12" StrCpy $R6 "SD" ${Case} "13" StrCpy $R6 "MMC" ${CaseElse} StrCpy $R6 "" ${EndSelect} ${If} $R6 != "" StrCpy $R1 "$R6:" ${EndIf} IntOp $R5 $R4 + 12 System::Call "*$R5(i.R6)" ${If} $R6 != 0 IntOp $R5 $R4 + $R6 System::Call "*$R5(&t1024.R6)" ${WordReplace} $R6 " " "" "{}*" $R7 ${If} $R7 != "" StrCpy $R1 $R1$R7- ${EndIf} ${EndIf} IntOp $R5 $R4 + 16 System::Call "*$R5(i .R6)" ${If} $R6 != 0 IntOp $R5 $R4 + $R6 System::Call "*$R5(&t1024.R6)" ${WordReplace} $R6 " " "" "{}*" $R7 ${If} $R1 != "" ${AndIf} $R7 != "" StrCpy $R1 "$R1$R7" ${EndIf} ${EndIf} IntOp $R5 $R4 + 20 System::Call "*$R5(i.R6)" ${If} $R6 != 0 IntOp $R5 $R4 + $R6 System::Call "*$R5(&t1024.R6)" ${WordReplace} $R6 " " "" "{}*" $R7 ${If} $R7 != "" StrCpy $R1 "$R1($R7)" ${EndIf} ${EndIf} ${EndIf} StrCpy $R1 "$R1 ($R8)" System::Free $R3 System::Free $R4 System::Call "kernel32::CloseHandle(iR2)" ${EndIf} FunctionEnd Function EnumParts SendMessage $PART_LIST ${CB_RESETCONTENT} 0 0 $R1 ${NSD_GetText} $DISK_LIST $R1 StrCpy $R2 $R1 1 4 ${If} $R2 != ":" StrCpy $R2 $R1 3 ${Else} StrCpy $R2 $R1 4 ${EndIf} StrCpy $PriPtNumber 0 StrCpy $ExtPtNumber 4 ${If} $R2 == "fd0" ${OrIf} $R2 == "fd1" Return ${EndIf} StrCpy $R2 $R2 "" 2 StrCpy $R0 "\\.\PhysicalDrive$R2" System::Call "kernel32::CreateFile(tR0,i${GENERIC_READ},i${FILE_SHARE_WRITE},i0,i${OPEN_EXISTING},i0,i0)i.R2" ${If} $R2 > 0 System::Alloc 4096 Pop $R1 System::Call "kernel32::DeviceIoControl(iR2,i${IOCTL_DISK_GET_DRIVE_LAYOUT},i0,i0,iR1,i4096,*i.R5,i0)i.R4" ${If} $R4 == 0 Goto lblenumptret ${EndIf} System::Call "*$R1(i .R5)" ${If} $R5 < 1 Goto lblenumptret ${EndIf} IntOp $R0 $R1 + 8 ${For} $R3 1 $R5 System::Call "*$R0(l.R6)" ${If} $R6 != 0 System::Call "*$R0(l..,l.R4)" System::Call 'shlwapi::StrFormatByteSize64(lR4,t.R4,t${MAX_PATH})' System::Call "*$R0(&i20..,i.R7,&i1.R8,&i1.R9)" ${If} $R7 == 0 ${If} $R3 <= 4 IntOp $PriPtNumber $PriPtNumber + 1 ${EndIf} GoTo lblenumptloop ${EndIf} ${If} $R3 <= 4 StrCpy $R7 $PriPtNumber IntOp $PriPtNumber $PriPtNumber + 1 ${Else} StrCpy $R7 $ExtPtNumber IntOp $ExtPtNumber $ExtPtNumber + 1 ${EndIf} Call GetFSType ${If} $R9 == 1 StrCpy $R9 ", 活动" ${Else} StrCpy $R9 "" ${EndIf} SendMessage $PART_LIST ${CB_ADDSTRING} 0 "STR:$R7 ($R4, $R8$R9)" ${EndIf} lblenumptloop: IntOp $R0 $R0 + 32 ${Next} lblenumptret: System::Call "kernel32::CloseHandle(iR2)" System::Free $R1 ${Else} Call EnumDisks Return ${EndIf} FunctionEnd Function GetFSType IntFmt $R8 "%02X" $R8 ${Select} $R8 ${Case} "01" StrCpy $R8 "FAT12" ${Case3} "04" "06" "0E" StrCpy $R8 "FAT16" ${Case} "07" StrCpy $R8 "NTFS/exFAT" ${Case2} "0B" "0C" StrCpy $R8 "FAT32" ${Case} "11" StrCpy $R8 "隐藏 FAT12" ${Case3} "14" "16" "1E" StrCpy $R8 "隐藏 FAT16" ${Case} "17" StrCpy $R8 "隐藏 NTFS/exFAT" ${Case2} "1B" "1C" StrCpy $R8 "隐藏 FAT32" ${Case} "27" StrCpy $R8 "隐藏 NTFS (RE)" ${Case} "35" StrCpy $R8 "JFS" ${Case2} "80" "81" StrCpy $R8 "MINIX" ${Case} "82" StrCpy $R8 "LINUX SWAP" ${Case} "83" StrCpy $R8 "LINUX" ${CaseElse} StrCpy $R8 "不支持的分区" ${EndSelect} FunctionEnd