Esempio n. 1
0
        unsafe HRESULT SaveHdropToHandle(ref IntPtr handle, string[] files)
        {
            int size = sizeof(Shell32.DROPFILES);

            foreach (var f in files)
            {
                size += (f.Length + 1) * 2;
            }

            size += 2; // Terminal null

            var hg = Kernel32.GlobalReAlloc(handle, size, Kernel32.GMEM.GMEM_MOVEABLE);

            if (hg.IsNull)
            {
                return(HRESULT.E_OUTOFMEMORY);
            }

            var lc = Kernel32.GlobalLock(hg);

            Shell32.DROPFILES *df = (Shell32.DROPFILES *)lc.ToPointer();
            df->pFiles = (uint)files.Length;
            df->fNC    = false;
            df->fWide  = false;

            char *ptr = ((char *)df) + sizeof(Shell32.DROPFILES);

            foreach (var f in files)
            {
                fixed(char *str = f)
                {
                    Buffer.MemoryCopy(str, ptr, f.Length + 2, f.Length + 2);
                    ptr[f.Length] = '\0';
                    ptr          += f.Length + 1;
                }

                *ptr = '\0';
            }
            Kernel32.GlobalUnlock(hg);
            return(HRESULT.S_OK);
        }
Esempio n. 2
0
        private unsafe HRESULT SaveFileListToHandle(IntPtr handle, string[] files)
        {
            if (files is null || files.Length == 0)
            {
                return(HRESULT.S_OK);
            }

            if (handle == IntPtr.Zero)
            {
                return(HRESULT.E_INVALIDARG);
            }

            // CF_HDROP consists of a DROPFILES struct followed by an list of strings
            // including the terminating null character. An additional null character
            // is appended to the final string to terminate the array.
            // E.g. if the files c:\temp1.txt and c:\temp2.txt are being transferred,
            // the character array is: "c:\temp1.txt\0c:\temp2.txt\0\0"

            // Determine the size of the data structure.
            uint sizeInBytes = (uint)sizeof(Shell32.DROPFILES);

            for (int i = 0; i < files.Length; i++)
            {
                sizeInBytes += ((uint)files[i].Length + 1) * 2;
            }
            sizeInBytes += 2;

            // Allocate 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);
            }

            // Write out the DROPFILES struct.
            Shell32.DROPFILES *pDropFiles = (Shell32.DROPFILES *)basePtr;
            pDropFiles->pFiles = (uint)sizeof(Shell32.DROPFILES);
            pDropFiles->pt     = Point.Empty;
            pDropFiles->fNC    = BOOL.FALSE;
            pDropFiles->fWide  = BOOL.TRUE;

            char *dataPtr = (char *)(basePtr + (int)pDropFiles->pFiles);

            // Write out the strings.
            for (int i = 0; i < files.Length; i++)
            {
                int bytesToCopy = files[i].Length * 2;
                fixed(char *pFile = files[i])
                {
                    Buffer.MemoryCopy(pFile, dataPtr, bytesToCopy, bytesToCopy);
                }

                dataPtr = (char *)((IntPtr)dataPtr + bytesToCopy);
                *dataPtr = '\0';
                dataPtr++;
            }

            *dataPtr = '\0';
            dataPtr++;

            Kernel32.GlobalUnlock(newHandle);
            return(HRESULT.S_OK);
        }