How can I get the ID of a machine? I tried seraching APIs like GetSystemInfo but they don't seem to provide, unless I overlooked it by mistake.
Thankyou.
Are you looking for the computer name (ie: GetComputerName\GetComputerNameEx)?
Does that return a number or just the name of the computer (for example 'NilremComputer')?
Name.
What number are you looking for?
Nilrem,
If you were to run the following program:
Quoteipconfig /all >MachineID.txt
It will create a file called MachineID.txt with lots of neat stuff in it. In there you will find a line called Physical Address, it contains the Machine ID. On my machine, it shows:
QuotePhysical Address. . . . . . . . . : 08-00-46-59-27-41
So, 08-00-46-59-27-41 is my Machine ID.
Now, if you use CreateProcess to run the above command line, you can then open the file and read in the Macine ID, that does it.
Cheers,
Paul
Quote from: pbrennick on January 31, 2005, 06:34:32 PM
Nilrem,
If you were to run the following program:
Quoteipconfig /all >MachineID.txt
It will create a file called MachineID.txt with lots of neat stuff in it. In there you will find a line called Physical Address, it contains the Machine ID. On my machine, it shows:
QuotePhysical Address. . . . . . . . . : 08-00-46-59-27-41
So, 08-00-46-59-27-41 is my Machine ID.
Now, if you use CreateProcess to run the above command line, you can then open the file and read in the Macine ID, that does it.
Cheers,
Paul
Paul,
The machine ID you listed (Physical Address) is actually your MAC address of your network card.
Nilrem,
What machine ID are you trying to get? There are a lot of different type of IDs. CPU, Network, Hard Drive, etc.
Relvinian
Sorry I got confused. Again. I need to retrieve the serial of the hard-disk, I'm guessing GetVolumeInfo or something along those lines?
I've looked up the API but I need to specify the path of the disk, but what if it isn't called C:\ what if it is something else like F:\ how would one determine the hardisk drive letter? I looked up GetDriveType but needs the root also.
Relvinian,
Where I googled, it says it is also the Machine ID. http://www.elysiuminc.com/login/misc/machineid.html is where I got the information. All I did was copy what was posted minus the pictures. :'(
Cheers,
Paul
I've figured this much out but it's not working, also when having one line code over more than one line how to do it?
.data
lpDrive DB "C:",0
.data?
nSize DD ?
lpNumber DD ?
lpMaximumComponentLength DD ?
lpFileSystemFlags DD ?
nFileSystemNameSize DD ?
lpszVolumeName DD ?
ID PROC
LOCAL lpFileSystemNameBuffer:DWORD; Points to a buffer that receives the name of the file system (such as FAT or NTFS).
LOCAL lpBuffer:DWORD
LOCAL lpstring[128]:DWORD
LOCAL cchBufferLength:DWORD
;invoke FindFirstVolume,lpszVolumeName,cchBufferLength
invoke GetVolumeInformation,lpDrive,lpBuffer,nSize,lpNumber,lpMaximumComponentLength,lpFileSystemFlags,lpFileSystemNameBuffer,nFileSystemNameSize
invoke StdOut, [lpNumber]
mov lpstring, input ()
ID endp
Quote from: Nilrem on January 31, 2005, 10:02:40 PM
I've looked up the API but I need to specify the path of the disk, but what if it isn't called C:\ what if it is something else like F:\ how would one determine the hardisk drive letter? I looked up GetDriveType but needs the root also.
Take a look at GetLogicalDrives and/or GetLogicalDriveStrings. It will give you all the list of the drive letter that exist in your machine.
:U
Quote from: pbrennick on January 31, 2005, 10:33:47 PM
Relvinian,
Where I googled, it says it is also the Machine ID. http://www.elysiuminc.com/login/misc/machineid.html is where I got the information. All I did was copy what was posted minus the pictures. :'(
Cheers,
Paul
Hehe. The only reason I mentioned that is because if you don't have a network card installed (which is still possible), doing IPCONFIG will produce nothing. Your machine is still valid and does have an ID still. Just no MAC information (or any TCP/IP information too -- unless you have a virtual TCP/IP driver for some other device).
Terminology is the biggest obstical in communications. ;-) I'm not saying you are wrong in what you posted, just putting an extra clarification on what that was.
Relvinian
Relvinian,
Thank you for your words. I notice that you usually are a lot of help to others and that is my goal, also.
BTW I used to be a CNA (Novell 4.1 cert.) and have seen all the MAC addresses I care to for one lifetime. :dazzled:
Cheers,
Paul
Paul,
Hehe. Yep, I bet you have seen a lot of addresses then eh?
I never did get into the certifcation thing (novell, microsoft, cisco, etc). I would rather program then work on networks or be an admin type.
You answer a lot more post then ever will and because of that, you'll always help more. I just chime in when and where I can. Sometimes my information isn't the best, wrong or I don't clair myself enough.
Relvinian
Nilrem,
IIRC the volume serial number is assigned when the volume is formatted. I don't know how the number is derived, but considering that the volume serial number thing started back in the DOS days, I doubt that it has anything to do with the hardware. The hard drive will have a serial number assigned by the manufacturer, and it should be accessible in the data returned by the Identify Device command. See this thread:
http://www.masmforum.com/simple/index.php?topic=45.0
Windows 2000 (and probably later versions) uses the model number returned by Identify Device to identify the hard disk in Device Manager. But I couldn't find my hard disk serial number anywhere in the registry, probably indicating that it is not available. I think WinIo could be used to run an Identify Device command on the hard disk from within Windows. But to do it you would need to change several of the command/control block registers, and without some way to temporarily prevent Windows from accessing the drive, I think this would be more than a little risky. And assuming you could prevent Windows from accessing the drive while you are running the command, you still would need to be very careful to restore all of the registers you changed.
Nilrem,
This should get you past your coding issues for now. After calling the code, lpnumber will have the 32 bit serial number. What I tried to get, but could not, was how to format it for output.
lpDrive DB "C:\",0
lpNumber DD ?
lpMaximumComponentLength DD ?
lpFileSystemFlags DD ?
invoke GetVolumeInformation,
addr lpDrive,NULL,0,
addr lpNumber,
addr lpMaximumComponentLength,
addr lpFileSystemFlags,NULL,0
Plus, if your are trying to serialize the system, try googling for solutions that you may code into MASM. Be aware users change stuff in their systems and which break certain kinds of serials.
Regards, P1 :8)
Hi,
I got an example for doing exactly that at my website in the win32asm section.
http://www.tomasm.tk/ . the program is called GetHdSerial
Thomas Antony :U
Well there is a program that (to register) gets your machine id (hard-drive serial) and then mixes it with another code to give you a unique code. I am interested in this protection. I'm not going to develop it now, but when I use programs I like to understand fully their protections. 8-) I am a very curious person. I will try the code to night, would wsprintf help with the formatting?
Hi Thomas,
GetHDSerial returns 00403034 on both of the systems I tested it on. On my spare system the actual HDD serial number (from the information returned by IdDevice) is WD-WCAHM1149190. I did not take the time to restart my primary system, but the HDD is a higher capacity version of the drive in the spare system, so the serial number would be similar. For the C volume on my primary system the volume serial number is 1941-090A (obtained from a DIR command).
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.486 ; create 32 bit code
.model flat, stdcall ; 32 bit memory model
option casemap :none ; case sensitive
include \masm32\include\windows.inc
include \masm32\include\masm32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\kernel32.lib
include \masm32\macros\macros.asm
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.data
RootPathName db "c:\",0
VolumeNameBuffer db 128 dup(0)
nVolumeNameSize dd 128
VolumeSerialNumber dd 0
MaximumComponentLength dd 0
FileSystemFlags dd 0
FileSystemNameBuffer db 128 dup(0)
nFileSystemNameSize dd 128
.code
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
invoke GetVolumeInformation,ADDR RootPathName,
ADDR VolumeNameBuffer,
nVolumeNameSize,
ADDR VolumeSerialNumber,
ADDR MaximumComponentLength,
ADDR FileSystemFlags,
ADDR FileSystemNameBuffer,
nFileSystemNameSize
print chr$("RootPathName: ")
print ADDR RootPathName
print chr$(13,10,"VolumeNameBuffer: ")
print ADDR VolumeNameBuffer
print chr$(13,10,"VolumeSerialNumber (dec): ")
print ustr$(VolumeSerialNumber)
print chr$(13,10,"VolumeSerialNumber (hex): ")
print uhex$(VolumeSerialNumber)
print chr$(13,10,"MaximumComponentLength: ")
print ustr$(MaximumComponentLength)
.IF FileSystemFlags & FILE_NAMED_STREAMS
print chr$(13,10,"FILE_NAMED_STREAMS")
.ENDIF
.IF FileSystemFlags & FILE_READ_ONLY_VOLUME
print chr$(13,10,"FILE_READ_ONLY_VOLUME")
.ENDIF
.IF FileSystemFlags & FILE_SUPPORTS_OBJECT_IDS
print chr$(13,10,"FILE_SUPPORTS_OBJECT_IDS")
.ENDIF
.IF FileSystemFlags & FILE_SUPPORTS_REPARSE_POINTS
print chr$(13,10,"FILE_SUPPORTS_REPARSE_POINTS")
.ENDIF
.IF FileSystemFlags & FILE_SUPPORTS_SPARSE_FILES
print chr$(13,10,"FILE_SUPPORTS_SPARSE_FILES")
.ENDIF
.IF FileSystemFlags & FILE_VOLUME_QUOTAS
print chr$(13,10,"FILE_VOLUME_QUOTAS")
.ENDIF
.IF FileSystemFlags & FS_CASE_IS_PRESERVED
print chr$(13,10,"FS_CASE_IS_PRESERVED")
.ENDIF
.IF FileSystemFlags & FS_CASE_SENSITIVE
print chr$(13,10,"FS_CASE_SENSITIVE")
.ENDIF
;.IF FileSystemFlags & FS_FILE_COMPRESSION
; print chr$(13,10,"FS_FILE_COMPRESSION")
;.ENDIF
;.IF FileSystemFlags & FS_FILE_ENCRYPTION
; print chr$(13,10,"FS_FILE_ENCRYPTION")
;.ENDIF
.IF FileSystemFlags & FS_PERSISTENT_ACLS
print chr$(13,10,"FS_PERSISTENT_ACLS")
.ENDIF
.IF FileSystemFlags & FS_UNICODE_STORED_ON_DISK
print chr$(13,10,"FS_UNICODE_STORED_ON_DISK")
.ENDIF
;.IF FileSystemFlags & FS_VOL_IS_COMPRESSED
; print chr$(13,10,"FS_VOL_IS_COMPRESSED")
;.ENDIF
print chr$(13,10,"FileSystemNameBuffer: ")
print ADDR FileSystemNameBuffer
mov eax, input(13,10,13,10,"Press enter to exit...")
exit
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start
BOOL GetVolumeInformation(
LPCTSTR lpRootPathName,
LPTSTR lpVolumeNameBuffer,
DWORD nVolumeNameSize,
LPDWORD lpVolumeSerialNumber,
LPDWORD lpMaximumComponentLength,
LPDWORD lpFileSystemFlags,
LPTSTR lpFileSystemNameBuffer,
DWORD nFileSystemNameSize
);
FILE_NAMED_STREAMS
FILE_READ_ONLY_VOLUME
FILE_SUPPORTS_OBJECT_IDS
FILE_SUPPORTS_REPARSE_POINTS
FILE_SUPPORTS_SPARSE_FILES
FILE_VOLUME_QUOTAS
FS_CASE_IS_PRESERVED
FS_CASE_SENSITIVE
FS_FILE_COMPRESSION
FS_FILE_ENCRYPTION
FS_PERSISTENT_ACLS
FS_UNICODE_STORED_ON_DISK
FS_VOL_IS_COMPRESSED
RootPathName: c:\
VolumeNameBuffer:
VolumeSerialNumber (dec): 423692554
VolumeSerialNumber (hex): 1941090A
MaximumComponentLength: 255
FS_CASE_IS_PRESERVED
FS_UNICODE_STORED_ON_DISK
FileSystemNameBuffer: FAT32
If I change the root path to "d:\" I get a different volume serial number (even though both volumes are on the same physical drive), and again it matches the volume serial number returned by DIR.
Thankyou. 8-) I won'tbe using all of that code because I don't need it but bits of it I am interested in and it helped a lot. 8-)
Tested it, why does my serial number come up a negative number, to do with signed and unsigned? It gives a postive number on my d:\ drive so...?
Signed numbers are taken as the upper-half of the number space (the topmost bit is set) so depending on the drive, if the number is 'large' then it will be printed as negative.
Though this depends on what options you give to wsprintf - "%d" or "%i" will give negatives, "%lu" just gives the whole number, treating the topmost bit as significant and not as a sign.
The DIR command displays the hex value of the number, so I assume the number should be interpreted as an unsigned value.
Well what would you do to rectify the situation Michael?
I doubt that the sign of the number has any meaning here. In my version I used the uhex$ macro which displays the number as unsigned hex. If you are using wsprintf to convert the value, you could try "%lX". Run a "DIR /p" on a directory and see what it returns, as this is how MS intended that the value be ihnterpreted.
I am not using wsprintf, I will show you my code, a trimmed version of yours.
.data
RootPathName db "c:\",0
VolumeNameBuffer db 128 dup(0)
nVolumeNameSize dd 128
VolumeSerialNumber dd 0
MaximumComponentLength dd 0
FileSystemFlags dd 0
FileSystemNameBuffer db 128 dup(0)
nFileSystemNameSize dd 128
ID PROC
LOCAL lpstring[128]:DWORD
invoke GetVolumeInformation,ADDR RootPathName,
ADDR VolumeNameBuffer,
nVolumeNameSize,
ADDR VolumeSerialNumber,
ADDR MaximumComponentLength,
ADDR FileSystemFlags,
ADDR FileSystemNameBuffer,
nFileSystemNameSize
print chr$("RootPathName: ")
print ADDR RootPathName
print chr$(13,10,"VolumeSerialNumber (dec): ")
print ustr$(VolumeSerialNumber)
print chr$(13,10,"VolumeSerialNumber (hex): ")
print uhex$(VolumeSerialNumber)
mov lpstring, input ()
ret
ID endp
When accessing the C:\ drive it gives a negative number (dec) but when doing it with the D:\ it gives a positive integer.
Solutions?
Perhaps there is an error in the ustr$ macro. It's supposed to convert the value to an unsigned decimal number. In any event, I think the sign is not relevant to using the number as an identifier. In my tests Microsoft displays the number in hex, with a "-" between the upper and lower words, so effectively they are treating it as a string. If the number were intended to be treated as a number, then I think Microsoft would have documented the fields that make up the number, which AFAIK they have not.
Also, I have doubts that a volume serial number would be a reasonable machine ID, because I doubt that it would uniquely identify the system. I think Microsoft intended it to be a reasonable volume identifier in an environment where there would be only a limited number of volumes. For a uinique identifier I think your network adapter MAC address would be a much better choice, because AFAIK every network adapter has a unique MAC address.
Quote from: Nilrem on February 01, 2005, 01:33:19 PM
When accessing the C:\ drive it gives a negative number (dec) but when doing it with the D:\ it gives a positive integer.
The serial is to be display in HEX for this very reason. Also so it format neatly for the Dir output to the console. Try dw2hex in MASM32 for output. And compare it to your hard drive Dir output.
Regards, P1 :8)
This code doesn't work for entering either C, c, C:, c:, C:\, or c:\, why?
ID PROC
LOCAL lpstring[128]:DWORD
mov lpstring, input ("Enter the drive letter please: ")
invoke GetVolumeInformation,ADDR lpstring,
ADDR VolumeNameBuffer,
nVolumeNameSize,
ADDR VolumeSerialNumber,
ADDR MaximumComponentLength,
ADDR FileSystemFlags,
ADDR FileSystemNameBuffer,
nFileSystemNameSize
print chr$(13,10,"RootPathName: ")
print ADDR lpstring
print chr$(13,10,"VolumeSerialNumber (dec): ")
print ustr$(VolumeSerialNumber)
print chr$(13,10,"VolumeSerialNumber (hex): ")
print uhex$(VolumeSerialNumber)
mov lpstring, input ("Press Enter to Exit")
ret
ID endp
hi, Nilrem,
here is a code written by Babek( Russian )with TASM. I translated it into MASM. it can work fine.
;==============================================================================
Mr. Thomas Antony,
your GetHdSerial has some problem. i addid a HandleError proc. the [invoke GetVolumeInformation,ADDR RootPath,ADDR VolName,255,Serial,ecx,edx,0,0] returned false value. i tested it on windows xp home edition.
;@echo off
;goto make
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Author:Thomas Antony
; Date: 5 January 2004
; Licence:GPL
; ASM Format:MASM32
; Tested on Win98SE and WinXP Professional
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386
.model flat,stdcall
option casemap:none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data
MsgCaption db "The Serial Number of your HDD is:",0
pzCaption db "Error!!!",0
RootPath db "C:\",0
SerialFmt db "%08lX",0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
SerialNo db 8 dup(?)
Serial dd ?
VolName db 255 dup(?)
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
HandleError proc lpTitle:DWORD
LOCAL lpMsgBuffer : LPVOID ;dword
; calculate language ID, asm version of MAKELANGID
mov cx, SUBLANG_DEFAULT
shl ecx, 10
;or cx, LANG_NEUTRAL ; LANG_NEUTRAL = 0, nothing necessary
; Setup parameters for FormatMessage, normal pushing to use some
; params directly (e.g. GetLastError returns the ID in eax, but I
; can't use this register in "invoke")
push NULL ; we don't need this
push 0 ; min. size of output buffer if we use
; FORMAT_MESSAGE_ALLOCATE_BUFFER
lea ebx,lpMsgBuffer ; get address of our buffer
push ebx ; address of buffer
push ecx ; our language ID, calculated above
invoke GetLastError ; get error number
push eax ; push return value = error ID
push NULL ; can be used to format a string, we don't need it
mov edx, FORMAT_MESSAGE_ALLOCATE_BUFFER or FORMAT_MESSAGE_FROM_SYSTEM
push edx ; some flags, check your doc for more
call FormatMessage ; here we go
; Display error-message
invoke MessageBox, NULL, lpMsgBuffer, lpTitle, MB_OK or MB_ICONSTOP
; free memory
invoke LocalFree, lpMsgBuffer
ret
HandleError endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
invoke GetVolumeInformation,ADDR RootPath,ADDR VolName,255,Serial,ecx,edx,0,0
.if eax==0
invoke HandleError, addr pzCaption
jmp qexit
.endif
invoke wsprintfA,ADDR SerialNo,ADDR SerialFmt,ADDR Serial
invoke MessageBoxA,0,ADDR SerialNo,ADDR MsgCaption,0
qexit: invoke ExitProcess,0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
:make
set name=hds_1
\masm32\bin\ml /c /coff /Cp %name%.bat
\masm32\bin\Link /subsystem:windows %name%.obj
if exist *.bak del *.bak
if exist *.obj del *.obj
echo.
regards.
[attachment deleted by admin]
Hi, thankyou, however the problem with my code is user input. Compile it and you will see.
Nilrem,
The input macro allocates a 128-byte buffer, copies the user input to the buffer, and returns the address of the buffer. Your lpString variable should be a single DWORD, and the contents of lpString rather than the address of lpString should be passed to GetVolumeInformation, and to the print macro.
Thankyou Michael.
How would one go about getting the IDE serial number?
Hello,
Machine ID from MAC address network card? OK! Example, source code and exec is on this link
http://www.sendme.cz/sg-5/new/source/MacAddr.zip
View source code:
.586
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\IpHlpApi.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\IpHlpApi.lib
.data
pinfo IP_ADAPTER_INFO <>
len dd 0
String db '%02X:%02X:%02X:%02X:%02X:%02X',0
Buffer db 18 dup (0)
Text db 'MAC Address,',0
.code
Start:
invoke GetAdaptersInfo,addr pinfo,addr len
invoke GlobalAlloc,GMEM_FIXED,len
push eax
invoke GetAdaptersInfo,eax,addr len
pop esi
push esi
assume esi:ptr IP_ADAPTER_INFO
movzx eax,byte ptr [esi].Address[5]
push eax
movzx eax,byte ptr [esi].Address[4]
push eax
movzx eax,byte ptr [esi].Address[3]
push eax
movzx eax,byte ptr [esi].Address[2]
push eax
movzx eax,byte ptr [esi].Address[1]
push eax
movzx eax,byte ptr [esi].Address[0]
push eax
push offset String
push offset Buffer
call wsprintf
pop eax
invoke GlobalFree,eax
invoke MessageBox,0,addr Buffer,addr Text,MB_OK
invoke ExitProcess,eax
end Start
Sorry my english
Thankyou.
For Machine ID from HDD this link http://www.winsim.com/diskid32/diskid32.html sorry source code is C++.