首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JNA接入NTFS USN (win32)。如何从内存对象中获取数据?

JNA接入NTFS USN (win32)。如何从内存对象中获取数据?
EN

Stack Overflow用户
提问于 2018-08-29 11:16:41
回答 1查看 74关注 0票数 1

从内存中提取USN数据,结果数据不正确。该怎么办呢

代码语言:javascript
复制
public static void main(String[] args) throws IOException {
    // get c volume handle
    WinNT.HANDLE handle = Kernel32.INSTANCE.CreateFile("\\\\.\\C:",WinNT.GENERIC_READ|WinNT.GENERIC_WRITE,
        WinNT.FILE_SHARE_READ|WinNT.FILE_SHARE_WRITE,null,WinNT.OPEN_EXISTING,0,null);

    IntByReference bytesByReturned = new IntByReference();
    // output to memory
    Memory memory = new Memory(Integer.MAX_VALUE);
    memory.clear();

    // input query args
    MFT_ENUM_DATA med = new MFT_ENUM_DATA();
    med.StartFileReferenceNumber = 0;
    med.LowUsn = 0;
    med.HighUsn = 99999999;
    med.write();

    int FSCTL_ENUM_USN_DATA = 0x000900B3;

    // access device, get usn data to memory buffer object
    boolean ok = Kernel32.INSTANCE.DeviceIoControl(handle,FSCTL_ENUM_USN_DATA, med.getPointer(),
        med.size(), memory, (int)memory.size(), bytesByReturned, null);

    if(ok) {
        // that's wrong!!! , get the wrong data!
        int RecordLength = memory.getInt(0);
        short MajorVersion = memory.getShort(4);
        short MinorVersion = memory.getShort(6);
        long FileReferenceNumber = memory.getLong(8);

        // error value
        System.out.println("RecordLength:\t"+RecordLength);
        System.out.println("MajorVersion:\t"+MajorVersion);
        System.out.println("MinorVersion:\t"+MinorVersion);
        System.out.println("FileReferenceNumber:\t"+FileReferenceNumber);
        // ...
    }else {
        System.out.println("ERROR "+Kernel32.INSTANCE.GetLastError()+" "+ Kernel32Util.getLastErrorMessage());

        throw new IOException("DeviceIoControl() returned false", new Win32Exception(Kernel32.INSTANCE.GetLastError()));

    }
}

static public class MFT_ENUM_DATA extends Structure {
    public long StartFileReferenceNumber;
    public long LowUsn;
    public long HighUsn;

    @Override
    protected List<String> getFieldOrder() {
        List<String> order = new ArrayList<>();
        order.add("StartFileReferenceNumber");
        order.add("LowUsn");
        order.add("HighUsn");
        return order;
    }
}

无法从内存缓冲区对象获取结构数据,该怎么办?

代码语言:javascript
复制
typedef struct USN_RECORD_V2 {
  DWORD         RecordLength;
  WORD          MajorVersion;
  WORD          MinorVersion;
  DWORDLONG     FileReferenceNumber;
  DWORDLONG     ParentFileReferenceNumber;
  USN           Usn;
  LARGE_INTEGER TimeStamp;
  DWORD         Reason;
  DWORD         SourceInfo;
  DWORD         SecurityId;
  DWORD         FileAttributes;
  WORD          FileNameLength;
  WORD          FileNameOffset;
  WCHAR         FileName[1];
}  *PUSN_RECORD_V2;

链接:

从内存中获取USN_RECORD_V2。非常感谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-08-30 04:11:16

欢迎来到StackOverflow!

链接到的文档显示,来自此函数的内存输出缓冲区如下:

指向输出缓冲区的指针,接收USN,后面跟着零个或多个USN_RECORD_V2或USN_RECORD_V3结构。USN是一个DWORDLONG值,它表示缓冲区中最后一条记录之后的USN。

您正在尝试读取从偏移量0开始的内存,但是前8个字节是一个USN,您可以在以后的调用中使用它。

您将向现有代码中添加8个字节以获得正确的值;然而,要做到这一点,一个更易读的方法是用所有的Structure字段及其字节值映射一个USN_RECORD_V2,从memory.share(8)映射结构的read()

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52076164

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档