Exemplo n.º 1
0
        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);
        }
Exemplo n.º 2
0
        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);
        }