mirror of https://github.com/dahall/Vanara.git
457 lines
15 KiB
C#
457 lines
15 KiB
C#
using NUnit.Framework;
|
|
using System;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Runtime.InteropServices;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Vanara.Extensions;
|
|
using Vanara.InteropServices;
|
|
using static Vanara.PInvoke.Kernel32;
|
|
using static Vanara.PInvoke.Tests.Kernel32Tests;
|
|
|
|
namespace Vanara.PInvoke.Tests
|
|
{
|
|
[TestFixture]
|
|
public class FileApiTests
|
|
{
|
|
//[Test]
|
|
public void AsyncReadWriteTest()
|
|
{
|
|
var fn = Path.GetTempFileName();
|
|
uint sz = 1024 * 1024 * 128;
|
|
using (var hFile = CreateFile(fn, Kernel32.FileAccess.GENERIC_WRITE, FileShare.Write, null, FileMode.OpenOrCreate,
|
|
FileFlagsAndAttributes.FILE_FLAG_OVERLAPPED, IntPtr.Zero))
|
|
{
|
|
var bytes = GetBigBytes(sz, 1);
|
|
Assert.That(bytes[1024], Is.EqualTo(1));
|
|
new TaskFactory().FromAsync<HFILE, byte[], uint>(BeginWriteFile, EndWriteFile, hFile, bytes, (uint)bytes.Length, 1).Wait();
|
|
}
|
|
var fi = new FileInfo(fn);
|
|
Assert.That(fi.Exists);
|
|
Assert.That(fi.Length, Is.EqualTo(sz));
|
|
|
|
var cfp2 = new CREATEFILE2_EXTENDED_PARAMETERS { dwFileFlags = FileFlagsAndAttributes.FILE_FLAG_OVERLAPPED, dwSize = (uint)Marshal.SizeOf(typeof(CREATEFILE2_EXTENDED_PARAMETERS)) };
|
|
using (var hFile = CreateFile2(fn, Kernel32.FileAccess.GENERIC_READ, FileShare.Read, FileMode.Open, cfp2))
|
|
{
|
|
var bytes = GetBigBytes(sz);
|
|
Assert.That(bytes[1024], Is.EqualTo(0));
|
|
new TaskFactory().FromAsync<HFILE, byte[], uint>(BeginReadFile, EndReadFile, hFile, bytes, (uint)bytes.Length, 1).Wait();
|
|
Assert.That(bytes[1024], Is.EqualTo(1));
|
|
}
|
|
|
|
Assert.That(DeleteFile(fn), Is.True);
|
|
}
|
|
|
|
[Test]
|
|
public void CompareFileTimeTest()
|
|
{
|
|
var now = DateTime.Now.ToFileTimeStruct();
|
|
var today = DateTime.Today.ToFileTimeStruct();
|
|
Assert.That(CompareFileTime(now, today), Is.GreaterThan(0));
|
|
Assert.That(CompareFileTime(now, now), Is.Zero);
|
|
}
|
|
|
|
[Test]
|
|
public void CreateDirectoryTest()
|
|
{
|
|
string dir = TestCaseSources.TempChildDir;
|
|
Assert.That(CreateDirectory(dir), Is.True);
|
|
Assert.That(System.IO.Directory.Exists(dir), Is.True);
|
|
Assert.That(RemoveDirectory(dir), Is.True);
|
|
}
|
|
|
|
[Test]
|
|
public void CreateReadFileTest()
|
|
{
|
|
var rofn = CreateTempFile();
|
|
using (var f = CreateFile(rofn, Kernel32.FileAccess.GENERIC_READ, FileShare.Read, null, FileMode.Open, FileFlagsAndAttributes.FILE_ATTRIBUTE_NORMAL, IntPtr.Zero))
|
|
{
|
|
var sb = new SafeCoTaskMemString(100, CharSet.Ansi);
|
|
var b = ReadFile(f, (IntPtr)sb, (uint)sb.Capacity, out var read, IntPtr.Zero);
|
|
if (!b) TestContext.WriteLine($"ReadFile:{Win32Error.GetLastError()}");
|
|
Assert.That(b);
|
|
if (read < sb.Capacity) Marshal.WriteInt16((IntPtr)sb, (int)read, '\0');
|
|
Assert.That(read, Is.Not.Zero.And.LessThanOrEqualTo(sb.Capacity));
|
|
Assert.That((string)sb, Is.EqualTo(tmpstr));
|
|
|
|
b = SetFilePointerEx(f, 0, out var pos, SeekOrigin.Begin);
|
|
if (!b) TestContext.WriteLine($"SetFilePointerEx:{Win32Error.GetLastError()}");
|
|
Assert.That(b);
|
|
Assert.That(pos, Is.Zero);
|
|
|
|
var bytes = new byte[100];
|
|
b = ReadFile(f, bytes, (uint)bytes.Length, out read, IntPtr.Zero);
|
|
if (!b) TestContext.WriteLine($"ReadFile:{Win32Error.GetLastError()}");
|
|
Assert.That(b);
|
|
Assert.That(read, Is.Not.Zero.And.LessThanOrEqualTo(bytes.Length));
|
|
Assert.That(Encoding.ASCII.GetString(bytes, 0, (int)read), Is.EqualTo(tmpstr));
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void CreateWriteFileTest()
|
|
{
|
|
using (var f = CreateFile(Path.GetTempFileName(), Kernel32.FileAccess.GENERIC_WRITE, FileShare.Write, null, FileMode.OpenOrCreate, FileFlagsAndAttributes.FILE_ATTRIBUTE_NORMAL, IntPtr.Zero))
|
|
{
|
|
var txt = "Some text to push.";
|
|
var bytes = txt.GetBytes(false);
|
|
var b = WriteFile(f, bytes, (uint)bytes.Length, out var written, IntPtr.Zero);
|
|
if (!b) TestContext.WriteLine($"WriteFile:{Win32Error.GetLastError()}");
|
|
Assert.That(b);
|
|
Assert.That(written, Is.EqualTo(bytes.Length));
|
|
var ptr = new SafeCoTaskMemString(" More text to push.");
|
|
b = WriteFile(f, (IntPtr)ptr, (uint)ptr.Capacity, out written, IntPtr.Zero);
|
|
if (!b) TestContext.WriteLine($"WriteFile:{Win32Error.GetLastError()}");
|
|
Assert.That(b);
|
|
Assert.That(written, Is.EqualTo(ptr.Capacity));
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void DefineDosDeviceTest()
|
|
{
|
|
const string src = "M:";
|
|
string target = TestCaseSources.TempDir;
|
|
|
|
var c = QueryDosDevice(src).ToArray().Length;
|
|
Assert.That(DefineDosDevice(DDD.DDD_NO_BROADCAST_SYSTEM, src, target), Is.True);
|
|
Assert.That(QueryDosDevice(src).ToArray(), Has.Member(@"\??\" + target).And.Length.EqualTo(c + 1));
|
|
Assert.That(DefineDosDevice(DDD.DDD_NO_BROADCAST_SYSTEM | DDD.DDD_REMOVE_DEFINITION, src, target), Is.True);
|
|
Assert.That(QueryDosDevice(src).ToArray(), Has.Length.EqualTo(c));
|
|
}
|
|
|
|
[Test]
|
|
public void DeleteSetVolumeMountPointTest()
|
|
{
|
|
// TODO: SetVolumeMountPoint();
|
|
}
|
|
|
|
[Test]
|
|
public void EnumFilesExTest()
|
|
{
|
|
Assert.That(EnumFilesEx(@"C:\Temp\*.txt").ToArray(), Is.Not.Empty);
|
|
}
|
|
|
|
[Test]
|
|
public void EnumVolumesTest()
|
|
{
|
|
Assert.That(EnumVolumes().ToArray(), Is.Not.Empty);
|
|
}
|
|
|
|
[Test]
|
|
public void FileTimeToLocalFileTimeTest()
|
|
{
|
|
var utc = DateTime.UtcNow.ToFileTimeStruct();
|
|
FileTimeToSystemTime(utc, out var st);
|
|
Assert.That(FileTimeToLocalFileTime(utc, out var ftlocal), Is.True);
|
|
FileTimeToSystemTime(ftlocal, out var stl);
|
|
Assert.That(stl.wHour, Is.EqualTo(DateTime.Now.Hour));
|
|
Assert.That(LocalFileTimeToFileTime(ftlocal, out var utc2), Is.True);
|
|
Assert.That(utc.ToUInt64(), Is.EqualTo(utc2.ToUInt64()));
|
|
}
|
|
|
|
[Test]
|
|
public void FindFirstChangeNotificationTest()
|
|
{
|
|
var keepGoing = true;
|
|
var thread = new Thread(FileMaker);
|
|
try
|
|
{
|
|
using (var h = FindFirstChangeNotification(TestCaseSources.TempDir, false, FILE_NOTIFY_CHANGE.FILE_NOTIFY_CHANGE_FILE_NAME))
|
|
{
|
|
Assert.That(h.IsInvalid, Is.False);
|
|
thread.Start();
|
|
Assert.That(WaitForSingleObject(h, 5000), Is.EqualTo(WAIT_STATUS.WAIT_OBJECT_0));
|
|
Assert.That(FindNextChangeNotification(h), Is.True);
|
|
Assert.That(WaitForSingleObject(h, 5000), Is.EqualTo(WAIT_STATUS.WAIT_OBJECT_0));
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
keepGoing = false;
|
|
thread.Join(650);
|
|
}
|
|
|
|
void FileMaker()
|
|
{
|
|
string fn = TestCaseSources.TempDir + @"\_tempFile.txt";
|
|
while (keepGoing)
|
|
{
|
|
Thread.Sleep(200);
|
|
File.WriteAllText(fn, "a;sldkfjal;skdjfl;akjsdfl;kj");
|
|
Thread.Sleep(100);
|
|
File.Delete(fn);
|
|
}
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void GetDiskFreeSpaceExTest()
|
|
{
|
|
var b = GetDiskFreeSpaceEx(null, out var fba, out var tb, out var tfb);
|
|
Assert.That(b, Is.True);
|
|
Assert.That(fba, Is.Not.EqualTo(0));
|
|
Assert.That(tb, Is.Not.EqualTo(0));
|
|
Assert.That(tfb, Is.Not.EqualTo(0));
|
|
b = GetDiskFreeSpaceEx("Q", out fba, out tb, out tfb);
|
|
Assert.That(b, Is.False);
|
|
}
|
|
|
|
[Test]
|
|
public void GetDiskFreeSpaceTest()
|
|
{
|
|
var b = GetDiskFreeSpace(null, out var spc, out var bps, out var fc, out var cc);
|
|
Assert.That(b, Is.True);
|
|
Assert.That(spc, Is.Not.EqualTo(0));
|
|
Assert.That(bps, Is.Not.EqualTo(0));
|
|
Assert.That(fc, Is.Not.EqualTo(0));
|
|
Assert.That(cc, Is.Not.EqualTo(0));
|
|
b = GetDiskFreeSpace("Q", out spc, out bps, out fc, out cc);
|
|
Assert.That(b, Is.False);
|
|
}
|
|
|
|
[Test]
|
|
public void GetDriveTypeTest()
|
|
{
|
|
Assert.That(GetDriveType(null), Is.EqualTo(DRIVE_TYPE.DRIVE_FIXED));
|
|
}
|
|
|
|
[Test]
|
|
public void GetFileInformationByHandleTest()
|
|
{
|
|
using (var tmp = new TempFile(Kernel32.FileAccess.FILE_GENERIC_READ, FileShare.Read))
|
|
{
|
|
Assert.That(GetFileInformationByHandle(tmp.hFile, out var fi), Is.True);
|
|
Assert.That(fi.nFileSizeLow, Is.EqualTo(tmpstr.Length));
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void GetFileSizeTest()
|
|
{
|
|
using (var tmp = new TempFile(Kernel32.FileAccess.FILE_GENERIC_READ, FileShare.Read))
|
|
{
|
|
Assert.That(GetFileSize(tmp.hFile, out var hw), Is.EqualTo(TempFile.tmpstr.Length));
|
|
Assert.That(hw, Is.Zero);
|
|
Assert.That(GetFileSizeEx(tmp.hFile, out var sz), Is.True);
|
|
Assert.That(sz, Is.EqualTo(TempFile.tmpstr.Length));
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void GetFileTypeTest()
|
|
{
|
|
using (var tmp = new TempFile(Kernel32.FileAccess.FILE_GENERIC_READ, FileShare.Read))
|
|
Assert.That(GetFileType(tmp.hFile), Is.EqualTo(FileType.FILE_TYPE_DISK));
|
|
}
|
|
|
|
[Test]
|
|
public void GetFinalPathNameByHandleTest()
|
|
{
|
|
var sb = new StringBuilder(MAX_PATH);
|
|
using (var tmp = new TempFile(Kernel32.FileAccess.FILE_GENERIC_READ, FileShare.Read))
|
|
{
|
|
var u = GetFinalPathNameByHandle(tmp.hFile, sb, MAX_PATH, FinalPathNameOptions.FILE_NAME_NORMALIZED);
|
|
Assert.That(u, Is.Not.Zero);
|
|
TestContext.WriteLine(sb);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void GetFullPathNameTest()
|
|
{
|
|
var sb = new StringBuilder(1024);
|
|
var u = GetFullPathName("notepad.exe", (uint)sb.Capacity, sb, out _);
|
|
Assert.That(u, Is.Not.Zero);
|
|
TestContext.WriteLine(sb);
|
|
}
|
|
|
|
[Test]
|
|
public void GetLogicalDrivesTest()
|
|
{
|
|
Assert.That(GetLogicalDrives(), Is.Not.Zero);
|
|
}
|
|
|
|
[Test]
|
|
public void GetLogicalDriveStringsTest()
|
|
{
|
|
var ie = Enumerable.Empty<string>();
|
|
Assert.That(ie = GetLogicalDriveStrings(), Is.Not.Empty);
|
|
ie.WriteValues();
|
|
}
|
|
|
|
[Test]
|
|
public void GetSetFileAttributesTest()
|
|
{
|
|
using (var tmp = new TempFile())
|
|
{
|
|
var attr = FileFlagsAndAttributes.FILE_ATTRIBUTE_ARCHIVE | FileFlagsAndAttributes.FILE_ATTRIBUTE_TEMPORARY;
|
|
Assert.That(SetFileAttributes(tmp.FullName, attr), Is.True);
|
|
Assert.That(GetFileAttributes(tmp.FullName), Is.EqualTo(attr));
|
|
Assert.That(GetFileAttributesEx(tmp.FullName, GET_FILEEX_INFO_LEVELS.GetFileExInfoStandard, out var fi), Is.True);
|
|
Assert.That(fi.dwFileAttributes, Is.EqualTo(attr));
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void GetSetFileTimeTest()
|
|
{
|
|
using (var tmp = new TempFile(Kernel32.FileAccess.FILE_ALL_ACCESS, FileShare.Read))
|
|
{
|
|
Assert.That(GetFileTime(tmp.hFile, out var ft1, out var ft2, out var ft3), Is.True);
|
|
var nft = DateTime.UtcNow.ToFileTimeStruct();
|
|
var b = SetFileTime(tmp.hFile, ft1, ft2, nft);
|
|
if (!b) TestContext.WriteLine($"SetFileTime:{Win32Error.GetLastError()}");
|
|
Assert.That(b, Is.True);
|
|
Assert.That(GetFileTime(tmp.hFile, out var nft1, out var nft2, out var nft3), Is.True);
|
|
Assert.That(ft1, Is.EqualTo(nft1));
|
|
Assert.That(nft, Is.EqualTo(nft3));
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void GetShortLongPathNameTest()
|
|
{
|
|
var sb = new StringBuilder(1024);
|
|
Assert.That(GetShortPathName(GetType().Assembly.Location, sb, (uint)sb.Capacity), Is.Not.Zero);
|
|
TestContext.WriteLine($"Short: {sb}");
|
|
var shfn = sb.ToString();
|
|
sb.Clear();
|
|
Assert.That(GetLongPathName(shfn, sb, (uint)sb.Capacity), Is.Not.Zero);
|
|
TestContext.WriteLine($"Long: {sb}");
|
|
}
|
|
|
|
[Test]
|
|
public void GetTempFileNameTest()
|
|
{
|
|
var sb = new StringBuilder(1024);
|
|
Assert.That(GetTempFileName(".", "tmp", 0, sb), Is.Not.Zero);
|
|
TestContext.WriteLine(sb);
|
|
}
|
|
|
|
[Test]
|
|
public void GetTempPathTest()
|
|
{
|
|
var sb = new StringBuilder(1024);
|
|
Assert.That(GetTempPath((uint)sb.Capacity, sb), Is.Not.Zero);
|
|
TestContext.WriteLine(sb);
|
|
}
|
|
|
|
[Test]
|
|
public void GetVolumeInformationByHandleWTest()
|
|
{
|
|
var vn = new StringBuilder(1024);
|
|
var fsn = new StringBuilder(1024);
|
|
using (var tmp = new TempFile(Kernel32.FileAccess.FILE_GENERIC_READ, FileShare.Read))
|
|
{
|
|
var b = GetVolumeInformationByHandleW(tmp.hFile, vn, (uint)vn.Capacity, out var vsn, out var mcl, out var fsf, fsn, (uint)fsn.Capacity);
|
|
Assert.That(b, Is.True);
|
|
Assert.That(vn.ToString(), Is.Not.Null.And.Not.Empty);
|
|
Assert.That(vsn, Is.Not.EqualTo(0));
|
|
Assert.That(mcl, Is.Not.EqualTo(0));
|
|
Assert.That(fsf, Is.Not.EqualTo(0));
|
|
Assert.That(fsn.ToString(), Is.Not.Null.And.Not.Empty);
|
|
TestContext.WriteLine($"{vn}:{vsn}:{mcl}:{fsf}:{fsn}");
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void GetVolumeInformationTest()
|
|
{
|
|
var b = GetVolumeInformation(null, out var vn, out var vsn, out var mcl, out var fsf, out var fsn);
|
|
Assert.That(b, Is.True);
|
|
Assert.That(vn, Is.Not.Null.And.Not.Empty);
|
|
Assert.That(vsn, Is.Not.EqualTo(0));
|
|
Assert.That(mcl, Is.Not.EqualTo(0));
|
|
Assert.That(fsf, Is.Not.EqualTo(0));
|
|
Assert.That(fsn, Is.Not.Null.And.Not.Empty);
|
|
}
|
|
|
|
[Test]
|
|
public void GetVolumeNameForVolumeMountPointTest()
|
|
{
|
|
var sb = new StringBuilder(1024);
|
|
Assert.That(GetVolumeNameForVolumeMountPoint(@"C:\", sb, (uint)sb.Capacity), Is.True);
|
|
TestContext.WriteLine(sb);
|
|
}
|
|
|
|
[Test]
|
|
public void GetVolumePathNamesForVolumeNameTest()
|
|
{
|
|
var sb = new StringBuilder(1024);
|
|
Assert.That(GetVolumePathNamesForVolumeName(EnumVolumes().First(), sb, (uint)sb.Capacity, out var l), Is.True);
|
|
TestContext.WriteLine(sb);
|
|
}
|
|
|
|
[Test]
|
|
public void GetVolumePathNameTest()
|
|
{
|
|
var sb = new StringBuilder(1024);
|
|
Assert.That(GetVolumePathName(".", sb, (uint)sb.Capacity), Is.True);
|
|
TestContext.WriteLine(sb);
|
|
}
|
|
|
|
[Test]
|
|
public unsafe void LockFileExTest()
|
|
{
|
|
using (var tmp = new TempFile(Kernel32.FileAccess.FILE_GENERIC_READ, FileShare.Read))
|
|
{
|
|
var nativeOverlapped = new NativeOverlapped();
|
|
Assert.That(LockFileEx(tmp.hFile, LOCKFILE.LOCKFILE_FAIL_IMMEDIATELY, 0, 5, 0, &nativeOverlapped), Is.True);
|
|
SleepEx(0, true);
|
|
Assert.That(UnlockFileEx(tmp.hFile, 0, 5, 0, &nativeOverlapped), Is.True);
|
|
SleepEx(0, true);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void LockFileTest()
|
|
{
|
|
using (var tmp = new TempFile(Kernel32.FileAccess.FILE_GENERIC_READ, FileShare.Read))
|
|
{
|
|
Assert.That(LockFile(tmp.hFile, 0, 0, 5, 0), Is.True);
|
|
Assert.That(UnlockFile(tmp.hFile, 0, 0, 5, 0), Is.True);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public unsafe void ReadFileExTest()
|
|
{
|
|
using (var tmp = new TempFile(Kernel32.FileAccess.FILE_GENERIC_READ, FileShare.Read))
|
|
using (var sb = new SafeCoTaskMemString(100, CharSet.Ansi))
|
|
{
|
|
var read = 0U;
|
|
var nativeOverlapped = new NativeOverlapped();
|
|
var b = ReadFileEx(tmp.hFile, (byte*)(IntPtr)sb, (uint)sb.Capacity, &nativeOverlapped, fnComplete);
|
|
if (!b) TestContext.WriteLine($"ReadFileEx:{Win32Error.GetLastError()}");
|
|
Assert.That(b);
|
|
SleepEx(0, true);
|
|
//if (read < sb.Capacity) Marshal.WriteInt16((IntPtr)sb, (int)read, '\0');
|
|
//Assert.That(read, Is.Not.Zero.And.LessThanOrEqualTo(sb.Capacity));
|
|
//Assert.That((string)sb, Is.EqualTo(tmpstr));
|
|
|
|
unsafe void fnComplete(uint dwErrorCode, uint dwNumberOfBytesTransfered, NativeOverlapped* lpOverlapped)
|
|
{
|
|
if (dwErrorCode == 0)
|
|
GetOverlappedResult(tmp.hFile, lpOverlapped, out read, false);
|
|
else
|
|
read = dwNumberOfBytesTransfered;
|
|
}
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void SetFileInformationByHandleTest()
|
|
{
|
|
using (var tmp = new TempFile(Kernel32.FileAccess.FILE_ALL_ACCESS, FileShare.Read))
|
|
{
|
|
var fai = new FILE_ALLOCATION_INFO { AllocationSize = 512 };
|
|
var b = SetFileInformationByHandle(tmp.hFile, FILE_INFO_BY_HANDLE_CLASS.FileAllocationInfo, fai);
|
|
if (!b) TestContext.WriteLine($"SetFileInformationByHandle:{Win32Error.GetLastError()}");
|
|
Assert.That(b, Is.True);
|
|
}
|
|
}
|
|
}
|
|
} |