// Helper function to handle common scenario of translating a remote // unmanaged char/wchar buffer in to a managed string object. internal bool ReadString(out string str, int maxLength) { // Clear the return string str = null; // Ensure there is a buffer size if (0 >= maxLength) { return(false); } // Ensure proper allocation using (SafeCoTaskMem ptr = new SafeCoTaskMem(maxLength)) { if (ptr.IsInvalid) { return(false); } // Copy remote buffer back to local process... ReadFrom(ptr, new IntPtr(maxLength * sizeof(char))); // Convert the local unmanaged buffer in to a string object str = ptr.GetStringUni(maxLength); // Note: lots of "old world" strings are null terminated // Leaving the null termination in the System.String may lead // to some issues when used with the StringBuilder int nullTermination = str.IndexOf('\0'); if (-1 != nullTermination) { // We need to strip null terminated char and everything behind it from the str str = str.Remove(nullTermination, maxLength - nullTermination); } return(true); } }
internal void ReadFrom(SafeCoTaskMem destAddress, IntPtr cbSize) { IntPtr count; Misc.ReadProcessMemory(_processHandle, handle, destAddress, cbSize, out count); }
// Helper function to handle common scenario of translating a remote // unmanaged char/wchar buffer in to a managed string object. internal bool ReadString (out string str, int maxLength) { // Clear the return string str = null; // Ensure there is a buffer size if (0 >= maxLength) { return false; } // Ensure proper allocation using (SafeCoTaskMem ptr = new SafeCoTaskMem(maxLength)) { if (ptr.IsInvalid) { return false; } // Copy remote buffer back to local process... ReadFrom(ptr, new IntPtr(maxLength * sizeof (char))); // Convert the local unmanaged buffer in to a string object str = ptr.GetStringUni(maxLength); // Note: lots of "old world" strings are null terminated // Leaving the null termination in the System.String may lead // to some issues when used with the StringBuilder int nullTermination = str.IndexOf('\0'); if (-1 != nullTermination) { // We need to strip null terminated char and everything behind it from the str str = str.Remove(nullTermination, maxLength - nullTermination); } return true; } }
private static string ListView_V6_GetGroupTextOnWinXp(IntPtr hwnd, LVGROUP_64 group) { // Due to the ListView Group bug on WinXP we need to have a special implementation // for retrieving a text of the group for WinXP // On WinXP the code to give back the header text looks something like that: // if (plvgrp->mask & LVGF_HEADER) // { // plvgrp->pszHeader = pgrp->pszHeader; // } // Instead of something along the lines of StringCchCopy(plvgrp->pszHeader, plvgrp->cchHeader, pgrp->pszHeader); // Hence after the call to CommCtrl.Common_GetSetText() we will get back an internal buffer pointer // and not the text itself (ref string str will be ""). It makes no sense to call CommCtrl.Common_GetSetText() // Use XSendMessage to get the internal buffer pointer and than "manually" read the string // get internal buffer pointer (group.pszHeader) // NOTE: do no check XSendMessage.XSend since, LVM_GETGROUPINFO returns id of the group which can be 0, hence // can be treated as failure // We will check group.pszHeader to IntPtr.Zero after the call unsafe { XSend(hwnd, NativeMethods.LVM_GETGROUPINFO, new IntPtr(group.iGroupID), new IntPtr(&group), group.cbSize, ErrorValue.NoCheck); } if (group.pszHeader != 0) { // Read the string manually... // allocate memory from the unmanaged memory using (SafeCoTaskMem copyTo = new SafeCoTaskMem(NativeMethods.MAX_PATH)) { if (!copyTo.IsInvalid) { using (SafeProcessHandle hProcess = new SafeProcessHandle(hwnd)) { if (!hProcess.IsInvalid) { int count; if (Misc.ReadProcessMemory(hProcess, new IntPtr(group.pszHeader), copyTo, new IntPtr(NativeMethods.MAX_PATH), out count)) { return copyTo.GetStringAuto(); } } } } } } return ""; }