00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 #include "stdafx.h"
00078
00079 #if ( NTDDI_VERSION < NTDDI_LONGHORN )
00080 # error NTDDI_VERSION must be defined as NTDDI_LONGHORN or later
00081 #endif
00082
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00099
00100
00101
00102 #ifndef _tsizeof
00103 # define _tsizeof( s ) (sizeof(s)/sizeof(s[0]))
00104 #endif//_tsizeof
00105
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119 BOOL IsVista();
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133 #ifndef WIN64
00134
00135 BOOL
00136 IsWow64();
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153 #endif//WIN64
00154
00155
00156 HRESULT GetElevationType( TOKEN_ELEVATION_TYPE * ptet );
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185 HRESULT
00186 IsElevated( _opt BOOL * pbElevated = NULL );
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214 BOOL
00215 RunElevated(
00216 __in HWND hwnd,
00217 __in LPCTSTR pszPath,
00218 __in_opt LPCTSTR pszParameters = NULL,
00219 __in_opt LPCTSTR pszDirectory = NULL );
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252 #ifndef DONTWANT_RunNonElevated
00253
00254 #ifdef NO_DLL_IMPORTS
00255 # error RunNonElevated must be used in a DLL project!
00256 #endif//NO_DLL_IMPORTS
00257
00258
00259 BOOL
00260 RunNonElevated(
00261 __in HWND hwnd,
00262 __in LPCTSTR pszPath,
00263 __in_opt LPCTSTR pszParameters = NULL,
00264 __in_opt LPCTSTR pszDirectory = NULL );
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298 #endif //DONTWANT_RunNonElevated
00299
00301 #ifdef WANT_RunAsStdUser
00302
00303 #include <comdef.h>
00304 #include <taskschd.h>
00305
00306 BOOL
00307 RunAsStdUser(
00308 __in HWND hwnd,
00309 __in LPCTSTR pszPath,
00310 __in_opt LPCTSTR pszParameters = NULL,
00311 __in_opt LPCTSTR pszDirectory = NULL );
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360 #endif // WANT_RunAsStdUser
00362
00363
00365
00366
00367
00368 BOOL
00369 MyShellExec( HWND hwnd,
00370 LPCTSTR pszVerb,
00371 LPCTSTR pszPath,
00372 LPCTSTR pszParameters = NULL,
00373 LPCTSTR pszDirectory = NULL );
00374
00375
00376 #ifdef IMPLEMENT_VISTA_TOOLS
00377
00379
00380
00381
00382 BOOL
00383 MyShellExec( HWND hwnd,
00384 LPCTSTR pszVerb,
00385 LPCTSTR pszPath,
00386 LPCTSTR pszParameters,
00387 LPCTSTR pszDirectory )
00388 {
00389 SHELLEXECUTEINFO shex;
00390
00391 memset( &shex, 0, sizeof( shex) );
00392
00393 shex.cbSize = sizeof( SHELLEXECUTEINFO );
00394 shex.fMask = 0;
00395 shex.hwnd = hwnd;
00396 shex.lpVerb = pszVerb;
00397 shex.lpFile = pszPath;
00398 shex.lpParameters = pszParameters;
00399 shex.lpDirectory = pszDirectory;
00400 shex.nShow = SW_NORMAL;
00401
00402 return ::ShellExecuteEx( &shex );
00403 }
00404
00405 BOOL IsVista()
00406 {
00407 OSVERSIONINFO osver;
00408
00409 osver.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
00410
00411 if ( ::GetVersionEx( &osver ) &&
00412 osver.dwPlatformId == VER_PLATFORM_WIN32_NT &&
00413 (osver.dwMajorVersion >= 6 ) )
00414 return TRUE;
00415
00416 return FALSE;
00417 }
00418
00419 #ifndef WIN64 // we need this when compiling 32-bit code only
00420
00421 typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE hProcess,PBOOL Wow64Process);
00422
00423 LPFN_ISWOW64PROCESS fnIsWow64Process =
00424 (LPFN_ISWOW64PROCESS)::GetProcAddress( ::GetModuleHandle(_T("kernel32")),"IsWow64Process");
00425
00426 BOOL
00427 IsWow64()
00428 {
00429 BOOL bIsWow64 = FALSE;
00430
00431 if (NULL != fnIsWow64Process)
00432 {
00433 if ( !fnIsWow64Process( ::GetCurrentProcess(),&bIsWow64) )
00434 {
00435 ASSERT_HERE;
00436 }
00437 }
00438
00439 return bIsWow64;
00440 }
00441
00442 #endif//WIN64
00443
00444 HRESULT
00445 GetElevationType( TOKEN_ELEVATION_TYPE * ptet )
00446 {
00447 ASSERT( IsVista() );
00448 ASSERT( ptet );
00449
00450 HRESULT hResult = E_FAIL;
00451 HANDLE hToken = NULL;
00452
00453 if ( !::OpenProcessToken(
00454 ::GetCurrentProcess(),
00455 TOKEN_QUERY,
00456 &hToken ) )
00457 {
00458 ASSERT_HERE;
00459 return hResult;
00460 }
00461
00462 DWORD dwReturnLength = 0;
00463
00464 if ( !::GetTokenInformation(
00465 hToken,
00466 TokenElevationType,
00467 ptet,
00468 sizeof( *ptet ),
00469 &dwReturnLength ) )
00470 {
00471 ASSERT_HERE;
00472 }
00473 else
00474 {
00475 ASSERT( dwReturnLength == sizeof( *ptet ) );
00476 hResult = S_OK;
00477 }
00478
00479 ::CloseHandle( hToken );
00480
00481 return hResult;
00482 }
00483
00484 HRESULT
00485 IsElevated( _opt BOOL * pbElevated )
00486 {
00487 ASSERT( IsVista() );
00488
00489 HRESULT hResult = E_FAIL;
00490 HANDLE hToken = NULL;
00491
00492 if ( !::OpenProcessToken(
00493 ::GetCurrentProcess(),
00494 TOKEN_QUERY,
00495 &hToken ) )
00496 {
00497 ASSERT_HERE;
00498 return hResult;
00499 }
00500
00501 TOKEN_ELEVATION te = { 0 };
00502 DWORD dwReturnLength = 0;
00503
00504 if ( !::GetTokenInformation(
00505 hToken,
00506 TokenElevation,
00507 &te,
00508 sizeof( te ),
00509 &dwReturnLength ) )
00510 {
00511 ASSERT_HERE;
00512 }
00513 else
00514 {
00515 ASSERT( dwReturnLength == sizeof( te ) );
00516
00517 hResult = te.TokenIsElevated ? S_OK : S_FALSE;
00518
00519 if ( pbElevated)
00520 *pbElevated = (te.TokenIsElevated != 0);
00521 }
00522
00523 ::CloseHandle( hToken );
00524
00525 return hResult;
00526 }
00527
00529
00530
00531
00532 BOOL
00533 RunElevated(
00534 __in HWND hwnd,
00535 __in LPCTSTR pszPath,
00536 __in_opt LPCTSTR pszParameters,
00537 __in_opt LPCTSTR pszDirectory )
00538 {
00539 return MyShellExec( hwnd, _T("runas"), pszPath, pszParameters, pszDirectory );
00540 }
00541
00542 #ifndef DONTWANT_RunNonElevated
00544 // RunNonElevated() implementation
00545
00547
00548
00549
00550 #pragma section( "ve_shared", read, write, shared )
00551
00552 __declspec(allocate("ve_shared"))
00553 HHOOK hHook = NULL;
00554
00555 __declspec(allocate("ve_shared"))
00556 UINT uVistaElevatorMsg = 0;
00557
00558 __declspec(allocate("ve_shared"))
00559 BOOL bSuccess = FALSE;
00560
00561 __declspec(allocate("ve_shared"))
00562 TCHAR szVE_Path[ MAX_PATH ] = _T("");
00563
00564 __declspec(allocate("ve_shared"))
00565 TCHAR szVE_Parameters[ MAX_PATH ] = _T("");
00566
00567 __declspec(allocate("ve_shared"))
00568 TCHAR szVE_Directory[ MAX_PATH ] = _T("");
00569
00571
00572
00573 LRESULT CALLBACK
00574 VistaEelevator_HookProc_MsgRet( int code, WPARAM wParam, LPARAM lParam )
00575 {
00576 if ( code >= 0 && lParam )
00577 {
00578 CWPRETSTRUCT * pwrs = (CWPRETSTRUCT *)lParam;
00579
00580 if (pwrs->message == uVistaElevatorMsg )
00581 {
00582 bSuccess = ::MyShellExec(
00583 pwrs->hwnd,
00584 NULL,
00585 szVE_Path,
00586 szVE_Parameters,
00587 szVE_Directory );
00588 }
00589 }
00590
00591 return ::CallNextHookEx( hHook, code, wParam, lParam );
00592 }
00593
00594 BOOL
00595 RunNonElevated(
00596 __in HWND hwnd,
00597 __in LPCTSTR pszPath,
00598 __in_opt LPCTSTR pszParameters,
00599 __in_opt LPCTSTR pszDirectory )
00600 {
00601 ASSERT( pszPath && *pszPath );
00602
00603 ASSERT( IsVista() );
00604 ASSERT( pszPath );
00605
00606 if ( S_FALSE == IsElevated() )
00607 {
00608
00609
00610 return MyShellExec( hwnd,
00611 NULL,
00612 pszPath,
00613 pszParameters,
00614 pszDirectory );
00615 }
00616
00617 #ifndef WIN64
00618
00619
00620
00621
00622 if ( IsWow64() )
00623 {
00624 ASSERT_HERE;
00625 return FALSE;
00626 }
00627
00628 #endif//WIN64
00629
00630
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00648
00649
00650 if ( !uVistaElevatorMsg )
00651 uVistaElevatorMsg = ::RegisterWindowMessage( _T("VistaElevatorMsg") );
00652
00654
00655
00656 HWND hwndShell = ::FindWindow( _T("Progman"), NULL);
00657
00658 if ( !hwndShell )
00659 {
00660 ASSERT_HERE;
00661 return FALSE;
00662 }
00663
00665
00666
00667 HMODULE hModule = NULL;
00668
00669 if ( !::GetModuleHandleEx(
00670 GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
00671 (LPCTSTR)VistaEelevator_HookProc_MsgRet,
00672 &hModule ) )
00673 {
00674 ASSERT_HERE;
00675 return FALSE;
00676 }
00677
00678 ASSERT( hModule );
00679
00680 hHook = ::SetWindowsHookEx( WH_CALLWNDPROCRET,
00681 (HOOKPROC)VistaEelevator_HookProc_MsgRet, hModule, 0);
00682
00683 if ( !hHook )
00684 {
00685 ASSERT_HERE;
00686 return FALSE;
00687 }
00688
00690
00691
00692
00693 if ( FAILED( StringCchCopy(
00694 szVE_Path,
00695 _tsizeof(szVE_Path),
00696 pszPath ) ) )
00697 {
00698 ASSERT_HERE;
00699 return FALSE;
00700 }
00701
00702 if ( FAILED( StringCchCopy(
00703 szVE_Parameters,
00704 _tsizeof(szVE_Parameters),
00705 pszParameters ? pszParameters : _T("") ) ) )
00706 {
00707 ASSERT_HERE;
00708 return FALSE;
00709 }
00710
00711 if ( FAILED( StringCchCopy(
00712 szVE_Directory,
00713 _tsizeof(szVE_Directory),
00714 pszDirectory ? pszDirectory : _T("") ) ) )
00715 {
00716 ASSERT_HERE;
00717 return FALSE;
00718 }
00719
00721
00722
00723 bSuccess = FALSE;
00724
00725 ::SendMessage( hwndShell, uVistaElevatorMsg, 0, 0 );
00726
00728
00729
00731
00732
00733 ::UnhookWindowsHookEx( hHook );
00734 hHook = NULL;
00735
00737
00738
00739 return bSuccess;
00740 }
00741 #endif //DONTWANT_RunNonElevated
00742
00744 #ifdef WANT_RunAsStdUser
00745
00746 # pragma comment(lib, "taskschd.lib")
00747 # pragma comment(lib, "comsupp.lib")
00748 # pragma comment(lib, "credui.lib")
00749
00751
00752
00753
00754
00755
00756 class ITaskServiceHelper
00757 {
00758 public:
00759 ITaskServiceHelper() { p = NULL; }
00760 ~ITaskServiceHelper() { if ( p ) p->Release(); }
00761
00762 ITaskService * p;
00763 };
00764
00765 class ITaskFolderHelper
00766 {
00767 public:
00768 ITaskFolderHelper() { p = NULL; }
00769 ~ITaskFolderHelper() { if ( p ) p->Release(); }
00770
00771 ITaskFolder * p;
00772 };
00773
00774 class ITaskDefinitionHelper
00775 {
00776 public:
00777 ITaskDefinitionHelper() { p = NULL; }
00778 ~ITaskDefinitionHelper() { if ( p ) p->Release(); }
00779
00780 ITaskDefinition * p;
00781 };
00782
00783 class IRegistrationInfoHelper
00784 {
00785 public:
00786 IRegistrationInfoHelper() { p = NULL; }
00787 ~IRegistrationInfoHelper() { if ( p ) p->Release(); }
00788
00789 IRegistrationInfo * p;
00790 };
00791
00792 class IPrincipalHelper
00793 {
00794 public:
00795 IPrincipalHelper() { p = NULL; }
00796 ~IPrincipalHelper() { if ( p ) p->Release(); }
00797
00798 IPrincipal * p;
00799 };
00800
00801 class ITaskSettingsHelper
00802 {
00803 public:
00804 ITaskSettingsHelper() { p = NULL; }
00805 ~ITaskSettingsHelper() { if ( p ) p->Release(); }
00806
00807 ITaskSettings * p;
00808 };
00809
00810 class ITriggerCollectionHelper
00811 {
00812 public:
00813 ITriggerCollectionHelper() { p = NULL; }
00814 ~ITriggerCollectionHelper() { if ( p ) p->Release(); }
00815
00816 ITriggerCollection * p;
00817 };
00818
00819 class ITriggerHelper
00820 {
00821 public:
00822 ITriggerHelper() { p = NULL; }
00823 ~ITriggerHelper() { if ( p ) p->Release(); }
00824
00825 ITrigger * p;
00826 };
00827
00828 class IRegistrationTriggerHelper
00829 {
00830 public:
00831 IRegistrationTriggerHelper(){ p = NULL; }
00832 ~IRegistrationTriggerHelper(){ if ( p ) p->Release(); }
00833
00834 IRegistrationTrigger * p;
00835 };
00836
00837 class IActionCollectionHelper
00838 {
00839 public:
00840 IActionCollectionHelper() { p = NULL; }
00841 ~IActionCollectionHelper() { if ( p ) p->Release(); }
00842
00843 IActionCollection * p;
00844 };
00845
00846 class IActionHelper
00847 {
00848 public:
00849 IActionHelper() { p = NULL; }
00850 ~IActionHelper() { if ( p ) p->Release(); }
00851
00852 IAction * p;
00853 };
00854
00855 class IExecActionHelper
00856 {
00857 public:
00858 IExecActionHelper() { p = NULL; }
00859 ~IExecActionHelper() { if ( p ) p->Release(); }
00860
00861 IExecAction * p;
00862 };
00863
00864 class IRegisteredTaskHelper
00865 {
00866 public:
00867 IRegisteredTaskHelper() { p = NULL; }
00868 ~IRegisteredTaskHelper() { if ( p ) p->Release(); }
00869
00870 IRegisteredTask * p;
00871 };
00872
00874
00875
00876
00877
00878 #define DO( action ) \
00879 if( FAILED( action ) ) \
00880 { \
00881 ASSERT_HERE; \
00882 return FALSE; \
00883 }
00884
00886
00887
00888 BOOL
00889 RunAsStdUser(
00890 __in HWND hwnd,
00891 __in LPCTSTR pszPath,
00892 __in_opt LPCTSTR pszParameters,
00893 __in_opt LPCTSTR pszDirectory )
00894 {
00895 ASSERT( IsVista() );
00896 ASSERT( pszPath );
00897
00898 if ( S_FALSE == IsElevated() )
00899 {
00900
00901
00902 return MyShellExec( hwnd,
00903 NULL,
00904 pszPath,
00905 pszParameters,
00906 pszDirectory );
00907 }
00908
00909
00910
00911
00912
00913
00914 HRESULT hr = 0;
00915
00916
00917
00918 LPCWSTR pszTaskName = L"RunAsStdUser Task";
00919
00920
00921
00922 ITaskServiceHelper iService;
00923
00924 DO( hr = CoCreateInstance( CLSID_TaskScheduler,
00925 NULL,
00926 CLSCTX_INPROC_SERVER,
00927 IID_ITaskService,
00928 (void**)&iService.p ) )
00929
00930
00931 DO( iService.p->Connect( _variant_t(), _variant_t(), _variant_t(), _variant_t()) )
00932
00933
00934
00935
00936 ITaskFolderHelper iRootFolder;
00937
00938 DO( iService.p->GetFolder( _bstr_t( L"\\") , &iRootFolder.p ) )
00939
00940
00941 iRootFolder.p->DeleteTask( _bstr_t( pszTaskName), 0 );
00942
00943
00944
00945 ITaskDefinitionHelper iTask;
00946
00947 DO( iService.p->NewTask( 0, &iTask.p ) )
00948
00949
00950
00951 IRegistrationInfoHelper iRegInfo;
00952
00953 DO( iTask.p->get_RegistrationInfo( &iRegInfo.p ) )
00954
00955 DO( iRegInfo.p->put_Author( L"RunAsStdUser" ) )
00956
00957
00958
00959 IPrincipalHelper iPrincipal;
00960
00961 DO( iTask.p->get_Principal( &iPrincipal.p ) )
00962
00963
00964 DO( iPrincipal.p->put_Id( _bstr_t(L"RunAsStdUser_Principal") ) )
00965
00966 DO( iPrincipal.p->put_LogonType( TASK_LOGON_INTERACTIVE_TOKEN ) )
00967
00968
00969 DO( iPrincipal.p->put_RunLevel( TASK_RUNLEVEL_LUA ) )
00970
00971
00972
00973 ITaskSettingsHelper iSettings;
00974
00975 DO( iTask.p->get_Settings( &iSettings.p ) )
00976
00977
00978 DO( iSettings.p->put_StartWhenAvailable(VARIANT_BOOL(true)) )
00979
00980
00981
00982 ITriggerCollectionHelper iTriggerCollection;
00983
00984 DO( iTask.p->get_Triggers( &iTriggerCollection.p ) )
00985
00986
00987
00988 ITriggerHelper iTrigger;
00989
00990 DO( iTriggerCollection.p->Create( TASK_TRIGGER_REGISTRATION, &iTrigger.p ) )
00991
00992 IRegistrationTriggerHelper iRegistrationTrigger;
00993
00994 DO( iTrigger.p->QueryInterface(
00995 IID_IRegistrationTrigger, (void**) &iRegistrationTrigger.p ) )
00996
00997 DO( iRegistrationTrigger.p->put_Id( _bstr_t( L"RunAsStdUser_Trigger" ) ) )
00998
00999
01000 DO( iRegistrationTrigger.p->put_Delay( L"PT0S" ) )
01001
01002
01003
01004 IActionCollectionHelper iActionCollection;
01005
01006
01007 DO( iTask.p->get_Actions( &iActionCollection.p ) )
01008
01009
01010 IActionHelper iAction;
01011
01012 DO( iActionCollection.p->Create( TASK_ACTION_EXEC, &iAction.p ) )
01013
01014 IExecActionHelper iExecAction;
01015
01016
01017 DO( iAction.p->QueryInterface(
01018 IID_IExecAction, (void**) &iExecAction.p ) )
01019
01020
01021 DO( iExecAction.p->put_Path( _bstr_t( pszPath ) ) )
01022
01023 if( pszParameters )
01024 {
01025 DO( iExecAction.p->put_Arguments( _bstr_t( pszParameters ) ) )
01026 }
01027
01028 if( pszDirectory )
01029 {
01030 DO( iExecAction.p->put_WorkingDirectory( _bstr_t( pszDirectory ) ) )
01031 }
01032
01033
01034
01035 IRegisteredTaskHelper iRegisteredTask;
01036
01037 DO( iRootFolder.p->RegisterTaskDefinition(
01038 _bstr_t( pszTaskName ),
01039 iTask.p,
01040 TASK_CREATE_OR_UPDATE,
01041 _variant_t(),
01042 _variant_t(),
01043 TASK_LOGON_INTERACTIVE_TOKEN,
01044 _variant_t(L""),
01045 &iRegisteredTask.p) )
01046
01047 return TRUE;
01048 }
01049 #endif // WANT_RunAsStdUser
01051
01052 #endif// IMPLEMENT_VISTA_TOOLS