В WinAPI есть такие функции как FindFirstFile и FindNextFile, которые используют структуру WIN32_FIND_DATA, для .NET, Микрософт определяет её в виде класса:
[Serializable, StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto), BestFitMapping(false)]
internal class WIN32_FIND_DATA
{
internal int dwFileAttributes;
internal int ftCreationTime_dwLowDateTime;
internal int ftCreationTime_dwHighDateTime;
internal int ftLastAccessTime_dwLowDateTime;
internal int ftLastAccessTime_dwHighDateTime;
internal int ftLastWriteTime_dwLowDateTime;
internal int ftLastWriteTime_dwHighDateTime;
internal int nFileSizeHigh;
internal int nFileSizeLow;
internal int dwReserved0;
internal int dwReserved1;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=260)]
internal string cFileName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=14)]
internal string cAlternateFileName;
public WIN32_FIND_DATA();
}
Я его чуть переделал, и расчета того что ftCreationTime_dwLowDateTime и ftCreationTime_dwHighDateTime располагаются как раз в таком порядке, что если их накрыть long-полем, то оно получит валидное значение:
[Serializable]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
[BestFitMapping(false)]
class WIN32_FIND_DATA
{
public int dwFileAttributes;
//public int ftCreationTime_dwLowDateTime;
//public int ftCreationTime_dwHighDateTime;
public long CreationTime;
public int ftLastAccessTime_dwLowDateTime;
public int ftLastAccessTime_dwHighDateTime;
public int ftLastWriteTime_dwLowDateTime;
public int ftLastWriteTime_dwHighDateTime;
public int nFileSizeHigh;
public int nFileSizeLow;
int Reserved0;
int Reserved1;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string FileName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
public string AlternateFileName;
}
но не тут то было, DateTime.FromFileTime() вылетает с руганью на неверное значение параметра. Тогда я поменял в long-поле первое слово и второе местами:
fileData.CreationTime = (long)(((ulong)fileData.CreationTime >> 32) | ((ulong)fileData.CreationTime << 32));
и, о чудо, оно зароботало. Но появилась другая проблема. FileName сдвинулось на одно слово (4 байта) так, как будто я добавил лишнее intовое поле (пример: fileData.FileName вместо "Yahoo!" теперь содержит "hoo!").
Вопрос не жизненно важный, я проблему решил оставив структуру в прежнем виде
public static DateTime FileTimeToDateTime(int highWord, int lowWord)
{
return DateTime.FromFileTime((((long)highWord) << 32) + lowWord);
}
Интересно почему при замене двух Int32 на одно Int64 поля сдвинулись, и почему Int64 ведет себя так, как будто слова в нем располагаются в big-endian порядке т.е. сначала старшее слово потом младшее, а не так как принято на x86 платформе?