Frage

Bevor ich mein Problem beschreiben, hier ist eine Beschreibung des Programms (IHExplorer.exe) Ich bin writting:

Dies ist eine C ++ Anwendung.

Die IHExplorer Anwendung ist so viel wie ein Windows Explorer-Fenster wie möglich aussehen. Mit einer Ausnahme, und dass diese Dateien starten aus diesem Fenster Explorer sie zuerst die Benutzer Tempfaltblatt entschlüsselt, dann starten Sie die App mit der Dateierweiterung zugeordnet ist, und die Datei auf der Nähe löschen.

Das Problem, das ich habe, ist mit dem Auto löschen, wenn die Datei geschlossen wird. Hier ist ein Szenario:

  1. Benutzer doppelklickt eine verschlüsselte .txt-Datei in IHExplorer.
  2. IHExplorer entschlüsselt die TXT-Datei im Speicher, schreibt sie dann in% TEMP% unter Verwendung :: Createfile, das einen Griff in die Datei zurückgibt (IHExplorer hat diesen Griff geöffnet atleast zu halten, bis die TXT-Datei-Shell ausgeführt wird ).

  3. IHExplorer Shell führt die TXT-Datei (durch Aufruf von :: ShellExecute) von seinen temporären Speicherort.

  4. Jetzt IHExplorer und Notizblock beide haben einen Griff in die Datei zu öffnen.
  5. Die Datei muss automatisch gelöscht werden, wenn beide IHExplorer und Notizblock haben beide ihren Griff in die Datei geschlossen, auch wenn IHExplorer schließt zuerst.

ok. Das ist ein Basical User-Fall, der beschreibt, was ich passieren soll. Das Problem, das ich habe, ist, wenn ich :: ShellExecute (), Notizblock sagt: „Der Prozess kann nicht die Datei zugreifen, da sie von einem anderen Prozess verwendet werden.“ (Das wäre IHExplorer). Ich muss dies umgehen, und haben es Notizblock öffnen, auch wenn ich immer noch den Griff offen in IHExplorer.

Hier ist, was mein Aufruf :: Create wie folgt aussieht:

DWORD dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE;
HANDLE hFile = ::CreateFile(strTempFile.c_str(), GENERIC_WRITE, dwShareMode, &sa, CREATE_NEW, dwFlagsAndAttributes, NULL);

Hinweis habe ich FILE_SHARE_DELETE so dass andere Prozesse (wie Editor) um die Datei mit Löschzugriff öffnen kann.

Beachten Sie, dass ich die FILE_ATTRIBUTE_TEMPORARY verwendet | FILE_FLAG_DELETE_ON_CLOSE indicicate Attribute die die Datei ist temporär und sollte auf eine enge gelöscht werden.

Beachten Sie auch die & sa Parameter. Dies ist die SECURITY_ATTRIBUTES Struktur, dass ich verwende, und ich fühle mich (Hoffnung) das ist, wo mein Problem liegt. Hier ist der Code wieder, dieses Mal werde ich die gesamte Funktion veröffentlichen, so können Sie sehen, wie ich die SECURITY_ATTRIBUTES Struktur ausfüllen:

