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];
};
}
更新:好消息!事实证明,问题确实存在于对CreateFile的调用中的FILE_SHARE_WRITE标志中。除非我是管理员,否则通知不会发生。当我删除此标志时,所有内容现在都在非管理员帐户上工作。
答案 0 :(得分:5)
我使用ReadDirectoryChangesW
而不需要管理员权限,至少在Vista上是这样。我认为您不需要手动提升流程,以便在用户已有权查看的文件夹上使用它。
查看用于调用ReadDirectoryChangesW
的实际代码会更有帮助,包括如何创建传入的句柄。
答案 1 :(得分:4)
我没有看到MSDN说你需要备份或恢复权限。它会指示您在设置CreateFile
标记时调用File_Flag_Backup_Semantics
,并在该标记的说明中MSDN says this:
系统确保在进程具有
SE_BACKUP_NAME
和SE_RESTORE_NAME
权限时,调用进程将覆盖文件安全检查。
我读它的方式,如果你有这些权限,那么系统会为你覆盖文件安全检查。因此,如果您不拥有这些权限,那么程序将继续受到通常有效的文件安全检查的约束。
答案 2 :(得分:2)
Alex,在CreateFile()
电话中,您将FILE_FLAG_OVERLAPPED
置于错误的位置。它应该从第2个参数移到第6个参数。