如何获取锁定的文件路径的句柄

时间:2014-09-04 23:49:17

标签: winapi

mydesktop parent.lock上有一个文件,它是一个文本文件。我想要锁定此文件的PID。所以我设法列出了所有使用的句柄。代码在下面打了出来。

我想使用CreateFile在我的桌面上打开parent.lock以获取它的句柄,因为我不知道打开它的过程我无法使用DuplicateHandle。这可能吗?

由于某些原因,

GetFullPathFinal不适合我。一个是它唯一的Vista +。

我用NtQuerySystemInformation(SystemHandleInformation....列出了所有句柄,它返回了54000个句柄(这个数字听起来不错吗?)

mydesktop parent.lock上有一个文件,它是一个文本文件。我想要锁定此文件的PID。但是我无法找到桌面上parent.lock文件的文件句柄。

这就是我枚举句柄的方法:

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

var STATUS_BUFFER_TOO_SMALL = 0xC0000023>>0;
var STATUS_INFO_LENGTH_MISMATCH = 0xC0000004>>0;
var SystemHandleInformation = 16;

var UNICODE_STRING = new ctypes.StructType("UNICODE_STRING", [
{'Length': ctypes.unsigned_short}, //USHORT
{'MaximumLength': ctypes.unsigned_short}, //USHORT
{'Buffer': ctypes.jschar.ptr} ]); //PWSTR  

//https://github.com/tjguk/winsys/blob/5f11b308171382046ff0f67ef3129e47e9fee06c/random/file_handles.py#L100
var SYSTEM_HANDLE_TABLE_ENTRY_INFO = new ctypes.StructType('SYSTEM_HANDLE_TABLE_ENTRY_INFO', [ //typedef struct _TagHANDLEINFO
{'UniqueProcessId': ctypes.unsigned_short}, //USHORT dwPid; //UniqueProcessId
{'CreatorBackTraceIndex': ctypes.unsigned_short}, //USHORT CreatorBackTraceIndex; //CreatorBackTraceIndex
{'ObjectTypeIndex': ctypes.unsigned_long}, //BYTE ObjType; //ObjectTypeIndex UCHAR
{'HandleAttributes': ctypes.unsigned_long}, //BYTE HandleAttributes; //im not sure if byte should be unsigned_long, maybe unsigned_char //HandleAttributes UCHAR
{'HandleValue': ctypes.unsigned_short}, //USHORT HndlOffset; //HandleValue USHORT
{'Object': ctypes.void_t.ptr}, //DWORD dwKeObject; //Object PVOID
{'GrantedAccess': ctypes.unsigned_long} //ULONG GrantedAccess; //GrantedAccess ULONG
]); //HANDLEINFO, PHANDLEINFO;


var SYSTEM_HANDLE_INFORMATION = new ctypes.StructType('SYSTEM_HANDLE_INFORMATION', [
{'NumberOfHandles': ctypes.unsigned_long},
{'Handles': ctypes.ArrayType(SYSTEM_HANDLE_TABLE_ENTRY_INFO, 5)}
]);

var NtQuerySystemInformation = lib_ntdll.declare("NtQuerySystemInformation",
ctypes.winapi_abi,
ctypes.long, // return //NTSTATUS 
ctypes.int, // SystemInformationClass //SYSTEM_INFORMATION_CLASS
ctypes.void_t.ptr, // SystemInformation //PVOID 
ctypes.unsigned_long, // SystemInformationLength //ULONG 
ctypes.unsigned_long.ptr); // ReturnLength //PULONG 

/* http://msdn.microsoft.com/en-us/library/ms633499%28v=vs.85%29.aspx
* HWND WINAPI FindWindow(
* __in_opt LPCTSTR lpClassName,
* __in_opt LPCTSTR lpWindowName
* );
*/
// NOT SUPPORTED BY WINXP so just doing this to test and then later will figure out how to get handle to path name then look in here
var GetFinalPathNameByHandle = lib_kernel32.declare('GetFinalPathNameByHandleW', ctypes.winapi_abi, ctypes.uint32_t, //DWORD
ctypes.unsigned_short, // HANDLE
ctypes.void_t.ptr, // LPTSTR
ctypes.uint32_t, // DWORD
ctypes.uint32_t // DWORD
);



function enumHandles() {
    var res = {};
    var _enumBufSize = new ctypes.unsigned_long(0x4000);
    var buffer = ctypes.char.array(_enumBufSize.value)();

    while (true) {
        var status = NtQuerySystemInformation(SystemHandleInformation, buffer,
            _enumBufSize, _enumBufSize.address());
        if (status == STATUS_BUFFER_TOO_SMALL || status == STATUS_INFO_LENGTH_MISMATCH) {
            buffer = ctypes.char.array(_enumBufSize.value)();
        } else break;
    }

    if (status < 0) return null;
    var proc = ctypes.cast(buffer.addressOfElement(0), SYSTEM_HANDLE_INFORMATION.ptr).contents;

    for (var i=0; i<proc.Handles.length; i++) {
        //console.log('i:', proc.Handles[i].HandleValue);
        //var nbuff = ctypes.jschar.array()(32); //nbuff.length == 32
        //var ret = GetFinalPathNameByHandle(proc.Handles[i].HandleValue, nbuff.address(), nbuff.length, 0);
        //console.log(nbuff.readString()); //always blank i have no idea why
      if (res[proc.Handles[i].HandleValue]) {
        res[proc.Handles[i].HandleValue].push(proc.Handles[i]);
        //console.error('multiple handlevalue occourance for handle value of ', res[proc.Handles[i].HandleValue])
      } else {
        res[proc.Handles[i].HandleValue] = [proc.Handles[i]]
      }
    }
    return res;
}

var allHandles = enumHandles();
console.log('enumHandles:', Object.keys(allHandles).length, allHandles);

lib_ntdll.close();
lib_kernel32.close();

1 个答案:

答案 0 :(得分:4)

NtQuerySystemInformation(SystemHandleInformation, ...)返回SYSTEM_HANDLE_INFORMATION项的数组,而不是SYSTEM_HANDLE_TABLE_ENTRY_INFO项。请参阅Enumerating the processes referencing an objectHOWTO: Enumerate handles

如果您已经打开HANDLE文件/目录路径,例如来自CreateFile(),那么您应该已经拥有用于打开HANDLE的原始路径。要查找同一路径的其他句柄,您可以:

  1. 遍历数组,查找Handle字段与您已有的HANDLE匹配的所有条目(如果有)。

  2. 遍历数组,查找ObjectTypeNumber字段为HANDLE_TYPE_FILE的条目。对于每个Handle,使用DuplicateHandle()使其可以访问您应用的流程空间,然后使用NtQueryInformationFile(..., FileNameInformation)GetFinalPathNameByHandle()查询其路径,然后您可以将其与您正在寻找的路径(请参阅File handle operations demo)。