Get SYSTEM DRIVE PhysicalSerialNumber
The Code Updated And Some Bugs Fixed.
;------------------------------------------------
!include "X64.nsh"
!include "StrRep.nsh"
;------------------------------------------------
Function SSD_HDD_SerialNumber
Var /Global TheSystemDrive_DriveLetter
Var /Global TheSystemDrive_DiskNumber
Var /Global TheSystemDrive_PhysicalSerialNumber
StrCpy $1 $SYSDIR 3
Push $1
;Push "I:\"
; File Access Modes
!define GENERIC_READ 0x80000000
!define GENERIC_WRITE 0x40000000
; File Sharing Modes
!define FILE_SHARE_READ 0x00000001
!define FILE_SHARE_WRITE 0x00000002
; File Creation Flags
!define OPEN_EXISTING 3
!define INVALID_HANDLE_VALUE -1
; Maximum length of volume GUID (including terminating zero)
!define MAXLEN_VOLUME_GUID 51
; I/O control command
!define IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS 0x00560000
!define EXTENTS_BUFFER_SIZE 512
; Get hard disk number from drive letter
; provided as a parameter to this function.
;The hard disk number is returned in $0.
; Save registers
Exch $1
Push $2
Push $3
Push $4
Push $5
Push $6
Push $7
; Get volume name associated with drive letter
System::Call "kernel32::GetVolumeNameForVolumeMountPoint(t r1, t r3r3, i ${MAXLEN_VOLUME_GUID}) i.r2"
${If} $2 != 0
; Get handle of volume
StrCpy $3 $3 -1
System::Call "kernel32::CreateFile(t r3, i ${GENERIC_READ}|${GENERIC_WRITE}, i ${FILE_SHARE_READ}|${FILE_SHARE_WRITE}, i 0, i ${OPEN_EXISTING}, i 0, i 0) i.r2"
${If} $2 != ${INVALID_HANDLE_VALUE}
; Allocate output buffer
System::Alloc ${EXTENTS_BUFFER_SIZE}
Pop $4
IntOp $5 0 + 0
; Send IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS command
System::Call "kernel32::DeviceIoControl(i r2, i ${IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS}, i 0, i 0, i r4, i ${EXTENTS_BUFFER_SIZE}, *i r5r5, i 0) i.r3"
${If} $3 != 0
; Extract HDD number
System::Call "*$4(i .r5, i, i .r0)"
${If} $5 == 0
StrCpy $0 "Error: Invalid DISK_EXTENT data"
${EndIf}
${Else}
StrCpy $0 "Error: DeviceIoControl failed"
${EndIf}
System::Free $4
System::Call "kernel32::CloseHandle(i r2) i.r3"
${Else}
StrCpy $0 "Error: CreateFile failed for $3"
${EndIf}
${Else}
StrCpy $0 "Error: GetVolumeNameForVolumeMountPoint failed for $1"
${EndIf}
; Restore registers
Pop $7
Pop $6
Pop $5
Pop $4
Pop $3
Pop $2
Pop $1
StrCpy $TheSystemDrive_DiskNumber $0
StrCpy $TheSystemDrive_DriveLetter $1
;------------------------------------------------------------
#Get SYSDIR Physical Disk SerialNumber
nsExec::ExecToStack "wmic path Win32_PhysicalMedia where Tag='\\\\.\\PHYSICALDRIVE$TheSystemDrive_DiskNumber' get SerialNumber /value"
Pop $0 # return value/error/timeout
Pop $1 # printed text, up to ${NSIS_MAX_STRLEN}
StrCpy $TheSystemDrive_PhysicalSerialNumber $1
${StrRep} '$TheSystemDrive_PhysicalSerialNumber' '$TheSystemDrive_PhysicalSerialNumber' 'SerialNumber=' ''
${StrRep} '$TheSystemDrive_PhysicalSerialNumber' '$TheSystemDrive_PhysicalSerialNumber' ' ' ''
${StrRep} '$TheSystemDrive_PhysicalSerialNumber' '$TheSystemDrive_PhysicalSerialNumber' '$\r$\n' ''
${StrRep} '$TheSystemDrive_PhysicalSerialNumber' '$TheSystemDrive_PhysicalSerialNumber' '$\n' ''
${StrRep} '$TheSystemDrive_PhysicalSerialNumber' '$TheSystemDrive_PhysicalSerialNumber' '$\r' ''
;------------------------------------------------------------
MessageBox MB_OK "\
SYSDIR DriveLetter=[$TheSystemDrive_DriveLetter]$\r$\n\
SYSDIR DiskNumber=[$TheSystemDrive_DiskNumber]$\r$\n\
SYSDIR Physical SerialNumber=[$TheSystemDrive_PhysicalSerialNumber]\
"
Quit
FunctionEnd
Function .onInit
FunctionEnd
Section
Call SSD_HDD_SerialNumber
SectionEnd