Accessing HDD serial #

Posted on 1997-04-14
Last Modified: 2013-12-03
I need to be able to access the serial number of any given disk drive (ie. the one that comes up every time you do a dir from DOS) from within Windows.  The only functions I could find are in the File Manager extension library, which require the File Manager.  How do you get this info direct from Windows?
Question by:scce
  • 3
  • 2
LVL 23

Accepted Solution

chensu earned 100 total points
ID: 1334598
The Win32 function GetVolumeInformation() returns this info.

BOOL GetVolumeInformation(
    LPCTSTR lpRootPathName,      // address of root directory of the file system
    LPTSTR lpVolumeNameBuffer,      // address of name of the volume
    DWORD nVolumeNameSize,      // length of lpVolumeNameBuffer
    LPDWORD lpVolumeSerialNumber,      // address of volume serial number
    LPDWORD lpMaximumComponentLength,      // address of system's maximum filename length
    LPDWORD lpFileSystemFlags,      // address of file system flags
    LPTSTR lpFileSystemNameBuffer,      // address of name of file system
    DWORD nFileSystemNameSize       // length of lpFileSystemNameBuffer
LVL 23

Expert Comment

ID: 1334599
My answer is for 32-bit applications only. In case you are writing 16-bit applications, I copied an article from Visaul C++ KBase here.

Retrieving a Disk Volume Serial Number from C  

PSS ID Number: Q69223
Article last modified on 01-24-1995
5.10 6.00 6.00a 6.00ax 7.00 | 1.00 1.50
MS-DOS                      | WINDOWS

The information in this article applies to:
 - The C Run-time (CRT) included with:
    - Microsoft C for MS-DOS, versions 5.1, 6.0, 6.0a, and 6.0ax
    - Microsoft C/C++ for MS-DOS, version 7.0
    - Microsoft Visual C++ for Windows, versions 1.0 and 1.5
Beginning with MS-DOS version 4.0, a semi-random 32-bit binary
identification number (ID) is assigned to each disk that MS-DOS
formats. The volume serial number (or ID) is stored at offset 27H to
2AH in the boot sector of each disk.
NOTE: code compiled with Visual C++ version 1.5 may yield the following
message from Windows NT:
   An applicaion has attempted to directly access the hard disk, which
   cannot be supported. This may cause the application to function
It provides Terminate and Ignore buttons. If the user is logged on with
Administrative privileges, this will succeed for a FAT partition, else it
fails for a FAT partition. It always fails for an NTFS partition. After
clicking Terminate or Ignore the program returns with the error message
that has been coded (error on int 25).
The following program illustrates how to retrieve this information:
/*                                                             */
/* This program reads the volume serial number (or ID) from    */
/* the boot sector of a specified disk. The DOS interrupt 25   */
/* Absolute Disk Read is used to read in the boot sector.      */
/*                                                             */
/* Note: The volume ID is only implemented from MS-DOS 4.0     */
/*       and later.                                            */
/*                                                             */
/* The output consists of the OEM name and version of the      */
/* disk-formatting program (stored at offset 03H to 0AH in the */
/* boot sector), the disk volume label, and the disk-volume    */
/* serial number.                                              */
/*                                                             */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dos.h>
#include <conio.h>
char bootsector[1024];
char volume[12];
char ver[9];
char block[10];
void main(void)
   int ax, _far *p, drive;
   struct find_t fileinfo;
   char filename[13], _far *myvar, _far *q;
   union REGS inregs, outregs;
   struct SREGS segregs;
   printf("Enter drive number (0=A,1=B,2=C, ...): ");
   drive = getche() - '0';
   /* Parameter block for int 25H        */
   /* Bytes    Description               */
   /* -------  -----------               */
   /* 00H-03H  32-bit sector number      */
   /* 04H-05H  Number of sectors to read */
   /* 06H-07H  Offset of buffer          */
   /* 08H-09H  Segment of buffer         */
   block[0] = block[1] = block[2] = block[3] = 0;
   block[4] = 1;
   block[5] = 0;
   myvar = bootsector;
   p = (int *)&block[6];
   *p = FP_OFF(myvar);
   p = (int *)&block[8];
   *p = FP_SEG(myvar);
   q = block; = (char)drive; = -1;
   inregs.x.bx = FP_OFF(q);
   segregs.ds = FP_SEG(q);
   ax = int86x(0x25, &inregs, &outregs, &segregs);
   /*** Error routine ***/
   if (outregs.x.cflag)
      printf("\n\nerror on int 25\n");
      printf("this is AX:%04X", ax);
   /*** Output ***/
   printf("\n\nDrive %c\n-------\n\n", drive +'A');
   strncpy(ver, &bootsector[3], 8);
   printf("OEM name and version: %s\n", ver);
   /* Use _dos_findfirst for the volume label */
   filename[0] = (char)(drive + 'A');
   filename[1] = '\0';
   strcat(filename, ":\\*.*");
   if(!_dos_findfirst(filename, _A_VOLID, &fileinfo))
   printf("Volume name         : %s\n",;
   /* Before printing serial number, check if version >= 4.x */
   if ((ver[6] == '.') && (ver[5] >= '4') && (ver[5] <= '9'))
      printf("Serial number       : %02X%02X-%02X%02X\n\n",
                              (unsigned char) bootsector[0x2a],
                              (unsigned char) bootsector[0x29],
                              (unsigned char) bootsector[0x28],
                              (unsigned char) bootsector[0x27]);
Additional reference words: kbinf 5.10 6.00 6.00a 6.00ax 7.00 1.00 1.50
KBCategory: kbprg
KBSubcategory: CRTIss
Copyright Microsoft Corporation 1995.



Author Comment

ID: 1334600
To chensu,

Thanks, that was exactly what I was after - just as well you added the comment, since it is in fact Win16 I'm targetting.  Since the solution for this platform involves the low-level DOS interrupt, will it work with Win NT/95? Do you know if it returns a sensible answer for net/removable drives?

You can contact me on

Thanks again,

LVL 23

Expert Comment

ID: 1334601
Yes, it will work with Win NT/95 since your program is 16-bit. Win32 does not support most of the DOS interrupt. And it will work with removeable drives such as floppy drives. But I am not sure if it will work with network drives (I think it is unlikely).

Good Luck!


Author Comment

ID: 1334602
Thank you!

Featured Post

3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

As more and more people are shifting to the latest .Net frameworks, the windows presentation framework is gaining importance by the day. Many people are now turning to WPF controls to provide a rich user experience. I have been using WPF controls fo…
For most people, the WrapPanel seems like a magic when they switch from WinForms to WPF. Most of us will think that the code that is used to write a control like that would be difficult. However, most of the work is done by the WPF engine, and the W…
This Micro Tutorial hows how you can integrate  Mac OSX to a Windows Active Directory Domain. Apple has made it easy to allow users to bind their macs to a windows domain with relative ease. The following video show how to bind OSX Mavericks to …
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA.…

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question