/*
** 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 .
*/
/*****************************************************************************\
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
*******************************************************************************
File: patch.cpp
Programmer: Neal Kettler
StartDate: Feb 6, 1998
LastUpdate: Feb 10, 1998
-------------------------------------------------------------------------------
This is where all the code is for applying various types of patches.
\*****************************************************************************/
#include "patch.h"
#include
#include
//
// For the text box showing patch info
//
BOOL CALLBACK Update_Info_Proc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
static int unselectText=0;
switch(iMsg)
{
case WM_INITDIALOG:
{
FILE *in = fopen("launcher.txt","r");
if (in==NULL)
{
EndDialog(hwnd,-1);
return(1);
}
char line[270];
int lastsel=0;
char *cptr=NULL;
while(fgets(line,255,in))
{
//Get rid of any trailing junk
while(1)
{
if (strlen(line)<1)
break;
cptr=line+(strlen(line))-1;
if ((*cptr=='\r')||(*cptr=='\n'))
*cptr=0;
else
break;
}
// ...and add back the gunk that windows likes
strcat(line,"\r\r\n");
SendDlgItemMessage(hwnd, IDC_TEXT, EM_SETSEL, (WPARAM)lastsel, (LPARAM)lastsel );
SendDlgItemMessage(hwnd, IDC_TEXT, EM_REPLACESEL, 0, (LPARAM)(line) );
SendDlgItemMessage(hwnd, IDC_TEXT, EM_GETSEL, (WPARAM)NULL, (LPARAM)&lastsel );
}
unselectText=1;
fclose(in);
return(1); // 1 means windows handles focus issues
}
break;
case WM_PAINT:
if (unselectText)
SendDlgItemMessage(hwnd, IDC_TEXT, EM_SETSEL, -1, 0);
unselectText=0;
return(0);
break;
case WM_COMMAND:
switch(wParam) {
case IDOK:
{
EndDialog(hwnd,0);
return(1);
}
default:
break;
}
default:
break;
case WM_CLOSE:
EndDialog(hwnd,0);
return(1);
break;
}
return(FALSE);
}
// Restart the computer for certain types of patches
void Shutdown_Computer_Now(void);
LPVOID CALLBACK __export PatchCallBack(UINT ID, LPVOID Param);
typedef LPVOID (CALLBACK* PATCHCALLBACK)(UINT, LPVOID);
typedef UINT (CALLBACK *PATCHFUNC)( LPSTR, PATCHCALLBACK, BOOL);
//
// Apply any type of patch. Filename in patchfile. Product base registry
// (eg: "SOFTWARE\Westwood\Red Alert") should be in the config file as
// SKUX SKU base reg dir where X = index
//
void Apply_Patch(char *patchfile,ConfigFile &config,int skuIndex)
{
DBGMSG("PATCHFILE : "<SetRTPErrCode(Id);
int percent;
switch( Id )
{
case 1:
case 2:
// Warning message header/text
DBGMSG("P_MSG: "<<((char *)Param));
break;
case 3:
// Error message header
DBGMSG("P_MSG: "<<((char *)Param));
break;
case 4:
// Error message header/text
///////*g_LogFile << (char *)Parm << endl;
MessageBox(NULL,(char *)Param,"ERROR",MB_OK);
{
FILE *out=fopen("patch.err","a");
time_t timet=time(NULL);
fprintf(out,"\n\nPatch Erorr: %s\n",ctime(&timet));
fprintf(out,"%s\n",(char *)Param);
fclose(out);
}
break;
case 9:
// progress message
break;
case 0xa:
// help message
break;
case 0xb:
// patch file comment
break;
case 0xc:
// copyright message
break; // these just display text
case 5:
// % completed
// so adjust the progress bar using the global Dialog pointer
/////////g_DlgPtr->SetProgressBar((int)((float)(*(UINT *)Parm)/(float)0x8000*(float)100));
percent=((*(UINT *)Param)*100)/0x8000;
SendMessage(GetDlgItem(PatchDialog,IDC_PROGRESS2),PBM_SETPOS,percent,0);
break;
case 6:
// Number of patch files
DBGMSG("6: "<<*((uint32 *)Param));
fileCount=*((uint32 *)Param);
currFile=0;
break;
case 7:
//// begin patch
//LoadString(g_AppInstance, IDS_PROCESSING, lpcBuf, 256);
//strcpy(buf,lpcBuf);
//strcat(buf,(char *)Parm);
//g_DlgPtr->SetProgressText(buf);
//*g_LogFile << buf << " : ";
//fileModified = true;
DBGMSG("7: "<<(char *)Param);
SetWindowText(GetDlgItem(PatchDialog,IDC_FILENAME),(char *)Param);
percent=0;
SendMessage(GetDlgItem(PatchDialog,IDC_PROGRESS2),PBM_SETPOS,percent,0);
currFile++;
char xofy[64];
LoadString(NULL,IDS_FILE_X_OF_Y,xofy,64);
sprintf(string,xofy,currFile,fileCount);
SetWindowText(GetDlgItem(PatchDialog,IDC_CAPTION),string);
break;
case 8:
//// end patch
//LoadString(g_AppInstance, IDS_PROCCOMPLETE, lpcBuf, 256);
//g_DlgPtr->SetProgressText(lpcBuf);
//*g_LogFile << " complete" << endl;
percent=100;
SendMessage(GetDlgItem(PatchDialog,IDC_PROGRESS2),PBM_SETPOS,percent,0);
DBGMSG("P_DONE");
break;
case 0xd:
//// this one shouldn't happen (only occurs if the command line
//// doesn't have a patch file in it, and we insure that it does).
//Abort = TRUE;
//*g_LogFile << "Incorrect (or none) patch file specified in command line." << endl;
break;
case 0xe:
//// this one shouldn't happen either (same reason)
//Abort = TRUE;
//*g_LogFile << "Incorrect (or none) path specified in command line." << endl;
break;
case 0xf:
//// Password Dialog
break;
case 0x10:
//// Invalid Password Alert
break;
case 0x11:
//// Disk Change Dialog
break;
case 0x12:
//// Disk Change Alert
break;
case 0x13:
//// Confirmation Dialog
break;
case 0x14:
//// Location Dialog
//Abort = TRUE;
//*g_LogFile << "Specified path is incorrect." << endl;
break;
case 0x16:
//// Searching Call-back
break;
case 0x15:
//// Idle...
break;
default:
break;
}
if(Abort)
return (NULL);
else
return (RetVal);
}