204 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			204 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/*
 | 
						|
**	Command & Conquer Red Alert(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/>.
 | 
						|
*/
 | 
						|
 | 
						|
#include "findpatch.h"
 | 
						|
 | 
						|
//
 | 
						|
// Locate a patch file
 | 
						|
//  If a patch can be found then TRUE is returned and the name is filled in,
 | 
						|
//  otherwise FALSE is returned.
 | 
						|
//
 | 
						|
// Patch Types:
 | 
						|
//   - *.rtp = RTPatch file that can be applied right now
 | 
						|
//   - *.exe = Executable that should be put in the RunOnce registry entry & reboot
 | 
						|
//   - *.exn = Executable that should be run right now
 | 
						|
//   - *.web = Link to a web page that will have the patch
 | 
						|
//   - else  = File is ignored, possibly a resource file for one of the other types
 | 
						|
//
 | 
						|
int Find_Patch(OUT char *filename,int maxlen, ConfigFile &config)
 | 
						|
{
 | 
						|
  WIN32_FIND_DATA     findData;
 | 
						|
  char                string[128];
 | 
						|
  HANDLE              hFile;
 | 
						|
  char               *extensions[]={"web","exe","exn","rtp",NULL};
 | 
						|
  int                 i;
 | 
						|
  int                 skuIndex=0;
 | 
						|
  Wstring             key;
 | 
						|
  Wstring             path;
 | 
						|
  Wstring             sku;
 | 
						|
  char                gamePath[MAX_PATH];
 | 
						|
  bit8                ok;
 | 
						|
 | 
						|
 | 
						|
  while(1)
 | 
						|
  {
 | 
						|
    //
 | 
						|
    // Loop through the apps we're responsible for
 | 
						|
    //
 | 
						|
    skuIndex++;
 | 
						|
    ok=Get_App_Dir(gamePath,MAX_PATH,config,skuIndex);
 | 
						|
    if (ok==FALSE)
 | 
						|
      break;
 | 
						|
    
 | 
						|
    i=0;
 | 
						|
    while(extensions[i++])
 | 
						|
    {
 | 
						|
      _chdir(gamePath);  // goto the directory with the game
 | 
						|
 | 
						|
      // should probably get the registry entry for the wchat install path
 | 
						|
      sprintf(string,"patches\\*.%s",extensions[i]);
 | 
						|
      hFile=FindFirstFile(string,&findData);
 | 
						|
      if (hFile!=INVALID_HANDLE_VALUE)
 | 
						|
      {
 | 
						|
        _getcwd(filename,MAX_PATH);
 | 
						|
        strcat(filename,"\\patches\\");
 | 
						|
        strcat(filename,findData.cFileName);
 | 
						|
        FindClose(hFile);
 | 
						|
        return(skuIndex);
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return(FALSE);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
//
 | 
						|
// Get the directory for the N'th application in the config file
 | 
						|
//
 | 
						|
// Returns FALSE if not in the config file or invalid for some reason.
 | 
						|
//
 | 
						|
bit8 Get_App_Dir(OUT char *filename,int maxlen, ConfigFile &config,int index)
 | 
						|
{
 | 
						|
  char                string[128];
 | 
						|
  Wstring             key;
 | 
						|
  Wstring             path;
 | 
						|
  Wstring             sku;
 | 
						|
  int                 temp;
 | 
						|
  char                gamePath[MAX_PATH];
 | 
						|
 | 
						|
 | 
						|
  sprintf(string,"SKU%d",index);
 | 
						|
 | 
						|
  // Can't find this product
 | 
						|
  if (config.getString(string,key)==FALSE)
 | 
						|
    return(FALSE);
 | 
						|
 | 
						|
 
 | 
						|
  DBGMSG("KEY = "<<key.get());
 | 
						|
  // Get the InstallPath from the specified registry key
 | 
						|
  temp=0;
 | 
						|
  temp=key.getToken(temp," ",sku);
 | 
						|
  path=key;
 | 
						|
  path.remove(0,temp);
 | 
						|
  while((*(path.get()))==' ')  // remove leading spaces
 | 
						|
    path.remove(0,1);
 | 
						|
 | 
						|
 | 
						|
  DBGMSG("CONFIG:   SKU = "<<sku.get()<<"  PATH = '"<<path.get()<<"'");
 | 
						|
  HKEY   regKey;
 | 
						|
  LONG   regRetval;
 | 
						|
  /////////////DWORD  regPrevious;
 | 
						|
  regRetval=RegOpenKeyEx(HKEY_LOCAL_MACHINE,path.get(),0,KEY_READ,®Key);
 | 
						|
  if (regRetval!=ERROR_SUCCESS)
 | 
						|
  {
 | 
						|
    DBGMSG("RegOpenKey failed");
 | 
						|
    return(FALSE);
 | 
						|
  }
 | 
						|
  DWORD  type;
 | 
						|
  DWORD  length=MAX_PATH;
 | 
						|
  regRetval=RegQueryValueEx(regKey,"InstallPath",NULL,&type,(uint8 *)gamePath,
 | 
						|
      &length);
 | 
						|
  DBGMSG("GAME PATH = "<<gamePath);
 | 
						|
  if ((regRetval!=ERROR_SUCCESS)||(type!=REG_SZ))
 | 
						|
  {
 | 
						|
    DBGMSG("Reg failure");
 | 
						|
    return(FALSE);
 | 
						|
  }
 | 
						|
 | 
						|
  // Find the last '\\' in a string and put a 0 after it
 | 
						|
  //  If you only put a directory in the InstallPath key instead of a full
 | 
						|
  //  path to a file, you better end the directory with a trailing '\\'!!!
 | 
						|
  char *cptr=gamePath;
 | 
						|
  char *tempPtr;
 | 
						|
  while( (tempPtr=strchr(cptr,'\\')) !=NULL)
 | 
						|
    cptr=tempPtr+1;
 | 
						|
  if (cptr)
 | 
						|
    *cptr=0;
 | 
						|
 | 
						|
  DBGMSG("Game path = "<<gamePath);
 | 
						|
  strncpy(filename,gamePath,maxlen);
 | 
						|
 | 
						|
  return(TRUE);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
//
 | 
						|
// Delete any patch files
 | 
						|
//
 | 
						|
void Delete_Patches(ConfigFile &config)
 | 
						|
{
 | 
						|
  char dir[MAX_PATH];
 | 
						|
  int  i=1;
 | 
						|
  WIN32_FIND_DATA     findData;
 | 
						|
  HANDLE              hFile;
 | 
						|
 | 
						|
  DBGMSG("IN DELPATCH");
 | 
						|
 | 
						|
  //
 | 
						|
  // Loop through all the application directories in the config file
 | 
						|
  //
 | 
						|
  while (Get_App_Dir(dir,MAX_PATH,config,i++)==TRUE)
 | 
						|
  {
 | 
						|
    // Make sure path is at least 3 for "c:\".  I really hope nobody's
 | 
						|
    //   dumb enough to install a game to the root directory. (It's OK though
 | 
						|
    //   since only the '\patches' folder is cleared out.
 | 
						|
    if (strlen(dir)<3)
 | 
						|
      continue;
 | 
						|
 | 
						|
    //
 | 
						|
    // Delete everything in case a .exe patch had some data files it used.
 | 
						|
    //
 | 
						|
    strcat(dir,"patches\\*.*");
 | 
						|
 | 
						|
    DBGMSG("DELPATCH: "<<dir);
 | 
						|
 | 
						|
    hFile=FindFirstFile(dir,&findData);
 | 
						|
    if (hFile!=INVALID_HANDLE_VALUE)
 | 
						|
    {
 | 
						|
      if (findData.cFileName[0]!='.')
 | 
						|
      {
 | 
						|
        //_unlink(findData.cFileName);
 | 
						|
        DBGMSG("UNLINK: "<<findData.cFileName);
 | 
						|
      }
 | 
						|
      while(FindNextFile(hFile,&findData))
 | 
						|
      {
 | 
						|
        if (findData.cFileName[0]!='.')
 | 
						|
        {
 | 
						|
          //_unlink(findData.cFileName);
 | 
						|
          DBGMSG("UNLINK: "<<findData.cFileName);
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }  // If there's at least one file
 | 
						|
    FindClose(hFile);
 | 
						|
  }  // while there's apps in config
 | 
						|
  return;
 | 
						|
} 
 |