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 플래그에 있음을 알게되었습니다. 내가 관리자가 아니면 통지는 오지 않았다. 이 플래그를 제거하면 모든 항목이 현재 비 관리자 계정에서도 작동합니다.
어떻게 ReadDirectoryChangesW를 호출합니까? 드라이브 루트 또는 폴더? – MSN
MSDN은 정확히 어디에서 말하는가? – avakar
폴더에서 사용하고 있습니다. 그러나 AdjustTokenPrivileges가 끝나면 GetLastError는 ERROR_NOT_ALL_ASSIGNED를 반환합니다. –