Как открыть каталог с CreateFile в C #, чтобы проверить записи удаленных файлов? Или это сейчас невозможно? Я помню, как когда-то назад была возможность открыть каталог в разделе NTFS с помощью CreateFile или, возможно, CreateFileEx, но это было с использованием 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, но я не уверен, как указать их, кроме как записать это как службу, которая работает как Локальная машина (что-то, у меня есть только самое туманное представление о том, как это сделать).