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();
答案 0 :(得分:4)
NtQuerySystemInformation(SystemHandleInformation, ...)
返回SYSTEM_HANDLE_INFORMATION
项的数组,而不是SYSTEM_HANDLE_TABLE_ENTRY_INFO
项。请参阅Enumerating the processes referencing an object和HOWTO: Enumerate handles。
如果您已经打开HANDLE
文件/目录路径,例如来自CreateFile()
,那么您应该已经拥有用于打开HANDLE
的原始路径。要查找同一路径的其他句柄,您可以:
遍历数组,查找Handle
字段与您已有的HANDLE
匹配的所有条目(如果有)。
遍历数组,查找ObjectTypeNumber
字段为HANDLE_TYPE_FILE
的条目。对于每个Handle
,使用DuplicateHandle()
使其可以访问您应用的流程空间,然后使用NtQueryInformationFile(..., FileNameInformation)
或GetFinalPathNameByHandle()
查询其路径,然后您可以将其与您正在寻找的路径(请参阅File handle operations demo)。