2013-03-22 49 views
0

我正在尝试使用GetFileInformationByHandle函数获取FILE_ID_BOTH_DIR_INFO。调用后,我所有的值都设置为零。
我得到win32错误信息:
ERROR_BAD_LENGTH 程序发出一个命令,但命令长度不正确。Pinvoke命令长度不正确

IntPtr handle = CreateFile(dir, EFileAccess.GenericRead, EFileShare.Read, IntPtr.Zero, ECreationDisposition.OpenExisting, EFileAttributes.BackupSemantics | EFileAttributes.Normal, IntPtr.Zero); 
FILE_ID_BOTH_DIR_INFO fileStruct = new FILE_ID_BOTH_DIR_INFO(); 
GetFileInformationByHandleEx(handle, FILE_INFO_BY_HANDLE_CLASS.FileIdBothDirectoryInfo, out fileStruct, (uint)Marshal.SizeOf(fileStruct)); 

FILE_ID_BOTH_DIR_INFO结构

typedef struct _FILE_ID_BOTH_DIR_INFO { 
    DWORD   NextEntryOffset; 
    DWORD   FileIndex; 
    LARGE_INTEGER CreationTime; 
    LARGE_INTEGER LastAccessTime; 
    LARGE_INTEGER LastWriteTime; 
    LARGE_INTEGER ChangeTime; 
    LARGE_INTEGER EndOfFile; 
    LARGE_INTEGER AllocationSize; 
    DWORD   FileAttributes; 
    DWORD   FileNameLength; 
    DWORD   EaSize; 
    CCHAR   ShortNameLength; 
    WCHAR   ShortName[12]; 
    LARGE_INTEGER FileId; 
    WCHAR   FileName[1]; 
    } FILE_ID_BOTH_DIR_INFO, *PFILE_ID_BOTH_DIR_INFO 

在C#

public struct FILE_ID_BOTH_DIR_INFO 
    { 
     uint NextEntryOffset; 
     uint FileIndex; 
     LARGE_INTEGER CreationTime; 
     LARGE_INTEGER LastAccessTime; 
     LARGE_INTEGER LastWriteTime; 
     LARGE_INTEGER ChangeTime; 
     LARGE_INTEGER EndOfFile; 
     LARGE_INTEGER AllocationSize; 
     uint FileAttributes; 
     uint FileNameLength; 
     uint EaSize; 
     char ShortNameLength; 
     [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 12)] 
     string ShortName; 
     LARGE_INTEGER FileId; 
     [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 1)] 
     string FileName; 
    } 

    [StructLayout(LayoutKind.Explicit, Size = 8)] 
    struct LARGE_INTEGER 
    { 
     [FieldOffset(0)] 
     public Int64 QuadPart; 
     [FieldOffset(0)] 
     public UInt32 LowPart; 
     [FieldOffset(4)] 
     public Int32 HighPart; 
    } 
+0

您是否也需要FILE_ID_BOTH_DIR_INFO上的[StructLayout(LayoutKind.Explicit)]? – 2013-03-22 07:54:37

+0

@David Hefferman - 真的吗? MSDN说:“公共语言运行库默认使用Auto布局值。为了减少与Auto值相关的布局相关问题,C#,Visual Basic和C++编译器为值类型指定了Sequential布局。 – 2013-03-22 08:05:33

+0

@大卫,好的理解,谢谢澄清 - 无论如何你的答案是现货,只要你能看到被编组的东西,总是最好在非托管方面进行调试。所以,从我+1。 – 2013-03-22 08:23:31

回答

2

的字符集ByValTStr由StructLayout属性的字符集的参数来确定。由于您没有指定,使用8位ANSI的默认值。如果你将CharSet指定为CharSet.Unicode,那么应该处理这个问题。这个属性添加到您的结构:

[StructLayout(LayoutKind.Sequential, 
    CharSet=CharSet.Unicode)] 

为了调试的目的写一个C++程序,输出结构的大小。确保您的C#程序匹配该值。