Torna al Thread
enum AccessRights
{
PROCESS_VM_READ = 0x0010,
PROCESS_VM_WRITE = 0x0020,
PROCESS_VM_OPERATION = 0x0008
}
[DllImport("kernel32.dll")]
static extern IntPtr OpenProcess(AccessRights dwDesiredAcces, bool bInheritHandle, int dwProcessId);
[DllImport("kernel32.dll")]
static extern bool CloseHandle(IntPtr hObject);
[DllImport("kernel32.dll")]
static extern bool ReadProcessMemory(IntPtr hProcess,
IntPtr lpBaseAddress, IntPtr lpBuffer, int nSize, out int lpNumberOfBytesRead);
[DllImport("kernel32.dll")]
static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress,
IntPtr lpBuffer, int nSize, out int lpNumberOfBytesWritten);
//Questa struttura deve essere identica a quella
//dichiarata nell'altra applicazione
struct SharedData
{
public int v1;
public bool v2;
public char v3;
public Point v4;
}
IntPtr processHandle;
IntPtr sharedMemPtr;
IntPtr mustRefreshPtr;
IntPtr newDataPtr;
IntPtr sharedData;
int dataSize;
SharedData data;
//Questa funzione ottiene gli indirizzi e le informazioni dal registro di sistema
void InitRead()
{
//Apre la chiave di registro
RegistryKey swKey = Registry.LocalMachine.OpenSubKey("Software");
RegistryKey infoKey = swKey.OpenSubKey("SharedMemTest");
//Ottiene l'ID del processo da cui leggere i dati
int processId = (int)infoKey.GetValue("ProcessID");
//Apre il processo con diritti di lettura e scrittura
this.processHandle = OpenProcess(AccessRights.PROCESS_VM_READ |
AccessRights.PROCESS_VM_WRITE | AccessRights.PROCESS_VM_OPERATION,
false, processId);
//Ottiene l'indirizzo della memoria condivisa
sharedMemPtr = (IntPtr)(int)infoKey.GetValue("MemPtr");
//Ottiene l'indirizzo del bool da impostare per richiedere l'aggiornamento
mustRefreshPtr = (IntPtr)(int)infoKey.GetValue("MustRefreshPtr");
//Ottiene l'indirizzo della memoria da impostare per l'aggiornamento dei dati
newDataPtr = (IntPtr)(int)infoKey.GetValue("NewDataPtr");
//Chiude le chiavi di registro
infoKey.Close();
swKey.Close();
//Ottiene la dimensione della memoria da leggere
this.dataSize = Marshal.SizeOf(typeof(SharedData));
//Alloca la memoria in cui leggere i dati estranei
this.sharedData = Marshal.AllocHGlobal(dataSize);
}
//Questa funzione legge i dati condivisi
void Read()
{
int readBytes;
//Legge la memoria condivisa del processo
ReadProcessMemory(processHandle, sharedMemPtr, this.sharedData, this.dataSize, out readBytes);
//Converte la memoria non gestita nella struttura gestita
this.data = (SharedData)Marshal.PtrToStructure(this.sharedData, typeof(SharedData));
}
void Write(SharedData newData)
{
int written;
//Imposta nel ptr da scrivere i nuovi dati
Marshal.StructureToPtr(newData, this.sharedData, false);
//Scrive nella memoria condivisa i nuovi dati
WriteProcessMemory(processHandle, this.newDataPtr, this.sharedData, this.dataSize, out written);
//Imposta nel ptr da scrivere true, per indicare al processo di aggiornare i dati
Marshal.StructureToPtr(true, this.sharedData, false);
//Scrive nella memoria condivisa il true
WriteProcessMemory(processHandle, this.mustRefreshPtr, sharedData, sizeof(bool), out written);
//A questo punto la prossima volta che il processo esterno dovrà elaborare i dati
//saprà di dover aggiornare i dati dalla memoria condivisa, dove abbiamo copiato
//i nuovi valori
}
void EndRead()
{
//Chiude l'handle del processo
CloseHandle(this.processHandle);
//Dealloca la memoria non gestita
Marshal.FreeHGlobal(sharedData);
}