question

champixncynthia-2097 avatar image
0 Votes"
champixncynthia-2097 asked vvijayanlive published

C++ boot task schedule error: No Mapping between account names and security ids was done (0x80070534)

So pretty much I've been following this tutorial along (https://docs.microsoft.com/en-us/windows/win32/taskschd/boot-trigger-example--c---) to add notepad to load at boot using the task scheduler in C++.

The only issue is when I get to RegisterTaskDefinition(), the function fails with the error code 0x80070534 which translates as: "No mapping between account names and security ids was done."

I've read around that I have to replace the userId parameter with "S-1-5-32-544", but that didn't solve anything.
I'm quite lost on how to continue and I don't know where to look inside the code to fix the problem since it's a one-on-one copy of the one inside the tutorial.

The faulty bit:
Notice that DLL_DEBUG is a macro that translates to printf.

 //  Save the task in the root folder.
     IRegisteredTask *pRegisteredTask = NULL;
     VARIANT varPassword;
     varPassword.vt = VT_EMPTY;
     hr = pRootFolder->RegisterTaskDefinition(
             _bstr_t( wszTaskName ),
             pTask,
             TASK_CREATE_OR_UPDATE, 
             _variant_t(L"Local Service"), 
             varPassword, 
             TASK_LOGON_SERVICE_ACCOUNT,
             _variant_t(L""),
             &pRegisteredTask);
    
     if( FAILED(hr) )
     {
         DLL_DEBUG("\nError saving the Task : %x\n", hr );
         pRootFolder->Release();
         pTask->Release();
         CoUninitialize();
         return 1;
     }
        
     DLL_DEBUG("\n Success! Task successfully registered.\n" );

