在锁定文件上使用CreateFile来获取文件句柄

时间:2014-09-05 01:31:52

标签: winapi

我删除了我的其他问题。谢谢大家帮助我实现如何发布。

我的桌面上有一个名为rawr.txt的文件。该文件已被锁定。我想打开它的唯一原因是获取文件句柄。 (我将搜索枚举的归档句柄列表,以确定哪个进程ID正在锁定此文件)。

这是我的代码:

Cu.import("resource://gre/modules/ctypes.jsm");
var lib_kernel32 = ctypes.open("kernel32.dll");

//var INVALID_HANDLE_VALUE = ctypes.voidptr_t(-1);
var GENERIC_READ = 0x80000000;
var GENERIC_WRITE = 0x40000000;
var OPEN_EXISTING = 3;
var FILE_ATTRIBUTE_NORMAL = 0x80;
var FILE_FLAG_OVERLAPPED = 0x40000000;


      var OPEN_ALWAYS = 4;

      var INVALID_HANDLE_VALUE = new ctypes.Int64(-1);
      var FSCTL_SET_SPARSE = 0x900c4;
      var FSCTL_SET_ZERO_DATA = 0x980c8;
      var FILE_BEGIN = 0;


        let CreateFile = lib_kernel32.declare(
          "CreateFileW",
          ctypes.winapi_abi,
          ctypes.voidptr_t,            // return type: handle to the file
          ctypes.jschar.ptr, // in: lpFileName
          ctypes.uint32_t,   // in: dwDesiredAccess
          ctypes.uint32_t,   // in: dwShareMode
          ctypes.voidptr_t,  // in, optional: lpSecurityAttributes (note that
                             // we're cheating here by not declaring a
                             // SECURITY_ATTRIBUTES structure -- that's because
                             // we're going to pass in null anyway)
          ctypes.uint32_t,   // in: dwCreationDisposition
          ctypes.uint32_t,   // in: dwFlagsAndAttributes
          ctypes.voidptr_t             // in, optional: hTemplateFile
        );

          let CloseHandle = lib_kernel32.declare(
            "CloseHandle",
            ctypes.winapi_abi,
            ctypes.int32_t, //bool  // return type: 1 indicates success, 0 failure
            ctypes.voidptr_t // in: hObject
          );

        var aFile = FileUtils.getFile('Desk', ['rawr.txt']);

        let filePath = aFile.path;
        let hFile = CreateFile(filePath, GENERIC_READ, 0, null, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, null);
        let hFileInt = ctypes.cast(hFile, ctypes.intptr_t);
        if (ctypes.Int64.compare(hFileInt.value, INVALID_HANDLE_VALUE) == 0) {
          throw new Error("CreateFile failed for " + filePath + ", error " +
                          ctypes.winLastError);
        }
        CloseHandle(hFile);

lib_kernel32.close();

问题是我总是在throw new Error行上得到一些例外。我最常见的是错误32,有时在尝试使用标记时会出现错误。

由于

2 个答案:

答案 0 :(得分:2)

由于你想要的只是文件的句柄,你不应该使用GENERIC_READ。这要求其他进程使用FILE_SHARE_READ打开文件。

此外,需要允许其他进程打开文件,方法是指定FILE_SHARE_READFILE_SHARE_WRITEFILE_SHARE_DELETE

CreateFile(filepath, 0, 
           FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
           ...)

...在这之后,你有了一个没有访问权限的文件句柄,这几乎没用。 (你得到的句柄与其他进程的句柄没有任何关系,所以自己拥有一个句柄并不能帮助你以任何我能看到的方式搜索现有句柄列表。)

答案 1 :(得分:1)

  let hFile = CreateFile(filePath, GENERIC_READ, 0, ...)

为dwShareMode参数传递0不会让你到任何地方。要求对文件进行独占访问,您无法获得该文件,因为另一个进程已经获得了读取或写入访问权限。通常在日志文件的情况下访问GENERIC_WRITE。你需要FILE_SHARE_READ | FILE_SHARE_WRITE谦虚地问。

如果仍然不起作用,那么另一个进程 adamant 关于你没有弄乱文件。它故意省略了FILE_SHARE_READ。对于文本文件来说并不常见,但是当程序员认为无法正确读取文件时就会完成,因为他经常更改文件。除了拿起电话和致电程序员之外,你无法覆盖这个决定。