0

I am trying to list the contents of MFT with the use of Java and JNA. I have set up the kernel32.dll library correctly, and i am able to retrieve a handle to the file using CreateFile() method from windows API. However when trying to enumerate all entries using DeviceIoControl with FSCTL_ENUM_USN_DATA code, i recieve error code 5 - Access Denied. What am I doing wrong? The program is run with administrator privileges.

Relevant code snippet

public final Kernel32 libinstance = Kernel32.INSTANCE;
int FSCTL_ENUM_USN_DATA = WinioctlUtil.CTL_CODE(Winioctl.FILE_DEVICE_FILE_SYSTEM, Winioctl.FILE_ANY_ACCESS, 44, Winioctl.METHOD_NEITHER);
    int FSCTL_GET_RETRIEVAL_POINTERS = WinioctlUtil.CTL_CODE(Winioctl.FILE_DEVICE_FILE_SYSTEM, Winioctl.FILE_ANY_ACCESS, 28, Winioctl.METHOD_NEITHER);
    MFTEnumData med = new MFTEnumData();
    WinNT.HANDLE handle = libinstance.CreateFile("\\\\.\\PhysicalDrive0",
                                                GENERIC_READ,
                                                FILE_SHARE_READ | FILE_SHARE_WRITE,
                                                null,
                                                WinNT.OPEN_EXISTING,
                                                FILE_FLAG_BACKUP_SEMANTICS,
                                                null);
    int lastError = libinstance.GetLastError();
    Pointer pData = new Memory(WinDef.DWORDLONG.SIZE + 0x10000); // 64 kB
    IntByReference cb = new IntByReference(0);
    boolean r = libinstance.DeviceIoControl(handle, FSCTL_ENUM_USN_DATA, med.getPointer(), Native.getNativeSize(MFTEnumData.class), pData, (int)((Memory) pData).size(), cb, null);
        // after this call the lastError is 5
    lastError = libinstance.GetLastError();
    libinstance.CloseHandle(handle);

I would appreciate any help on how to Iterate through the MFT and list all the files. The performance is the most important thing for me in this task and the normal Files-based solution are way too slow.

zool
  • 11
  • 5

1 Answers1

0

I think the MFTEnumData is probably your problem. You need to set the the HighUSN member to the UsnJournal's NextUSN...otherwise, you're asking for an enumeration from USNs 0 to 0.

I wrote an answer describing how to read the MFT...but it's in C#. How do we access MFT through C#. I hope/believe it's not an awful translation problem to Java.

One thing I noticed that I did...that you didn't...and may be necessary...is adding ACCESS_SYSTEM_SECURITY when opening the volume handle. The docs for FSCTL_ENUM_USN_DATA didn't specifically say you had to do that...but the docs aren't always exhaustive.

Clay
  • 4,999
  • 1
  • 28
  • 45