and the whole code, for good measure:

 bool ScheduleTask()
 {
    
     HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
     if( FAILED(hr) )
     {
         printf("\nCoInitializeEx failed: %x", hr );
         return 1;
     }
    
     //  Set general COM security levels.
     hr = CoInitializeSecurity(
         NULL,
         -1,
         NULL,
         NULL,
         RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
         RPC_C_IMP_LEVEL_IMPERSONATE,
         NULL,
         0,
         NULL);
    
     if( FAILED(hr) )
     {
         DLL_DEBUG("\nCoInitializeSecurity failed: %x", hr );
         CoUninitialize();
         return 1;
     }
    
     //  Create a name for the task.
     LPCWSTR wszTaskName = L"Boot Trigger Test Task";
    
     //  Get the Windows directory and set the path to Notepad.exe.
     wstring wstrExecutablePath = _wgetenv( L"WINDIR");
     wstrExecutablePath += L"\\SYSTEM32\\NOTEPAD.EXE";
    
     //  Create an instance of the Task Service. 
     ITaskService *pService = NULL;
     hr = CoCreateInstance( CLSID_TaskScheduler,
                            NULL,
                            CLSCTX_INPROC_SERVER,
                            IID_ITaskService,
                            (void**)&pService );  
     if (FAILED(hr))
     {
           DLL_DEBUG("Failed to create an instance of ITaskService: %x", hr);
           CoUninitialize();
           return 1;
     }
            
     //  Connect to the task service.
     hr = pService->Connect(_variant_t(), _variant_t(),
         _variant_t(), _variant_t());
     if( FAILED(hr) )
     {
         DLL_DEBUG("ITaskService::Connect failed: %x", hr );
         pService->Release();
         CoUninitialize();
         return 1;
     }
    
     //  Get the pointer to the root task folder.  
     //  This folder will hold the new task that is registered.
     ITaskFolder *pRootFolder = NULL;
     hr = pService->GetFolder( _bstr_t( L"\\") , &pRootFolder );
     if( FAILED(hr) )
     {
         DLL_DEBUG("Cannot get Root Folder pointer: %x", hr );
         pService->Release();
         CoUninitialize();
         return 1;
     }
        
     //  If the same task exists, remove it.
     pRootFolder->DeleteTask( _bstr_t( wszTaskName), 0  );
        
     //  Create the task builder object to create the task.
     ITaskDefinition *pTask = NULL;
     hr = pService->NewTask( 0, &pTask );
    
     pService->Release();  // COM clean up.  Pointer is no longer used.
     if (FAILED(hr))
     {
           DLL_DEBUG("Failed to create a task definition: %x", hr);
           pRootFolder->Release();
           CoUninitialize();
           return 1;
     }
    
     //  Get the registration info for setting the identification.
     IRegistrationInfo *pRegInfo= NULL;
     hr = pTask->get_RegistrationInfo( &pRegInfo );
     if( FAILED(hr) )
     {
         DLL_DEBUG("\nCannot get identification pointer: %x", hr );
         pRootFolder->Release();
         pTask->Release();
         CoUninitialize();
         return 1;
     }
        
     hr = pRegInfo->put_Author(L"Vladimir Putin");
     pRegInfo->Release();
     if( FAILED(hr) )
     {
         DLL_DEBUG("\nCannot put identification info: %x", hr );
         pRootFolder->Release();
         pTask->Release();
         CoUninitialize();
         return 1;
     }
    
      //  Create the settings for the task
     ITaskSettings *pSettings = NULL;
     hr = pTask->get_Settings( &pSettings );
     if( FAILED(hr) )
     {
         DLL_DEBUG("\nCannot get settings pointer: %x", hr );
         pRootFolder->Release();
         pTask->Release();
         CoUninitialize();
         return 1;
     }
        
     //  Set setting values for the task. 
     hr = pSettings->put_StartWhenAvailable(VARIANT_TRUE);
     pSettings->Release();
     if( FAILED(hr) )
     {
         DLL_DEBUG("\nCannot put setting info: %x", hr );
         pRootFolder->Release();
         pTask->Release();
         CoUninitialize();
         return 1;
     }
    
     //  Get the trigger collection to insert the boot trigger.
     ITriggerCollection *pTriggerCollection = NULL;
     hr = pTask->get_Triggers( &pTriggerCollection );
     if( FAILED(hr) )
     {
         DLL_DEBUG("\nCannot get trigger collection: %x", hr );
         pRootFolder->Release();
         pTask->Release();
         CoUninitialize();
         return 1;
     }
    
     ITrigger *pTrigger = NULL;
     hr = pTriggerCollection->Create( TASK_TRIGGER_BOOT, &pTrigger ); 
     pTriggerCollection->Release();
     if( FAILED(hr) )
     {
         DLL_DEBUG("\nCannot create the trigger: %x", hr );
         pRootFolder->Release();
         pTask->Release();
         CoUninitialize();
         return 1;
     }
        
     IBootTrigger *pBootTrigger = NULL;
     hr = pTrigger->QueryInterface( 
         IID_IBootTrigger, (void**) &pBootTrigger );
     pTrigger->Release();
     if( FAILED(hr) )
     {
         DLL_DEBUG("\nQueryInterface call failed for IBootTrigger: %x", hr );
         pRootFolder->Release();
         pTask->Release();
         CoUninitialize();
         return 1;
     }
    
     hr = pBootTrigger->put_Id( _bstr_t( L"Trigger1" ) );
     if( FAILED(hr) )
        DLL_DEBUG("\nCannot put the trigger ID: %x", hr);
        
     //  Set the task to start at a certain time. The time 
     //  format should be YYYY-MM-DDTHH:MM:SS(+-)(timezone).
     //  For example, the start boundary below
     //  is January 1st 2005 at 12:05
     hr = pBootTrigger->put_StartBoundary( _bstr_t(L"2021-01-01T12:05:00") );
     if( FAILED(hr) )
        DLL_DEBUG("\nCannot put the start boundary: %x", hr);
      
     hr = pBootTrigger->put_EndBoundary( _bstr_t(L"2099-05-02T08:00:00") );
     if( FAILED(hr) )
        DLL_DEBUG("\nCannot put the end boundary: %x", hr);
    
     // Delay the task to start 30 seconds after system start. 
     hr = pBootTrigger->put_Delay( L"PT30S" );
     pBootTrigger->Release();
     if( FAILED(hr) )
     {
         DLL_DEBUG("\nCannot put delay for boot trigger: %x", hr );
         pRootFolder->Release();
         pTask->Release();
         CoUninitialize();
         return 1;
     } 
    
     //  Add an Action to the task. This task will execute Notepad.exe.     
     IActionCollection *pActionCollection = NULL;
    
     //  Get the task action collection pointer.
     hr = pTask->get_Actions( &pActionCollection );
     if( FAILED(hr) )
     {
         DLL_DEBUG("\nCannot get Task collection pointer: %x", hr );
         pRootFolder->Release();
         pTask->Release();
         CoUninitialize();
         return 1;
     }
            
     //  Create the action, specifying it as an executable action.
     IAction *pAction = NULL;
     hr = pActionCollection->Create( TASK_ACTION_EXEC, &pAction );
     pActionCollection->Release();
     if( FAILED(hr) )
     {
         DLL_DEBUG("\nCannot create the action: %x", hr );
         pRootFolder->Release();
         pTask->Release();
         CoUninitialize();
         return 1;
     }
    
     IExecAction *pExecAction = NULL;
     //  QI for the executable task pointer.
     hr = pAction->QueryInterface( 
         IID_IExecAction, (void**) &pExecAction );
     pAction->Release();
     if( FAILED(hr) )
     {
         DLL_DEBUG("\nQueryInterface call failed for IExecAction: %x", hr );
         pRootFolder->Release();
         pTask->Release();
         CoUninitialize();
         return 1;
     }
    
     //  Set the path of the executable to Notepad.exe.
     hr = pExecAction->put_Path( _bstr_t( wstrExecutablePath ) );
     pExecAction->Release(); 
     if( FAILED(hr) )
     {
         DLL_DEBUG("\nCannot set path of executable: %x", hr );
         pRootFolder->Release();
         pTask->Release();
         CoUninitialize();
         return 1;
     }
    
     //  Save the task in the root folder.
     //  The error happens here!!!
    
     IRegisteredTask *pRegisteredTask = NULL;
     VARIANT varPassword;
     varPassword.vt = VT_EMPTY;
     hr = pRootFolder->RegisterTaskDefinition(
             _bstr_t( wszTaskName ),
             pTask,
             TASK_CREATE_OR_UPDATE, 
             _variant_t(L"Local Service"), 
             varPassword, 
             TASK_LOGON_SERVICE_ACCOUNT,
             _variant_t(L""),
             &pRegisteredTask);
    
     if( FAILED(hr) )
     {
         DLL_DEBUG("\nError saving the Task : %x\n", hr );
         pRootFolder->Release();
         pTask->Release();
         CoUninitialize();
         return 1;
     }
        
     DLL_DEBUG("\n Success! Task successfully registered.\n" );
    
     //  Clean up.
     pRootFolder->Release();
     pTask->Release();
     pRegisteredTask->Release();
     CoUninitialize();
     return 0;
 }

