2010-04-14 106 views
6

MSDN說使用ReadDirectoryChangesW意味着調用進程具有備份和恢復權限。使用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]; 
    }; 

} 

更新:好消息!事實證明,問題確實發生在CreateFile調用中的FILE_SHARE_WRITE標誌中。除非我是管理員,否則通知不會到來。當我刪除此標誌時,所有內容現在都在非管理員帳戶上工作。

+0

你打電話給ReadDirectoryChangesW?隨着驅動器的根目錄或文件夾? – MSN 2010-04-14 20:07:29

+0

MSDN在哪裏說完全? – avakar 2010-04-14 20:08:49

+0

我在文件夾上使用它。但AdjustTokenPrivileges之後的GetLastError返回ERROR_NOT_ALL_ASSIGNED。 – 2010-04-14 20:16:01

回答

4

我已經使用ReadDirectoryChangesW而不需要管理員權限,至少在Vista上。我不認爲你需要手動提升進程才能在用戶已有權限查看的文件夾上使用它。

這將是更有益的,看看實際的代碼使用的是調用ReadDirectoryChangesW,包括如何創建你在通過手柄。

+0

謝謝!你說得對:創建包含錯誤的句柄 - 不需要的FILE_SHARE_WRITE標誌 – 2010-04-15 09:37:52

3

我沒有看到MSDN說,你需要備份或還原權限。它指導你打電話CreateFileFile_Flag_Backup_Semantics標誌設置,並在該標誌的說明,MSDN says this

系統確保調用進程忽略文件的安全檢查時,該工藝具有SE_BACKUP_NAMESE_RESTORE_NAME特權。

我讀的方式,如果你有這些特權,那麼系統將覆蓋文件安全檢查你。所以如果你沒有有這些特權,那麼程序將繼續受到任何文件安全檢查通常會生效的約束。

+0

你是對的,我誤解了MSDN的真實含義。問題出在CreateFile調用的FILE_SHARE_WRITE標誌中。 – 2010-04-15 09:32:11

2

亞歷克斯,在你的CreateFile()打電話給你,把FILE_FLAG_OVERLAPPED置於錯誤的位置。它應該從第2個參數移動到第6個參數。

相關問題