Supongo que para el caso lo mismo da usar ShellExecuteEx que CreateProcess ¿no? Lo unico que ShellExecuteEx permite ejecutar cosas diferentes como un archivo de texto y cosas asi y CreateProcess solo crea procesos. Esto es todo lo que tengo:
El Main.h del Form:
Código PHP:
//---------------------------------------------------------------------------
#ifndef MainH
#define MainH
#include <Classes.hpp>
#include <Controls.hpp>
#include <Dialogs.hpp>
#include <StdCtrls.hpp>
#include <ExtCtrls.hpp>
#include <jpeg.hpp>
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
TButton *ButtonParchear;
TButton *ButtonElegir;
TOpenDialog *OpenDialog1;
TButton *ButtonCerrar;
TCheckBox *CheckBox1;
TCheckBox *CheckBox2;
TCheckBox *CheckBox3;
TGroupBox *GroupBox1;
TListBox *ListBoxLog;
TLabel *Label1;
TImage *Image1;
void __fastcall ButtonParchearClick(TObject *Sender);
void __fastcall ButtonElegirClick(TObject *Sender);
void __fastcall ButtonCerrarClick(TObject *Sender);
void __fastcall FormCreate(TObject *Sender);
private: // User declarations
AnsiString NombreArchivoData;
AnsiString NombreHerramienta;
AnsiString PathHerramienta;
AnsiString GameSettingSet;
AnsiString Parametros;
AnsiString PathData;
void Encriptar();
void Desencriptar();
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
El Main.cpp del Form:
Código PHP:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Main.h"
#include "ThreadPfdtool.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
//Este evento se produce al presionar el boton de Abrir
void __fastcall TForm1::ButtonElegirClick(TObject *Sender)
{
//Elijo el fichero a modificar
if(OpenDialog1->Execute()){
ListBoxLog->Clear();
ButtonParchear->Enabled=true;
}else{
ButtonParchear->Enabled=false;
}
}
//---------------------------------------------------------------------------
//Este evento se produce al presionar el boton de Parchear
void __fastcall TForm1::ButtonParchearClick(TObject *Sender)
{
//unsigned int Bytes_Copy = 0x39883050; //Los bytes a copiar en el fichero
//En hexadecimal la memoria se pone al reves de como se escribe
//Tambien se puede usar cadenas de caracteres en lugar de enteros:
unsigned char Check1[] = "1234";
unsigned char Check2[] = "5678";
unsigned char Check3[] = "9ABC";
int hFile;
ListBoxLog->Items->Add("Iniciando el proceso...");
//Aqui ya habria que desencriptarlo
Desencriptar();
ListBoxLog->Items->Add("Aplicando las modificaciones...");
//Abro el fichero con permisos de escritura
hFile= FileOpen(OpenDialog1->FileName.c_str(),fmOpenWrite);
if(CheckBox1->Checked==true)
{
//Coloco el puntero en el primer byte a modificar
FileSeek (hFile,0,0);
//Escribo en el fichero el numero de bytes indicado
FileWrite(hFile, &Check1,4);
}
if(CheckBox2->Checked==true)
{
//Coloco el puntero en el primer byte a modificar
FileSeek (hFile,4,0);
//Escribo en el fichero el numero de bytes indicado
FileWrite(hFile, &Check2,4);
}
if(CheckBox3->Checked==true)
{
//Coloco el puntero en el primer byte a modificar
FileSeek (hFile,8,0);
//Escribo en el fichero el numero de bytes indicado
FileWrite(hFile, &Check3,4);
}
//Cierro el fichero
FileClose(hFile);
ListBoxLog->Items->Add("Modificaciones aplicadas");
//Aqui habria que firmarlo y encriptarlo
Encriptar();
//Muestro un mensaje para avisar de que terminó
Application->MessageBoxA("Archivo parcheado con éxito.","Prueba de parche PS3",MB_ICONINFORMATION | MB_APPLMODAL);
}
//---------------------------------------------------------------------------
//Este evento se produce al presionar el boton de Cerrar
void __fastcall TForm1::ButtonCerrarClick(TObject *Sender)
{
//Cierro la ventana
Close();
}
//---------------------------------------------------------------------------
//Este evento se produce al crearse la ventana
void __fastcall TForm1::FormCreate(TObject *Sender)
{
PathHerramienta=ExtractFilePath(Application->ExeName);
NombreHerramienta= "pfdtool.exe";
GameSettingSet = "BLUS30270"; //Hay que cambiarlo por el que corresponda a cada DATA
//Muestro un mensaje
Application->MessageBoxA("Creado por Agustin","Prueba de parche PS3",MB_ICONINFORMATION);
}
//-------------------------------------------------------------------------
void TForm1::Desencriptar(void)
{
AnsiString PathBackup=OpenDialog1->FileName + ".BACKUP";
//Compruebo si ya existe un archivo de copia de seguridad del DATA con
//el mismo nombre que el que se va a crear
if (FileExists(PathBackup)) //Si ya existe un archivo con el nombre que se le pondrá al backup
//Muestro un mensaje
if(Application->MessageBoxA("Ya existe un archivo de copia de seguridad con ese nombre. Si sigue adelante se sobreescribirá.\n¿Desea continuar igualmente?","Prueba de parche PS3",MB_ICONWARNING | MB_YESNO)==IDNO)
return; //Si se pulsa el boton NO se termina el proceso de desencriptado
//Creo la copia del archivo DATA con la extension .BACKUP
if (CopyFile(OpenDialog1->FileName.c_str(),PathBackup.c_str(),false)==0)
{
//Si falla muestro un mensaje
if(Application->MessageBoxA("No se pudo crear la copia de seguridad del archivo de datos original.\n¿Desea seguir con el proceso de todos modos?","Prueba de parche PS3",MB_ICONWARNING | MB_YESNO)==IDNO)
return; //Si se contesta NO se termina el proceso de desencriptado
}else{
ListBoxLog->Items->Add("Creada copia de seguridad del SaveData");
}
//Para desencriptar
NombreArchivoData = ExtractFileName(OpenDialog1->FileName);
PathData = OpenDialog1->FileName.SubString(1,ExtractFilePath(OpenDialog1->FileName).Length()-1);
Parametros = " -g " + GameSettingSet + " -d \"" + PathData + "\" " + NombreArchivoData;
//Ejecuto el programa pfdtool con los parametros
ThreadPfdtool *pfdtool= new ThreadPfdtool(false,PathHerramienta,Parametros,NombreHerramienta);
pfdtool->WaitFor();
delete pfdtool;
ListBoxLog->Items->Add("Se ha desencriptado el archivo");
ButtonParchear->Enabled=true;
}
//---------------------------------------------------------------------------
void TForm1::Encriptar()
{
//Para encriptar
NombreArchivoData = ExtractFileName(OpenDialog1->FileName);
PathData = OpenDialog1->FileName.SubString(1,ExtractFilePath(OpenDialog1->FileName).Length()-1);
Parametros = " -g " + GameSettingSet + " -e \"" + PathData + "\" " + NombreArchivoData;
//Ejecuto el programa pfdtool con los parametros
ThreadPfdtool *pfdtool= new ThreadPfdtool(false,PathHerramienta,Parametros,NombreHerramienta);
pfdtool->WaitFor();
delete pfdtool;
ListBoxLog->Items->Add("Se ha encriptado el archivo");
ButtonParchear->Enabled=false;
}
//---------------------------------------------------------------------------
El .h del hilo:
Código PHP:
//---------------------------------------------------------------------------
#ifndef Unit2H
#define Unit2H
//---------------------------------------------------------------------------
#include <Classes.hpp>
//---------------------------------------------------------------------------
class ThreadPfdtool : public TThread
{
private:
AnsiString PathPfdtool;
AnsiString Parametros;
AnsiString Nombre;
protected:
void __fastcall Execute();
public:
__fastcall ThreadPfdtool(bool CreateSuspended,AnsiString pathPfdtool, AnsiString parametros, AnsiString nombre);
};
//---------------------------------------------------------------------------
#endif
El .cpp del hilo:
Código PHP:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "ThreadPfdtool.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
// Important: Methods and properties of objects in VCL can only be
// used in a method called using Synchronize, for example:
//
// Synchronize(UpdateCaption);
//
// where UpdateCaption could look like:
//
// void __fastcall ThreadPfdtool::UpdateCaption()
// {
// Form1->Caption = "Updated in a thread";
// }
//---------------------------------------------------------------------------
__fastcall ThreadPfdtool::ThreadPfdtool(bool CreateSuspended,AnsiString pathPfdtool, AnsiString parametros, AnsiString nombre)
: TThread(CreateSuspended)
{
PathPfdtool=pathPfdtool;
Parametros=parametros;
Nombre=nombre;
}
//---------------------------------------------------------------------------
void __fastcall ThreadPfdtool::Execute()
{
//---- Place thread code here ----
SHELLEXECUTEINFO execInfo;
ZeroMemory(&execInfo, sizeof(SHELLEXECUTEINFO));
// Llenamos la estructura
execInfo.cbSize = sizeof(SHELLEXECUTEINFO);
execInfo.fMask = SEE_MASK_FLAG_DDEWAIT + SEE_MASK_FLAG_NO_UI + SEE_MASK_NOCLOSEPROCESS;
execInfo.lpVerb = "open";
execInfo.lpFile = AnsiString(PathPfdtool + Nombre).c_str();
execInfo.lpParameters = Parametros.c_str();
execInfo.lpDirectory = PathPfdtool.c_str();
execInfo.nShow = SW_HIDE;
execInfo.hInstApp = 0;
// Lanzamos el archivo
ShellExecuteEx(&execInfo);
// Verificamos que no hayan errores
if ((int)execInfo.hInstApp <= 32)
{
if ((int)execInfo.hInstApp == SE_ERR_NOASSOC)
MessageBox(NULL,
"No existe una aplicación asociada \na la extensión del archivo",
"Error",
MB_ICONERROR);
MessageBox(NULL,
"No se ha podido ejecutar el archivo",
"Error",
MB_ICONERROR);
}
// Esperamos a que termine el proceso
WaitForSingleObject(execInfo.hProcess, INFINITE);
}
//---------------------------------------------------------------------------
Supongo que se congela porque mi estructura no es la mejor y querría ver si pueden ayudarme.
PD:El proceso inicia al hacer clic en el botón Parchear.