Recent

Author Topic: [Solved] Get "serial number" of (removable) disk  (Read 1653 times)

Bart

  • Hero Member
  • *****
  • Posts: 5648
    • Bart en Mariska's Webstek
[Solved] Get "serial number" of (removable) disk
« on: November 15, 2025, 07:36:59 pm »
Hi,

On Windows it's relatively easy to obtain the "Volume Serial" of a disk.
I use this for one of my utilities that copies graphical files from SD-cards.
I store the serial number with thet last time the program copied the files, so when I ind=sert the same SD-card next time, I can offer the options "copy files newer than <last visted date and time>".

Since I've move my trusty old laptop to Linux (Mint 22.0 Mate), I would like to achiev the same (or similar) on Linux.

For reference here's the code used in Windows:
Code: Pascal  [Select][+][-]
  1. function GetVolumeInfo(const Volume: String; out VolLabel: String; out SerialID: DWORD;
  2.                        out MaxComponentLength, VolumeFlags: DWORD;
  3.                        out FileSystemName: String): Boolean;
  4. var
  5.   VolumeInfo, FileSystemNameBuffer:  array[0..MAX_PATH] of Char;
  6.   OldMode: UINT;
  7. begin
  8.   FillChar(VolumeInfo{%H-}, SizeOf(VolumeInfo), #0);
  9.   FillChar(FileSystemNameBuffer{%H-}, SizeOf(VolumeInfo), #0);
  10.   MaxComponentLength := 0;
  11.   VolumeFlags := 0;
  12.   OldMode := SetErrorMode(SEM_FAILCRITICALERRORS);
  13.   Result := GetVolumeInformationA(PChar(Volume), @VolumeInfo, SizeOf(VolumeInfo),
  14.            @SerialID, MaxComponentLength,
  15.            VolumeFlags, PChar(FileSystemNameBuffer), SizeOf(FileSystemNameBuffer));
  16.   if Result then
  17.   begin
  18.     VolLabel := PChar(VolumeInfo);
  19.     FileSystemName := PChar(FileSystemNameBuffer);
  20.   end;
  21.   SetErrorMode(OldMode);
  22. end;
  23.  
  24. function GetVolumeSerial(const Volume: String): DWORD;
  25. var
  26.   MaxComponentLength: DWORD;
  27.   VolumeFlags: DWORD;
  28.   {%H-}VolumeInfo:  array[0..MAX_PATH] of Char;
  29.   {%H-}VolumeSerialNumber: DWORD;
  30.   VolLabel, FSN: String;
  31. begin
  32.   MaxComponentLength := 0;
  33.   VolumeFlags := 0;
  34.   if not GetVolumeInfo(Volume, VolLabel, Result, MaxComponentLength, VolumeFlags,FSN) then
  35.     Result := sidInvalid;
  36. end;  

Bart
« Last Edit: November 29, 2025, 06:16:09 pm by Bart »

Thaddy

  • Hero Member
  • *****
  • Posts: 18521
  • Here stood a man who saw the Elbe and jumped it.
Re: Get "serial number" of (removable) disk
« Reply #1 on: November 16, 2025, 08:39:31 am »
Try ls -l /dev/disk/by-uuid/
Doing it programmatically other than with process redirection is a bit more cumbersome.
That requires libblkid-dev and a Pascal translation for -parts of - blkid.h
Usually blkid is installed, as is libblkid: it is used by many more utilities.
Note that direct device access is restricted to root, but userspace can access the information from the cache.
Will translate this example to pascal later:
Code: C  [Select][+][-]
  1. #include <blkid/blkid.h>
  2. #include <stdio.h>
  3.  
  4. int main() {
  5. blkid_cache cache;
  6. blkid_dev dev;
  7.  
  8. // Initialize the blkid cache
  9. if (blkid_get_cache(&cache, NULL) < 0) {
  10. perror("Failed to initialize cache");
  11. return 1;
  12. }
  13.  
  14. // Retrieve device information
  15. dev = blkid_get_dev(cache, "/dev/sda1", BLKID_DEV_NORMAL);
  16. if (dev) {
  17. const char *uuid = blkid_dev_devname(dev);
  18. printf("Device UUID: %s\n", uuid);
  19. } else {
  20. printf("Device not found.\n");
  21. }
  22.  
  23. // Free the cache
  24. blkid_put_cache(cache);
  25. return 0;
  26. }

I have also an example that needs root.
« Last Edit: November 16, 2025, 08:57:42 am by Thaddy »
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

Hartmut

  • Hero Member
  • *****
  • Posts: 1028
Re: Get "serial number" of (removable) disk
« Reply #2 on: November 16, 2025, 09:17:41 am »
On Linux Ubuntu I use command 'lsblk' for this. I call this command with 'TProcess' and store it's results into a 'TStringList' which I then parse.

Command 'lsblk' has plenty of possible parameters. I created a procedure which always uses:
lsblk -l -p -e 7 -oNAME,MOUNTPOINT,LABEL,FSTYPE,SIZE,TYPE,PARTTYPE,UUID,MODEL

The benefit is, that each value which I ever may need has a fixed column in the result which makes common parsing easier.

The result of above command looks like this:
Code: Text  [Select][+][-]
  1. NAME      MOUNTPOINT            LABEL      FSTYPE   SIZE TYPE PARTTYPE UUID                                 MODEL
  2. /dev/sda                                          931,5G disk                                               Samsung SSD 860 EVO 1TB
  3. /dev/sda1                       Win7       ntfs      55G part 0x7      60D898E99C1DD456
  4. /dev/sda2 /media/D              DOS        vfat       2G part 0xe      BE2A-F2D1
  5. /dev/sda3                                             1K part 0xf
  6. /dev/sda4 /                     Ubuntu     ext4     100G part 0x83     ada05431-c5b7-4241-b1a8-ecbfe2d987cb
  7. /dev/sda5                       INSTALL    vfat       2G part 0x6      5B53-12F7
  8. /dev/sda6 /media/F              MAILS      vfat       2G part 0x6      A1FF-3DF2
  9. /dev/sda7                       WinXP      ntfs       4G part 0x7      6532098E648037CE
  10. /dev/sda8 /media/H              BigSize    ntfs   765,5G part 0x7      D09567D4F718A7BA
  11. /dev/sda9 /media/X              XCHG       vfat    1023M part 0xb      4749-6ED3
  12. /dev/sdb                                            1,8T disk                                               Samsung SSD 870 QVO 2TB
  13. /dev/sdb1                       Filme      ntfs     1,7T part 0x7      58F4C81735ED08D0
  14. /dev/sdb2                       Ubuntu2    ext4     100G part 0x83     0cdde00b-c715-4d01-8938-b7174f9f574d
  15. /dev/sdc                                              0B disk                                               STORAGE DEVICE
  16. /dev/sdd                                           14,5G disk                                               OnlyDisk
  17. /dev/sdd1 /media/hg6/NETAC      NETAC      vfat    14,5G part 0xc      08BB-83BA
  18. /dev/sde                                           59,5G disk                                               STORE N GO
  19. /dev/sde1 /media/hg6/STORE N GO STORE N GO vfat    59,5G part 0xc      D3C0-2DE8

You find the "Volume Serial" in column UUID. Please notice, that sometimes this number on Linux is longer than on Windows, but the 8 rightmost digits on Linux are the same than the "Volume Serial" on Windows.

Thaddy

  • Hero Member
  • *****
  • Posts: 18521
  • Here stood a man who saw the Elbe and jumped it.
Re: Get "serial number" of (removable) disk
« Reply #3 on: November 16, 2025, 09:25:53 am »
Here's how to do it in code. Paramstr(1) is the device name , like /dev/sda1
Compile: fpc -k-lblkid blkidexample.pas
Code: Pascal  [Select][+][-]
  1. program BlkidExample;
  2. {$mode objfpc}{$H+}
  3.  
  4. uses
  5.   ctypes;
  6.  
  7. const
  8.   libblkid = 'blkid';
  9.  
  10. type
  11.   Pblkid_cache = type POpaqueData; // from system.pas
  12.   Pblkid_dev = type POpaqueData;
  13.   Pblkid_tag_iterate = type POpaqueData;
  14. const
  15.   BLKID_DEV_NORMAL = 0;
  16.  
  17. { Function prototypes from blkid.h }
  18. function blkid_get_cache(var cache: Pblkid_cache; filename: PChar): cint; cdecl; external libblkid;
  19. function blkid_get_dev(cache: Pblkid_cache; devname: PChar; flags: cint): Pblkid_dev; cdecl; external libblkid;
  20. function blkid_dev_devname(dev: Pblkid_dev): PChar; cdecl; external libblkid;
  21. function blkid_get_tag_value(cache: Pblkid_cache; tagname: PChar; devname: PChar): PChar; cdecl; external libblkid;
  22. function blkid_devno_to_devname(devno: culong): PChar; cdecl; external libblkid;
  23. procedure blkid_put_cache(cache: Pblkid_cache); cdecl; external libblkid;
  24.  
  25. var
  26.   cache: Pblkid_cache;
  27.   dev: Pblkid_dev;
  28.   devname, uuid, fstype, labelstr: PChar;
  29.  
  30. begin
  31.   // Initialize the blkid cache
  32.   if blkid_get_cache(cache, nil) < 0 then
  33.   begin
  34.     WriteLn('Failed to initialize cache');
  35.     Halt(1);
  36.   end;
  37.  
  38.   // Retrieve device information
  39.   dev := blkid_get_dev(cache, PChar(ParamStr(1)), BLKID_DEV_NORMAL);
  40.   if dev <> nil then
  41.   begin
  42.     devname := blkid_dev_devname(dev);
  43.     WriteLn('Device name: ', devname);
  44.    
  45.     // Get UUID
  46.     uuid := blkid_get_tag_value(cache, 'UUID', devname);
  47.     if uuid <> nil then
  48.       WriteLn('Device UUID: ', uuid)
  49.     else
  50.       WriteLn('UUID: not found');
  51.    
  52.     // Get filesystem type
  53.     fstype := blkid_get_tag_value(cache, 'TYPE', devname);
  54.     if fstype <> nil then
  55.       WriteLn('Filesystem: ', fstype)
  56.     else
  57.       WriteLn('Filesystem: not found');
  58.    
  59.     // Get label
  60.     labelstr := blkid_get_tag_value(cache, 'LABEL', devname);
  61.     if labelstr <> nil then
  62.       WriteLn('Label: ', labelstr)
  63.     else
  64.       WriteLn('Label: not found');
  65.   end
  66.   else
  67.   begin
  68.     WriteLn('Device not found.');
  69.   end;
  70.  
  71.   // Free the cache
  72.   blkid_put_cache(cache);
  73. end.
The opaquedata types are something I introduced in system a couple of years ago:
The above is a good example of its use.

Sample output:
Code: Text  [Select][+][-]
  1. $ ./blkidexample /dev/sdd
  2. Device name: /dev/sdd
  3. Device UUID: 4c4ca96c-e3ef-43d1-b3f5-6b2869757af3
  4. Filesystem: ext4
  5. Label: not found

Tested Ubuntu lts24 and Debian trixie. both 64 bit intel.

@Harmut lsblk uses the same library.
@Bart The first C code was wrong, this code is based on my development version.
Note that not every drive has a UUID. (same as on Windows, btw)
« Last Edit: November 16, 2025, 09:42:52 am by Thaddy »
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

Bart

  • Hero Member
  • *****
  • Posts: 5648
    • Bart en Mariska's Webstek
Re: Get "serial number" of (removable) disk
« Reply #4 on: November 16, 2025, 11:05:18 pm »
The benefit is, that each value which I ever may need has a fixed column in the result which makes common parsing easier.

But, what's up with the SIZE column?
It seems that for all other columns, the values start at the same point as where the name of the colums starts, but SIZE seems to be right-justified (both the column nam and it's values)?
How then do you know, at what point the values of SIZE start and where they end?

Bart

Aruna

  • Hero Member
  • *****
  • Posts: 764
Re: Get "serial number" of (removable) disk
« Reply #5 on: November 17, 2025, 04:26:04 am »
The benefit is, that each value which I ever may need has a fixed column in the result which makes common parsing easier.

But, what's up with the SIZE column?
It seems that for all other columns, the values start at the same point as where the name of the colums starts, but SIZE seems to be right-justified (both the column nam and it's values)?
How then do you know, at what point the values of SIZE start and where they end?

Bart

Use -P / --pairs option. (Produces KEY="VALUE" format).
Code: Text  [Select][+][-]
  1. aruna@debian:~/console$ lsblk -p -o NAME,RM,LABEL,SIZE,UUID,SERIAL,FSTYPE,PTTYPE,MODEL
  2. NAME        RM LABEL              SIZE UUID                                 SERIAL           FSTYPE PTTYPE MODEL
  3. /dev/sda     0                  931.5G                                      S1DGB98C                dos    ST1000DM003-1CH162
  4. ├─/dev/sda1  0 Ubuntu 12.04.4 L   250G 092d3383-368f-4945-b0c7-b1a3d3ed64df                  ext4   dos    
  5. ├─/dev/sda2  0 kernel-stuff       250G 15684a31-dbbf-4411-8fe9-593d79d3a86f                  ext4   dos    
  6. ├─/dev/sda3  0 back-up           16.8G b416f822-d40a-44ba-a4ca-82a3c65705e0                  ext4   dos    
  7. ├─/dev/sda4  0                      1K                                                              dos    
  8. ├─/dev/sda5  0                    204G 3c8fce17-5948-43e7-9662-921e65c7faa7                  ext3   dos    
  9. ├─/dev/sda6  0                  196.9G 200f9328-ae6b-4fe9-9d94-24ffd391bbe9                  ext4   dos    
  10. ├─/dev/sda7  0                    6.2G 561317be-3304-4d36-ab68-301c6fb8d2ec                  swap   dos    
  11. └─/dev/sda8  0                    7.7G eaadb2c8-4967-47e4-90eb-e012cdded9b0                  swap   dos    
  12. /dev/sdb     0                  232.9G                                      JP0272J20E462M          dos    Hitachi HDS721025CLA682
  13. ├─/dev/sdb1  0 System Reserved    100M 72E2E3AAE2E370B1                                      ntfs   dos    
  14. ├─/dev/sdb2  0 OS               212.2G 46C81FD6C81FC2DB                                      ntfs   dos    
  15. ├─/dev/sdb3  0                      1K                                                              dos    
  16. ├─/dev/sdb5  0                   19.7G 460c8aa0-2f69-43ef-887c-0b14e6ecff68                  ext4   dos    
  17. └─/dev/sdb6  0                    903M 25fda5b3-7fff-45b0-900d-54d07f5afbef                  swap   dos    
  18. /dev/sdc     0                  931.5G                                      WD-WCC3F4NA3TFY         dos    WDC WD10EZEX-75M2NA0
  19. ├─/dev/sdc1  0                  930.6G 94b73f9c-748d-4bd9-876b-3281762b03c6                  ext4   dos    
  20. ├─/dev/sdc2  0                      1K                                                              dos    
  21. └─/dev/sdc5  0                    976M b1d91238-053b-44b0-b329-98d0bf73eb87                  swap   dos    
  22. /dev/sdd     1                      0B                                      0000000000000006               Compact Flash
  23. /dev/sde     1                      0B                                      0000000000000006               SM/xD-Picture
  24. /dev/sdf     1                      0B                                      0000000000000006               SDXC/MMC
  25. /dev/sdg     1                      0B                                      0000000000000006               MS/MS-Pro/HG
  26. /dev/sdh     1                      0B                                      0000000000000006               SD/MMC/MS/MSPRO
  27. /dev/sr0     1                   1024M                                      KK3D9KI3929                    HL-DT-ST DVDRAM GH24NSB0
  28. aruna@debian:~/console$
  29.  
  30.  

Your friend is:
Code: Text  [Select][+][-]
  1. lsblk -h

-J gives you JSON.
Code: Text  [Select][+][-]
  1. aruna@debian:~/console$ lsblk -J /dev/sda -o NAME,SIZE,LABEL,TYPE,MODEL
  2. {
  3.    "blockdevices": [
  4.       {
  5.          "name": "sda",
  6.          "size": "931.5G",
  7.          "label": null,
  8.          "type": "disk",
  9.          "model": "ST1000DM003-1CH162",
  10.          "children": [
  11.             {
  12.                "name": "sda1",
  13.                "size": "250G",
  14.                "label": "Ubuntu 12.04.4 L",
  15.                "type": "part",
  16.                "model": null
  17.             },{
  18.                "name": "sda2",
  19.                "size": "250G",
  20.                "label": "kernel-stuff",
  21.                "type": "part",
  22.                "model": null
  23.             },{
  24.                "name": "sda3",
  25.                "size": "16.8G",
  26.                "label": "back-up",
  27.                "type": "part",
  28.                "model": null
  29.             },{
  30.                "name": "sda4",
  31.                "size": "1K",
  32.                "label": null,
  33.                "type": "part",
  34.                "model": null
  35.             },{
  36.                "name": "sda5",
  37.                "size": "204G",
  38.                "label": null,
  39.                "type": "part",
  40.                "model": null
  41.             },{
  42.                "name": "sda6",
  43.                "size": "196.9G",
  44.                "label": null,
  45.                "type": "part",
  46.                "model": null
  47.             },{
  48.                "name": "sda7",
  49.                "size": "6.2G",
  50.                "label": null,
  51.                "type": "part",
  52.                "model": null
  53.             },{
  54.                "name": "sda8",
  55.                "size": "7.7G",
  56.                "label": null,
  57.                "type": "part",
  58.                "model": null
  59.             }
  60.          ]
  61.       }
  62.    ]
  63. }
  64.  
« Last Edit: November 17, 2025, 04:51:13 am by Aruna »

Hartmut

  • Hero Member
  • *****
  • Posts: 1028
Re: Get "serial number" of (removable) disk
« Reply #6 on: November 17, 2025, 08:48:22 am »
The benefit is, that each value which I ever may need has a fixed column in the result which makes common parsing easier.

But, what's up with the SIZE column?
It seems that for all other columns, the values start at the same point as where the name of the colums starts, but SIZE seems to be right-justified (both the column nam and it's values)?
How then do you know, at what point the values of SIZE start and where they end?

Bart

I'm sorry, I gave you the wrong parameters (picked up a line which I had only used for testing purposes). I recommend to use:
lsblk -l -e 7 -oNAME,FSTYPE,UUID,PARTTYPE,TYPE,MOUNTPOINT

The result of above command looks like this:
Code: Text  [Select][+][-]
  1. NAME FSTYPE UUID                                 PARTTYPE TYPE MOUNTPOINT
  2. sda                                                       disk
  3. sda1 ntfs   60D898E99C1DD456                     0x7      part
  4. sda2 vfat   BE2A-F2D1                            0xe      part /media/D
  5. sda3                                             0xf      part
  6. sda4 ext4   ada05431-c5b7-4241-b1a8-ecbfe2d987cb 0x83     part /
  7. sda5 vfat   5B53-12F7                            0x6      part
  8. sda6 vfat   A1FF-3DF2                            0x6      part /media/F
  9. sda7 ntfs   6532098E648037CE                     0x7      part
  10. sda8 ntfs   D09567D4F718A7BA                     0x7      part /media/H
  11. sda9 vfat   4749-6ED3                            0xb      part /media/X
  12. sdb                                                       disk
  13. sdb1 ntfs   58F4C81735ED08D0                     0x7      part
  14. sdb2 ext4   0cdde00b-c715-4d01-8938-b7174f9f574d 0x83     part
  15. sdc                                                       disk
  16. sdd                                                       disk
  17. sdd1 vfat   08BB-83BA                            0xc      part /media/hg6/NETAC
  18. sde                                                       disk
  19. sde1 vfat   D3C0-2DE8                            0xc      part /media/hg6/STORE N GO

I placed colum MOUNTPOINT as the last colum, because it is the only one which can contain blanks.
Some parsing hints:
 - split each line into "words" (separated by blanks)
 - skip all lines which have less than 5 "words" (they have no UUID)
 - if you want to find the requested line by NAME it should be easy
 - if you want to find the requested line by MOUNTPOINT and if this can contain blanks in your case, then you must determine the start of the 6th "word" and use everything from this position on. Or search for the 1st "/" and use everything from this position on.

If you need more help you are welcome.

Bart

  • Hero Member
  • *****
  • Posts: 5648
    • Bart en Mariska's Webstek
Re: Get "serial number" of (removable) disk
« Reply #7 on: November 17, 2025, 11:18:07 am »
My solution would have been to drop SIZE as well.
I think the order does not matter that much, since (at least it looks that way) all fields have fixed sizes, which can be determined by examining the header (first line).
For the last field you can simply use Copy(Line, StartPos, MaxInt).

Thanks for the help so far.
I'm not in a rush, just getting familiar with this kind of stuff.

Bart

Aruna

  • Hero Member
  • *****
  • Posts: 764
Re: Get "serial number" of (removable) disk
« Reply #8 on: November 20, 2025, 01:51:15 am »
Hi,

On Windows it's relatively easy to obtain the "Volume Serial" of a disk.
I use this for one of my utilities that copies graphical files from SD-cards.
I store the serial number with thet last time the program copied the files, so when I ind=sert the same SD-card next time, I can offer the options "copy files newer than <last visted date and time>".

Since I've move my trusty old laptop to Linux (Mint 22.0 Mate), I would like to achiev the same (or similar) on Linux.
Bart

Hi, the attached console program does the job. Simple, lean, and blazing fast!   

Bart

  • Hero Member
  • *****
  • Posts: 5648
    • Bart en Mariska's Webstek
Re: Get "serial number" of (removable) disk
« Reply #9 on: November 20, 2025, 06:49:45 pm »
Hi, the attached console program does the job. Simple, lean, and blazing fast!

Thanks for the example.
In the mean time I've written my own parser for the lsblk output.
Maybe not very fast, but since this is about disk IO, it'll be orders of magnitude faste than the actual runnig of lsblk.

In the long run I'm plannig to make a TBlockDeviceComboBox usable on Windows and Linux, where I can fill it's contents depending onm e.g. disk type and wether or not "disk in drive".

Bart

PascalDragon

  • Hero Member
  • *****
  • Posts: 6235
  • Compiler Developer
Re: Get "serial number" of (removable) disk
« Reply #10 on: November 20, 2025, 09:48:48 pm »
On Windows it's relatively easy to obtain the "Volume Serial" of a disk.

Please note that this is the “Volume ID” or “File system ID” of the volume or file system, not of the disk. If the disk is partitioned with MBR or GPT it will have its own “Disk ID”. And the disk itself will also have one or more hardware serials. E.g. if you have a ATA disk attached to a USB adapter you will have the USB serial, the SCSI VPD serial and the ATA serial or if you have a NVMe you'll have the controller serial, the namespace EUI and the namespace GUID.

So while you clarified that you need this for detecting the same file system (for which the volume ID is fine) the title is a bit misleading in that regard.

Bart

  • Hero Member
  • *****
  • Posts: 5648
    • Bart en Mariska's Webstek
Re: Get "serial number" of (removable) disk
« Reply #11 on: November 20, 2025, 11:30:28 pm »
Yes, I found that out by now.
But, for my needs, what I've got so far (SerialID that GetVolumeInfo, which is the same as UUID that lsblk gives) is what I need.
It identifies this particular disk with the current filesystem on it (well: this filesystem on this particular disk).
Ir's the contenst of the disc I'm interested in.
If someone formats the disk or changes the filesystem, it'll be  a "new" disk for all intends and purposes (in the context of my program).

It might not be fail safe, but for my simple needs it will do.

Bart

Aruna

  • Hero Member
  • *****
  • Posts: 764
Re: Get "serial number" of (removable) disk
« Reply #12 on: November 21, 2025, 03:44:42 am »
Hi, the attached console program does the job. Simple, lean, and blazing fast!

Thanks for the example.
Your most welcome.
In the mean time I've written my own parser for the lsblk output.
Maybe not very fast, but since this is about disk IO, it'll be orders of magnitude faste than the actual runnig of lsblk.

In the long run I'm plannig to make a TBlockDeviceComboBox usable on Windows and Linux, where I can fill it's contents depending onm e.g. disk type and wether or not "disk in drive".

Bart
I would love to see your parser once finished if we may? I did something similar a while back and all I am saying is if your going with a Tcombo or TStringGrid may all the gods grant you patience and strength. It is doable but why go bald trying when a Tmemo gets the job done and very well with a mono space font  ;)  I have attached a zip which hopefully will get you started. The screenshots speak for themselevs.

d2010

  • Full Member
  • ***
  • Posts: 235
Re: Get "serial number" of (removable) disk
« Reply #13 on: November 21, 2025, 07:43:01 am »

Code: Pascal  [Select][+][-]
  1. //nb: GetDiskFree() is used internally only when creating
  2. //multi-disk archives on floppies so I've chosen to ignore free space > 2gig
  3. function GetDiskFree(const Filename: string): cardinal;
  4. var
  5.    SectorsPCluster, BytesPSector, FreeClusters, TotalClusters: DWORD;
  6.    Drive: string;
  7. begin
  8.    Result   := 0;
  9.    if (length(Filename) < 3) or (pos(':\',Filename) <> 2) then exit;
  10.    Drive := copy(Filename,1,3);
  11.    if GetDiskFreeSpace( pChar( Drive ),
  12.      SectorsPCluster, BytesPSector, FreeClusters, TotalClusters ) then
  13.         result := FreeClusters * SectorsPCluster * BytesPSector;
  14. end;
  15. //---------------------------------------------------------------------
  16.  
  17. function GetVolumeName(DrivePath: string; out VolumeName: string): boolean;
  18. var
  19.   OldErrMode: dword;
  20.   VolName: array[0..255] of char; //nb: can be > 11 chars with NTFS drives
  21.   dummy1: {$IFDEF VER120_PLUS}Cardinal{$ELSE}Integer{$ENDIF};
  22.   dummy2: dword;
  23. begin
  24.   DrivePath := AppendSlash(DrivePath);
  25.   OldErrMode := SetErrorMode( SEM_FAILCRITICALERRORS );
  26.   result := GetVolumeInformation(pchar(DrivePath),
  27.                VolName, sizeof(VolName), nil, dummy1, dummy2, nil, 0 );
  28.   if result then VolumeName := VolName;
  29.   SetErrorMode( OldErrMode );
  30. end;
  31.  


Thaddy

  • Hero Member
  • *****
  • Posts: 18521
  • Here stood a man who saw the Elbe and jumped it.
Re: Get "serial number" of (removable) disk
« Reply #14 on: November 21, 2025, 10:22:40 am »
That is Windows.... Did you read the original question? I answered that.
As did some others by deferring to TProcess.. I gave the code.
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

 

TinyPortal © 2005-2018