2014-09-05 130 views
1

我刪除了我的其他問題。感謝所有幫助我實現如何發佈。使用鎖定文件上的CreateFile來獲取文件句柄

我的桌面上有一個名爲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,有時候使用標誌進行測試。

感謝

回答

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

爲dwShareMode參數傳遞0是不會讓你隨時隨地。這要求對文件進行獨佔訪問,因爲另一個進程已經獲得了讀取或寫入訪問權限,所以無法獲得該文件。通常在日誌文件的情況下GENERIC_WRITE訪問。你需要FILE_SHARE_READ | FILE_SHARE_WRITE謙虛地問。

如果這仍然不起作用,那麼另一個進程是adamant關於你沒有搞亂文件。它故意省略FILE_SHARE_READ。對於文本文件不是很常見,但在程序員認爲無法正確讀取文件時完成,因爲他經常更改它。除了拿起電話和給程序員打電話以外,你不能重寫這個決定。

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, 
      ...) 

...之後這一切,你已經有了一個手柄到無法訪問的文件,這是非常無用的。 (您得到的手柄與其他過程的手柄沒有任何關係,因此自己手動操作並不能幫助您以任何方式查找現有手柄的列表。)