Locating an Application CD

Home | Up | Search | X-Zone News | Services | Book Support | Links | Feedback | Smalltalk MT | The Scrapyard | FAQ | Technical Articles

 

Locating your Application's CD on the User's System

Written by Robert Dunlop
Microsoft DirectX MVP

Introduction

When releasing a title, one of the issues that often arises is how to deal with the fact the files will not be located on the user's system at the same path that they are available on your development systems.

Much of the problems that occur are because of absolute addressing, that is, paths that specify a location based upon the root of the drive  This is easily avoided by strictly using relative addressing from the start, and with proper management is not a problem.  Normally an application is started within the installed directory, and can use relative paths to access subdirectories without a hitch.

The Problem of Removable Media

With the increasing bulk of media in today's games, however, it is often not practical to place the whole game on the user's hard drive.  To support a larger customer base, installers usually offer options for varying levels of file migration to the local drive, and rely on the application disk being available in the CD-ROM drive during use.

This can cause a number of difficult problems:

bulletThe application directory on the hard drive and the CD-ROM volume do not have a specific relative path that can be relied on.
bulletThe CD-ROM drives could be anywhere within the range of drive letters.
bulletThe drive letter assignment of the CD could change due to hardware changes, or even just due to drive mapping changes.
bulletThere may be multiple CD drives available, so how to determine which drive contains the CD.

Avoiding the Mayhem

There are a variety of approaches that have been taken, some of which have shortcomings when put out in the field.  I will provide a method that has worked well for me.  To start, let's take a look at the basic steps that are performed:

  1. The GetLogicalDrives() function is called, which returns a bitmask indicating which drive  letters are valid.
  2. Next, we loop through the 26 possible drive letters (A-Z) and check the bitmask for available drive.
  3. When one is found, GetDriveType() is called to determine if the drive is a CD-ROM drive, as opposed to a hard drive, floppy drive, or network drive.
  4. If the drive is a CD-ROM drive, next we read in the volume label with GetVolumeInformation() and compare it to the correct label.
  5. If the search completes without finding the CD, the user is prompted for the disk, and they are given the option to retry or cancel the load of the application.

It may look like overkill at first, but the operation is very quick and it insures less problems in the field.  Often I have seen applications that will take most, but not all, of this path - sometimes resulting in system specific problems.  To give an idea of the range of problems that I have seen:

bulletApplications that try to load off of the first CD drive that they find restrict the use to that drive.  The first drive might be a low speed burner, instead of the 32x drive that the user would prefer to use.
bulletPrograms that assume that the CD drive that the game was installed from will be constant will often stop working after configuration changes, requiring a new installation.
bulletIf your application requires the CD to be available for the application to execute, to lower piracy concerns, an application that only checks volume labels is easy to trick by creating a partition with the same volume label.  By checking the drive type, you insure that it really is a CD and not a hard drive with an unlicensed copy of your software.
bulletSome applications scan through the drives and try to read known files that are on the CD.  This can take quite a bit of time on some systems, especially if there is a CD changer installed.  Usually the volume name will be cached on insertion, and not require you to spin the drive back up to find out.

I can think of many other issues that I have encountered, but you probably didn't come here to listen to me gripe ;-)  So, without further adieu, I have included source code for CD detection and volume name verification.  I have utilized this in quite a few applications without problem, but one note of caution : 

This code is freshly stripped out of my code library, and I have removed some things that are specific to my existing in-house libraries.  I don't suspect any issues, but if you should have any problems e-mail me at rdunlop@mvps.org and I will update the code on this site right away. 

#define VOL_NAME "GAMEVOL"
char dr_str[]="c:\\";		// drive path
BOOL log_disk(void)
{
	int i;					// general index counter
	DWORD drives;				// drive bit map
	BOOL status;				// return status from volume function
	char vol_buf[40];			// volume name buffer
	DWORD max_file_len;			// maximum file length
	DWORD system_flags;			// volume file system flags
	int stat;				// message box return value
	// find what drives are available
lp:	drives=GetLogicalDrives();
	// loop through drives
	for (i=0;i<26;i++) {
		// is this drive available?
		if (drives&(1<<i)) {
			// yes, is it a CD?
			dr_str[0]='A'+i;
			UINT driveType=GetDriveType(dr_str);
			if (driveType==DRIVE_CDROM) {
				// yes, get the volume name
				SetErrorMode(SEM_FAILCRITICALERRORS);
				status=GetVolumeInformation(dr_str,
							    vol_buf,
							    sizeof(vol_buf),
							    NULL,
							    &max_file_len,
							    &system_flags,
							    NULL,NULL);
				SetErrorMode(0);
				// did we successfully get it?
				if (status) {
					// yes, is this the one?
					if (!memicmp(vol_buf,VOL_NAME,sizeof(VOL_NAME))) {
						// yes, return success to caller
						return TRUE;
					}
				}
			}
		}
	}
	// not found, display error message and query user
	stat=MessageBox(NULL,"Please Insert Game CD","CD Not Found",
						MB_ABORTRETRY|MB_ICONEXCLAMATION);
	// does the user want to retry?
	if (stat==IDRETRY)
		// yes, try again
		goto lp;
	// return failure to caller
	return FALSE;   
}

This site, created by DirectX MVP Robert Dunlop and aided by the work of other volunteers, provides a free on-line resource for DirectX programmers.

Special thanks to WWW.MVPS.ORG, for providing a permanent home for this site.

Visitors Since 1/1/2000: Hit Counter
Last updated: 07/26/05.