1 year ago

#334750

test-img

ghylander

CopyFileEx() fails with ERROR_SHARING_VIOLATION for file created by CreateFile()

I want to create a temporary copy of a DLL file in the temp folder, and have it deleted on application exit. Due to unrelated reasons too long to explain, I cannot simply remove the file at the end of the function/script that creates it.

I tried using CreateFile() with FILE_FLAG_DELETE_ON_CLOSE, but when I try to copy the original file to this file, I get ERROR_SHARING_VIOLATION.

Here's my code:

BOOL CopySuccess = 0;

if ((_waccess(TempFilePath, 0)) == -1) {
    printf("Temp copy \'%ls\' not found, creating copy now\n", TempFilePath);
    CreateFileW(TempFilePath, (GENERIC_READ | GENERIC_WRITE), (FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE), NULL, CREATE_NEW, FILE_FLAG_DELETE_ON_CLOSE, NULL);
    CopySuccess = CopyFileExW(OriFilePath, TempFilePath, NULL, NULL, FALSE, NULL);
    if (!CopySuccess)
    {
        ErrorExit(TEXT("Copy dll to temp file failed"));
    }
}

AFAIK, I used the correct flags in the CreateFile() call to enable shared access to the file.

What am I doing wrong/what is an alternative approach?

I need the logic to maintain this structure. Without going into details, for reasons that escape my control, this script will be run around 10 times per second, so I need a way to copy the file just once, then have it deleted once the application exits, due to error, ctrl-c event, or normal exit.


As a reply to the comments:

I tried writing the contents of the original file to the tempfile created with CreateFile(). This didn't work because the handle returned by CreateFile() is not valid to use as a library (library handles are of type HMODULE). Closing the handle then re-opening it not a possibility, as closing all handles to the file causes it to be deleted as per the FILE_FLAG_DELETE_ON_CLOSE flag.

I figured the issue would be on CopyFile()'s side. I didn't think of writing my own function, so instead I tackled the problem the following way:

There's one specific var that increases by a fixed amount in every iteration of the main script, so I wrote an if statement that would check:

  • If the copy of the dll already existed
  • If the current value of the variable was below the 2nd iteration value

If both conditions were met, the already existing copies of the dlls would be deleted. Similarly, the dlls are only attempted to be copied in the 1st iteration of the main script.

This is not an actual answer to the question, but a way to circumvent it. I'll give a try to writing my own version of CopyFile(). If I succeed and it behaves as I intend it to behave, I'll post the code and an explanation as an answer here. Thanks all!

c

winapi

temp

0 Answers

Your Answer

Accepted video resources