解决方法
有几种根本不同的方式.最普遍的
不幸的是,这是相当乏味的.它涉及寻找当前
用户的SID,然后找到他所属的组,然后
查找其中一个是否为Administrators组:
不幸的是,这是相当乏味的.它涉及寻找当前
用户的SID,然后找到他所属的组,然后
查找其中一个是否为Administrators组:
#include <windows.h> #include <vector> bool is_administrator() { HANDLE access_token; DWORD buffer_size = 0; PSID admin_SID; TOKEN_GROUPS *group_token = NULL; SID_IDENTIFIER_AUTHORITY NT_authority = Security_NT_AUTHORITY; if (!OpenProcesstoken(GetCurrentProcess(),TOKEN_READ,&access_token)) return false; GetTokeninformation( access_token,TokenGroups,group_token,&buffer_size ); std::vector<char> buffer(buffer_size); group_token = reinterpret_cast<TOKEN_GROUPS*>(&buffer[0]); bool succeeded = GetTokeninformation( access_token,buffer_size,&buffer_size ); CloseHandle(access_token); if (!succeeded) return false; if (!AllocateAndInitializeSid( &NT_authority,2,Security_BUILTIN_DOMAIN_RID,DOMAIN_ALIAS_RID_ADMINS,&admin_SID )) { return false; } bool found=false; for(int i=0; !found && i < group_token->GroupCount; i++) found = EqualSid(admin_SID,group_token->Groups[i].Sid); FreeSid(admin_SID); return found; }
还有另一种方法,虽然有点简单:
bool is_administrator() { bool result; DWORD rc; wchar_t user_name[256]; USER_INFO_1 *info; DWORD size = sizeof( user_name ); GetUserNameW( user_name,&size); rc = NetUserGetInfo( NULL,user_name,1,(byte **) &info ); if ( rc != NERR_Success ) return false; result = info->usri1_priv == USER_PRIV_ADMIN; NetApiBufferFree( info ); return result; }
在任何一种情况下,如果你有一个域,事情可能有点毛茸茸,
因为特定用户可能是本地的管理员
机器,但不在域上,反之亦然.查找信息
并不一定会有太大变化,但你可能需要考虑一下
找出你真正想要的东西.
编辑:正如@Benj指出的那样,第一种方法确实可以使用一些更新.虽然我已经修复了它所带来的明显泄漏,但它仍然是一个巨大的单片功能,没有异常安全,而且通常是过时的编码风格.也许是一个小的更新:
#include <windows.h> #include <vector> #include <algorithm> class sid { PSID s; public: sid(SID_IDENTIFIER_AUTHORITY auth,std::vector<DWORD> sub_auths) { DWORD count = sub_auths.size(); sub_auths.resize(7,DWORD()); if (!AllocateAndInitializeSid( &auth,count,sub_auths[0],sub_auths[1],sub_auths[2],sub_auths[3],sub_auths[4],sub_auths[5],sub_auths[6],sub_auths[7],&s )) { throw std::runtime_error("Unable to allocate Admin SID"); } } sid(PSID const &p=NULL) : s(p) {} bool operator==(sid const &r) const { return EqualSid(s,r.s); } }; class access_token { HANDLE token; public: access_token(HANDLE PID=GetCurrentProcess(),DWORD access=TOKEN_READ) { if (!OpenProcesstoken(PID,access,&token)) throw std::runtime_error("Unable to open process token"); } operator HANDLE() { return token; } ~access_token() { CloseHandle(token); } }; std::vector<sid> get_group_sids() { DWORD buffer_size = 0; TOKEN_GROUPS *group_token = NULL; std::vector<sid> groups; access_token token; GetTokeninformation(token,&buffer_size); std::vector<char> buffer(buffer_size); group_token = reinterpret_cast<TOKEN_GROUPS*>(&buffer[0]); if (GetTokeninformation(token,&buffer_size)) for (int i=0; i<group_token->GroupCount; i++) groups.push_back(group_token->Groups[i].Sid); return groups; } bool is_administrator() { std::vector<sid> groups = get_group_sids(); SID_IDENTIFIER_AUTHORITY NT_authority = Security_NT_AUTHORITY; std::vector<DWORD> sub_auths; sub_auths.push_back(Security_BUILTIN_DOMAIN_RID); sub_auths.push_back(DOMAIN_ALIAS_RID_ADMINS); sid admin_SID(NT_authority,sub_auths); return std::find(groups.begin(),groups.end(),admin_SID) != groups.end(); } #ifdef TEST #include <iostream> #include <iomanip> int main() { std::cout << std::boolalpha << is_administrator() << "\n"; } #endif