8 Stimmen

Erfordert die Verwendung von ReadDirectoryChangesW Administratorrechte?

Im MSDN steht, dass die Verwendung von ReadDirectoryChangesW voraussetzt, dass der aufrufende Prozess über die Berechtigung zum Sichern und Wiederherstellen verfügt.

Bedeutet dies, dass nur Prozesse, die unter einem Administratorkonto gestartet werden, korrekt funktionieren?

Ich habe den folgenden Code ausprobiert, aber es gelingt mir nicht, die erforderlichen Berechtigungen zu aktivieren, wenn ich als eingeschränkter Benutzer ausgeführt werde.

void enablePrivileges() 
{       
    enablePrivilege(SE_BACKUP_NAME);
    enablePrivilege(SE_RESTORE_NAME);
}

void enablePrivilege(LPCTSTR name) 
{       
    HANDLE hToken;    
    DWORD status;
    if (::OpenProcessToken(::GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))  
    {        
        TOKEN_PRIVILEGES tp = { 1 };   
        if( ::LookupPrivilegeValue(NULL, name,  &tp.Privileges[0].Luid) )
        {
            tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
            BOOL result = ::AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL);
            verify (result != FALSE);
            status = ::GetLastError();      
        }
        ::CloseHandle(hToken); 
    } 
}

Mache ich etwas falsch? Gibt es einen Workaround für die Verwendung von ReadDirectoryChangesW von einem Nicht-Administrator-Benutzerkonto? Es scheint, dass der FileSystemWatcher von .NET dies tun kann. Vielen Dank!

更新情報 : Hier ist der vollständige Code der Klasse:

  class DirectoryChangesWatcher
  {
  public:
   DirectoryChangesWatcher(wstring directory)
   {
    enablePrivileges();

    hDir = ::CreateFile(directory.c_str(), 
     FILE_LIST_DIRECTORY | FILE_FLAG_OVERLAPPED, 
     FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 
     FILE_FLAG_BACKUP_SEMANTICS, NULL);

    ensure (hDir != INVALID_HANDLE_VALUE, err::SystemException);

    ::ZeroMemory(&overlapped, sizeof(OVERLAPPED));
    overlapped.hEvent = dirChangedEvent.getHandle();  
   }

   ~DirectoryChangesWatcher() { ::CloseHandle(hDir); }

  public:
   Event& getEvent() { return dirChangedEvent; }

   FILE_NOTIFY_INFORMATION* getBuffer() { return buffer; }

  public:
   void startAsyncWatch()
   {
    DWORD bytesReturned;   

    const BOOL res = ::ReadDirectoryChangesW(
     hDir,                                  
     &buffer,                                    
     sizeof(buffer),                                
     TRUE,                                 
     FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_SIZE,
     &bytesReturned,              
     &overlapped,                          
     NULL);

    ensure(res != FALSE, err::SystemException);
   }

  private:
   void enablePrivileges() 
   {       
    enablePrivilege(SE_BACKUP_NAME);
    enablePrivilege(SE_RESTORE_NAME);
   }

   void enablePrivilege(LPCTSTR name) 
   {       
    HANDLE hToken;    
    DWORD status;
    if (::OpenProcessToken(::GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))  
    {        
     TOKEN_PRIVILEGES tp = { 1 };   
     if( ::LookupPrivilegeValue(NULL, name,  &tp.Privileges[0].Luid) )
     {
      tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
      BOOL result = ::AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL);
      verify (result != FALSE);
      status = ::GetLastError();      
     }
     ::CloseHandle(hToken); 
    } 
   }

  private:
   HANDLE hDir;
   OVERLAPPED overlapped;
   Event dirChangedEvent;
   FILE_NOTIFY_INFORMATION buffer[1024];   
  };

 }

更新情報 : Gute Nachrichten! Es stellte sich heraus, dass das Problem wirklich in der FILE_SHARE_WRITE-Flagge im Aufruf von CreateFile lag. Die Benachrichtigungen kamen nur, wenn ich ein Administrator war. Als ich dieses Flag entfernt habe, funktioniert jetzt alles auch unter einem Nicht-Admin-Konto.

5voto

MSN Punkte 51308

Ich habe verwendet ReadDirectoryChangesW ohne Administratorrechte zu benötigen, zumindest unter Vista. Ich glaube nicht, dass Sie den Prozess manuell erhöhen müssen, um ihn für einen Ordner zu verwenden, für den der Benutzer bereits Zugriffsrechte hat.

Es wäre hilfreicher, den tatsächlichen Code zu sehen, den Sie für den Aufruf von ReadDirectoryChangesW einschließlich der Art und Weise, wie Sie den Handle erstellen, den Sie eingeben.

4voto

Rob Kennedy Punkte 158781

Ich kann nicht erkennen, wo MSDN sagt, dass Sie entweder Sicherungs- oder Wiederherstellungsberechtigungen benötigen. Es weist Sie an, Folgendes aufzurufen CreateFile mit dem File_Flag_Backup_Semantics gesetzt ist, und in der Beschreibung dieses Kennzeichens, MSDN sagt dies :

Das System stellt sicher, dass der aufrufende Prozess die Dateisicherheitsprüfungen außer Kraft setzt, wenn der Prozess SE_BACKUP_NAME y SE_RESTORE_NAME Privilegien.

So wie ich es gelesen habe, wenn Wenn Sie diese Rechte haben, setzt das System die Dateisicherheitsprüfungen für Sie außer Kraft. Wenn Sie also nicht diese Rechte haben, dann unterliegt das Programm einfach weiterhin den normalerweise geltenden Dateisicherheitsprüfungen.

2voto

agile Punkte 81

Alex, in deinem CreateFile() Anruf Sie setzen FILE_FLAG_OVERLAPPED in die falsche Position. Er sollte vom 2. auf den 6. Parameter verschoben werden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X