windows-apic++
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

MotoX80 avatar image
0 Votes"
MotoX80 answered

I would suggest that you might want to describe the overall problem that you are trying to solve.

Writing a C++ program to schedule a task would not be my first choice. Even if you found a solution to the account mapping problem, running notepad at boot time will not accomplish anything. It is a GUI program that expects to interact with a user. But scheduling the program like this will cause it to run in a non-interactive session. The only way that you would know that is is executing would be to look in task manager.

I assume that you are trying to launch notepad just as an example. Does the real program that you want to run expect to interact with the desktop user? Are you trying to run a program more or less like a Windows service? There are other options.

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Castorix31 avatar image
0 Votes"
Castorix31 answered vvijayanlive published

It works for me, as Admin (Manifest), by replacing this line :

 hr = pRootFolder->RegisterTaskDefinition(
     _bstr_t(wszTaskName), pTask, TASK_CREATE_OR_UPDATE,
     _variant_t(), _variant_t(), TASK_LOGON_INTERACTIVE_TOKEN,
     _variant_t(L""), &pRegisteredTask);
· 3
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

That might create the task, but I don't think it will run. If the user is INTERACTIVE, then the task trigger will need to be "at user logon", not "at system startup". That kind of falls back to my question of: what are you really trying to accomplish?

0 Votes 0 ·

I did not test with INTERACTIVE (I had just tested that the Task was added),
but I tested by keeping SERVICE_ACCOUNT and Notepad is correctly launched after I rebooted (it is in the process list, but it does not have GUI, which is normal...) :=>

 SID sid;
 WELL_KNOWN_SID_TYPE eSidId;
 DWORD dwBytes = sizeof(sid);
 eSidId = WinLocalServiceSid;
 WCHAR* pStringSID = NULL;

 _variant_t vUser;
 CreateWellKnownSid(eSidId, NULL, &sid, &dwBytes);
 ConvertSidToStringSid(&sid, &pStringSID);
 vUser = (BSTR)pStringSID;
 // pStringSID = L"S-1-5-19"
 hr = pRootFolder->RegisterTaskDefinition(
 _bstr_t(wszTaskName),
 pTask,
 TASK_CREATE_OR_UPDATE,
 vUser,
 _variant_t(),
 TASK_LOGON_SERVICE_ACCOUNT,
 _variant_t(L""),
 &pRegisteredTask);

1 Vote 1 ·

Perfect, it just works for me!

0 Votes 0 ·