Рассматриваю только ОС Виста+. На ХП все то делается просто. Ситуация такова: Сессия 0: Система Сессия 1: Пользователь 1 Его пароля я не знаю и знать не должен. Сессия 2: Пользователь 2 Пароль этого пользователя узнать возможно. Нужно имея агента в сессии 0 и 1, запустить процесс в сессии 2 от имени пользователя 1. Для начала пробовал делать следующее(Запуская свой процесс с помощью psexec во второй сессии): 1. WTSQueryUserToken( hUser1Token ) на 1 сессию. 2. DuplicateTokenEx(hUser1Token ) или DuplicateHandle( hUser1Token ) для клонирования. 3. SetTokenInformation( hUser1Token ) что бы сменить сессию на 2. 4. CreateEnvironmentBlock( hUser1Token ) 5. ImpersonateLoggedOnUser( hUser1Token ) 6. CreateProcessAsUser( hUser1Token , "WinSta0\\Default") Процесс создавался но: 1. Не имел хэндла на ALPC порты, и на "\Sessions\2\BaseNamedObjects". Из за этого функции CreateInstance пытаясь открыть BaseNamedObjects\__ComCasheCatalog(вроде так) падали с ACCESS_DENIED. Так же рождалось окно при старте процесса(Винда действительно не лицензионная на тестовой машине, но откуда оно появлялось при исполнении кода не ясно.): Пробовал и другие варианты. Смотрел как это делает runas(Там это делает svchost -> seclogon.dll -> SlrCreateProcessWithLogon), пробовал повторить, то есть: 1. Использовал InitializeProcThreadAttributeList, UpdateProcThreadAttribute + EXTENDED_STARTUPINFO_PRESENT. Родительский процесс то менялся, но все равно процесс глючил и не имел "\Sessions\2\BaseNamedObjects". 2. Job назначать не пробовал, но если пропустить назначение задачи(в виндбг изменил порядок выполнения в дллке seclogon.dll -> SlrCreateProcessWithLogon) то тот код все равно отрабатывает. То есть задания отношения к проблеме не имеют. Возможно кто то сталкивался с такой проблемой. П.С. Отрисовка у процесса идет вроде бы как нормально.
самому не писал, но видел в зверях типа zeus 2.x реализацию запуска самого себя во все сессии. там получаются привелегии SeTcbPrivilege. WTSEnumerateSessions, WTSQueryUserToken, GetTokenInformation(TokenUser), CreateEnvironmentBlock CreateProcessAsUser, пишу по памяти, мб что-то пропустил.
freyr Самого себя запустить во всех сессиях от имени пользователей тех сессий, у меня тоже получается. Сейчас код может оформлю и выложу чуть позже, может где то очевидное упустил. Отредактировал: Добавил код. На XP работает чудесно, на Висте приложения становятся обрубками. Вот список хэндлов обычного блокнота: Вот список хэндлов блокнота запущеного через CreateProcessWithDifferentSessionRights. Код (Text): BOOL CreateProcessWithDifferentSessionRights( WCHAR* lpUserName , WCHAR* lpUserPass , WCHAR* lpDomain , WCHAR* lpCommandLine , ULONG iDestinationSession ) { BOOL rv = FALSE; HANDLE hOriginalUserToken = FALSE; HANDLE hNewSessionUserToken = FALSE; PSID SourceUserSid = NULL; PSID LogonSid = NULL; PSID LocalSid = NULL; LUID LogonId; LUID LogonLuid; PTOKEN_GROUPS PTokenGroups = NULL; USHORT cbUserName; USHORT cbDomain; USHORT cbPassword; SID_IDENTIFIER_AUTHORITY IdentifierAuthority = SECURITY_LOCAL_SID_AUTHORITY; PVOID AuthInfoBuf = NULL; ULONG AuthInfoSize; PMSV1_0_INTERACTIVE_LOGON pMsvAuthInfo; LSA_STRING LsaString; HANDLE hLsa = NULL; DWORD dwTemp; ULONG AuthenticationPackage; TOKEN_SOURCE SourceContext; PVOID ProfileBuffer; ULONG ProfileBufferLength; HANDLE hNewUserToken = NULL; QUOTA_LIMITS Quotas; NTSTATUS SubStatus; PVOID pEnvironmentBlock = NULL; STARTUPINFOW si; PROCESS_INFORMATION pi; BOOL bImpersonated = FALSE; HDESK hDesktop = NULL; HDESK hOldDesktop = NULL; HWINSTA hWinSta = NULL; HWINSTA hOldWinSta = NULL; #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "WTSGetActiveConsoleSessionId() = %d. iDestinationSession = %d. cmd = <%ls>\n" , WTSGetActiveConsoleSessionId( ) , iDestinationSession , lpCommandLine ); #endif if ( !WTSQueryUserToken( WTSGetActiveConsoleSessionId( ) , &hOriginalUserToken ) ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "WTSQueryUserToken fails.\n" ); #endif goto end; } if ( !ObtainSid( hOriginalUserToken , &SourceUserSid ) ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "GetLogonSID fails.\n" ); #endif goto end; } if ( !AllocateLocallyUniqueId( &LogonLuid ) ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "AllocateLocallyUniqueId fails.\n" ); #endif goto end; } #define TOKEN_GROUP_COUNT 3 PTokenGroups = (PTOKEN_GROUPS)HeapAlloc( GetProcessHeap( ) , 0 , sizeof(TOKEN_GROUPS) + TOKEN_GROUP_COUNT * sizeof(SID_AND_ATTRIBUTES)); if ( !PTokenGroups ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "HeapAlloc fails.\n" ); #endif goto end; } if ( !AllocateAndInitializeSid( &IdentifierAuthority , 3 , SECURITY_LOGON_IDS_RID , LogonLuid.HighPart , LogonLuid.LowPart , 0 , 0 , 0 , 0 , 0 , &LogonSid ) ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "AllocateAndInitializeSid fails.\n" ); #endif goto end; } if ( !AllocateAndInitializeSid( &IdentifierAuthority , 1 , SECURITY_LOCAL_RID , 0 , 0 , 0 , 0 , 0 , 0 , 0 , &LocalSid ) ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "AllocateAndInitializeSid fails.\n" ); #endif goto end; } PTokenGroups->GroupCount = TOKEN_GROUP_COUNT; PTokenGroups->Groups[0].Sid = LogonSid; PTokenGroups->Groups[0].Attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_LOGON_ID; PTokenGroups->Groups[1].Sid = LocalSid; PTokenGroups->Groups[1].Attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT; PTokenGroups->Groups[2].Sid = SourceUserSid; PTokenGroups->Groups[2].Attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT; cbUserName = (USHORT)(lstrlenW(lpUserName) * sizeof(WCHAR)); cbDomain = (USHORT)(lstrlenW(lpDomain) * sizeof(WCHAR)); cbPassword = (USHORT)(lstrlenW(lpUserPass) * sizeof(WCHAR)); AuthInfoSize = sizeof(MSV1_0_INTERACTIVE_LOGON) + cbUserName + sizeof(WCHAR) + cbDomain + sizeof(WCHAR) + cbPassword + sizeof(WCHAR); AuthInfoBuf = HeapAlloc( GetProcessHeap() , HEAP_ZERO_MEMORY , AuthInfoSize ); if ( !AuthInfoBuf ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "HeapAlloc fails.\n" ); #endif goto end; } pMsvAuthInfo = (PMSV1_0_INTERACTIVE_LOGON)AuthInfoBuf; pMsvAuthInfo->MessageType = MsV1_0InteractiveLogon; pMsvAuthInfo->UserName.Length = cbUserName; pMsvAuthInfo->UserName.MaximumLength = cbUserName + sizeof(WCHAR); pMsvAuthInfo->UserName.Buffer = (PWSTR)(pMsvAuthInfo + 1); lstrcpyW(pMsvAuthInfo->UserName.Buffer, lpUserName); pMsvAuthInfo->LogonDomainName.Length = cbDomain; pMsvAuthInfo->LogonDomainName.MaximumLength = cbDomain + sizeof(WCHAR); pMsvAuthInfo->LogonDomainName.Buffer = (PWSTR)((PBYTE)(pMsvAuthInfo->UserName.Buffer) + pMsvAuthInfo->UserName.MaximumLength); lstrcpyW(pMsvAuthInfo->LogonDomainName.Buffer, lpDomain); pMsvAuthInfo->Password.Length = cbPassword; pMsvAuthInfo->Password.MaximumLength = cbPassword + sizeof(WCHAR); pMsvAuthInfo->Password.Buffer = (PWSTR)((PBYTE)(pMsvAuthInfo->LogonDomainName.Buffer) + pMsvAuthInfo->LogonDomainName.MaximumLength); lstrcpyW(pMsvAuthInfo->Password.Buffer, lpUserPass); LsaString.Buffer = "User32LogonProcess"; LsaString.Length = lstrlenA( LsaString.Buffer ); LsaString.MaximumLength = LsaString.Length + 1; if ( LsaRegisterLogonProcess( &LsaString , &hLsa , &dwTemp ) ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "LsaRegisterLogonProcess fails.\n" ); #endif goto end; } LsaString.Buffer = "MICROSOFT_AUTHENTICATION_PACKAGE_V1_0"; LsaString.Length = lstrlenA( LsaString.Buffer ); LsaString.MaximumLength = LsaString.Length + 1; if ( LsaLookupAuthenticationPackage( hLsa , &LsaString , &AuthenticationPackage ) ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "LsaLookupAuthenticationPackage fails.\n" ); #endif goto end; } LsaString.Buffer = "TTY1"; LsaString.Length = lstrlenA( LsaString.Buffer ); LsaString.MaximumLength = LsaString.Length + 1; lstrcpyA( SourceContext.SourceName , "Source" ); if ( !AllocateLocallyUniqueId( &SourceContext.SourceIdentifier ) ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "AllocateLocallyUniqueId fails.\n" ); #endif goto end; } if ( LsaLogonUser( hLsa , &LsaString , Interactive , AuthenticationPackage , AuthInfoBuf , AuthInfoSize , PTokenGroups , &SourceContext , &ProfileBuffer , &ProfileBufferLength , &LogonId , &hNewUserToken , &Quotas , &SubStatus ) ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "LsaLogonUser fails.\n" ); #endif goto end; } if ( !DuplicateTokenEx( hOriginalUserToken , TOKEN_WRITE | TOKEN_ADJUST_SESSIONID | TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_IMPERSONATE , NULL , SecurityAnonymous , TokenPrimary , &hNewSessionUserToken ) ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "DuplicateHandleEx fails.\n" ); #endif goto end; } if ( !SetTokenInformation( hNewSessionUserToken , TokenSessionId , (LPVOID)&iDestinationSession , sizeof(iDestinationSession) ) ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "SetTokenInformation fails.\n" ); #endif goto end; } if ( !CreateEnvironmentBlock( &pEnvironmentBlock , hNewSessionUserToken , FALSE ) ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "CreateEnvironmentBlock fails.\n" ); #endif goto end; } hOldWinSta = GetProcessWindowStation( ); hOldDesktop = GetThreadDesktop( GetCurrentThreadId( ) ); hWinSta = OpenWindowStation( _T("WinSta0") , FALSE , MAXIMUM_ALLOWED ); if ( !hWinSta ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "OpenWindowStation fails.\n" ); #endif goto end; } if ( !SetProcessWindowStation( hWinSta ) ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "SetProcessWindowStation fails.\n" ); #endif goto end; } hDesktop = OpenDesktop( _T("Default") , 0 , FALSE , MAXIMUM_ALLOWED ); if ( !hDesktop ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "OpenDesktop fails.\n" ); #endif goto end; } if ( !SetThreadDesktop( hDesktop ) ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "SetThreadDesktop fails.\n" ); #endif goto end; } if ( !AddTheAceWindowStation( hWinSta , SourceUserSid ) ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "AddTheAceWindowStation fails.\n" ); #endif goto end; } if ( !AddTheAceDesktop( hDesktop , SourceUserSid ) ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "AddTheAceDesktop fails.\n" ); #endif goto end; } if ( !ImpersonateLoggedOnUser( hNewSessionUserToken ) ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "ImpersonateLoggedOnUser fails.\n" ); #endif goto end; } bImpersonated = TRUE; SecureZeroMemory( &si , sizeof( si ) ); si.cb = sizeof( si ); si.lpDesktop = L"WinSta0\\Default"; if ( !CreateProcessAsUserW( hNewSessionUserToken , NULL , lpCommandLine , NULL , NULL , FALSE , CREATE_UNICODE_ENVIRONMENT , pEnvironmentBlock , NULL , &si , &pi ) ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "CreateProcessAsUserW fails.\n" ); #endif goto end; } CloseHandle( pi.hProcess ); CloseHandle( pi.hThread ); rv = TRUE; end: if ( bImpersonated ) RevertToSelf( ); if ( SourceUserSid != NULL ) HeapFree( GetProcessHeap( ) , 0 , SourceUserSid ); if ( PTokenGroups != NULL ) HeapFree( GetProcessHeap( ) , 0 , PTokenGroups ); if ( LogonSid != NULL ) FreeSid( LogonSid ); if ( LocalSid != NULL ) FreeSid( LocalSid ); if ( AuthInfoBuf != NULL ) HeapFree( GetProcessHeap( ) , 0 , AuthInfoBuf ); if ( hLsa != NULL ) LsaDeregisterLogonProcess( hLsa ); if ( pEnvironmentBlock != NULL ) DestroyEnvironmentBlock( pEnvironmentBlock ); if ( hNewUserToken != NULL ) CloseHandle( hNewUserToken ); if ( hOriginalUserToken != NULL ) CloseHandle( hOriginalUserToken ); if ( hNewSessionUserToken != NULL ) CloseHandle( hNewSessionUserToken ); if ( hDesktop != NULL ) CloseDesktop( hDesktop ); if ( hWinSta != NULL ) CloseWindowStation( hWinSta ); if ( hOldDesktop != NULL ) SetThreadDesktop( hOldDesktop ); if ( hOldWinSta != NULL ) SetProcessWindowStation( hOldWinSta ); return rv; }
Нашел причину. В исходном коде что я привел, LsaLogonUser вообще юзать не нужно, вместо этого нужно создать токен через NtCreateToken с группами пользователя 1 и 2. И тогда на новом токене уже создавать процесс. (Никакие SetThreadDesktop и AddTheAceWindowStation тогда тоже не нужны). Надеюсь скоро освободиться от работы и чиркнуть статью по этому поводу(на тему: наши друзья токены), думаю многим будет интересно.
Так видно все таки я еще что то упустил. Работают все процессы кроме iexplore.exe.(то есть калькулятор,блокнот, обычный експлорер(приятно сидеть в рабочей среде другого пользователя), опера и остальные браузеры и программы). Вернее iexplorer тоже работает но его дочерний процесс сразу завершаеться(в итоге висит только родительский, но он то ничего не рисует, кроме диалого: восстановить предыдущую сессию) Вот код, все равно я потом его намерен как и саму утилиту выложить в сорцы\статью, так что скрывать нечего. Кто знает посмотрите, что я упустил.(6 Експлорер работает, не работает только 8 на 7 еще не тестил) Код (Text): BOOL ExecuteProcessInSession( WCHAR* lpCommandLine , ULONG iSourceSession , ULONG iDestinationSession ) { HANDLE hSourceSessionUserHandle = NULL; HANDLE hDestinationSessionUserHandle = NULL; HANDLE hNewUsersToken = NULL; PSID DestinationSessionUserSid = NULL; PSID SourceSessionUserSid = NULL; PSID NewUsersSid = NULL; NTSTATUS ntStatus; SECURITY_QUALITY_OF_SERVICE sqos = { sizeof sqos , SecurityAnonymous , SECURITY_STATIC_TRACKING , FALSE }; OBJECT_ATTRIBUTES oa = { sizeof oa , 0 , 0 , 0 , 0 , &sqos }; LUID authid = SYSTEM_LUID; LUID luid; PTOKEN_STATISTICS pTokenStatistics = NULL; PTOKEN_GROUPS pTokenGroups = NULL; PTOKEN_PRIVILEGES pTokenPrivileges = NULL; PTOKEN_OWNER pTokenOwner = NULL; PTOKEN_PRIMARY_GROUP pTokenPrimaryGroup = NULL; PTOKEN_DEFAULT_DACL pTokenDefaultDacl = NULL; TOKEN_SOURCE source; TOKEN_USER TokenUser; BOOL bImpersonated = FALSE; TCHAR UserName[MAX_PATH]; DWORD dwSizeofUserName; PVOID pEnvironmentBlock = NULL; STARTUPINFOW si; PROCESS_INFORMATION pi; BOOL rv = FALSE; /*HDESK hDesktop = NULL; HDESK hOldDesktop = NULL; HWINSTA hWinSta = NULL; HWINSTA hOldWinSta = NULL;*/ if ( !WTSQueryUserToken ( iSourceSession , &hSourceSessionUserHandle ) ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "WTSQueryUserToken(iSourceSession) fails.\n" ); #endif goto end; } if ( !ImpersonateLoggedOnUser( hSourceSessionUserHandle ) ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "ImpersonateLoggedOnUser fails.\n" ); #endif goto end; } bImpersonated = TRUE; dwSizeofUserName = sizeof( UserName ); if ( !GetUserName( UserName , &dwSizeofUserName ) ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "GetUserName fails.\n" ); #endif goto end; } RevertToSelf( ); bImpersonated = FALSE; SourceSessionUserSid = Name2SID( UserName , NULL ); if ( !SourceSessionUserSid ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "Name2SID fails.\n" ); #endif goto end; } if ( !WTSQueryUserToken ( iDestinationSession , &hDestinationSessionUserHandle ) ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "WTSQueryUserToken(iDestinationSession) fails.\n" ); #endif goto end; } if ( !ObtainSid( hDestinationSessionUserHandle , &DestinationSessionUserSid ) ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "ObtainSid fails.\n" ); #endif goto end; } if ( !AllocateLocallyUniqueId( &luid ) ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "Name2SID fails.\n" ); #endif goto end; } pTokenStatistics = PTOKEN_STATISTICS( GetFromToken( hSourceSessionUserHandle , TokenStatistics ) ); if ( !pTokenStatistics ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "GetFromToken(TokenStatistics) fails.\n" ); #endif goto end; } pTokenGroups = PTOKEN_GROUPS( GetFromToken( hSourceSessionUserHandle , TokenGroups ) ); if ( !pTokenGroups ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "GetFromToken(TokenGroups) fails.\n" ); #endif goto end; } { PTOKEN_GROUPS pTempTokenGroups = (PTOKEN_GROUPS)HeapAlloc( GetProcessHeap( ) , 0 , sizeof(TOKEN_GROUPS) + ( pTokenGroups->GroupCount + 1 ) * sizeof( SID_AND_ATTRIBUTES ) ); if ( pTempTokenGroups == NULL ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "HeapAlloc fails.\n" ); #endif goto end; } pTempTokenGroups->GroupCount = pTokenGroups->GroupCount + 1 ; for ( ULONG i = 0 ; i < pTokenGroups->GroupCount ; i++ ) { pTempTokenGroups->Groups[i].Attributes = pTokenGroups->Groups[i].Attributes; pTempTokenGroups->Groups[i].Sid = pTokenGroups->Groups[i].Sid; } pTempTokenGroups->Groups[pTempTokenGroups->GroupCount - 1].Sid = DestinationSessionUserSid; pTempTokenGroups->Groups[pTempTokenGroups->GroupCount - 1].Attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT; HeapFree( GetProcessHeap( ) , 0 , pTokenGroups ); pTokenGroups = pTempTokenGroups; } pTokenPrivileges = PTOKEN_PRIVILEGES( GetFromToken( hSourceSessionUserHandle , TokenPrivileges ) ); if ( !pTokenPrivileges ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "GetFromToken(TokenPrivileges) fails.\n" ); #endif goto end; } pTokenOwner = NULL; pTokenPrimaryGroup = PTOKEN_PRIMARY_GROUP( GetFromToken( hSourceSessionUserHandle , TokenPrimaryGroup ) ); if ( !pTokenPrimaryGroup ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "GetFromToken(TokenPrimaryGroup) fails.\n" ); #endif goto end; } pTokenDefaultDacl = NULL; RtlCopyMemory( source.SourceName , "*SYSTEM*" , 8 ); source.SourceIdentifier.LowPart = luid.LowPart; source.SourceIdentifier.HighPart = luid.HighPart; TokenUser.User.Sid = SourceSessionUserSid; TokenUser.User.Attributes = 0; ntStatus = NtCreateToken( &hNewUsersToken , TOKEN_ALL_ACCESS , &oa , TokenPrimary , PLUID( &authid ) , PLARGE_INTEGER( &pTokenStatistics->ExpirationTime ) , &TokenUser , pTokenGroups , pTokenPrivileges , pTokenOwner , pTokenPrimaryGroup , pTokenDefaultDacl , &source ); if ( ntStatus ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "NtCreateToken fails with status 0x%X.\n" , ntStatus ); #endif goto end; } if ( !SetTokenInformation( hNewUsersToken , TokenSessionId , (LPVOID)&iDestinationSession , sizeof(iDestinationSession) ) ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "SetTokenInformation fails.\n" ); #endif goto end; } if ( !CreateEnvironmentBlock( &pEnvironmentBlock , hSourceSessionUserHandle , FALSE ) ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "CreateEnvironmentBlock fails.\n" ); #endif goto end; } SecureZeroMemory( &si , sizeof( si ) ); si.cb = sizeof( si ); si.lpDesktop = L"WinSta0\\Default"; /* if ( !ObtainSid( hSourceSessionUserHandle , &NewUsersSid ) )//change hSourceSessionUserHandle != NewUsersSid { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "ObtainSid fails.\n" ); #endif goto end; } hOldWinSta = GetProcessWindowStation( ); hOldDesktop = GetThreadDesktop( GetCurrentThreadId( ) ); hWinSta = OpenWindowStation( _T("WinSta0") , FALSE , MAXIMUM_ALLOWED ); if ( !hWinSta ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "OpenWindowStation fails.\n" ); #endif goto end; } if ( !SetProcessWindowStation( hWinSta ) ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "SetProcessWindowStation fails.\n" ); #endif goto end; } hDesktop = OpenDesktop( _T("Default") , 0 , FALSE , MAXIMUM_ALLOWED ); if ( !hDesktop ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "OpenDesktop fails.\n" ); #endif goto end; } if ( !SetThreadDesktop( hDesktop ) ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "SetThreadDesktop fails.\n" ); #endif goto end; } if ( !AddTheAceWindowStation( hWinSta , NewUsersSid ) ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "AddTheAceWindowStation fails.\n" ); #endif goto end; } if ( !AddTheAceDesktop( hDesktop , NewUsersSid ) ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "AddTheAceDesktop fails.\n" ); #endif goto end; } if ( !ImpersonateLoggedOnUser( hDestinationSessionUserHandle ) ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "ImpersonateLoggedOnUser fails.\n" ); #endif goto end; } bImpersonated = TRUE; */ if ( !CreateProcessAsUserW( hNewUsersToken , NULL , lpCommandLine , NULL , NULL , FALSE , CREATE_UNICODE_ENVIRONMENT + CREATE_NEW_PROCESS_GROUP , pEnvironmentBlock , NULL , &si , &pi ) ) { #ifdef _DEBUG DbgMsg( __FILE__ , __LINE__ , "CreateProcessAsUserW fails.\n" ); #endif goto end; } rv = TRUE; CloseHandle( pi.hProcess ); CloseHandle( pi.hThread ); end: if ( bImpersonated ) RevertToSelf( ); if ( hSourceSessionUserHandle ) CloseHandle( hSourceSessionUserHandle ); if ( hDestinationSessionUserHandle ) CloseHandle( hDestinationSessionUserHandle ); if ( hNewUsersToken ) CloseHandle( hNewUsersToken ); if ( DestinationSessionUserSid != NULL ) HeapFree( GetProcessHeap( ) , 0 , DestinationSessionUserSid ); if ( SourceSessionUserSid != NULL ) LocalFree( SourceSessionUserSid ); if ( pTokenStatistics ) HeapFree( GetProcessHeap( ) , 0 , pTokenStatistics ); if ( pTokenGroups ) HeapFree( GetProcessHeap( ) , 0 , pTokenGroups ); if ( pTokenPrivileges ) HeapFree( GetProcessHeap( ) , 0 , pTokenPrivileges ); if ( pTokenOwner ) HeapFree( GetProcessHeap( ) , 0 , pTokenOwner ); if ( pTokenPrimaryGroup ) HeapFree( GetProcessHeap( ) , 0 , pTokenPrimaryGroup ); if ( pTokenDefaultDacl ) HeapFree( GetProcessHeap( ) , 0 , pTokenDefaultDacl ); if ( pEnvironmentBlock != NULL ) DestroyEnvironmentBlock( pEnvironmentBlock ); /*if ( hDesktop != NULL ) CloseDesktop( hDesktop ); if ( hWinSta != NULL ) CloseWindowStation( hWinSta ); if ( hOldDesktop != NULL ) SetThreadDesktop( hOldDesktop ); if ( hOldWinSta != NULL ) SetProcessWindowStation( hOldWinSta );*/ return rv; }
ОФФТОП: вот это просто жуть: сделай как-нить так: Код (Text): // в хедере каком-нить #ifdef _DEBUG #define DBGMSG(String) DbgMsg( __FILE__ , __LINE__ , String "\n" ) #else #define DBGMSG(String) #endif // вызов из кода: DBGMSG("CreateProcessAsUserW fails."); культура кода так сказать)))
если ие7 работает нормально нужно копать в сторону protected mode введенного в ие8. там 2ой процесс запускается хитро(это все начиная с висты, опять же, на сколько помню), не могу найти ссылку, попадется - скину. п.с нашел, вроде это: http://www.microsoft.com/whdc/system/vista/process_Vista.mspx
Rel спасибо, так и сделаю. freyr На Хп такая же ерунда, а там нет protected mode. Всем спасибо, решил сделать дедовским методом через простое копирование токена и изменения сессии. Заказ увы ждать не может.