I am using the code found here to drag-drop .msg files directly from outlook. The FileDescriptorA
class is implemented like this:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public sealed class FILEDESCRIPTORA
{
public uint dwFlags;
public Guid clsid;
public SIZEL sizel;
public POINTL pointl;
public uint dwFileAttributes;
public System.Runtime.InteropServices.ComTypes.FILETIME ftCreationTime;
public System.Runtime.InteropServices.ComTypes.FILETIME ftLastAccessTime;
public System.Runtime.InteropServices.ComTypes.FILETIME ftLastWriteTime;
public uint nFileSizeHigh;
public uint nFileSizeLow;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string cFileName;
}
And the code to get the file names is:
MemoryStream fgdStream =
(MemoryStream)e.Data.GetData("FileGroupDescriptor");
byte[] fgdBytes = new byte[fgdStream.Length];
fgdStream.Read(fgdBytes, 0, fgdBytes.Length);
fgdStream.Close();
//copy the file group descriptor into unmanaged memory
IntPtr fgdaPtr = Marshal.AllocHGlobal(fgdBytes.Length);
Marshal.Copy(fgdBytes, 0, fgdaPtr, fgdBytes.Length);
int numFiles = Marshal.ReadInt32(fgdaPtr);
string[] fileNames = new string[numFiles];
//get the pointer to the first file descriptor
IntPtr fdPtr = (IntPtr)((int)fgdaPointer + Marshal.SizeOf(fgdaPointer));
//loop for the number of files acording to the file group descriptor
for(int fdIndex = 0;fdIndex < numfiles;fdIndex++)
{
//marshal the pointer to the file descriptor as a FILEDESCRIPTORA struct
object fdObj = Marshal.PtrToStructure(fdPtr,
typeof(NativeMethods.FILEDESCRIPTORA));
NativeMethods.FILEDESCRIPTORA fd = (NativeMethods.FILEDESCRIPTORA)fdObj;
//get file name of file descriptor and put in array
fileNames[fdIndex] = fd.cFileName;
//move the file descriptor pointer to the next file descriptor
fdPtr = (IntPtr)((int)fdPtr + Marshal.SizeOf(fd));
}
This all works great, except for that the file name coming back is always missing the first couple characters. Does anyone know what would cause that and/or how to fix it?
In the comments on the codeproject page another person mentions the same problem - in that case the offset of an array item was computed from the start of the structure, not taking into account the first 32/64 bits that contain the number of items in the array:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public sealed class FILEGROUPDESCRIPTORA
{
public uint cItems;
public FILEDESCRIPTORA[] fgd;
}