vb6中正在处理的重复文件名 [英] duplicate filename in process in vb6
本文介绍了vb6中正在处理的重复文件名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我使用下面的代码获取过程中打开的文件的列表,此代码可以正常工作,但有时此代码在当前过程中获得重复的文件名.例如,如果在媒体播放器中打开了视频文件abc.mpg和def.mpg文件如果我关闭abc.mpg文件,则在km播放器中打开.此代码仍显示abc.mpg文件正在运行.
这是我的代码
i use below code to get list of opened files in proccess this code works fine but sometime this code get duplicate file name in current proccess.for example if a video file abc.mpg open in media player and a def.mpg file opened in km player if i close abc.mpg file this code still show the abc.mpg file is runing.
here is my code
Private Const DUPLICATE_SAME_ACCESS As Long = &H2
Private Const DUPLICATE_CLOSE_SOURCE As Long = &H1
Private Const STATUS_INFO_LENGTH_MISMATCH As Long = &HC0000004
Private Const PROCESS_ALL_ACCESS As Long = &H1F0FFF
Private Const FILE_MAP_READ As Long = &H4
Private Const PAGE_READONLY As Long = &H2
Private Const HEAP_ZERO_MEMORY As Long = &H8
Private Const TOKEN_ADJUST_PRIVILEGES As Long = &H20
Private Const SE_PRIVILEGE_ENABLED As Long = &H2
Private Const SE_PRIVILEGE_NAME As String = "SeDebugPrivilege"
Private Const TOKEN_QUERY As Long = &H8
Private Const SystemHandleInformation As Long = &H10
' 16 bytes.
Private Type SYSTEM_HANDLE_INFORMATION
ProcessID As Long
ObjectTypeNumber As Byte
Flags As Byte
Handle As Integer
Object_Pointer As Long
GrantedAccess As Long
End Type
Private Type LUID
LowPart As Long
HighPart As Long
End Type
Private Type TOKEN_PRIVILEGES
PrivilegeCount As Long
LuidUDT As LUID
Attributes As Long
End Type
Private Declare Function GetProcessHeap Lib "kernel32.dll" () As Long
Private Declare Function HeapAlloc Lib "kernel32.dll" (ByVal hHeap As Long, ByVal dwFlags As Long, ByVal dwBytes As Long) As Long
Private Declare Function HeapFree Lib "kernel32.dll" (ByVal hHeap As Long, ByVal dwFlags As Long, ByVal lpMem As Long) As Long
Private Declare Function HeapDestroy Lib "kernel32.dll" (ByVal hHeap As Long) As Long
Private Declare Function NtQuerySystemInformation Lib "ntdll.dll" (ByVal SystemInformationClass As Long, ByVal pSystemInformation As Long, ByVal SystemInformationLength As Long, ByRef ReturnLength As Long) As Long
Private Declare Function GetCurrentProcess Lib "kernel32" () As Long
Private Declare Function DuplicateHandle Lib "kernel32.dll" (ByVal hSourceProcessHandle As Long, ByVal hSourceHandle As Long, ByVal hTargetProcessHandle As Long, ByRef lpTargetHandle As Long, ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwOptions As Long) As Long
Private Declare Function OpenProcess Lib "kernel32.dll" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function CloseHandle Lib "kernel32.dll" (ByVal hObject As Long) As Long
Private Declare Function CreateFileMappingW Lib "kernel32" (ByVal hFile As Long, ByVal lpFileMappigAttributes As Long, ByVal flProtect As Long, ByVal dwMaximumSizeHigh As Long, ByVal dwMaximumSizeLow As Long, ByVal lpName As String) As Long
Private Declare Function MapViewOfFile Lib "kernel32" (ByVal hFileMappingObject As Long, ByVal dwDesiredAccess As Long, ByVal dwFileOffsetHigh As Long, ByVal dwFileOffsetLow As Long, ByVal dwNumberOfBytesToMap As Long) As Long
Private Declare Function GetMappedFileNameW Lib "Psapi.dll" (ByVal hProcess As Long, ByVal lpv As Long, ByVal lpFileName As Long, ByVal nSize As Long) As Long
Private Declare Function UnmapViewOfFile Lib "kernel32" (ByVal lpBaseAddress As Long) As Long
Private Declare Function OpenProcessToken Lib "advapi32" (ByVal ProcessHandle As Long, ByVal DesiredAccess As Long, TokenHandle As Long) As Long
Private Declare Function LookupPrivilegeValueA Lib "advapi32" (ByVal lpSystemName As String, ByVal lpName As String, lpLuid As LUID) As Long
Private Declare Function AdjustTokenPrivileges Lib "advapi32" (ByVal TokenHandle As Long, ByVal DisableAllPrivileges As Long, NewState As TOKEN_PRIVILEGES, ByVal BufferLength As Long, PreviousState As Any, ReturnLength As Any) As Long
Private Declare Sub RtlMoveMemory Lib "kernel32.dll" (Destination As Any, Source As Any, ByVal Length As Long)
Private Declare Sub RtlZeroMemory Lib "kernel32.dll" (Destination As Any, ByVal Length As Long)
Private Declare Function GetModuleFileNameExW Lib "Psapi.dll" (ByVal hProcess As Long, ByVal hModule As Long, ByVal lpFileName As Long, ByVal nSize As Long) As Long
Dim HandleInfo() As SYSTEM_HANDLE_INFORMATION
Dim m_cHandles As Long
Dim hProcess As Long
Dim hHandle As Long
Dim szName As String
Dim szAppName As String
Public Sub QueryHandlesBuffer()
' The following method obtains all the handles on the system
' followed by an array of SYSTEM_HANDLE_INFORMATION structs
' that can be used to obtain information.
' Need to be admin on XP
' Need to be admin and elevated on vista and above.
' Need to have SE_DEBUG_PRIVS
' Use DUPLICATE_CLOSE_SOURCE to close the handle to the remote
' process and local process when passed to DuplicateHandle.
Dim lpBufferHandles As Long
Dim Length As Long
Dim ret As Long
Dim n As Long
' 256 byte offset
Length = &H100
' Allocate block of memory
lpBufferHandles = HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY, Length)
' Check if valid buffer
If lpBufferHandles = 0 Then
Exit Sub
End If
' Obtain the size required for SystemHandleInformation class
While (NtQuerySystemInformation(SystemHandleInformation, lpBufferHandles, Length, ret) = STATUS_INFO_LENGTH_MISMATCH)
Length = Length * 2
' free memory
HeapFree GetProcessHeap, 0, lpBufferHandles
' allocate memory
lpBufferHandles = HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY, Length)
Wend
' Check if valid buffer
If lpBufferHandles = 0 Then
Exit Sub
End If
' The number of system handles first 4 bytes.
m_cHandles = ReadLong(lpBufferHandles)
' Resize array to system handle count.
ReDim HandleInfo(m_cHandles) As SYSTEM_HANDLE_INFORMATION
' Initialize memory
RtlZeroMemory HandleInfo(0), LenB(HandleInfo(0)) * m_cHandles
' Copy the information into the array
RtlMoveMemory HandleInfo(0), ByVal lpBufferHandles + 4, LenB(HandleInfo(0)) * m_cHandles
' free memory
HeapFree GetProcessHeap, 0, lpBufferHandles
' Get information from the SYSTEM_HANDLE_INFORMATION arrays
For n = 0 To m_cHandles - 1
' Check if the object is a type FILE.
If HandleInfo(n).ObjectTypeNumber = 28 Then ' 26 for Win2K
' Get real process handle.
OpenProcessForHandle HandleInfo(n).ProcessID
' Have to duplicate the file handle so it's valid in our process context.
DuplicateHandle hProcess, HandleInfo(n).Handle, GetCurrentProcess, hHandle, 0, 0, DUPLICATE_SAME_ACCESS
' Checksum
If hHandle <> 0 Then
' Get DOS path,filename and process name.
szName = GetObjectName(hHandle)
szAppName = GetProcessName(hProcess)
' // TODO: SOME FILTERING GOES HERE. if szName Like "pewpew" Then return results.
If LenB(szName) > 0 Then
If InStr(1, szName, ".tax", vbTextCompare) > 0 Then
List1.AddItem "hProcess = " & hProcess
List1.AddItem "File = " & szName
List1.AddItem "Process = " & szAppName
List1.AddItem "handle= " & HandleInfo(n).Handle
List1.AddItem HandleInfo(n).ProcessID
'' Dim hdup As Long
'' Call DuplicateHandle(hProcess, HandleInfo(n).Handle, GetCurrentProcess, hdup, DUPLICATE_SAME_ACCESS, 0, DUPLICATE_CLOSE_SOURCE)
'' If hdup > 0 Then
'' CloseHandle (hdup)
'' End If
End If
End If
'//
' Free handle
CloseHandle hHandle
End If
End If
Next n
End Sub
Private Function GetObjectName(ByVal dwHandle As Long) As String
' This method gets a filename from a file handle. Only if the file
' in question is atleast one byte. If a file is zero bytes
' it can't be mapped and the function fails. Choose to use this method
' instead of NtQueryObject because it's more stable and typically if
' the file is zero bytes it's used by an application that the user
' doesn't care about.
Dim hFileMap As Long
Dim pMem As Long
Dim cbLength As Long
Dim bName(8192) As Byte
' Create a file mapping in our process.
hFileMap = CreateFileMappingW(dwHandle, 0, PAGE_READONLY, 0, 1, 0)
' Check valid handle
If hFileMap = 0 Then
Exit Function
End If
' Map the file into memory
pMem = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 1)
' Check valid memory pointer to file.
If pMem = 0 Then
CloseHandle hFileMap
Exit Function
End If
' Obtain the name from the mapped file.
cbLength = GetMappedFileNameW(GetCurrentProcess, pMem, VarPtr(bName(0)), 8192)
' Check buffer for valid data.
If cbLength <> 0 Then
GetObjectName = Left$(bName, cbLength)
Else
GetObjectName = vbNullString
End If
' free handles free mapping
CloseHandle hFileMap
UnmapViewOfFile pMem
' free memory
Erase bName
End Function
Private Function GetProcessName(ByVal dwProcess As Long) As String
' The method obtains the process name associated with the real
' process handle.
Dim bProcess(8192) As Byte
Dim cbLength As Long
cbLength = GetModuleFileNameExW(dwProcess, 0, VarPtr(bProcess(0)), 8192)
' check return buffer length
If cbLength <> 0 Then
GetProcessName = Left$(bProcess, cbLength)
Else
GetProcessName = vbNullString
End If
' free memory
Erase bProcess
End Function
Private Sub OpenProcessForHandle(ByVal ProcessID As Long)
' The method obtains a real process handle that can be used
' to get additional information about a process.
' If the PID is the same don't open the handle again. Only
' open the handle if the PID has changed.
Dim LastPID As Long
If ProcessID <> LastPID Then
' free handle
CloseHandle hProcess
' get real process handle.
hProcess = OpenProcess( _
PROCESS_ALL_ACCESS, _
0, _
ProcessID)
' checksum
LastPID = ProcessID
End If
End Sub
Public Sub SeDebugPrivilege()
' The following method gives SE_DEBUG_PRIVS.
Dim Success As Long
Dim hToken As Long
Dim TokenPriv As TOKEN_PRIVILEGES
' Do work.
Success = OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY, hToken)
Success = LookupPrivilegeValueA(vbNullString, SE_PRIVILEGE_NAME, TokenPriv.LuidUDT)
TokenPriv.PrivilegeCount = 1
TokenPriv.Attributes = SE_PRIVILEGE_ENABLED
Success = AdjustTokenPrivileges(hToken, 0, TokenPriv, 0, ByVal 0&, ByVal 0&)
CloseHandle hToken
End Sub
Private Function ReadLong(ByVal Ptr As Long) As Long
' Helper function reads 4 bytes from memory address.
Dim Bogus As Long
RtlMoveMemory Bogus, ByVal Ptr, 4
ReadLong = Bogus
End Function
请帮帮我.
[edit]Added code blocks[/edit]
Please help me.
[edit]Added code blocks[/edit]
推荐答案
(bName, cbLength) 其他 GetObjectName = vbNullString 结束 如果 ' free handles free mapping CloseHandle hFileMap UnmapViewOfFile pMem ' free memory Erase bName 结束 功能 Private Function GetProcessName(ByVal dwProcess As Long) As String ' The method obtains the process name associated with the real ' process handle. Dim bProcess(8192) As Byte Dim cbLength As Long cbLength = GetModuleFileNameExW(dwProcess, 0, VarPtr(bProcess(0)), 8192) ' check return buffer length If cbLength <> 0 然后 GetProcessName = Left
(bName, cbLength) Else GetObjectName = vbNullString End If ' free handles free mapping CloseHandle hFileMap UnmapViewOfFile pMem ' free memory Erase bName End Function Private Function GetProcessName(ByVal dwProcess As Long) As String ' The method obtains the process name associated with the real ' process handle. Dim bProcess(8192) As Byte Dim cbLength As Long cbLength = GetModuleFileNameExW(dwProcess, 0, VarPtr(bProcess(0)), 8192) ' check return buffer length If cbLength <> 0 Then GetProcessName = Left
(bProcess, cbLength) 其他 GetProcessName = vbNullString 结束 如果 ' free memory Erase bProcess 结束 功能 Private Sub OpenProcessForHandle(ByVal ProcessID As Long) ' The method obtains a real process handle that can be used ' to get additional information about a process. ' If the PID is the same don't open the handle again. Only ' open the handle if the PID has changed. Dim LastPID As Long If ProcessID <> LastPID Then ' free handle CloseHandle hProcess ' get real process handle. hProcess = OpenProcess( _ PROCESS_ALL_ACCESS, _ 0 ,_ ProcessID) ' checksum LastPID = ProcessID 结束 如果 结束 子 Public Sub SeDebugPrivilege() ' The following method gives SE_DEBUG_PRIVS. Dim Success As Long Dim hToken As Long Dim TokenPriv As TOKEN_PRIVILEGES ' Do work. Success = OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY, hToken) Success = LookupPrivilegeValueA(vbNullString, SE_PRIVILEGE_NAME, TokenPriv.LuidUDT) TokenPriv.PrivilegeCount = 1 TokenPriv.Attributes = SE_PRIVILEGE_ENABLED Success = AdjustTokenPrivileges(hToken, 0, TokenPriv, 0, ByVal 0&, ByVal 0&) CloseHandle hToken 结束 子 Private Function ReadLong(ByVal Ptr As Long) As Long ' Helper function reads 4 bytes from memory address. Dim Bogus As Long RtlMoveMemory Bogus, ByVal Ptr, 4 ReadLong = Bogus 结束 功能
(bProcess, cbLength) Else GetProcessName = vbNullString End If ' free memory Erase bProcess End Function Private Sub OpenProcessForHandle(ByVal ProcessID As Long) ' The method obtains a real process handle that can be used ' to get additional information about a process. ' If the PID is the same don't open the handle again. Only ' open the handle if the PID has changed. Dim LastPID As Long If ProcessID <> LastPID Then ' free handle CloseHandle hProcess ' get real process handle. hProcess = OpenProcess( _ PROCESS_ALL_ACCESS, _ 0, _ ProcessID) ' checksum LastPID = ProcessID End If End Sub Public Sub SeDebugPrivilege() ' The following method gives SE_DEBUG_PRIVS. Dim Success As Long Dim hToken As Long Dim TokenPriv As TOKEN_PRIVILEGES ' Do work. Success = OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY, hToken) Success = LookupPrivilegeValueA(vbNullString, SE_PRIVILEGE_NAME, TokenPriv.LuidUDT) TokenPriv.PrivilegeCount = 1 TokenPriv.Attributes = SE_PRIVILEGE_ENABLED Success = AdjustTokenPrivileges(hToken, 0, TokenPriv, 0, ByVal 0&, ByVal 0&) CloseHandle hToken End Sub Private Function ReadLong(ByVal Ptr As Long) As Long ' Helper function reads 4 bytes from memory address. Dim Bogus As Long RtlMoveMemory Bogus, ByVal Ptr, 4 ReadLong = Bogus End Function
请帮帮我.
[edit]Added code blocks[/edit]
Please help me.
[edit]Added code blocks[/edit]
Couldn''t it just be that the os has some delay in updating this information? Or that the media player used has a delay.
Check out sysinternals suite:
http://technet.microsoft.com/en-us/sysinternals/bb842062.aspx[^]
Have a look at the handle tool which also checks the files opened by a process:
http://technet.microsoft.com/en-us/sysinternals/bb896655[^]
祝你好运!
Couldn''t it just be that the os has some delay in updating this information? Or that the media player used has a delay.
Check out sysinternals suite:
http://technet.microsoft.com/en-us/sysinternals/bb842062.aspx[^]
Have a look at the handle tool which also checks the files opened by a process:
http://technet.microsoft.com/en-us/sysinternals/bb896655[^]
Good luck!
这篇关于vb6中正在处理的重复文件名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文