2010-04-14 78 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个参数。

相关问题