Требует ли использование ReadDirectoryChangesW прав администратора? - PullRequest
7 голосов
/ 15 апреля 2010

В MSDN говорится, что использование ReadDirectoryChangesW подразумевает вызывающий процесс с правами резервного копирования и восстановления.

Означает ли это, что только процесс, запущенный под учетной записью администратора, будет работать правильно?

Я попробовал следующий код, он не может включить необходимые привилегии при работе от имени пользователя с ограниченными правами.

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); 
    } 
}

Я что-то не так делаю? Есть ли обходной путь для использования ReadDirectoryChangesW из учетной записи пользователя без прав администратора? Кажется, что .NET FileSystemWatcher может сделать это. Спасибо!

Обновление : Вот полный код класса:

  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];   
  };

 }

Обновление : Хорошие новости! Оказалось, что проблема действительно заключалась в флаге FILE_SHARE_WRITE при вызове CreateFile. Уведомления не приходили, если я не был администратором. Когда я убрал этот флаг, теперь все работает и на учетной записи без прав администратора.

Ответы [ 3 ]

5 голосов
/ 15 апреля 2010

Я использовал ReadDirectoryChangesW, не требуя прав администратора, по крайней мере, в Vista. Я не думаю, что вам нужно вручную повышать процесс, чтобы использовать его в папке, которую пользователь уже имеет права на просмотр.

Было бы более полезно увидеть фактический код, который вы используете для вызова ReadDirectoryChangesW, включая способ создания дескриптора, который вы передаете.

4 голосов
/ 15 апреля 2010

Я не вижу, где MSDN говорит, что вам нужны права на резервное копирование или восстановление. Он инструктирует вас вызывать CreateFile с установленным флагом File_Flag_Backup_Semantics, а в описании этого флага MSDN говорит: :

Система гарантирует, что вызывающий процесс отменяет проверки безопасности файлов, когда процесс имеет права SE_BACKUP_NAME и SE_RESTORE_NAME.

Как я прочел, , если у вас есть эти привилегии, то система отменит проверки безопасности файлов для вас. Поэтому, если у вас нет этих привилегий, программа просто будет по-прежнему связана с любыми проверками безопасности файлов, которые обычно действуют.

2 голосов
/ 13 ноября 2015

Алекс, на ваш CreateFile() звонок вы поставили FILE_FLAG_OVERLAPPED в неправильное положение. Его следует переместить со 2-го на 6-й параметр.

...