int CIHExplorerDoc::OpenFile(std::string strFileName, bool bIsFullPath) {
    std::string strFullFilePath;
    if(bIsFullPath) {
        strFullFilePath = strFileName;
        strFileName = IHawk::RemovePath(strFileName);
    }else {
        strFullFilePath = m_strDirectory + strFileName;
    }

    if(!HasEncryptionFileExtension(strFullFilePath)) {
        LaunchFile(strFullFilePath);
    }else {
        //it's an encrypted file, so open it and copy unencrypted file to temp.
        IHawk::EncryptedFileHandle hEncryptedFile(strFullFilePath.c_str(), true, theApp.GetKeyServer());
        if(hEncryptedFile.IsValid()) {
            std::string strTempFile = g_strTempFolder + IHawk::ChangeFileExtension(strFileName, "");

            //TODO: Determine what the LPSECURITY_ATTRIBUTES should be.

            SECURITY_ATTRIBUTES sa;
            SECURITY_DESCRIPTOR sd;

            if(!InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION)) {
                DWORD dwLastError = ::GetLastError();
                LOG4CPLUS_ERROR(m_Logger, "Cannot launch file '" << strFullFilePath << "'.  Failed to initialize security descriptor.  GetLastError=" << dwLastError);
                return dwLastError;
            }

            if(!SetSecurityDescriptorDacl(
                &sd,    // A pointer to the SECURITY_DESCRIPTOR structure to which the function adds the DACL
                TRUE,   // presence of a DACL in the security descriptor
                NULL,   // allows all access to the object
                FALSE   // DACL has been explicitly specified by a user
            )) 
            {
                DWORD dwLastError = ::GetLastError();
                LOG4CPLUS_ERROR(m_Logger, "Cannot launch file '" << strFullFilePath << "'.  Failed to set security descriptor DACL.  GetLastError=" << dwLastError);
                return dwLastError;
            }

            if(!SetSecurityDescriptorGroup(
                &sd,    // A pointer to the SECURITY_DESCRIPTOR structure whose primary group is set by this function
                NULL,   // no primary group
                FALSE   // Indicates whether the primary group information was derived from a default mechanism
            ))
            {
                DWORD dwLastError = ::GetLastError();
                LOG4CPLUS_ERROR(m_Logger, "Cannot launch file '" << strFullFilePath << "'.  Failed to set security descriptor primary group.  GetLastError=" << dwLastError);
                return dwLastError;
            }

            if(!SetSecurityDescriptorOwner(
                &sd,    // A pointer to the SECURITY_DESCRIPTOR structure whose owner is set by this function.
                NULL,   // If this parameter is NULL, the function clears the security descriptor's owner information. This marks the security descriptor as having no owner.
                FALSE   // Indicates whether the owner information is derived from a default mechanism.
            ))
            {
                DWORD dwLastError = ::GetLastError();
                LOG4CPLUS_ERROR(m_Logger, "Cannot launch file '" << strFullFilePath << "'.  Failed to set security descriptor owner information.  GetLastError=" << dwLastError);
                return dwLastError;
            }

            if(!SetSecurityDescriptorSacl(
                &sd,    // A pointer to the SECURITY_DESCRIPTOR structure to which the function adds the SACL
                FALSE,  // the security descriptor does not contain a SACL
                NULL,   // security descriptor has a NULL SACL
                FALSE   // A pointer to a flag that is set to the value of the SE_SACL_DEFAULTED flag in the SECURITY_DESCRIPTOR_CONTROL structure if a SACL exists for the security descriptor
            ))
            {
                DWORD dwLastError = ::GetLastError();
                LOG4CPLUS_ERROR(m_Logger, "Cannot launch file '" << strFullFilePath << "'.  Failed to set security descriptor SACL.  GetLastError=" << dwLastError);
                return dwLastError;
            }

            sa.nLength = sizeof(SECURITY_ATTRIBUTES);
            sa.lpSecurityDescriptor = &sd;
            sa.bInheritHandle = TRUE;

            DWORD dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
//          DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
            DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE;
            HANDLE hFile = ::CreateFile(strTempFile.c_str(), GENERIC_WRITE, dwShareMode, &sa, CREATE_NEW, dwFlagsAndAttributes, NULL);

            //verify we created the file.
            if(hFile == INVALID_HANDLE_VALUE) {
                DWORD dwLastError = ::GetLastError();
                return dwLastError;
            }

            //copy to temp
            char buffer[64*1024];
            size_t nBytesRead = hEncryptedFile.Read(buffer, sizeof(buffer));
            while(nBytesRead) {
                DWORD numBytesWritten;
                if(!::WriteFile(hFile, buffer, nBytesRead, &numBytesWritten, (LPOVERLAPPED) NULL)) {
                    DWORD dwLastError = ::GetLastError();
                    LOG4CPLUS_ERROR(m_Logger, "Failed to write file to %TEMP% folder.  GetLastError=" << dwLastError);
                    return dwLastError;
                }
                nBytesRead = hEncryptedFile.Read(buffer, sizeof(buffer));
            }
            hEncryptedFile.Close();

            //execute the file from temp.
            LaunchFile(strTempFile);
        }
    }
    return 0;
}

denke ich, wenn ich die richtige SECURITY_DESCRIPTOR bestimmen passieren :: Createfile kann es funktionieren wie ich es will. Bitte Hilfe.

btw, die LaunchFile Funktion endet nur bis Aufruf :: ShellExecute die Datei zu starten.

War es hilfreich?

Lösung

Nach dem Msdn doc Re-Lektüre, ich fürchte, ich habe meine eigene Frage beantwortet. FILE_FLAG_DELETE_ON_CLOSE Die Datei gelöscht werden soll unmittelbar nach der alle seine Griffe geschlossen sind, die die spezifizierten Griff und alle anderen offenen oder dupliziert Griffe umfasst. Wenn bestehende offenes Handles in eine Datei ist, schlägt der Aufruf fehl, wenn sie nicht alle mit dem FILE_SHARE_DELETE Share-Modus geöffnet wurden. Im Anschluss offene Anfragen für die Datei nicht, es sei denn, der FILE_SHARE_DELETE Share-Modus angegeben wird. In meinem Fall, ich bezweifle Notizblock ist die FILE_SHARE_DELETE einer Erlaubnis eingeholt, so dass es die Datei nicht öffnen kann,

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top