Skip to content
⌘ NSIS Forum Archive

hard disk physical serial nember

7 posts

r2du-soft#edited

hard disk physical serial nember

how can get hard disk physical serial number?

!include WMI.nsh
!include StrRep.nsh

Section

#All physical drives
${WMIGetInfo} root\CIMV2 win32_physicalmedia SerialNumber callback_Function


Quit
SectionEnd

Function callback_Function

${StrRep} '$2' '$2' '$\n$\r' ''
${StrRep} '$2' '$2' '$\n' ''
${StrRep} '$2' '$2' '$\r' ''
${StrRep} '$2' '$2' ' ' ''

${IF} $2 != ""
MessageBox MB_OK "[$2]"
${EndIF}

FunctionEnd 

this code show all disk drives serial number (Hard Disk 0,Hard Disk 1,Hard Disk 2,Flash Disk,...)
i just want get Physical serial number of Windows installed on that hard disk
r2du-soft#
is possible convert Batch to nsis


@echo off &setlocal
for /f tokens^=2^ delims^=^" %%i in ('wmic path Win32_LogicalDiskToPartition get^|findstr "\"%SystemDrive%\""') do (
for /f "tokens=2 delims=#," %%j in ("%%i") do (
for /f "tokens=2 delims== " %%k in ('wmic path Win32_PhysicalMedia where "Tag='\\\\.\\PHYSICALDRIVE%%j'" get SerialNumber /value') do (
for /f "delims=" %%l in ("%%k") do set "SerialNumber=%%l"
)
)
)
echo %SerialNumber%
pause

Nutzzz#
You could just use nsExec::ExecToStack to call your batch file rather than using the WMI.nsh macros...
r2du-soft#
Yes i know but i do not want open this command as batch fule to stack,i want convert to nsis code...
r2du-soft#edited
Find the hard drive that windows has installed on it by PHYSICAL DRIVE number from among the hard disks and the flash disks connected to the computer and find Serial Number For making software locks

!include WMI.nsh
!include StrRep.nsh
!include "x64.nsh"
!include "StrCount.nsh"

Var StackS1
Var LineReaded
Var FindWord



Section
${WMIGetInfo} root\CIMV2 Win32_LogicalDiskToPartition /value HDDPhysicalDiskP1
Call HDDPhysicalDiskP2
nsExec::ExecToStack "wmic path Win32_PhysicalMedia where Tag='\\\\.\\PHYSICALDRIVE$3' get SerialNumber /value"
	Pop $0 # return value/error/timeout
	Pop $1 # printed text, up to ${NSIS_MAX_STRLEN}
;MessageBox MB_OK "$1"
${StrRep} '$1' '$1' 'SerialNumber=' ''
${StrRep} '$1' '$1' ' ' ''
${StrRep} '$1' '$1' '$\n$\r' ''
${StrRep} '$1' '$1' '$\n' ''
${StrRep} '$1' '$1' '$\r' ''
MessageBox MB_OK "Physical serial number of Windows installed on that hard disk is:$\n$\r[$1]"
SectionEnd



Function HDDPhysicalDiskP2
StrCpy $FindWord "$%HomeDrive%" #Searching String In Variable
;------------------------------------------------------------
StrCpy $1 0
StrCpy $5 0
StrCpy $6 0
;------
loop:
IntOp $6 $6 + 1
StrCpy $2 $StackS1 1 $1
;-------------------
IntOp $1 $1 + 1
StrCmp $2 '$\n' found
StrCmp $2 '' found loop
IntOp $5 $5 + 1
;------
found:
IntOp $3 $3 + 1
StrCpy $LineReaded $StackS1 $6 $5
StrCpy $5 ""
StrCpy $6 ""
;------------------------------------------------------------
${StrCount} "$LineReaded" "$FindWord" "i"
Pop $0
;--------
${If} $0 != "0"
StrCpy $4 "$LineReaded" 1
${else}
StrCpy $5 $1
Goto loop #read Next Line
${endIf}
;------------------------------------------------------------

;------------------------------------------------------------
IntOp $3 $3 - 1

StrCpy $1 "0"
loop20:
IntOp $1 $1 + 1
StrCpy $2 $3 1 $1
;MessageBox MB_OK "$2"
StrCmp $2 ',' found20
StrCmp $2 '' found20 loop20
	found20:
		StrCpy $3 $3 $1 ""
		;MessageBox MB_OK "Windows Installed On PhysicalDrive $3"
		DetailPrint "Windows Installed On PhysicalDrive $3"
;------------------------------------------------------------
FunctionEnd


Function HDDPhysicalDiskP1
${StrRep} '$2' '$2' '$\n$\r' ''
${StrRep} '$2' '$2' '$\n' ''
${StrRep} '$2' '$2' '$\r' ''
${StrRep} '$2' '$2' ' ' ''
${IF} $2 != ""
;MessageBox MB_OK "[$2]"
StrCpy $StackS1 "$StackS1$2$\n$\r"
${EndIF}
FunctionEnd 
But a question:
this way is standard?
I mean, is there a better way to do this?
Anders#
You could maybe do it with DeviceIoControl or the SetupAPI but the code would be longer and more complicated...
r2du-soft#
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