@@ -6,14 +6,17 @@ struct IUnknown;
66#include < taskschd.h>
77#include < comdef.h>
88#include < shellapi.h>
9+ #include < lmaccess.h>
10+ #include < lmapibuf.h>
11+ #include < LMErr.h>
912#define SECURITY_WIN32
1013#include < Security.h>
1114#pragma comment(lib, "taskschd.lib")
1215#pragma comment(lib, "shell32.lib")
1316#pragma comment(lib, "secur32.lib")
17+ #pragma comment(lib, "Netapi32.lib")
1418
1519#define APPNAME L ## " ElevatedNotepadExample"
16- #define DO_USERNAME_CHECK 1
1720
1821int MainAdmin (PWSTR pCmdLine, int nCmdShow);
1922
@@ -186,10 +189,41 @@ bool IsSameFile(const wchar_t* path1, const wchar_t* path2)
186189
187190}
188191
189- IRegisteredTask* GetThisTask ()
192+ _bstr_t GetComputerName ()
193+ {
194+ // computer names are 15 characters max
195+ const int MAXSIZE = 256 ;
196+ DWORD bufferSize = MAXSIZE;
197+ wchar_t buffer[MAXSIZE];
198+ BOOL okay = GetComputerNameW (buffer, &bufferSize);
199+ return buffer;
200+ }
201+
202+ _bstr_t GetUserName ()
203+ {
204+ // usernames are 64 characters max
205+ const int MAXSIZE = 256 ;
206+ DWORD bufferSize = MAXSIZE;
207+ wchar_t buffer[MAXSIZE];
208+ BOOL okay = GetUserNameW (buffer, &bufferSize);
209+ return buffer;
210+ }
211+
212+ _bstr_t GetSamName ()
213+ {
214+ // SAM name should be 80 characters max
215+ const int MAXSIZE = 256 ;
216+ DWORD bufferSize = MAXSIZE;
217+ wchar_t buffer[MAXSIZE];
218+ GetUserNameExW (NameSamCompatible, buffer, &bufferSize);
219+ return buffer;
220+ }
221+
222+ IRegisteredTask* GetThisTask (const _bstr_t &userName)
190223{
191224 HRESULT hr = 0 ;
192- IRegisteredTask* task = GetScheduledTask (APPNAME);
225+ _bstr_t taskName = APPNAME L" for " + userName;
226+ IRegisteredTask* task = GetScheduledTask (taskName);
193227 ITaskDefinition* taskDefinition = NULL ;
194228 IPrincipal* principal = NULL ;
195229 IActionCollection* actionCollection = NULL ;
@@ -201,6 +235,7 @@ IRegisteredTask* GetThisTask()
201235 wchar_t thisPath[MAX_PATH];
202236 ULONG bufferSize = MAX_PATH;
203237 _bstr_t userId;
238+ _bstr_t samName = GetComputerName () + " \\ " + userName;
204239 TASK_RUNLEVEL_TYPE runLevel;
205240 VARIANT_BOOL allowDemandStart;
206241 VARIANT_BOOL enabled;
@@ -234,10 +269,7 @@ IRegisteredTask* GetThisTask()
234269 hr = principal->get_RunLevel (&runLevel);
235270 hr = principal->get_UserId (userId.GetAddress ());
236271 if (runLevel != TASK_RUNLEVEL_HIGHEST) { goto failed; }
237- GetUserNameExW (NameSamCompatible, thisPath, &bufferSize);
238- #if DO_USERNAME_CHECK
239- if (0 != wcscmp (thisPath, userId.GetBSTR ())) { goto failed; }
240- #endif
272+ if (userId != samName) { goto failed; }
241273
242274 // verify settings
243275 hr = taskDefinition->get_Settings (&taskSettings);
@@ -277,7 +309,12 @@ IRegisteredTask* GetThisTask()
277309 return NULL ;
278310}
279311
280- bool CreateThisTask ()
312+ IRegisteredTask* GetThisTask ()
313+ {
314+ return GetThisTask (GetUserName ());
315+ }
316+
317+ bool CreateThisTask (const _bstr_t &userName)
281318{
282319 HRESULT hr;
283320 ITaskService* taskService = NULL ;
@@ -291,7 +328,8 @@ bool CreateThisTask()
291328 ITaskSettings* taskSettings = NULL ;
292329 _bstr_t path;
293330 wchar_t thisPath[MAX_PATH];
294- _bstr_t userId;
331+ _bstr_t userId = GetComputerName () + " \\ " + userName;
332+ _bstr_t taskName = APPNAME L" for " + userName;
295333 ULONG bufferSize = MAX_PATH;
296334
297335 if (!GetModuleFileNameW (NULL , thisPath, ARRAYSIZE (thisPath))) { goto failed; }
@@ -320,8 +358,6 @@ bool CreateThisTask()
320358 if (principal == NULL || !SUCCEEDED (hr)) { goto failed; }
321359 hr = principal->put_RunLevel (TASK_RUNLEVEL_HIGHEST);
322360 if (!SUCCEEDED (hr)) { goto failed; }
323- GetUserNameExW (NameSamCompatible, thisPath, &bufferSize);
324- userId = thisPath;
325361 hr = principal->put_UserId (userId.GetBSTR ());
326362 if (!SUCCEEDED (hr)) { goto failed; }
327363 hr = taskDefinition->put_Principal (principal);
@@ -348,7 +384,7 @@ bool CreateThisTask()
348384 if (!SUCCEEDED (hr)) { goto failed; }
349385 hr = taskDefinition->put_Settings (taskSettings);
350386 if (!SUCCEEDED (hr)) { goto failed; }
351- hr = rootFolder->RegisterTaskDefinition (_bstr_t (APPNAME ), taskDefinition, TASK_CREATE_OR_UPDATE, _variant_t (userId), _variant_t (), TASK_LOGON_INTERACTIVE_TOKEN, _variant_t (), ®isteredTask);
387+ hr = rootFolder->RegisterTaskDefinition (_bstr_t (taskName ), taskDefinition, TASK_CREATE_OR_UPDATE, _variant_t (userId), _variant_t (), TASK_LOGON_INTERACTIVE_TOKEN, _variant_t (), ®isteredTask);
352388 if (registeredTask == NULL || !SUCCEEDED (hr)) { goto failed; }
353389okay:
354390 SafeRelease (taskService);
@@ -374,6 +410,40 @@ bool CreateThisTask()
374410 return false ;
375411}
376412
413+ bool CreateThisTask ()
414+ {
415+ return CreateThisTask (GetUserName ());
416+ }
417+
418+ bool CreateThisTaskForAllUsers ()
419+ {
420+ bool success = true ;
421+ BYTE* buffer = NULL ;
422+ DWORD entriesRead, totalEntries;
423+ DWORD okay;
424+ okay = NetUserEnum (NULL , 2 , FILTER_NORMAL_ACCOUNT, &buffer, MAX_PREFERRED_LENGTH, &entriesRead, &totalEntries, NULL );
425+ if (okay == NERR_Success)
426+ {
427+ USER_INFO_2* userInfoArray = (USER_INFO_2*)buffer;
428+ for (int i = 0 ; i < entriesRead; i++)
429+ {
430+ USER_INFO_2& userInfo = userInfoArray[i];
431+ DWORD flags = userInfo.usri2_flags ;
432+ DWORD priv = userInfo.usri2_priv ;
433+
434+ bool isDisabled = flags & UF_ACCOUNTDISABLE;
435+ bool isGuest = priv == USER_PRIV_GUEST;
436+
437+ if (!isDisabled && !isGuest)
438+ {
439+ success &= CreateThisTask (userInfo.usri2_name );
440+ }
441+ }
442+ }
443+ NetApiBufferFree (buffer);
444+ return success;
445+ }
446+
377447bool RunTask (IRegisteredTask* task, LPCWSTR commandLine)
378448{
379449 HRESULT hr;
@@ -419,6 +489,6 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine
419489 RunElevated (pCmdLine, nCmdShow);
420490 return 0 ;
421491 }
422- CreateThisTask ();
492+ CreateThisTaskForAllUsers ();
423493 return MainAdmin (pCmdLine, nCmdShow);
424494}
0 commit comments