G
Guest
Hi
If it is wrong newsgroup, please let me know where to find the answer.
I am trying to get item text form ListView (there are few items and 5
columns) from other application (application written in MFC). As I know I
have to allocate memory in target application address space, send a message
and than read from allocated memory. But I still doing something wrong and
can't find correct solution. I fell I am close to it. Please find code below
(C#) :
[StructLayout( LayoutKind.Sequential)]
public struct LV_ITEMA
{
public int mask;
public int iItem;
public int iSubItem;
public int state;
public int stateMask;
public IntPtr pszText;
public int cchTextMax;
public int iImage;
public int lParam;
public int iIndent;
}
/// <summary>
/// Summary description for ListViewItem.
/// </summary>
public class ListViewItem
{
public ListViewItem()
{
}
public const int PROCESS_QUERY_INFORMATION = 1024;
public const int PROCESS_VM_OPERATION = 0x8;
public const int PROCESS_VM_READ = 0x10;
public const int PROCESS_VM_WRITE = 0x20;
public const int STANDARD_RIGHTS_REQUIRED = 0xF0000;
public const int MAX_LVMSTRING = 255;
public const int MEM_COMMIT = 0x1000;
public const int MEM_RELEASE = 0x8000;
public const int PAGE_READWRITE = 0x4;
public const int LVIF_TEXT = 0x1;
private const int LVM_FIRST = 0x1000;
private const int LVM_GETITEMCOUNT = LVM_FIRST + 4;
private const int LVM_GETCOLUMN = LVM_FIRST + 25;
private const int LVM_GETITEM = LVM_FIRST + 5;
private const int LVM_GETITEMTEXT = 0x102D;
bool result;
IntPtr pHandle;
IntPtr pStrBufferMemory;
IntPtr pMyItemMemory;
[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(int dwDesiredAccess, bool
bInheritHandle, int dwProcId );
[DllImport("kernel32.dll")]
public static extern IntPtr VirtualAllocEx(IntPtr hProcess,IntPtr lpAddress,
int dwSize, int flAllocationType, int flProtect );
[DllImport("kernel32.dll")]
public static extern bool VirtualFreeEx(IntPtr hProcess, IntPtr lpAddress,
int dwSize, int dwFreeType);
[DllImport("kernel32.dll")]
public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr
lpBaseAddress,ref LV_ITEMA lpBuffer, int nSize, ref int
lpNumberOfBytesWritten);
[DllImport("kernel32.dll")]
public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr
lpBaseAddress, ref LV_ITEMA lpBuffer, int nSize, ref int
lpNumberOfBytesWritten);
[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam,
IntPtr lParam);
[DllImport("kernel32.dll")]
public static extern bool CloseHandle(IntPtr hObject);
public void Run(IntPtr ptr)
{
strBuffer = new byte[MAX_LVMSTRING];
Process [] localByName = Process.GetProcessesByName("myProcess");
Process proc = localByName[0];
pHandle = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ |
PROCESS_VM_WRITE, false, proc.Id);
pStrBufferMemory = VirtualAllocEx(pHandle,IntPtr.Zero, MAX_LVMSTRING,
MEM_COMMIT, PAGE_READWRITE);
LV_ITEMA lv = new LV_ITEMA();
lv.mask = LVIF_TEXT;
lv.iItem = 1;
lv.iSubItem = 5;
lv.pszText = pStrBufferMemory;
lv.cchTextMax = MAX_LVMSTRING;
pMyItemMemory = VirtualAllocEx(pHandle,IntPtr.Zero, Marshal.SizeOf(lv),
MEM_COMMIT, PAGE_READWRITE);
IntPtr lvptr = Marshal.AllocHGlobal(Marshal.SizeOf(lv));
Marshal.StructureToPtr(lv,lvptr,false);
int written = 0;
result = WriteProcessMemory(pHandle, pMyItemMemory,ref lv,
Marshal.SizeOf(lv), ref written);
int i = SendMessage(ptr, LVM_GETITEM, 0, pMyItemMemory);
i = SendMessage(ptr, LVM_GETITEMTEXT, 1, pStrBufferMemory);
IntPtr ppr = IntPtr.Zero;
int read = 0;
StringBuilder str = new StringBuilder(MAX_LVMSTRING);
result = ReadProcessMemory(pHandle, pMyItemMemory,ref lv, written,ref read);
string str1 = Marshal.PtrToStringAnsi(lv.pszText);
}
As a result of i = SendMessage(ptr, LVM_GETITEMTEXT, 1, pStrBufferMemory);
I'm receiving 0 - means false and
string str1 = Marshal.PtrToStringAnsi(lv.pszText);
Gives me an error : Object instance not set to object.
Please help
Thanks in advance
brgds
Jacek
If it is wrong newsgroup, please let me know where to find the answer.
I am trying to get item text form ListView (there are few items and 5
columns) from other application (application written in MFC). As I know I
have to allocate memory in target application address space, send a message
and than read from allocated memory. But I still doing something wrong and
can't find correct solution. I fell I am close to it. Please find code below
(C#) :
[StructLayout( LayoutKind.Sequential)]
public struct LV_ITEMA
{
public int mask;
public int iItem;
public int iSubItem;
public int state;
public int stateMask;
public IntPtr pszText;
public int cchTextMax;
public int iImage;
public int lParam;
public int iIndent;
}
/// <summary>
/// Summary description for ListViewItem.
/// </summary>
public class ListViewItem
{
public ListViewItem()
{
}
public const int PROCESS_QUERY_INFORMATION = 1024;
public const int PROCESS_VM_OPERATION = 0x8;
public const int PROCESS_VM_READ = 0x10;
public const int PROCESS_VM_WRITE = 0x20;
public const int STANDARD_RIGHTS_REQUIRED = 0xF0000;
public const int MAX_LVMSTRING = 255;
public const int MEM_COMMIT = 0x1000;
public const int MEM_RELEASE = 0x8000;
public const int PAGE_READWRITE = 0x4;
public const int LVIF_TEXT = 0x1;
private const int LVM_FIRST = 0x1000;
private const int LVM_GETITEMCOUNT = LVM_FIRST + 4;
private const int LVM_GETCOLUMN = LVM_FIRST + 25;
private const int LVM_GETITEM = LVM_FIRST + 5;
private const int LVM_GETITEMTEXT = 0x102D;
bool result;
IntPtr pHandle;
IntPtr pStrBufferMemory;
IntPtr pMyItemMemory;
[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(int dwDesiredAccess, bool
bInheritHandle, int dwProcId );
[DllImport("kernel32.dll")]
public static extern IntPtr VirtualAllocEx(IntPtr hProcess,IntPtr lpAddress,
int dwSize, int flAllocationType, int flProtect );
[DllImport("kernel32.dll")]
public static extern bool VirtualFreeEx(IntPtr hProcess, IntPtr lpAddress,
int dwSize, int dwFreeType);
[DllImport("kernel32.dll")]
public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr
lpBaseAddress,ref LV_ITEMA lpBuffer, int nSize, ref int
lpNumberOfBytesWritten);
[DllImport("kernel32.dll")]
public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr
lpBaseAddress, ref LV_ITEMA lpBuffer, int nSize, ref int
lpNumberOfBytesWritten);
[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam,
IntPtr lParam);
[DllImport("kernel32.dll")]
public static extern bool CloseHandle(IntPtr hObject);
public void Run(IntPtr ptr)
{
strBuffer = new byte[MAX_LVMSTRING];
Process [] localByName = Process.GetProcessesByName("myProcess");
Process proc = localByName[0];
pHandle = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ |
PROCESS_VM_WRITE, false, proc.Id);
pStrBufferMemory = VirtualAllocEx(pHandle,IntPtr.Zero, MAX_LVMSTRING,
MEM_COMMIT, PAGE_READWRITE);
LV_ITEMA lv = new LV_ITEMA();
lv.mask = LVIF_TEXT;
lv.iItem = 1;
lv.iSubItem = 5;
lv.pszText = pStrBufferMemory;
lv.cchTextMax = MAX_LVMSTRING;
pMyItemMemory = VirtualAllocEx(pHandle,IntPtr.Zero, Marshal.SizeOf(lv),
MEM_COMMIT, PAGE_READWRITE);
IntPtr lvptr = Marshal.AllocHGlobal(Marshal.SizeOf(lv));
Marshal.StructureToPtr(lv,lvptr,false);
int written = 0;
result = WriteProcessMemory(pHandle, pMyItemMemory,ref lv,
Marshal.SizeOf(lv), ref written);
int i = SendMessage(ptr, LVM_GETITEM, 0, pMyItemMemory);
i = SendMessage(ptr, LVM_GETITEMTEXT, 1, pStrBufferMemory);
IntPtr ppr = IntPtr.Zero;
int read = 0;
StringBuilder str = new StringBuilder(MAX_LVMSTRING);
result = ReadProcessMemory(pHandle, pMyItemMemory,ref lv, written,ref read);
string str1 = Marshal.PtrToStringAnsi(lv.pszText);
}
As a result of i = SendMessage(ptr, LVM_GETITEMTEXT, 1, pStrBufferMemory);
I'm receiving 0 - means false and
string str1 = Marshal.PtrToStringAnsi(lv.pszText);
Gives me an error : Object instance not set to object.
Please help
Thanks in advance
brgds
Jacek