gpt4 book ai didi

c# - 如何在 C# 中使用 CreateFile 打开目录以检查已删除的条目?

转载 作者:太空狗 更新时间:2023-10-29 22:35:18 25 4
gpt4 key购买 nike

如何在 C# 中使用 CreateFile 打开目录以检查已删除文件的条目?还是现在不可能了?我记得以前能够使用 CreateFile 或 CreateFileEx 打开 NTFS 分区上的目录,但那是在旧操作系统下使用 C++。

到目前为止,我的 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 权限,但我不确定如何指定这些权限,而不是将其编写为作为本地机器运行的服务(我对如何做只有最模糊的想法)。

最佳答案

据我所知,这是一个相当复杂的过程。您不能只使用 CreateFile 并枚举“已删除的文件”。您必须加载驱动器的主文件表,并枚举标记为已删除的文件,然后尝试从 MFT 中列出的磁盘位置加载数据。这将需要大量的平台调用代码,并且可能需要对 C# 中的 native 数据结构进行一些重新定义。

对您的问题的简短回答是:

CreateFile("\\\\.\\PhysicalDrive0",
GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE,
0,
OPEN_EXISTING,
0,
NULL)

您使用创建文件来打开磁盘本身。

Here is a really good article about the whole process on Code Project.但是,这一切都在 C++ 中。代码在那儿,看来你知道如何 p\invoke,所以移植过来应该不是问题。

编辑:

事实上,驱动器是外部的,这不会让它变得更难,您仍然可以按照我展示的方式打开磁盘(连接驱动器后,可以使用 WMI tool 来查找路径)。然后,您可以使用 Wikipedia page for FAT32 上的信息定义可以将 MFT 和文件系统的其他部分读入的数据结构。到达那里后,您只需遍历目录表中的 32 字节文件定义,查看第一个字节:

0xE5    Entry has been previously erased and is available. File undelete utilities must replace this character with a regular character as part of the undeletion process.

关于c# - 如何在 C# 中使用 CreateFile 打开目录以检查已删除的条目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1344094/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com