DELETE_ON_CLOSE发生得太早

DELETE_ON_CLOSE occurring too early

本文关键字:太早 CLOSE ON DELETE      更新时间:2023-10-16

我正试图在另一台机器上创建一个进程,该进程完成后会删除自己。我在CreateFile中使用DELETE_ON_CLOSE标志。这个方法有点流行,但我遇到了麻烦,因为我无法在它打开时执行它(这是意料之中的事,但有些解决方案就是这样做的)。为了解决这个问题,我尝试用读取权限打开文件。DELETE_ON_CLOSE标志表示,只有当指向文件的所有指针都消失时,它才应该删除该文件。我有一个带读的指针,我关闭写句柄,文件删除,使打开的句柄无法读取。任何其他方式都将不胜感激。

我还考虑了这样一种可能性,即由于这是一个远程文件系统,所以句柄有一些奇怪的地方。

我无法修改我发送的可执行文件的代码,所以我最不想做的就是自删除可执行文件

让我的程序等待清理服务会导致它挂起一段不可接受的长时间,因为销毁远程盒子上的服务可能需要很长时间。

//Open remote file for reading and set the delete flag
HANDLE remote_fh = CreateFile(&remote_file_location[0], 
    GENERIC_WRITE, 
    FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 
    NULL, 
    CREATE_ALWAYS, 
    FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, 
    NULL);
if(!remote_fh)
{
    debug.DebugMessage(Error::GetErrorMessageW(GetLastError()));
    RevertToSelf();
    return dead_return;
}
//File to read from
HANDLE local_fh = CreateFile(&local_file_location[0],
    GENERIC_READ,
    FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
    NULL,
    OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL,
    NULL);

if(!local_fh)
{
    debug.DebugMessage(Error::GetErrorMessageW(GetLastError()));
    RevertToSelf();
    return dead_return;
}
byte buf[256];
DWORD bytesRead;
DWORD bytesWritten;
//Copy the file
while(ReadFile(local_fh, buf, 256, &bytesRead, NULL) && bytesRead > 0)
{
    WriteFile(remote_fh, buf, bytesRead, &bytesWritten, NULL);
}
CloseHandle(local_fh);

//Create a file retainer to hold the pointer so the file doesn't get deleted before the service starts
HANDLE remote_retain_fh = CreateFile(&remote_file_location[0],
    GENERIC_READ,
    FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
    NULL,
    OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL,
    NULL);
if (!remote_retain_fh)
{
    debug.DebugMessage(Error::GetErrorMessageW(GetLastError()));
    RevertToSelf();
    return dead_return;
}

CloseHandle(remote_fh);

//if(!CopyFile(&local_file_location[0], &remote_file_location[0], false))
//{
//  debug.DebugMessage(Error::GetErrorMessageW(GetLastError()));
//  RevertToSelf();
//  return dead_return;
//}
remote_service.Create(Service::GetServiceName().c_str());
//In the words of my daughter: "OH, OH, FILE ALL GONE!"
Pipe pipe(L"\\" + *hostname + L"\pipe\dbg");
CloseHandle(remote_fh);

FILE_FLAG_DELETE_ON_CLOSE需要FILE_SHARE_DELTE权限。问题是,当进程启动时,操作系统会打开可执行文件的文件句柄,并要求不共享file_SHARE_DELTE权限,这样在进程打开时就无法删除可执行文件。

考虑:您打开一个可执行文件的句柄,但不使用file_SHARE_DELTE,而只使用file_GENERIC_READ。然后其他人(您,稍后,或者其他线程或进程)启动该可执行文件。没有问题,因为没有人试图删除可执行文件。但是,如果您当时试图获得FILE_SHARE_DELTE权限,则会失败,因为可执行文件已经以独占文件删除权限运行。