【发布时间】:2016-01-19 15:40:44
【问题描述】:
我正在尝试使用 WinAPI 将文件夹设为只读,然后再次使其读/写。我尝试通过拒绝写访问(对于只读部分)并授予所有访问权限(对于读/写部分)来做到这一点。第二部分有效,但对于第一部分,当我尝试打开文件夹时,它告诉我我没有访问它的权限,我什至看不到文件夹中有哪些文件。
这是代码(来自 MSDN 和其他来源):
#include <windows.h>
#include <stdio.h>
#include <accctrl.h>
#include <aclapi.h>
#include <stdio.h>
#pragma comment(lib, "advapi32.lib")
BOOL SetPrivilege(
HANDLE hToken, // access token handle
LPCTSTR lpszPrivilege, // name of privilege to enable/disable
BOOL bEnablePrivilege // to enable or disable privilege
)
{
TOKEN_PRIVILEGES tp;
LUID luid;
if (!LookupPrivilegeValue(
NULL, // lookup privilege on local system
lpszPrivilege, // privilege to lookup
&luid)) // receives LUID of privilege
{
printf("LookupPrivilegeValue error: %u\n", GetLastError());
return FALSE;
}
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
if (bEnablePrivilege)
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
else
tp.Privileges[0].Attributes = 0;
// Enable the privilege or disable all privileges.
if (!AdjustTokenPrivileges(
hToken,
FALSE,
&tp,
sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES)NULL,
(PDWORD)NULL))
{
printf("AdjustTokenPrivileges error: %u\n", GetLastError());
return FALSE;
}
if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
{
printf("The token does not have the specified privilege. \n");
return FALSE;
}
return TRUE;
}
BOOL TakeOwnership(LPTSTR lpszOwnFile, bool bAllowAccess)
{
BOOL bRetval = FALSE;
HANDLE hToken = NULL;
PSID pSIDAdmin = NULL;
PSID pSIDEveryone = NULL;
PACL pACL = NULL;
SID_IDENTIFIER_AUTHORITY SIDAuthWorld =
SECURITY_WORLD_SID_AUTHORITY;
SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY;
const int NUM_ACES = 1;
EXPLICIT_ACCESS ea[NUM_ACES];
DWORD dwRes;
ZeroMemory(&ea, NUM_ACES * sizeof(EXPLICIT_ACCESS));
// Set read access for Everyone.
ea[0].grfAccessPermissions = (bAllowAccess ? GENERIC_ALL : GENERIC_WRITE);
ea[0].grfAccessMode = (bAllowAccess ? GRANT_ACCESS : DENY_ACCESS);
ea[0].grfInheritance = NO_INHERITANCE;
ea[0].Trustee.TrusteeForm = TRUSTEE_IS_NAME;
ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
ea[0].Trustee.ptstrName = _T("EVERYONE");// (LPTSTR)pSIDEveryone;
dwRes = SetEntriesInAcl(NUM_ACES,
ea,
NULL,
&pACL);
if (ERROR_SUCCESS != dwRes)
{
printf("Failed SetEntriesInAcl with error %d\n", dwRes);
goto Cleanup;
}
// Try to modify the object's DACL.
dwRes = SetNamedSecurityInfo(
lpszOwnFile, // name of the object
SE_FILE_OBJECT, // type of object
DACL_SECURITY_INFORMATION, // change only the object's DACL
NULL, NULL, // do not change owner or group
pACL, // DACL specified
NULL); // do not change SACL
if (ERROR_SUCCESS == dwRes)
{
printf("Successfully changed DACL\n");
bRetval = TRUE;
// No more processing needed.
goto Cleanup;
}
if (dwRes != ERROR_ACCESS_DENIED)
{
printf("First SetNamedSecurityInfo call failed: %u\n",
dwRes);
goto Cleanup;
}
// If the preceding call failed because access was denied,
// enable the SE_TAKE_OWNERSHIP_NAME privilege, create a SID for
// the Administrators group, take ownership of the object, and
// disable the privilege. Then try again to set the object's DACL.
// Open a handle to the access token for the calling process.
if (!OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES,
&hToken))
{
printf("OpenProcessToken failed: %u\n", GetLastError());
goto Cleanup;
}
// Enable the SE_TAKE_OWNERSHIP_NAME privilege.
if (!SetPrivilege(hToken, SE_TAKE_OWNERSHIP_NAME, TRUE))
{
printf("You must be logged on as Administrator.\n");
goto Cleanup;
}
// Disable the SE_TAKE_OWNERSHIP_NAME privilege.
if (!SetPrivilege(hToken, SE_TAKE_OWNERSHIP_NAME, FALSE))
{
printf("Failed SetPrivilege call unexpectedly.\n");
goto Cleanup;
}
// Try again to modify the object's DACL,
// now that we are the owner.
dwRes = SetNamedSecurityInfo(
lpszOwnFile, // name of the object
SE_FILE_OBJECT, // type of object
DACL_SECURITY_INFORMATION, // change only the object's DACL
NULL, NULL, // do not change owner or group
pACL, // DACL specified
NULL); // do not change SACL
if (dwRes == ERROR_SUCCESS)
{
printf("Successfully changed DACL\n");
bRetval = TRUE;
}
else
{
printf("Second SetNamedSecurityInfo call failed: %u\n",
dwRes);
}
Cleanup:
if (pSIDAdmin)
FreeSid(pSIDAdmin);
if (pSIDEveryone)
FreeSid(pSIDEveryone);
if (pACL)
LocalFree(pACL);
if (hToken)
CloseHandle(hToken);
return bRetval;
}
int main(int argc, char* argv[])
{
bool allow = false; //true
TakeOwnership(argv[1], allow);
return 0;
}
谁能告诉我我做错了什么?
【问题讨论】:
标签: c winapi permissions