private HRESULT SaveStringToHandle(IntPtr handle, string str, bool unicode) { if (handle == IntPtr.Zero) { return(HRESULT.E_INVALIDARG); } IntPtr newHandle = IntPtr.Zero; if (unicode) { uint byteSize = (uint)str.Length * 2 + 2; newHandle = Kernel32.GlobalReAlloc( handle, byteSize, Kernel32.GMEM.MOVEABLE | Kernel32.GMEM.DDESHARE | Kernel32.GMEM.ZEROINIT); if (newHandle == IntPtr.Zero) { return(HRESULT.E_OUTOFMEMORY); } IntPtr ptr = Kernel32.GlobalLock(newHandle); if (ptr == IntPtr.Zero) { return(HRESULT.E_OUTOFMEMORY); } char[] chars = str.ToCharArray(0, str.Length); UnsafeNativeMethods.CopyMemoryW(ptr, chars, chars.Length * 2); } else { int pinvokeSize = UnsafeNativeMethods.WideCharToMultiByte(0 /*CP_ACP*/, 0, str, str.Length, null, 0, IntPtr.Zero, IntPtr.Zero); byte[] strBytes = new byte[pinvokeSize]; UnsafeNativeMethods.WideCharToMultiByte(0 /*CP_ACP*/, 0, str, str.Length, strBytes, strBytes.Length, IntPtr.Zero, IntPtr.Zero); newHandle = Kernel32.GlobalReAlloc( handle, (uint)pinvokeSize + 1, Kernel32.GMEM.MOVEABLE | Kernel32.GMEM.DDESHARE | Kernel32.GMEM.ZEROINIT); if (newHandle == IntPtr.Zero) { return(HRESULT.E_OUTOFMEMORY); } IntPtr ptr = Kernel32.GlobalLock(newHandle); if (ptr == IntPtr.Zero) { return(HRESULT.E_OUTOFMEMORY); } UnsafeNativeMethods.CopyMemory(ptr, strBytes, pinvokeSize); Marshal.Copy(new byte[] { 0 }, 0, (IntPtr)((long)ptr + pinvokeSize), 1); } if (newHandle != IntPtr.Zero) { Kernel32.GlobalUnlock(newHandle); } return(HRESULT.S_OK); }
private HRESULT SaveFileListToHandle(IntPtr handle, string[] files) { if (files == null || files.Length < 1) { return(HRESULT.S_OK); } if (handle == IntPtr.Zero) { return(HRESULT.E_INVALIDARG); } IntPtr currentPtr = IntPtr.Zero; uint baseStructSize = 4 + 8 + 4 + 4; uint sizeInBytes = baseStructSize; // First determine the size of the array for (int i = 0; i < files.Length; i++) { sizeInBytes += ((uint)files[i].Length + 1) * 2; } sizeInBytes += 2; // Alloc the Win32 memory IntPtr newHandle = Kernel32.GlobalReAlloc( handle, sizeInBytes, Kernel32.GMEM.MOVEABLE | Kernel32.GMEM.DDESHARE); if (newHandle == IntPtr.Zero) { return(HRESULT.E_OUTOFMEMORY); } IntPtr basePtr = Kernel32.GlobalLock(newHandle); if (basePtr == IntPtr.Zero) { return(HRESULT.E_OUTOFMEMORY); } currentPtr = basePtr; // Write out the struct... int[] structData = new int[] { (int)baseStructSize, 0, 0, 0, unchecked ((int)0xFFFFFFFF) }; Marshal.Copy(structData, 0, currentPtr, structData.Length); currentPtr = (IntPtr)((long)currentPtr + baseStructSize); // Write out the strings. for (int i = 0; i < files.Length; i++) { UnsafeNativeMethods.CopyMemoryW(currentPtr, files[i], files[i].Length * 2); currentPtr = (IntPtr)((long)currentPtr + (files[i].Length * 2)); Marshal.Copy(new byte[] { 0, 0 }, 0, currentPtr, 2); currentPtr = (IntPtr)((long)currentPtr + 2); } Marshal.Copy(new char[] { '\0' }, 0, currentPtr, 1); currentPtr = (IntPtr)((long)currentPtr + 2); Kernel32.GlobalUnlock(newHandle); return(HRESULT.S_OK); }