AppContainerUtils.zip/AuthzAnyPackageFolder/AuthzAnyPackageFolder/AuthzAnyPackageFolder.cpp
#include <iostream>
#include <vector>
#include <boost/shared_ptr.hpp>
#include <boost/type_traits/remove_pointer.hpp>
#include <boost/foreach.hpp>
#include <Windows.h>
typedef boost::shared_ptr<boost::remove_pointer<PSID>::type> SHARED_SID;
void MyFreeSid(PSID sid) {
if (sid != NULL) {
::FreeSid(sid);
}
}
SHARED_SID ToSharedSID(PSID sid) {
return SHARED_SID(sid, &MyFreeSid);
}
void MyLocalFree(PSID sid) {
if (sid != NULL) {
::LocalFree(sid);
}
}
typedef boost::shared_ptr<boost::remove_pointer<PACL>::type> SHARED_ACL;
unsigned int GetACLSize(const std::vector<SHARED_SID> &list) {
unsigned int size = sizeof(ACL) + (sizeof(ACCESS_ALLOWED_ACE) * list.size());
BOOST_FOREACH(const SHARED_SID &sid, list) {
size += ::GetLengthSid(sid.get()) - sizeof(DWORD);
}
// align
size = (size + sizeof(DWORD) - 1) & 0xfffffffc;
return size;
}
SHARED_ACL CreatePACL(const std::vector<SHARED_SID> &list) {
const unsigned int size = GetACLSize(list);
const SHARED_ACL acl(reinterpret_cast<PACL>(new unsigned char[size]));
if (::InitializeAcl(acl.get(), size, ACL_REVISION) == FALSE) {
return SHARED_ACL();
}
BOOST_FOREACH(const SHARED_SID &sid, list) {
if (::AddAccessAllowedAce(acl.get(), ACL_REVISION, GENERIC_ALL, sid.get()) == FALSE) {
return SHARED_ACL();
}
}
return acl;
}
typedef boost::shared_ptr<boost::remove_pointer<HANDLE>::type> SHARED_HANDLE;
void MyCloseHandle(const HANDLE handle) {
if (handle != NULL) {
::CloseHandle(handle);
}
}
SHARED_SID GetWellKnownSid(const WELL_KNOWN_SID_TYPE type) {
SHARED_SID sid(new unsigned char[SECURITY_MAX_SID_SIZE]);
DWORD sidSize = SECURITY_MAX_SID_SIZE;
if (::CreateWellKnownSid(type, NULL, sid.get(), &sidSize) == FALSE) {
return SHARED_SID();
}
return sid;
}
bool CreateSecurityDescriptor(boost::shared_ptr<SECURITY_DESCRIPTOR> &desc, SHARED_ACL &acl, const std::vector<SHARED_SID> &sidList, const SHARED_SID owner) {
acl = CreatePACL(sidList);
if (!acl) {
return false;
}
desc.reset(new SECURITY_DESCRIPTOR());
if (::InitializeSecurityDescriptor(desc.get(), SECURITY_DESCRIPTOR_REVISION) == FALSE) {
return false;
}
if (::SetSecurityDescriptorDacl(desc.get(), TRUE, acl.get(), FALSE) == FALSE) {
return false;
}
return true;
}
SHARED_SID GetUserSid(const wchar_t * const name) {
DWORD bufSize = 0;
wchar_t domain[256];
DWORD domainSize = _countof(domain);
SID_NAME_USE type;
::LookupAccountNameW(NULL, name, NULL, &bufSize, domain, &domainSize, &type);
SHARED_SID sid(new unsigned char[bufSize]);
::LookupAccountNameW(NULL, name, sid.get(), &bufSize, domain, &domainSize, &type);
return sid;
}
SHARED_SID GetCurrentUserSid() {
wchar_t name[256];
DWORD size = _countof(name);
if (::GetUserNameW(name, &size) == FALSE) {
return SHARED_SID();
}
return GetUserSid(name);
}
bool AuthzAnyPackage(const char * const path) {
const SHARED_SID owner = GetCurrentUserSid();
boost::shared_ptr<SECURITY_DESCRIPTOR> desc;
SHARED_ACL acl;
std::vector<SHARED_SID> sidList;
sidList.push_back(GetWellKnownSid(WinBuiltinAnyPackageSid));
sidList.push_back(GetWellKnownSid(WinLocalSystemSid));
sidList.push_back(owner);
sidList.push_back(GetWellKnownSid(WinBuiltinAdministratorsSid));
if (!CreateSecurityDescriptor(desc, acl, sidList, owner)) {
return false;
}
if (::SetFileSecurityA(path, DACL_SECURITY_INFORMATION, desc.get()) == FALSE) {
return false;
}
return true;
}
int main(const unsigned int argc, const char * const * const argv) {
std::locale::global(std::locale("japanese"));
if (argc != 2) {
std::wcout << L"usage: AuthzAnyPackageFolder.exe folder_path" << std::endl;
std::wcin.ignore();
return 1;
}
if (!AuthzAnyPackage(argv[1])) {
std::wcout << L"Error: ファイルの権限設定に失敗しました" << std::endl;
std::wcin.ignore();
return 1;
}
std::wcout << L"処理は正常に終了しました" << std::endl;
std::wcin.ignore();
return 0;
}