【问题标题】:C++ | Windows - Is there a way to find out which process has ownership of the locked file?C++ | Windows - 有没有办法找出哪个进程拥有锁定文件的所有权?
【发布时间】:2016-11-06 06:11:48
【问题描述】:

我想知道的是是否可以尝试打开一个文件(当它失败时,因为它是用另一个共享关闭的进程打开的)以确定哪个进程正在使用该文件?

我想知道这些信息的原因是因为我正在制作一个可以“修复”恶意文件的小应用程序。

例如,一些恶意/广告软件等设置了文件安全描述符,因此用户无法删除文件等。我的应用程序只是重置了安全描述符,允许用户重新获得控制权。

我还看到一个文件打开了它的子进程,例如 (CreateFile) 并关闭了共享模式,因此无法触摸文件,然后应用程序将从内存中执行子进程。

【问题讨论】:

    标签: c++ windows file process


    【解决方案1】:

    是的,一般情况下,您可以只使用openfiles 命令,在启用通过此信息收集后,会出现openfiles /local on

    在 Windows NT 和包括(似乎)Windows XP 中,有一个类似的名为 oh 的资源工具包命令,打开句柄的缩写。

    两者的替代方法是使用 SysInternal 的 Process Explorer


    注意:在某些情况下openfiles 将无法列出某些句柄。当 Windows 拒绝卸载 USB 磁盘并声称某个进程正在使用该磁盘上的文件时,就会发生这种情况。从来没有出现过这样的过程。

    【讨论】:

    • 可能openfiles 不包括内核模式句柄,例如防病毒软件可能会无意中保持打开状态。
    【解决方案2】:

    我已经开发了一个功能来定位这样的进程,杀死它并删除锁定的文件。

    bool ForceDeleteFile(LPWSTR FileName);
    

    这里是完整的源代码:

    bool KillFileProcess(LPWSTR FileName)
    {
        HANDLE hProcessSnap;
        HANDLE hProcess;
        PROCESSENTRY32 pe32;
        DWORD dwPriorityClass;
        bool result = false;
        // Take a snapshot of all processes in the system.
        hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
        if (hProcessSnap == INVALID_HANDLE_VALUE)
        {
            //printError(TEXT("CreateToolhelp32Snapshot (of processes)"));
            return(FALSE);
        }
    
        // Set the size of the structure before using it.
        pe32.dwSize = sizeof(PROCESSENTRY32);
    
        // Retrieve information about the first process,
        // and exit if unsuccessful
        if (!Process32First(hProcessSnap, &pe32))
        {
            //printError(TEXT("Process32First")); // show cause of failure
            CloseHandle(hProcessSnap);          // clean the snapshot object
            return(FALSE);
        }
    
        // Now walk the snapshot of processes, and
        // display information about each process in turn
        do
        {
            // Retrieve the priority class.
            dwPriorityClass = 0;
            hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);
            if (hProcess == NULL)
            {
                //printError(TEXT("OpenProcess"));
            }
            else
            {
                dwPriorityClass = GetPriorityClass(hProcess);
                if (!dwPriorityClass)
                {
                    //printError(TEXT("GetPriorityClass"));
                }
                CloseHandle(hProcess);
                if (HANDLE hProcess = ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pe32.th32ProcessID))
                {
                    WCHAR filename[MAX_PATH] = {};
    
                    if (GetModuleFileNameEx(hProcess, NULL, filename, MAX_PATH))
                    {
                        if (_wcsicmp((const wchar_t *)FileName, (const wchar_t *)filename) == NULL)
                        {
                            if (TerminateProcess(pe32.th32ProcessID, 0))
                            {
                                _tprintf(L"Found: Process full killed\nKILLED!\n");
                                result = true;
    
                            }
                            else
                            {
                                _tprintf(L"Found: Process full \nFailed to terminate\n");
                                DoRun(((CString)L"taskkill /F /IM " + (CString)pe32.szExeFile).GetBuffer());
    
                                result = false;
    
                            }
                        }
                    }
                    else
                    {
                        // handle error
                    }
    
                    CloseHandle(hProcess);
                }
            }
    
    
        } while (Process32Next(hProcessSnap, &pe32));
    
        CloseHandle(hProcessSnap);
        return(result);
    }
    bool ForceDeleteFile(LPWSTR FileName)
    {
        bool result = DeleteFile(FileName);
        if (!result)
        {
            _tprintf(L"Can't delete file. using DeleteFile(). Trying to locate process and kill it\n");
            result = KillFileProcess(FileName);
            if (!result)
                _tprintf(L"Couldn't find the process\n");
            else
            {
                Sleep(1000);
                result = DeleteFile(FileName);
                if (result)
                    _tprintf(L"DeleteFile success");
                else
                    _tprintf(L"DeleteFile  ============== failed ===============");
    
            }
        }
        return result;
    }
    BOOL TerminateProcess(DWORD dwProcessId, UINT uExitCode)
    {
        DWORD dwDesiredAccess = PROCESS_TERMINATE;
        BOOL  bInheritHandle = FALSE;
        HANDLE hProcess = OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId);
        if (hProcess == NULL)
            return FALSE;
    
        BOOL result = TerminateProcess(hProcess, uExitCode);
    
        CloseHandle(hProcess);
    
        return result;
    }
    

    【讨论】:

    • 我不是反对者,但这似乎仅限于锁定文件是可执行文件(正在运行)的情况?
    • 是的,事实上,相同的方法可以用于任何锁定的文件。
    猜你喜欢
    • 2012-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-24
    • 1970-01-01
    • 1970-01-01
    • 2021-12-23
    • 1970-01-01
    相关资源
    最近更新 更多