/// <summary>
        /// Returns the text for a specific item
        /// </summary>
        /// <param name="hWnd"></param>
        /// <param name="text"></param>
        /// <returns></returns>
        public string GetItemText(int itemHwnd)
        {
            const int dwBufferSize = 1024;

            int				dwProcessID;
            Win32.TVITEM    tvItem;
            string			retval;
            bool			bSuccess;
            IntPtr			hProcess        = IntPtr.Zero;
            IntPtr			lpRemoteBuffer  = IntPtr.Zero;
            IntPtr			lpLocalBuffer   = IntPtr.Zero;
            IntPtr			threadId        = IntPtr.Zero;

            try
            {
                tvItem = new Win32.TVITEM();

                // Allocate a buffer in the local process
                lpLocalBuffer = Marshal.AllocHGlobal(dwBufferSize);

                // Get the process id owning the treeview
                threadId = Win32.GetWindowThreadProcessId(handle, out dwProcessID);
                if((threadId == IntPtr.Zero) || (dwProcessID == 0))
                    throw new ArgumentException("Could not found thread process id");

                // Open the process with all access
                hProcess = Win32.OpenProcess(Win32.PROCESS_ALL_ACCESS, false, dwProcessID);
                if(hProcess == IntPtr.Zero)
                    throw new ApplicationException("Failed to access process");

                // Allocate a buffer in the remote process
                lpRemoteBuffer = Win32.VirtualAllocEx(hProcess, IntPtr.Zero, dwBufferSize, Win32.MEM_COMMIT, Win32.PAGE_READWRITE);
                if(lpRemoteBuffer == IntPtr.Zero)
                    throw new SystemException("Failed to allocate memory in remote process");

                // Fill in the TVITEM struct, this is in your own process
                // Set the pszText member to somewhere in the remote buffer,
                // In this case we use the address imediately following the TVITEM stuct
                tvItem.mask = ((int)Win32.TVIF.TEXT | (int)Win32.TVIF.HANDLE);
                tvItem.hItem = itemHwnd;
                tvItem.pszText = (IntPtr)(lpRemoteBuffer.ToInt32() + Marshal.SizeOf(typeof(Win32.TVITEM)));
                tvItem.cchTextMax = 1024;

                // Copy the local LVITEM to the remote buffer
                bSuccess = Win32.WriteProcessMemory(hProcess, lpRemoteBuffer, ref tvItem, Marshal.SizeOf(typeof(Win32.TVITEM)), IntPtr.Zero);
                if(!bSuccess)
                    throw new SystemException("Failed to write to process memory");

                // Send the message to the remote window with the address of the remote buffer
                Win32.SendMessage((System.IntPtr)handle, (int)Win32.TVM.GETITEM, itemHwnd, lpRemoteBuffer);

                // Read the struct back from the remote process into local buffer
                bSuccess = Win32.ReadProcessMemory(hProcess, lpRemoteBuffer, lpLocalBuffer, dwBufferSize, IntPtr.Zero);
                if(!bSuccess)
                    throw new SystemException("Failed to read from process memory");

                // At this point the lpLocalBuffer contains the returned LV_ITEM structure
                // the next line extracts the text from the buffer into a managed string
                retval = Marshal.PtrToStringAuto((IntPtr)(lpLocalBuffer.ToInt32() + Marshal.SizeOf(typeof(Win32.TVITEM))));
            }
            catch (Exception e)
            {
                // If an exception occurred, return the error string
                retval = e.Message;
            }
            finally
            {
                // Make sure to clean up memory buffers!
                if(lpLocalBuffer != IntPtr.Zero)
                    Marshal.FreeHGlobal( lpLocalBuffer );
                if(lpRemoteBuffer != IntPtr.Zero)
                    Win32.VirtualFreeEx(hProcess, lpRemoteBuffer, 0, Win32.MEM_RELEASE);
                if( hProcess != IntPtr.Zero )
                    Win32.CloseHandle(hProcess);
            }

            // Return what we found
            return retval;
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Returns the text for a specific item
        /// </summary>
        /// <param name="hWnd"></param>
        /// <param name="text"></param>
        /// <returns></returns>
        public string GetItemText(int itemHwnd)
        {
            const int dwBufferSize = 1024;

            int dwProcessID;

            Win32.TVITEM tvItem;
            string       retval;
            bool         bSuccess;
            IntPtr       hProcess       = IntPtr.Zero;
            IntPtr       lpRemoteBuffer = IntPtr.Zero;
            IntPtr       lpLocalBuffer  = IntPtr.Zero;
            IntPtr       threadId       = IntPtr.Zero;

            try
            {
                tvItem = new Win32.TVITEM();

                // Allocate a buffer in the local process
                lpLocalBuffer = Marshal.AllocHGlobal(dwBufferSize);

                // Get the process id owning the treeview
                threadId = Win32.GetWindowThreadProcessId(handle, out dwProcessID);
                if ((threadId == IntPtr.Zero) || (dwProcessID == 0))
                {
                    throw new ArgumentException("Could not found thread process id");
                }

                // Open the process with all access
                hProcess = Win32.OpenProcess(Win32.PROCESS_ALL_ACCESS, false, dwProcessID);
                if (hProcess == IntPtr.Zero)
                {
                    throw new ApplicationException("Failed to access process");
                }

                // Allocate a buffer in the remote process
                lpRemoteBuffer = Win32.VirtualAllocEx(hProcess, IntPtr.Zero, dwBufferSize, Win32.MEM_COMMIT, Win32.PAGE_READWRITE);
                if (lpRemoteBuffer == IntPtr.Zero)
                {
                    throw new SystemException("Failed to allocate memory in remote process");
                }

                // Fill in the TVITEM struct, this is in your own process
                // Set the pszText member to somewhere in the remote buffer,
                // In this case we use the address imediately following the TVITEM stuct
                tvItem.mask       = ((int)Win32.TVIF.TEXT | (int)Win32.TVIF.HANDLE);
                tvItem.hItem      = itemHwnd;
                tvItem.pszText    = (IntPtr)(lpRemoteBuffer.ToInt32() + Marshal.SizeOf(typeof(Win32.TVITEM)));
                tvItem.cchTextMax = 1024;

                // Copy the local LVITEM to the remote buffer
                bSuccess = Win32.WriteProcessMemory(hProcess, lpRemoteBuffer, ref tvItem, Marshal.SizeOf(typeof(Win32.TVITEM)), IntPtr.Zero);
                if (!bSuccess)
                {
                    throw new SystemException("Failed to write to process memory");
                }

                // Send the message to the remote window with the address of the remote buffer
                Win32.SendMessage((System.IntPtr)handle, (int)Win32.TVM.GETITEM, itemHwnd, lpRemoteBuffer);

                // Read the struct back from the remote process into local buffer
                bSuccess = Win32.ReadProcessMemory(hProcess, lpRemoteBuffer, lpLocalBuffer, dwBufferSize, IntPtr.Zero);
                if (!bSuccess)
                {
                    throw new SystemException("Failed to read from process memory");
                }

                // At this point the lpLocalBuffer contains the returned LV_ITEM structure
                // the next line extracts the text from the buffer into a managed string
                retval = Marshal.PtrToStringAuto((IntPtr)(lpLocalBuffer.ToInt32() + Marshal.SizeOf(typeof(Win32.TVITEM))));
            }
            catch (Exception e)
            {
                // If an exception occurred, return the error string
                retval = e.Message;
            }
            finally
            {
                // Make sure to clean up memory buffers!
                if (lpLocalBuffer != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(lpLocalBuffer);
                }
                if (lpRemoteBuffer != IntPtr.Zero)
                {
                    Win32.VirtualFreeEx(hProcess, lpRemoteBuffer, 0, Win32.MEM_RELEASE);
                }
                if (hProcess != IntPtr.Zero)
                {
                    Win32.CloseHandle(hProcess);
                }
            }

            // Return what we found
            return(retval);
        }