我正在尝试写一个备份和恢复工具。 我在WinPE光盘上运行我的代码( http://en.wikipedia.org/wiki/Windows_Preinstallation_Environment )。 我正在尝试读取整个C:分区并将其写入networking。 就像tar命令,但特定于Windows。 除了设置文件所有者之外,我有一切工作。 Windows对于未知的SID所拥有的文件似乎是不能容忍的。 由于我在WinPE中运行,所以在C:上定义的大多数用户不在本地用户数据库中。
以下是我尝试过的一些function:
我知道这可以做到。 SetACL( http://helgeklein.com/setacl/ )能够做到。
所以,这个问题。 如何将文件的所有者设置为不存在的用户/ SID? 任何帮助是极大的赞赏!
下面是我试过的代码示例:
#define _WIN32_WINNT 0x0500 #include <windows.h> #include <sddl.h> #include <aclapi.h> #include <tchar.h> INT _tmain(){ PSECURITY_DESCRIPTOR psdOwner = LocalAlloc(LPTR,SECURITY_DESCRIPTOR_MIN_LENGTH); if (InitializeSecurityDescriptor(psdOwner,SECURITY_DESCRIPTOR_REVISION)){ PSID psOwner = (PSID)0; if (ConvertStringSidToSid(TEXT("S-1-5-21-3626571138-2175758104-1447827851-1013"),&psOwner)){ if (SetSecurityDescriptorOwner(psdOwner,psOwner,FALSE)){ DWORD dwError = SetNamedSecurityInfo(TEXT("test.txt"),SE_FILE_OBJECT,OWNER_SECURITY_INFORMATION,psdOwner,NULL,NULL,NULL); if (dwError == ERROR_SUCCESS){ _tprintf(TEXT("Success!\n")); }else{ _tprintf(TEXT("Failed to set owner: %u\n"),dwError); } }else{ _tprintf(TEXT("Failed to set owner into SD: %u\n"),GetLastError()); } }else{ _tprintf(TEXT("Failed to covnert Sid string to Sid: %u\n"),GetLastError()); } if (psOwner) LocalFree(psOwner); }else{ _tprintf(TEXT("Failed to initialize SD: %u\n"),GetLastError()); } if (psdOwner) LocalFree(psdOwner); return 0; }
事实证明,您需要SE_RESTORE_NAME令牌特权。 您可以使用以下方法调整流程令牌:
BOOL TakeSecurityPriv(LPCTSTR szPriv){ BOOL bReturn = FALSE; HANDLE hProcToken = (HANDLE)0; if (OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,&hProcToken)){ TOKEN_PRIVILEGES tpTokPriv; if (LookupPrivilegeValue(NULL,szPriv,&tpTokPriv.Privileges[0].Luid)){ tpTokPriv.PrivilegeCount = 1; tpTokPriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if (AdjustTokenPrivileges(hProcToken,FALSE,&tpTokPriv,0,NULL,0)){ bReturn = TRUE; } } } return bReturn; }
那么你可以在我的例子中添加以下到main的开头:
if (TakeSecurityPriv(SE_RESTORE_NAME)){
这摆脱了1307错误。 不幸的是,在我的例子中有另一个错误,因为所有者没有设置正确的SID。 但是,当我切换回BackupRead / BackupWrite时,我不必创建一个SID或SECURITY_DESCRIPTOR。 我已经思考了一段时间没有运气的问题。 也许别人可以回答这个问题。