1.判断UAC是否启动
BOOL _stdcall IsRunUAC()//判断是否启动UAC
{
BOOL bRet = FALSE;
LONG lErr;
HKEY hKEY;
DWORD dwEnableLUA;
DWORD dwType = REG_DWORD;
DWORD dwSize = sizeof( DWORD );
if( IsVISTA() )
{
lErr = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
_T(“SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System\\”),
0,
KEY_READ,
&hKEY );
if( lErr == ERROR_SUCCESS )
{
lErr = RegQueryValueEx( hKEY,
_T( “EnableLUA” ),
NULL,
&dwType,
(BYTE*)&dwEnableLUA,
&dwSize );
if( lErr == ERROR_SUCCESS )
{
if( 0 == dwEnableLUA )
{
bRet = FALSE;
}
else
{
bRet = TRUE;
}
}
else;
RegCloseKey( hKEY );
}
else;
}
else;
return bRet;
}
以上代码是判断一个注册表键值,不是正规方式。UAC启动要通过重起系统完成,这个标志位不表示当前UAC状态,所以此代码要在系统启动时执行才有效。
2.解决UAC打开时,不同权限之间的应用程序间不能广播消息
Vista UAC打开时,不同权限的应用程序广播消息是收不到的。
UINT UIBroadcastCommand = ::RegisterWindowMessage( SNA_MESSAGE );
ON_REGISTERED_MESSAGE( UIBroadcastCommand, OnFromMessage )
将以下代码加入程序启始位置
BOOL AllowMeesageForVista( UINT uMessageID, BOOL bAllow )//注册Vista全局消息
{
BOOL bResult = FALSE;
HMODULE hUserMod = NULL;
do
{
//vista and later
hUserMod = LoadLibrary( “User32.dll” );
if( NULL == hUserMod ) break;
_ChangeWindowMessageFilter pChangeWindowMessageFilter = (_ChangeWindowMessageFilter)GetProcAddress( hUserMod, “ChangeWindowMessageFilter” );
if( NULL == pChangeWindowMessageFilter )break;
bResult = pChangeWindowMessageFilter( uMessageID, bAllow ? 1 : 2 );//MSGFLT_ADD: 1, MSGFLT_REMOVE: 2
}
while( 0 );
if( NULL != hUserMod )
{
FreeLibrary( hUserMod );
}
else;
return bResult;
}
这里使用Vista提供的标准函数ChangeWindowMessageFilter注册一个全局消息。但是由于系统服务与应用程序间的session不同,所以应用程序无法响应系统服务的广播消息。
3. 系统服务与应用程序的事件通讯
在Vista中高权限进程创建的事件使用低权限进程是无法open的(其它windows也一样)。在创建事件时使用以下代码
DWORD _stdcall MyCreateEvent( HANDLE* phEvent, BOOL bManualReset, BOOL bInitialState, LPCTSTR lpName )
{
DWORD dwRet = 0;
PSID pEveryoneSID = NULL, pAdminSID = NULL;
SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
EXPLICIT_ACCESS ea[1];
PSECURITY_DESCRIPTOR pSD = NULL;
PACL pACL = NULL;
SECURITY_ATTRIBUTES sa;
*phEvent = NULL;
do
{
// Create a well-known SID for the Everyone group.
if( !AllocateAndInitializeSid( &SIDAuthWorld,
1,
SECURITY_WORLD_RID,
0, 0, 0, 0, 0, 0, 0,
&pEveryoneSID ) )
{
dwRet = GetLastError();
break;
}
else;
// Initialize an EXPLICIT_ACCESS structure for an ACE.
ZeroMemory( &ea, sizeof(EXPLICIT_ACCESS) );
ea[0].grfAccessPermissions = EVENT_ALL_ACCESS;
ea[0].grfAccessMode = SET_ACCESS;
ea[0].grfInheritance= NO_INHERITANCE;
ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
ea[0].Trustee.ptstrName = (LPTSTR) pEveryoneSID;
// Create a new ACL that contains the new ACEs.
dwRet = SetEntriesInAcl( 1, ea, NULL, &pACL );
if( ERROR_SUCCESS != dwRet )
{
break;
}
else;
// Initialize a security descriptor.
pSD = (PSECURITY_DESCRIPTOR)LocalAlloc( LPTR,
SECURITY_DESCRIPTOR_MIN_LENGTH );
if( NULL == pSD )
{
dwRet = GetLastError();
break;
}
else;
if( !InitializeSecurityDescriptor( pSD, SECURITY_DESCRIPTOR_REVISION ) )
{
dwRet = GetLastError();
break;
}
else;
// Add the ACL to the security descriptor.
if (!SetSecurityDescriptorDacl( pSD,
TRUE, // bDaclPresent flag
pACL,
FALSE ) ) // not a default DACL
{
dwRet = GetLastError();
break;
}
else;
// Initialize a security attributes structure.
sa.nLength = sizeof( SECURITY_ATTRIBUTES );
sa.lpSecurityDescriptor = pSD;
sa.bInheritHandle = FALSE;
*phEvent = CreateEvent( &sa, bManualReset, bInitialState, lpName );
if( NULL == *phEvent )
{
dwRet = GetLastError();
break;
}
else;
}
while( 0 );
//
if( pEveryoneSID )
{
FreeSid( pEveryoneSID );
}
else;
if( pACL )
{
LocalFree( pACL );
}
else;
if( pSD )
{
LocalFree(pSD);
}
else;
return dwRet;
}
(文章来自:码农源库
http://www.vcclass.net/wordpress/?p=26)
BOOL _stdcall IsRunUAC()//判断是否启动UAC
{
BOOL bRet = FALSE;
LONG lErr;
HKEY hKEY;
DWORD dwEnableLUA;
DWORD dwType = REG_DWORD;
DWORD dwSize = sizeof( DWORD );
if( IsVISTA() )
{
lErr = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
_T(“SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System\\”),
0,
KEY_READ,
&hKEY );
if( lErr == ERROR_SUCCESS )
{
lErr = RegQueryValueEx( hKEY,
_T( “EnableLUA” ),
NULL,
&dwType,
(BYTE*)&dwEnableLUA,
&dwSize );
if( lErr == ERROR_SUCCESS )
{
if( 0 == dwEnableLUA )
{
bRet = FALSE;
}
else
{
bRet = TRUE;
}
}
else;
RegCloseKey( hKEY );
}
else;
}
else;
return bRet;
}
以上代码是判断一个注册表键值,不是正规方式。UAC启动要通过重起系统完成,这个标志位不表示当前UAC状态,所以此代码要在系统启动时执行才有效。
2.解决UAC打开时,不同权限之间的应用程序间不能广播消息
Vista UAC打开时,不同权限的应用程序广播消息是收不到的。
UINT UIBroadcastCommand = ::RegisterWindowMessage( SNA_MESSAGE );
ON_REGISTERED_MESSAGE( UIBroadcastCommand, OnFromMessage )
将以下代码加入程序启始位置
BOOL AllowMeesageForVista( UINT uMessageID, BOOL bAllow )//注册Vista全局消息
{
BOOL bResult = FALSE;
HMODULE hUserMod = NULL;
do
{
//vista and later
hUserMod = LoadLibrary( “User32.dll” );
if( NULL == hUserMod ) break;
_ChangeWindowMessageFilter pChangeWindowMessageFilter = (_ChangeWindowMessageFilter)GetProcAddress( hUserMod, “ChangeWindowMessageFilter” );
if( NULL == pChangeWindowMessageFilter )break;
bResult = pChangeWindowMessageFilter( uMessageID, bAllow ? 1 : 2 );//MSGFLT_ADD: 1, MSGFLT_REMOVE: 2
}
while( 0 );
if( NULL != hUserMod )
{
FreeLibrary( hUserMod );
}
else;
return bResult;
}
这里使用Vista提供的标准函数ChangeWindowMessageFilter注册一个全局消息。但是由于系统服务与应用程序间的session不同,所以应用程序无法响应系统服务的广播消息。
3. 系统服务与应用程序的事件通讯
在Vista中高权限进程创建的事件使用低权限进程是无法open的(其它windows也一样)。在创建事件时使用以下代码
DWORD _stdcall MyCreateEvent( HANDLE* phEvent, BOOL bManualReset, BOOL bInitialState, LPCTSTR lpName )
{
DWORD dwRet = 0;
PSID pEveryoneSID = NULL, pAdminSID = NULL;
SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
EXPLICIT_ACCESS ea[1];
PSECURITY_DESCRIPTOR pSD = NULL;
PACL pACL = NULL;
SECURITY_ATTRIBUTES sa;
*phEvent = NULL;
do
{
// Create a well-known SID for the Everyone group.
if( !AllocateAndInitializeSid( &SIDAuthWorld,
1,
SECURITY_WORLD_RID,
0, 0, 0, 0, 0, 0, 0,
&pEveryoneSID ) )
{
dwRet = GetLastError();
break;
}
else;
// Initialize an EXPLICIT_ACCESS structure for an ACE.
ZeroMemory( &ea, sizeof(EXPLICIT_ACCESS) );
ea[0].grfAccessPermissions = EVENT_ALL_ACCESS;
ea[0].grfAccessMode = SET_ACCESS;
ea[0].grfInheritance= NO_INHERITANCE;
ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
ea[0].Trustee.ptstrName = (LPTSTR) pEveryoneSID;
// Create a new ACL that contains the new ACEs.
dwRet = SetEntriesInAcl( 1, ea, NULL, &pACL );
if( ERROR_SUCCESS != dwRet )
{
break;
}
else;
// Initialize a security descriptor.
pSD = (PSECURITY_DESCRIPTOR)LocalAlloc( LPTR,
SECURITY_DESCRIPTOR_MIN_LENGTH );
if( NULL == pSD )
{
dwRet = GetLastError();
break;
}
else;
if( !InitializeSecurityDescriptor( pSD, SECURITY_DESCRIPTOR_REVISION ) )
{
dwRet = GetLastError();
break;
}
else;
// Add the ACL to the security descriptor.
if (!SetSecurityDescriptorDacl( pSD,
TRUE, // bDaclPresent flag
pACL,
FALSE ) ) // not a default DACL
{
dwRet = GetLastError();
break;
}
else;
// Initialize a security attributes structure.
sa.nLength = sizeof( SECURITY_ATTRIBUTES );
sa.lpSecurityDescriptor = pSD;
sa.bInheritHandle = FALSE;
*phEvent = CreateEvent( &sa, bManualReset, bInitialState, lpName );
if( NULL == *phEvent )
{
dwRet = GetLastError();
break;
}
else;
}
while( 0 );
//
if( pEveryoneSID )
{
FreeSid( pEveryoneSID );
}
else;
if( pACL )
{
LocalFree( pACL );
}
else;
if( pSD )
{
LocalFree(pSD);
}
else;
return dwRet;
}
(文章来自:码农源库
http://www.vcclass.net/wordpress/?p=26)