Solved

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

Posted on 1997-05-13
8
1,181 Views
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?
0
Comment
Question by:ehilder
8 Comments
 
LVL 2

Expert Comment

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

Author Comment

by:ehilder
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.
0
 

Expert Comment

by:claudeb
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
  }
}

0
 

Author Comment

by:ehilder
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?
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 23

Accepted Solution

by:
chensu earned 150 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
                   length
                       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
                  ----------------------------------------------------------------------
                   
                  SUMMARY
                  =======
                   
                  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
                     incorrectly.
                   
                  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);
                      exit(-1);
                     }
                   
                     /*** 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.

0
 

Author Comment

by:ehilder
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?
0
 
LVL 23

Expert Comment

by:chensu
ID: 1163384
The following is the example using GetVolumeInformation.

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

CHAR szBuf[256];
      ::wsprintf(szBuf,
                   "szVolumeName = %s\n"
                   "dwVolSerialNum = %lX\n"
                   "dwMaxCompLen = %lu\n"
                     "dwFSFlags = %lu\n"
                     "szFSName = %s\n",
                     szVolumeName,
               dwVolSerialNum,
               dwMaxCompLen,
               dwFSFlags,
               szFSName);
      ::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.

0
 
LVL 23

Expert Comment

by:chensu
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.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
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.

863 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

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now