Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium


Getting the Volume Serial Number using Borland C++ 4.5 (16-Bit)

Posted on 1997-05-13
Medium Priority
Last Modified: 2008-03-03
I am trying to write a dll in C++ that will return the Volume Serial Number of any drive (or at least Drive C:).  I am not sure exactly how to do this.  I'm sure there is a pretty easy way, but I am new at C and have very little time to learn it.  Could someone send me source for a simple 16-bit DLL that will return the Volume Serial Number?
Question by:ehilder

Expert Comment

ID: 1163378
Could you tell us some information concerning your environment? (Win 3.1x, Win95/NT). Do you absolutly need a 16-bit dll?

Author Comment

ID: 1163379
The application that will use the DLL is designed in Visual D-Base.  The application will be run on all platforms of Windows. (3.1x, Win95 and WinNt)  Since it is possible that the application will be run on Windows 3.1 without Win32s, I would prefer a 16-bit DLL.  If this is absolutely impossible, I could recommend that the application be run only in 32-bit mode.

Expert Comment

ID: 1163380
The following function will return you the volume name and serial number of any drive.

static      void      Get_Volume_Info(int Disk, char *Vol, char *SSN)
  unsigned      char buf[1024];
  int           i;

  strcpy(Vol, "");
  strcpy(SSN, "");

  i = biosdisk(2, Disk, Disk >= 0x80 ? 1 : 0, 0, 1, 1, &buf);
  if(i == 0)
#pragma warn -ucp
    strncpy(Vol, buf+0x2B, 11);
    Vol[11] = '\0';
    sprintf(SSN, "%02X%02X-%02X%02X", buf[0x2a], buf[0x29],       buf[0x28], buf[0x27]);
#pragma warn +ucp

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.


Author Comment

ID: 1163381
I know that I am new to C, but I was just wondering...  How exactly do you use a DOS ONLY function in a Windows DLL?
LVL 23

Accepted Solution

chensu earned 300 total points
ID: 1163382
I answered a similar question in Microsoft Windows Programming Topic Area. (4/14/97  10 Accessing HDD serial # <PAQ>)

For 32-bit:
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
                       LPDWORD lpFileSystemFlags, // address of file system flags
                       LPTSTR lpFileSystemNameBuffer, // address of name of file system
                       DWORD nFileSystemNameSize // length of lpFileSystemNameBuffer

For 16-bit:
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).
                  MORE INFORMATION
                  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;
                     inregs.h.al = (char)drive;
                     inregs.x.cx = -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", fileinfo.name);
                     /* 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: 1163383
The 16-Bit example works great, but I do need a little more information.  I am increasing the points to 150.

I am new to C++ and I was wondering if you could post an example using the GetVolumeInformation() function in Win32.  Also, is there a way to tell if Windows is running 16-bit or 32-bit.  
The reasoning is that this DLL needs to run in 16-bit and 32-bit and on Windows NT.

If I can tell that Windows is running in 32-bit, I can branch from the 16-bit routine to the 32-bit routine.  Even if they are in two DLL's.  Can you test for 32-bit mode in a 16-bit DLL???  If so, this is how I would like to work it.

Does this make sense?
LVL 23

Expert Comment

ID: 1163384
The following is the example using GetVolumeInformation.

CHAR szVolumeName[MAX_PATH], szFSName[MAX_PATH];
      DWORD dwVolSerialNum,
      ::GetVolumeInformation("c:\\",  // "d:\\" for d:, NULL for current directory

CHAR szBuf[256];
                   "szVolumeName = %s\n"
                   "dwVolSerialNum = %lX\n"
                   "dwMaxCompLen = %lu\n"
                     "dwFSFlags = %lu\n"
                     "szFSName = %s\n",
      ::MessageBox(NULL, szBuf, "GetVolumeInformation", MB_OK);

If your program is 32-bit, it must be running on a 32-bit platform (including Win32s on Windows 3.1, you can check it with GetVersionEx function). A 16-bit platform cannot run a 32-bit program.

If your program is 16-bit, it may be running on a 16-bit platform or a 32-bit platform. You can check the version with GetVersion function in a 16-bit program. For Windows 3.1, it returns version 3.1. For Windows 95, it returns version 3.95. I have not tried it on Windows NT. However, you cannot call a 32-bit DLL from a 16-bit program or DLL although you can run a 32-bit EXE from a 16-bit program or DLL.

So, in your case, you might need to provide two version: one is 16-bit, another is 32-bit.

LVL 23

Expert Comment

ID: 1163385
Sorry, I think I made a mistake. I said "you cannot call a 32-bit DLL from a 16-bit program or DLL". In fact, there is a way to do so. Generic Thunks allow a 16-bit Windows-based application to load and call a Win32-based DLL on Windows NT and Windows 95. See the following Win32 SDK documentation:
Win32 SDK/Programming Guides and Tools/Programming Techniques/Generic Thunks.

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
Suggested Courses

577 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