Blagoh
Blagoh

Reputation: 1235

Use CreateFile on locked file to get file handle

I deleted my other question. Thanks all for helping me realize how to post.

I have a file on my desktop named rawr.txt. The file is locked. I would like to open it for the sole reason of getting a filehandle to it. (i will search a list of enumerated filed handles to identify what process id's are locking this file).

This is my code:

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();

Problem with this is I always get some exception on the throw new Error line. I get error 32 most commonly and sometimes 87 when experimenting with flags.

Thanks

Upvotes: 1

Views: 1410

Answers (2)

Hans Passant
Hans Passant

Reputation: 941357

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

Passing 0 for the dwShareMode argument is not going to get you anywhere. That asks for exclusive access to the file, you cannot get that because another process already obtained read or write access. Usually GENERIC_WRITE access in the case of a log file. You'll need FILE_SHARE_READ | FILE_SHARE_WRITE to ask humbly.

If that still doesn't work then the other process was adamant about you not messing with the file. It intentionally omitted FILE_SHARE_READ. Not very common for a text file, but done when the programmer deems it impossible to read the file correctly because he is constantly changing it. You cannot override that decision, other than by picking up the phone and calling the programmer.

Upvotes: 1

Harry Johnston
Harry Johnston

Reputation: 36308

Since all you want is a handle to the file, you shouldn't be using GENERIC_READ. That requires that the other process opened the file with FILE_SHARE_READ.

Also, you need to allow other processes to have the file open, by specifying FILE_SHARE_READ, FILE_SHARE_WRITE, and FILE_SHARE_DELETE:

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

... and after all this, you've got a handle to the file with no access, which is pretty much useless. (The handle you get has no relationship to the handles of other processes, so having a handle yourself does not help you search a list of existing handles in any way I can see.)

Upvotes: 2

Related Questions