415 lines
12 KiB
C++

/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/****************************************************************************
***** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *****
****************************************************************************
* Project Name:: Command & Conquer *
* $Archive:: /Renegade Setup/Autorun/GETCD.CPP $Author:: Steve_t *
* $Modtime:: 1/28/02 10:54a $Revision:: 20 *
*--------------------------------------------------------------------------*
* Functions: *
* GetCDClass::GetCDClass -- default constructor *
* GetCDClass::~GetCDClass -- destructor *
* GetCDClass::GetCDDrive -- returns the logical CD drive *
* CD_Volume_Verification -- Check label of the CDRom. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
#include <windows.h>
#include <string.h>
//#include "always.h"
#include "getcd.h"
//#include "timer.h"
#include "wnd_file.h"
//#include "missiondisk.h"
#include "winfix.h"
#ifndef ROR_NOT_READY
#define ROR_NOT_READY 21
#endif
/**********************************************************************
** This macro serves as a general way to determine the number of elements
** within an array.
*/
#define ARRAY_SIZE(x) int(sizeof(x)/sizeof(x[0]))
#define size_of(typ,id) sizeof(((typ*)0)->id)
//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------
#if ( MISSION_DISK )
static char * _CD_Volume_Label[] = {
"Renegade Mission", // Yuri's Revenge (mission disk)
};
#else
static char * _CD_Volume_Label[] = {
"Renegade Game", // Red Alert 2
"Renegade Data", // Red Alert 2
};
#endif
static int _Num_Volumes = ARRAY_SIZE( _CD_Volume_Label );
GetCDClass CDList;
/****************************************************************************
* GetCDClass -- default constructor *
* *
* INPUT: *
* none *
* OUTPUT: *
* none *
* WARNINGS: *
* *
* HISTORY: *
* 05/26/1994 SW : Created. *
* 12/04/1995 ST : fixed for Win95 *
*==========================================================================*/
GetCDClass::GetCDClass( void )
{
char path[]={ "a:\\" };
CDCount = 0;
CDIndex = 0;
Msg( __LINE__, __FILE__, "GetCDClass constructor\n" );
/*--------------------------------------------------------------------------
** Set all CD drive placeholders to empty
*/
for( int j = 0; j < MAX_CD_DRIVES; j++ ) {
CDDrives[j] = NO_CD_DRIVE;
}
for( char i = 'c'; i <= 'z'; i++ ) {
path[0] = i;
if ( GetDriveType( path ) == DRIVE_CDROM ) {
CDDrives[ CDCount++ ] = (int)( i-'a' );
Msg( __LINE__, __FILE__, "CD drive found - %c:\n", i +'A'-'a' );
}
}
/*--------------------------------------------------------------------------
** Catch the case when there are NO CD-ROM drives available
*/
if ( CDCount == 0 ) {
for ( char i = 'a'; i <= 'b'; i++ ) {
path[0] = i;
if ( GetDriveType( path ) == DRIVE_CDROM ) {
CDDrives[ CDCount++ ] = (int)( i-'a' );
}
}
}
if ( CDCount == 0 ) {
Msg( __LINE__, __FILE__, "No CD drives found\n");
}
}
/********************************************************************************
* GetCDClass -- destructor *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: *
* *
* HISTORY: *
* 05/26/1994 SW: Created. *
* 12/4/95 ST: fixed for Win95 *
*==============================================================================*/
GetCDClass::~GetCDClass(void)
{
// if(cdDrive_addrp.seg)
// DPMI_real_free(cdDrive_addrp); // free up those conventional buffers
}
/********************************************************************************
* GetCDClass -- Get_CD_Drive_For_This_Volume *
* *
* INPUT: char *volume_name *
* *
* OUTPUT: int *
* *
* WARNINGS: *
* *
* HISTORY: *
* 10/18/2000 MML: Created. *
*==============================================================================*/
int GetCDClass::Get_CD_Drive_For_This_Volume ( char *volume_label )
{
char volume_name[128] = "";
int count = 0;
char buffer[128];
unsigned misc_dword;
unsigned filename_length;
int cd_drive;
CDIndex = 0;
while( CDIndex < CDCount ) {
//---------------------------------------------------------------------
// NOTE: A=0, B=1, C=2, D=3, etc...
//---------------------------------------------------------------------
cd_drive = CDDrives[ CDIndex++ ];
wsprintf( buffer, "%c:\\", 'A' + cd_drive );
if ( GetVolumeInformation(
(char const *)buffer,
&volume_name[0],
(unsigned long)sizeof(volume_name)-1,
(unsigned long *)NULL,
(unsigned long *)&filename_length,
(unsigned long *)&misc_dword,
(char *)NULL,
(unsigned long)0 )) {
//---------------------------------------------------------------------
// Windows '95 appears to have a volume name limit of 11 characters.
// I cannot find a Win32 call that will return the maximum volume name
// length so the value '11' is hard-coded here and the assumption made
// that all OS's have this length or better.
//---------------------------------------------------------------------
if( WinVersion.Is_Win95()) {
volume_name[11] = '\0';
}
if ( !_stricmp( volume_label, volume_name )) {
return( cd_drive );
}
} else {
#if _DEBUG
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
Msg( __LINE__, __FILE__, (LPTSTR)lpMsgBuf );
LocalFree( lpMsgBuf );
#endif
}
}
return( Get_First_CD_Drive());
}
/********************************************************************************
* GetCDClass -- Get_Volume_Label *
* *
* INPUT: int index *
* *
* OUTPUT: char * *
* *
* WARNINGS: *
* *
* HISTORY: *
* 10/31/2000 MML: Created. * Happy Halloween! * *
*==============================================================================*/
char * GetCDClass::Get_Volume_Label ( int index )
{
if( index >= 0 && index < _Num_Volumes ) {
return( _CD_Volume_Label[ index ]);
}
return( _CD_Volume_Label[0]);
}
/********************************************************************************
* GetCDClass -- Get_Volume_For_This_CD_Drive *
* *
* INPUT: char *volume_name *
* char *path *
* *
* OUTPUT: int *
* *
* WARNINGS: *
* *
* HISTORY: *
* 10/31/2000 MML: Created. * Happy Halloween! * *
*==============================================================================*/
char *GetCDClass::Get_Volume_For_This_CD_Drive ( char *path, char *volume_name )
{
char buffer[128];
unsigned misc_dword;
unsigned filename_length;
static char volume_label[ MAX_PATH ] = ""; // [OYO] add static
if ( path == NULL || volume_name == NULL ) {
return( NULL );
}
memset( volume_name, '\0', sizeof( volume_name ));
wsprintf( buffer, "%c:\\", path[0] );
if ( GetVolumeInformation(
(char const *)buffer,
&volume_label[0],
(unsigned long)sizeof(volume_label)-1,
(unsigned long *)NULL,
(unsigned long *)&filename_length,
(unsigned long *)&misc_dword,
(char *)NULL,
(unsigned long)0 )) {
strcpy( volume_name, volume_label );
} else {
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
Msg( __LINE__, __FILE__, (LPTSTR)lpMsgBuf );
LocalFree( lpMsgBuf );
strcpy( volume_name, _CD_Volume_Label[0] );
}
//-------------------------------------------------------------------------
// Windows '95 appears to have a volume name limit of 11 characters.
// I cannot find a Win32 call that will return the maximum volume name
// length so the value '11' is hard-coded here and the assumption made
// that all OS's have this length or better.
//-------------------------------------------------------------------------
bool winversion = WinVersion.Is_Win95();
if( winversion ) {
volume_name[11] = '\0';
}
return( volume_name );
}
/********************************************************************************
* CD_VOLUME_VERIFICATION -- Check volume label of the CD in the given drive. *
* *
* INPUT: int drive_number *
* char *lable *
* *
* OUTPUT: TRUE/FALSE *
* *
* WARNINGS: None *
* *
* HISTORY: *
* 01/11/99 4:20PM MML : Created *
*==============================================================================*/
bool CD_Volume_Verification ( int cd_drive, char *volume_label, char *volume_to_find )
{
char volume_name[128] = "";
int count = 0;
char buffer[128];
unsigned misc_dword;
unsigned filename_length;
/***************************************************************************
** Get the volume label. If we get a 'not ready' error then retry for the
** timeout period.
*/
for (;;) {
//---------------------------------------------------------------------
// NOTE: A=0, B=1, C=2, D=3, etc...
//---------------------------------------------------------------------
wsprintf( buffer, "%c:\\", 'A' + cd_drive );
if ( GetVolumeInformation(
(char const *)buffer,
&volume_name[0],
(unsigned long)sizeof(volume_name)-1,
(unsigned long *)NULL,
(unsigned long *)&filename_length,
(unsigned long *)&misc_dword,
(char *)NULL,
(unsigned long)0 )) {
/******************************************************************
** Match the volume label to the list of known volume labels.
*/
//---------------------------------------------------------------------
// Windows '95 appears to have a volume name limit of 11 characters.
// I cannot find a Win32 call that will return the maximum volume name
// length so the value '11' is hard-coded here and the assumption made
// that all OS's have this length or better.
//---------------------------------------------------------------------
if( WinVersion.Is_Win95()) {
volume_name[11] = '\0';
}
if ( volume_label != NULL ) {
strncpy( volume_label, volume_name, 128 );
}
if ( !_stricmp( volume_to_find, volume_name )) {
return TRUE;
}
if ( !count ) {
count++;
} else {
return FALSE;
}
} else {
/*********************************************************************
** Failed to get the volume label on a known CD drive. If this is a
** CD changer it may require time to swap the disks so don't return
** immediately if the error is ROR_NOT_READY
*/
return FALSE;
}
}
}
/* ==================================================================== */