我该如何使用C#中的CreateFile打开一个目录以查看已删除文件的条目?还是现在不可能了?我记得很久以前能够使用CreateFile或可能是CreateFileEx在旧操作系统下使用C++打开NTFS分区上的目录。到目前为止,我已经成功使用Windows API调用(kernel32.dll)读取现有文件,但无法打开目录:
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using Microsoft.Win32.SafeHandles;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using System.Runtime.ConstrainedExecution;
using System.Security;
namespace Kernel_Test
{
class Program
{
static void Main(string[] args)
{
Kernel_Tools cKT = new Kernel_Tools();
cKT.DoTest("C:\\Temp");
cKT.DoTest("C:\\Temp\\test.txt");
}
}
[SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
class Kernel_Tools
{
public void DoTest(string cTarget)
{
IntPtr cFile = NativeMethods.CreateFile(
cTarget,
NativeMethods.GENERIC_READ /* 0 or NativeMethods.GENERIC_READ */ ,
FileShare.Read,
IntPtr.Zero /* failed try: NativeMethods.OPEN_ALWAYS */,
(FileMode) NativeMethods.OPEN_EXISTING,
NativeMethods.FILE_FLAG_BACKUP_SEMANTICS /* 0 */ ,
IntPtr.Zero);
Console.WriteLine(cTarget);
Console.WriteLine(cFile);
if ((int)cFile != -1)
{
int length = 20;
byte[] bytes = new byte[length];
int numRead = 0;
int ErrorCheck = NativeMethods.ReadFile(cFile, bytes, length, out numRead, IntPtr.Zero);
// This sample code will not work for all files.
//int r = NativeMethods.ReadFile(_handle, bytes, length, out numRead, IntPtr.Zero);
// Since we removed MyFileReader's finalizer, we no longer need to
// call GC.KeepAlive here. Platform invoke will keep the SafeHandle
// instance alive for the duration of the call.
if (ErrorCheck == 0)
{
Console.WriteLine("Read failed.");
NativeMethods.CloseHandle(cFile);
return;
//throw new Win32Exception(Marshal.GetLastWin32Error());
}
if (numRead < length)
{
byte[] newBytes = new byte[numRead];
Array.Copy(bytes, newBytes, numRead);
bytes = newBytes;
}
for (int i = 0; i < bytes.Length; i++)
Console.Write((char)bytes[i]);
Console.Write("\n\r");
// Console.WriteLine();
NativeMethods.CloseHandle(cFile);
}
}
}
[SuppressUnmanagedCodeSecurity()]
internal static class NativeMethods
{
// Win32 constants for accessing files.
internal const int GENERIC_READ = unchecked((int)0x80000000);
internal const int FILE_FLAG_BACKUP_SEMANTICS = unchecked((int)0x02000000);
internal const int OPEN_EXISTING = unchecked((int)3);
// Allocate a file object in the kernel, then return a handle to it.
[DllImport("kernel32", CharSet = CharSet.Auto, SetLastError = true)]
internal extern static IntPtr CreateFile(
String fileName,
int dwDesiredAccess,
System.IO.FileShare dwShareMode,
IntPtr securityAttrs_MustBeZero,
System.IO.FileMode dwCreationDisposition,
int dwFlagsAndAttributes,
IntPtr hTemplateFile_MustBeZero);
// Use the file handle.
[DllImport("kernel32", SetLastError = true)]
internal extern static int ReadFile(
IntPtr handle,
byte[] bytes,
int numBytesToRead,
out int numBytesRead,
IntPtr overlapped_MustBeZero);
// Free the kernel's file object (close the file).
[DllImport("kernel32", SetLastError = true)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
internal extern static bool CloseHandle(IntPtr handle);
}
}
编辑1:修改为使用OPEN_EXISTING、FILE_FLAG_BACKUP_SEMANTICS和GENERIC_READ。
这将打开并显示指定文本文件的开头,就像原始程序在以Vista管理员用户身份运行时所做的那样,但它仍然无法打开目录。我猜我需要SE_BACKUP_NAME和SE_RESTORE_NAME权限,但不确定如何指定这些权限,除非编写一个作为本地机器运行的服务(我只有模糊的想法)。