using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Diagnostics;
// The 'windowHandle' parameter will contain the window handle for the:
// - Active window when run by hotkey
// - Window Location target when run by a Window Location rule
// - TitleBar Button owner when run by a TitleBar Button
// - Jump List owner when run from a Taskbar Jump List
// - Currently focused window if none of these match
//This function is to be used with a Window Location Rule or a Hotkey
//It will get Rocksmith 2014 to look for your own USB guitar cable if you don't own the Real Tone cable
public static class DisplayFusionFunction
{
[DllImport("kernel32.dll", EntryPoint = "ReadProcessMemory")]
public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] buffer, uint size, out uint lpNumberOfBytesRead);
[DllImport("kernel32.dll", EntryPoint = "WriteProcessMemory")]
public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] buffer, uint size, out uint lpNumberOfBytesWritten);
/*
to get the PID and VID of your cable:
1) Right click on the speaker icon on your taskbar and select 'Recording Devices'.
2) Find your cable and right click on it and select Properties
3) Click the Properties button again on the General tab
4) To to the details tab of the new window
5) Select 'Hardware Ids' from the dropdown
6) There should be a string that looks something like this:
USB\VID_0D8C&PID_0139&REV_0100&MI_00
The 4 character after the VID_ is your VID, and the 4 characters after the PID_ is your PID.
Enter those values into the static arrays below.
*/
//the vender id of your cable
private static byte[] VID = new byte[] {0x0D, 0x8C};
//the product id of your cable
private static byte[] PID = new byte[] {0x01, 0x39};
public static void Run(IntPtr windowHandle)
{//if this isn't a rocksmith window, exit
if (BFS.Application.GetMainFileByWindow(windowHandle).IndexOf("rocksmith", StringComparison.OrdinalIgnoreCase) == -1)
return;
//put the arrays into the proper bitness order
Array.Reverse(VID);
Array.Reverse(PID);
//get the rocksmith 2014 process
Process rocksmith = Process.GetProcessById((int)BFS.Application.GetAppIDByWindow(windowHandle));
if (rocksmith == null)
return;
//get the first address that we want to search. my version of rocksmith 2014 i find the value around 17000.
//offset the first search address to speed things up
IntPtr current = new IntPtr(rocksmith.MainModule.BaseAddress.ToInt64() + 10000);
long end = rocksmith.MainModule.ModuleMemorySize + rocksmith.MainModule.BaseAddress.ToInt64();
//Search for the value F806BA12
byte[] desiredAddress = new byte[] {0xF8, 0x06, 0xBA, 0x12};
byte[] buffer = new byte[4];
while (current.ToInt64() < end)
{
uint numberOfBytesRead;
//read some memory
if (!ReadProcessMemory(rocksmith.Handle, current, buffer, (uint)buffer.Length, out numberOfBytesRead))
return;
//couldnt read enough data
if (numberOfBytesRead != (uint)buffer.Length)
return;
//check to see if we were lucky enough to get the address
if (BitConverter.ToInt32(buffer, 0) == BitConverter.ToInt32(desiredAddress, 0))
break;
//check to see if the array contains the first element in the desired result
bool found = false;
for (int i = 1; i < buffer.Length; i++)
{
if (buffer[i] != desiredAddress[0])
continue;
//found it, grab the 4 bytes
current = new IntPtr(current.ToInt64() + i);
if (!ReadProcessMemory(rocksmith.Handle, current, buffer, (uint)buffer.Length, out numberOfBytesRead))
return;
//check to see if its what we want
if (BitConverter.ToInt32(buffer, 0) == BitConverter.ToInt32(desiredAddress, 0))
found = true;
break;
}
if (found == true)
break;
//increment the pointer
current = new IntPtr(current.ToInt64() + (uint)buffer.Length);
}
//write the memory
// Susbtitute the BA 12 with YOUR cable's vendor ID
// BA 12 is offset by 2 in F806BA12
current = new IntPtr(current.ToInt64() + 2);
uint numberOfByteWritten;
if (!WriteProcessMemory(rocksmith.Handle, current, VID, 2, out numberOfByteWritten))
return;
//Locate FF 00 in the line below
desiredAddress = new byte[] {0xFF, 0x00};
buffer = new byte[2];
while (current.ToInt64() < end)
{
uint numberOfBytesRead;
//read some memory
if (!ReadProcessMemory(rocksmith.Handle, current, buffer, (uint)desiredAddress.Length, out numberOfBytesRead))
return;
//couldnt read enough data
if (numberOfBytesRead != desiredAddress.Length)
return;
//check to see if we were lucky enough to get the address
if (BitConverter.ToInt16(desiredAddress, 0) == BitConverter.ToInt16(buffer, 0))
break;
//check to see if the array contains the first element in the desired result
bool found = false;
for (int i = 1; i < buffer.Length; i++)
{
if (buffer[i] != desiredAddress[0])
continue;
//found it, grab the 4 bytes
current = new IntPtr(current.ToInt64() + i);
if (!ReadProcessMemory(rocksmith.Handle, current, buffer, (uint)buffer.Length, out numberOfBytesRead))
return;
//check to see if its what we want
if (BitConverter.ToInt16(buffer, 0) == BitConverter.ToInt16(desiredAddress, 0))
found = true;
break;
}
if (found == true)
break;
//increment the pointer
current = new IntPtr(current.ToInt64() + desiredAddress.Length);
}
if (current.ToInt64() >= end)
return;
//substitute 0xff00 with YOUR cable's product ID
if (!WriteProcessMemory(rocksmith.Handle, current, PID, (uint)desiredAddress.Length, out numberOfByteWritten))
return;
}
}