首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >读取USN日志时出现错误1784

读取USN日志时出现错误1784
EN

Stack Overflow用户
提问于 2018-05-03 16:10:24
回答 1查看 217关注 0票数 0

我想使用Java JNA库读取Windows USN (文件系统)日志。我可以打开驱动器的句柄并查询日志信息。但是当我尝试读取日志数据(FSCTL_READ_USN_JOURNAL)时,我得到了错误1784 (所提供的用户缓冲区对于所请求的操作无效)。Windows 7/64、JNA版本4.5.1、java 8/32。我用C++做了同样的尝试,它工作得很好。

代码语言:javascript
复制
import java.io.IOException;
import java.util.List;

import com.sun.jna.Memory;
import com.sun.jna.Structure;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.Kernel32Util;
import com.sun.jna.platform.win32.WinNT;
import com.sun.jna.platform.win32.Winioctl;
import com.sun.jna.platform.win32.WinioctlUtil;
import com.sun.jna.ptr.IntByReference;

public class NtfsUsnJournal2
{
  public static void main(String[] args)
  {
    try
    {
      WinNT.HANDLE hDevice = openDisk('C');
      try
      {
    USN_JOURNAL_INFO_V0 journalInfo = queryJournal(hDevice);
    System.out.println(journalInfo);
    //
    Memory buffer = new Memory(4096);
    buffer.clear();
    IntByReference numBytesReturned = new IntByReference(0);
    READ_USN_JOURNAL_DATA_V0 journalData = new READ_USN_JOURNAL_DATA_V0();
    journalData.clear();
    journalData.ReasonMask = 0xFFFFFFFF;
    journalData.UsnJournalID = journalInfo.UsnJournalID;
    journalData.write();
    System.out.println(journalData);
    boolean ok = Kernel32.INSTANCE.DeviceIoControl(hDevice,
      FSCTL_READ_USN_JOURNAL, // = 590011
      journalData.getPointer(),journalData.size(),
      buffer.getPointer(0),(int)buffer.size(),
      numBytesReturned,null);
    if( !ok )
    {
      System.out.println("ERROR "+Kernel32.INSTANCE.GetLastError()+" "+Kernel32Util.getLastErrorMessage());
      return;
    }
    System.out.println(numBytesReturned.getValue());
    System.out.println(buffer.getInt(8));
      }
      finally
      {
    Kernel32.INSTANCE.CloseHandle(hDevice);
      }
    }
    catch( Exception e )
    {
      e.printStackTrace();
    }
  }

  static USN_JOURNAL_INFO_V0 queryJournal(WinNT.HANDLE hDevice) throws IOException
  {
    USN_JOURNAL_INFO_V0 journalInfo = new USN_JOURNAL_INFO_V0();
    journalInfo.clear();
    //
    IntByReference numBytesReturned = new IntByReference(0);
    boolean ok = Kernel32.INSTANCE.DeviceIoControl(hDevice,
      FSCTL_QUERY_USN_JOURNAL,null,0,
      journalInfo.getPointer(),journalInfo.size(),
      numBytesReturned,null);
    if( !ok )
    {
      throw new IOException(
    "ERROR "+Kernel32.INSTANCE.GetLastError()+": "+Kernel32Util.getLastErrorMessage());
    }
    journalInfo.read();
    return journalInfo;
  }

  static WinNT.HANDLE openDisk(char drive)
  {
    return Kernel32.INSTANCE.CreateFile("\\\\.\\"+drive+":",
      WinNT.GENERIC_READ|WinNT.GENERIC_WRITE,
      WinNT.FILE_SHARE_READ|WinNT.FILE_SHARE_WRITE,null,WinNT.OPEN_EXISTING,0,null);
  }

  static public class USN_JOURNAL_INFO_V0 extends Structure
  {
    public static final List<String> FIELDS = createFieldsOrder(
      "UsnJournalID","FirstUsn","NextUsn","LowestValidUsn","MaxUsn","MaximumSize","AllocationDelta");
    protected List<String> getFieldOrder() { return FIELDS; }
    //
    public long UsnJournalID;
    public long FirstUsn;
    public long NextUsn;
    public long LowestValidUsn;
    public long MaxUsn;
    public long MaximumSize;
    public long AllocationDelta;
  }

  static public class READ_USN_JOURNAL_DATA_V0 extends Structure
  {
    public static final List<String> FIELDS = createFieldsOrder(
      "StartUsn","ReasonMask","ReturnOnlyOnClose","Timeout","BytesToWaitFor","UsnJournalID");
    protected List<String> getFieldOrder() { return FIELDS; }
    //
    public long StartUsn;
    public int  ReasonMask;
    public int  ReturnOnlyOnClose;
    public long Timeout;
    public long BytesToWaitFor;
    public long UsnJournalID;
  }

  static final int FSCTL_QUERY_USN_JOURNAL =
    WinioctlUtil.CTL_CODE(Winioctl.FILE_DEVICE_FILE_SYSTEM, 61,
    Winioctl.METHOD_BUFFERED,Winioctl.FILE_ANY_ACCESS);

  static final int FSCTL_READ_USN_JOURNAL =
    WinioctlUtil.CTL_CODE(Winioctl.FILE_DEVICE_FILE_SYSTEM, 46,
    Winioctl.METHOD_NEITHER,Winioctl.FILE_ANY_ACCESS);
}
EN

回答 1

Stack Overflow用户

发布于 2018-08-30 16:15:39

内存扩展指针,不需要getPointer

代码语言:javascript
复制
boolean ok = Kernel32.INSTANCE.DeviceIoControl(hDevice,
         FSCTL_READ_USN_JOURNAL, // = 590011
         journalData.getPointer(),journalData.size(),
         buffer,(int)buffer.size(),
         numBytesReturned,null);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50150039

复制
相关文章

相似问题

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