/* ** 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); }