Remove file locked by another process

最后都变了- 提交于 2019-12-19 10:43:21

问题


While testing an application stability I am trying to remove/corrupt database used by the application. OS is Windows, file system is NTFS, tests language is C++.

What I need is to paste anything into the database file or remove it. But it is locked by the tested application during the run. So maybe someone faced this case before and you can give me/us an example on possible ways to bypass this lock in test code? Theory or source - I am appreciated for any kind of help.


回答1:


You'll have to close the handle that your application has to the file. Keep in mind that you'll have to open your file again on your application, I believe.

I found a different but similar question, with sample code that solves your problem: Force close file by its path on Windows

You just need to copy everything and substitute the part that deletes the file for something that corrupts it. I hope it helps :D




回答2:


#include <Windows.h>
#include <stdio.h>
#include <string.h>
#include <tchar.h>
#include <iostream>
#include <FileAPI.h>
#include <WinBase.h>
#include <conio.h>
#include <ctype.h>

#define START_ALLOC                 0x1000
#define STATUS_INFO_LENGTH_MISMATCH 0xC0000004
#define SystemHandleInformation     0x10

typedef long(__stdcall *NtQSI)(
    ULONG  SystemInformationClass,
    PVOID  SystemInformation,
    ULONG  SystemInformationLength,
    PULONG ReturnLength
    );

typedef struct _SYSTEM_HANDLE_ENTRY {
    ULONG  OwnerPid;
    BYTE   ObjectType;
    BYTE   HandleFlags;
    USHORT HandleValue;
    PVOID  ObjectPointer;
    ACCESS_MASK  AccessMask;
} SYSTEM_HANDLE_ENTRY, *PSYSTEM_HANDLE_ENTRY;

int main(int argc, char *argv[])
{
    HMODULE hNtDll = NULL;
    NtQSI   pNtQSI = NULL;
    PVOID   pMem = NULL;
    ULONG   allocSize = START_ALLOC;
    ULONG   retVal = 0;
    // --------------------------------
    ULONG   hCount = 0;
    PSYSTEM_HANDLE_ENTRY hFirstEntry = NULL;
    // --------------------------------
    ULONG   i;

    hNtDll = LoadLibraryA("NTDLL.dll");

    if (!hNtDll)
        return 1;

    pNtQSI = (NtQSI)GetProcAddress(hNtDll, "NtQuerySystemInformation");

    if (!pNtQSI) {
        FreeLibrary(hNtDll);
        return 2;
    }

    pMem = malloc(allocSize);

    while (pNtQSI(SystemHandleInformation, pMem, allocSize, &retVal)
        == STATUS_INFO_LENGTH_MISMATCH) {
        pMem = realloc(pMem, allocSize *= 2);
    }

    hCount = *(ULONG*)pMem;
    hFirstEntry = (PSYSTEM_HANDLE_ENTRY)((PBYTE)pMem + 4);

    int pid = atoi(argv[1]);

    for (i = 0; i < hCount; ++i)
    if ((hFirstEntry[i].ObjectType == 30) && (hFirstEntry[i].OwnerPid == pid))
    {
        HANDLE TargetHandleValueTemp = (HANDLE)hFirstEntry[i].HandleValue;
        HANDLE SourceProcHandleTemp = OpenProcess(PROCESS_DUP_HANDLE, FALSE, hFirstEntry[i].OwnerPid);
        char confirm ='n';

        DuplicateHandle(SourceProcHandleTemp, (HANDLE)hFirstEntry[i].HandleValue, GetCurrentProcess(), &TargetHandleValueTemp, 0, FALSE, DUPLICATE_SAME_ACCESS);

        TCHAR Path[MAX_PATH];
        DWORD dwret = GetFinalPathNameByHandle(TargetHandleValueTemp, Path, MAX_PATH, 0);
        if (!argv[2])
        {
            _tprintf(TEXT("PID: %d\tFileHandle: %d\tThe final path is: %s\n"), hFirstEntry[i].HandleValue, TargetHandleValueTemp, Path);
        }
        else if (_tcsstr(Path, _T(argv[2])))
        {
            _tprintf(TEXT("PID: %d\tFileHandle: %d\tThe final path is: %s\n\t Remove it? (y/n): "), hFirstEntry[i].HandleValue, TargetHandleValueTemp, Path);
            _flushall();
            std::cin.get(confirm);
            if (confirm == 'y')
                DuplicateHandle(SourceProcHandleTemp, (HANDLE)hFirstEntry[i].HandleValue, GetCurrentProcess(), &TargetHandleValueTemp, 0, FALSE, DUPLICATE_CLOSE_SOURCE);
        }

        CloseHandle(SourceProcHandleTemp);
        CloseHandle(TargetHandleValueTemp);
    }

    free(pMem);
    FreeLibrary(hNtDll);
}



回答3:


In general taking-over file lock ownership is not what Operating Systems provide or are supposed to do, not without the assistance of the original lock owner. (1) You can not easily bypass OS security guarantees, certainly not from your user-level testing code.

For some pointers on how this might be done with active assistance of the original owner see MSDN: Windows → Dev Center - Desktop → LockFileEx function and MSDN: Windows → Dev Center - Desktop → DuplicateHandle function but this is not likely the way you'd want to go.

Some description of the SqLite database locking approach (that your application uses) is described in http://www.sqlite.org/lockingv3.html and especially chapter "How To Corrupt Your Database Files" says

..Clearly, a hardware or operating system fault that introduces incorrect data into the middle of the database file or journal will cause problems. Likewise, if a rogue process opens a database file or journal and writes malformed data into the middle of it, then the database will become corrupt. There is not much that can be done about these kinds of problems so they are given no further attention..

If you really want to simulate how things get very wrong then one way is to (2) build custom test-only SqLite with the pager module (http://www.sqlite.org/src/finfo?name=src/pager.c) compromised, SqLite has the source code available so customization is possible

(3) The most commonly used theory says that for your testing scenarios you should use special testing environments equiped with Mock objects faking the behavior you want to test. In such a testing environment your application would be compiled in a special "under test" mode, where the application would voluntarily temporarily release the SqLite connection when asked to do so, so that the environment might simulate the OS or hardware failure and then continue.

Using mock objects within your application is much easier then e.g. faking a faulty file system driver in a black-box environment.

Relevant: http://en.wikipedia.org/wiki/Software_testing#Destructive_testing



来源:https://stackoverflow.com/questions/26482721/remove-file-locked-by-another-process

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!