private int WriteFileListToHGlobal(ref IntPtr hGlobal, IEnumerable <string> files) { if (!files?.Any() ?? false) { return(unchecked ((int)UnmanagedMethods.HRESULT.S_OK)); } char[] filesStr = (string.Join("\0", files) + "\0\0").ToCharArray(); _DROPFILES df = new _DROPFILES(); df.pFiles = Marshal.SizeOf <_DROPFILES>(); df.fWide = true; int required = (filesStr.Length * sizeof(char)) + Marshal.SizeOf <_DROPFILES>(); if (hGlobal == IntPtr.Zero) { hGlobal = UnmanagedMethods.GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, required); } long available = UnmanagedMethods.GlobalSize(hGlobal).ToInt64(); if (required > available) { return(STG_E_MEDIUMFULL); } IntPtr ptr = UnmanagedMethods.GlobalLock(hGlobal); try { Marshal.StructureToPtr(df, ptr, false); Marshal.Copy(filesStr, 0, ptr + Marshal.SizeOf <_DROPFILES>(), filesStr.Length); return(unchecked ((int)UnmanagedMethods.HRESULT.S_OK)); } finally { UnmanagedMethods.GlobalUnlock(hGlobal); } }
/// <summary> /// Returns the data packed after the DROPFILES structure. /// </summary> /// <param name="dropHandle"></param> /// <returns></returns> internal static string GetData(IntPtr dropHandle) { IntPtr data = UnsafeNativeMethods.GlobalLock(dropHandle); try { _DROPFILES df = (_DROPFILES)Marshal.PtrToStructure(data, typeof(_DROPFILES)); if (df.fWide != 0) { IntPtr pdata = new IntPtr((long)data + df.pFiles); return(Marshal.PtrToStringUni(pdata)); } } finally { if (data != IntPtr.Zero) { UnsafeNativeMethods.GlobalUnLock(data); } } return(null); }