Сообщений 13 Оценка 159 [+1/-0] Оценить |
Демонстрационное приложение к ОБЩИМ СООБРАЖЕНИЯМ
Демонстрационное приложение к СПЕЦИАЛЬНЫМ СООБРАЖЕНИЯМ
В связи с распространением Windows NT/2000/XP перед разработчиком может встать вопрос адаптации работы приложения применительно к указанным операционным системам. И немаловажным аспектом работы приложения будет являться его осведомленность о наличии необходимых прав, поскольку указанные системы активно используют разграничение прав для пользователей.
Чтобы узнать, есть ли у пользователя права администратора, программа должна определить, принадлежит ли пользователь к группе "Администраторы" на данной рабочей станции.
В первую очередь для этого необходимо создать идентификатор безопасности группы "Администраторы". Во времена былинные (до выхода Windows2000) после этого необходимо было получить токен процесса, а у токена запросить принадлежность его (а точнее пользователя, от имени которого выполняется процесс), к группам. Затем, перебирая полученные идентификаторы безопасности групп процесса, последовательно сравнить их с указанным идентификатором группы "Администраторы".
#pragma comment(lib, "advapi32") BOOL IsUserAdmin( PBOOL pbAdmin ) { #if WINVER < 0x0500 HANDLE hAccessToken = NULL; PBYTE pInfoBuffer = NULL; DWORD dwInfoBufferSize = 1024; // начальный размер буфера PTOKEN_GROUPS ptgGroups = NULL; #endif PSID psidAdministrators = NULL; SID_IDENTIFIER_AUTHORITY siaNtAuthority = SECURITY_NT_AUTHORITY; BOOL bResult = FALSE; __try { // инициализация идентификатора безопасности if( !AllocateAndInitializeSid( &siaNtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0,0,0,0,0,0, &psidAdministrators ) ) __leave; #if WINVER < 0x0500 // код для предшественников Windows2000 // откроем токен процесса if( !OpenProcessToken( GetCurrentProcess(),TOKEN_QUERY,&hAccessToken ) ) __leave; do // выделение буфера для запрошенной из токена информации { if( pInfoBuffer ) delete pInfoBuffer; pInfoBuffer = new BYTE[dwInfoBufferSize]; if( !pInfoBuffer ) __leave; SetLastError( 0 ); if( !GetTokenInformation( hAccessToken, TokenGroups, pInfoBuffer, dwInfoBufferSize, &dwInfoBufferSize ) && ( ERROR_INSUFFICIENT_BUFFER != GetLastError() ) ) __leave; else ptgGroups = (PTOKEN_GROUPS)pInfoBuffer; } while( GetLastError() ); // если была ошибка, значит начального размера недостаточно // переберем идентификаторы безопасности процесса в поисках необходимого нам for( UINT i = 0; i < ptgGroups->GroupCount; i++ ) { if( EqualSid(psidAdministrators,ptgGroups->Groups[i].Sid) ) { *pbAdmin = TRUE; bResult = TRUE; __leave; } } #else // код для Windows2000 bResult = CheckTokenMembership( NULL, psidAdministrators, pbAdmin ); #endif } __finally { #if WINVER < 0x0500 if( hAccessToken ) CloseHandle( hAccessToken ); if( pInfoBuffer ) delete pInfoBuffer; #endif if( psidAdministrators ) FreeSid( psidAdministrators ); } return bResult; } |
Внимательный читатель наверняка заметил, что версия указанного кода для Windows2000 гораздо более "худосочная" - дело в том, что CheckTokenMembership() самостоятельно открывает токен доступа и выясняет, включен ли в токен указанный идентификатор безопасности, т.е. выполняет все те процедуры, которые на предыдущих версиях WindowsNT мы должны были реализовать своими силами.
ПРИМЕЧАНИЕ IsUserAdmin.exe (релиз-версия) в демонстрационном проекте скомпилирован под Windows2000. Чтобы выполнить код в WindowsNT, необходимо изменить в настройках проекта директиву препроцессора WINVER на 0x0400 и пересобрать проект с новыми настройками. |
Для программирующего на C/C++ приведенный код не представляет собой ничего особенного. И в то же время программист, работающий в среде, предположим, Visual Basic получит немалую головную боль при попытке реализовать вышеприведенный код. Однако, об этих программистах фирма Microsoft уже позаботилась (хотя, возможно, не все об этом догадываются :-) ).
Дело в том, что системная библиотека setupapi.dll уже содержит реализацию приведенной функции, мало того, она имеет то же название, но несколько иной прототип:
BOOL WINAPI IsUserAdmin(); |
Объявление этой функции на VB будет выглядеть следующим образом:
Declare Function IsUserAdmin Lib "setupapi.dll" () As Long |
Надеюсь, для программирующих в других средах, впрочем, так же как и для C/C++ программистов, не составит труда самостоятельно воспользоваться приведенной информацией.
Сообщений 13 Оценка 159 [+1/-0] Оценить |