MI_Result WriteServerURLToCache(
    _In_ RegistrationManager* self,
    _In_z_ MI_Char* serverURL,
    _In_z_ MI_Char* thumbprint,
    _Outptr_result_maybenull_ MI_Instance **cimErrorDetails)
{
    size_t dwSize;
    int retValue;
    MI_Result result = MI_RESULT_OK;

    if (cimErrorDetails)
    {
        *cimErrorDetails = NULL;
    }

    if (self->serverURLs == NULL)
    {
        result = InitializeServerURLs(self, cimErrorDetails);
        EH_CheckResult(result);
    }
    
    dwSize = Tcslen(serverURL) + 1;
    self->serverURLs[self->numberOfServerURLs] = (MI_Char*)DSC_malloc(dwSize* sizeof(MI_Char), NitsHere());
    if (self->serverURLs[self->numberOfServerURLs] == NULL)
    {
        EH_Fail_(GetCimMIError(MI_RESULT_SERVER_LIMITS_EXCEEDED, cimErrorDetails, ID_LCMHELPER_MEMORY_ERROR));
    }
    retValue = Stprintf(self->serverURLs[self->numberOfServerURLs], dwSize, MI_T("%T"), serverURL);
    if (retValue == -1 || NitsShouldFault(NitsHere(), NitsAutomatic))
    {
        DSC_free(self->serverURLs[self->numberOfServerURLs]);
        EH_Fail_(GetCimMIError(MI_RESULT_FAILED, cimErrorDetails, ID_LCMHELPER_PRINTF_ERROR));
    }

    dwSize = Tcslen(thumbprint) + 1;
    self->serverCertificateThumbprints[self->numberOfServerURLs] = (MI_Char*)DSC_malloc(dwSize* sizeof(MI_Char), NitsHere());
    if (self->serverCertificateThumbprints[self->numberOfServerURLs] == NULL)
    {
        EH_Fail_(GetCimMIError(MI_RESULT_SERVER_LIMITS_EXCEEDED, cimErrorDetails, ID_LCMHELPER_MEMORY_ERROR));
    }
    retValue = Stprintf(self->serverCertificateThumbprints[self->numberOfServerURLs], dwSize, MI_T("%T"), thumbprint);
    if (retValue == -1 || NitsShouldFault(NitsHere(), NitsAutomatic))
    {
        DSC_free(self->serverCertificateThumbprints[self->numberOfServerURLs]);
        EH_Fail_(GetCimMIError(MI_RESULT_FAILED, cimErrorDetails, ID_LCMHELPER_PRINTF_ERROR));
    }

    self->numberOfServerURLs++;

    EH_UNWIND:

        return result;
}
Exemplo n.º 2
0
Shlib* Shlib_Open_Injected(
    _In_z_ const PAL_Char* path,
    NitsCallSite cs)
{
    if (NitsShouldFault(cs, NitsAutomatic))
    {
#if defined(_MSC_VER)
        /* Caller may call Shlib_Err(). */
        SetLastError(ERROR_OUTOFMEMORY);
#endif
        return NULL;
    }

    if(path == NULL)
        return NULL;
    
#if defined(_MSC_VER)
    return (Shlib*)LoadLibraryEx(path, NULL, 0);
#else
    const char *temp = NULL;

#if defined(CONFIG_ENABLE_WCHAR)
    char buffer[PAL_MAX_PATH_SIZE];
    StrWcslcpy(buffer, path, PAL_MAX_PATH_SIZE);
    temp = buffer;
#else
    temp = path;
#endif

    return (Shlib*)dlopen(temp, PAL_DLOPEN_FLAGS);
#endif
}
Exemplo n.º 3
0
MI_Result ValidateInfrastructureSchema(_In_ MI_ClassA *miClassArray, 
                                       _Outptr_result_maybenull_ MI_Instance **extendedError )
{
    MI_Result r = MI_RESULT_OK;
    MI_Uint32 xCount = 0, yCount = 0;
    if( extendedError )
        *extendedError = NULL;
    SetJobId();
    DSC_EventWriteValidatingInfrastructureSchema(miClassArray->size);
    //Validate various infrastructure classes
    for( xCount = 0 ; xCount < miClassArray->size ; xCount++)
    {
        for (yCount = 0; g_InfraSchemaValidators[yCount].wszClassName != NULL; yCount++)
        {
            if( Tcscasecmp(miClassArray->data[xCount]->classDecl->name, g_InfraSchemaValidators[yCount].wszClassName) == 0 )
            {
                break;
            }
        }

        if( g_InfraSchemaValidators[yCount].wszClassName == NULL || NitsShouldFault(NitsHere(), NitsAutomatic))
        {
            return GetCimMIError(MI_RESULT_INVALID_PARAMETER, extendedError, ID_MODMAN_VALIDATE_INFRASCHEMA); 
        }

        r = g_InfraSchemaValidators[yCount].Validator(miClassArray->data[xCount], extendedError);
        if( r != MI_RESULT_OK)
        {
            return r; 
        }
    }
    return r;
}
MI_Result GetThumbprintForRegisteredServerURL(
    _In_ RegistrationManager* self,
    _In_ MI_Instance* registrationData,
    _Outptr_result_maybenull_z_ MI_Char** thumbprint,
    _Outptr_result_maybenull_ MI_Instance **cimErrorDetails)
{
    size_t dwSize;
    MI_Value value;
    int retValue;
    MI_Uint32 i = 0;
    MI_Result result = MI_RESULT_OK;

    if (cimErrorDetails)
    {
        *cimErrorDetails = NULL;
    }

    *thumbprint = 0;

    if (self->serverURLs == NULL)
    {
        InitializeServerURLs(self, cimErrorDetails);
    }

    if (self->serverURLs != NULL)
    {
        result = MI_Instance_GetElement(registrationData, MSFT_ServerURL_Name, &value, NULL, NULL, NULL);
        EH_CheckResult(result);

        for (i = 0; i < self->numberOfServerURLs; i++)
        {
            if (self->serverURLs[i] != NULL && Tcscasecmp(self->serverURLs[i], value.string) == 0)
            {
                dwSize = Tcslen(self->serverCertificateThumbprints[i]) + 1;
                *thumbprint = (MI_Char*)DSC_malloc(dwSize*sizeof(MI_Char), NitsHere());
                if (*thumbprint == NULL)
                {
                    EH_Fail_(GetCimMIError(MI_RESULT_SERVER_LIMITS_EXCEEDED, cimErrorDetails, ID_LCMHELPER_MEMORY_ERROR));
                }

                retValue = Stprintf(*thumbprint, dwSize, MI_T("%T"), self->serverCertificateThumbprints[i]);
                if (retValue == -1 || NitsShouldFault(NitsHere(), NitsAutomatic))
                {
                    DSC_free(*thumbprint);
                    EH_Fail_(GetCimMIError(MI_RESULT_FAILED, cimErrorDetails, ID_LCMHELPER_PRINTF_ERROR));
                }

                result = MI_RESULT_OK;
                break;
            }
        }
    }

EH_UNWIND:

    return result;
}
Exemplo n.º 5
0
_Return_type_success_(return == 0) int CachedLock_Init_Checked(
    _Out_ CachedLock* self,
    unsigned long flags,
    NitsCallSite cs
)
{
    CachedLock_Pool* pool;
    int index;
    ReadWriteLock temp = READWRITELOCK_INITIALIZER;

    /* One-time initialization. Doesn't matter if called several times. */
    if (s_cpuMask == CPU_MASK_UNINITIALIZED)
        InitializeCachePool();

    if (flags & CACHEDLOCK_FLAG_SHARED)
    {
        Lock_Acquire(&s_latchPoolLock);

        if (NitsShouldFault(cs, NitsAutomatic))
            return -1;

        if (s_currentPool == NULL ||
            s_currentPool->mask == POOL_FULL_MASK)
        {
            /* The current pool is full. */
            s_currentPool = Pool_New();
            if (s_currentPool == NULL)
                return -1;
        }

        /* Search the pool for a zero bit. */
        pool = s_currentPool;
        for (index = 0; index < POOL_LINES; index++)
            if ((pool->mask & ((ptrdiff_t)1 << index)) == 0)
                break;

        /* Take ownership of this index. */
        pool->mask |= ((ptrdiff_t)1 << index);
        Lock_Release(&s_latchPoolLock);
    }
    else
    {
        pool = Pool_New();
        if (pool == NULL)
            return -1;
        pool->mask = 1;
        index = 0;
    }

    self->pool = pool;
    self->latches = pool->latches + index;
    self->lock = temp;
    self->master = 0;

    return 0;
}
Exemplo n.º 6
0
static NitsResult NITS_CALL ShouldFault_Checked(
    NitsCallSite line,
    NitsFaultMode mode)
{
    NitsCallSite reservedCallsite = NitsReservedCallSite();
    if(line.id == reservedCallsite.id)
    {
        return NitsFalse;    
    }
    
    CheckInjector();

    return NitsShouldFault(line, mode);
}
MI_Result GetRegisteredServerURLsFromCache(
    _Outptr_result_maybenull_z_ MI_Char** registeredServerURLs,
    _Outptr_result_maybenull_ MI_Instance **cimErrorDetails)
{
    MI_Value value;
    MI_Type  type;
    MI_Uint32 flags;
    size_t dwSize;
    int retValue;

    if (cimErrorDetails)
    {
        *cimErrorDetails = NULL;
    }

    memset(registeredServerURLs, 0, sizeof(MI_Char));

    if (g_DSCInternalCache)
    {
        if (DSC_MI_Instance_GetElement(g_DSCInternalCache, DSC_InternalStateCache_RegisteredServerURLs, &value, &type, &flags, NULL) == MI_RESULT_OK)
        {
            dwSize = Tcslen(value.string) + 1;
            *registeredServerURLs = (MI_Char*)DSC_malloc(dwSize*sizeof(MI_Char), NitsHere());
            if (*registeredServerURLs == NULL)
            {
                EH_Fail_(GetCimMIError(MI_RESULT_SERVER_LIMITS_EXCEEDED, cimErrorDetails, ID_LCMHELPER_MEMORY_ERROR));
            }
            memset(*registeredServerURLs, 0, dwSize);

            retValue = Stprintf(*registeredServerURLs, dwSize, MI_T("%T"), value.string);
            if (retValue == -1 || NitsShouldFault(NitsHere(), NitsAutomatic))
            {
                DSC_free(*registeredServerURLs);
                EH_Fail_(GetCimMIError(MI_RESULT_FAILED, cimErrorDetails, ID_LCMHELPER_PRINTF_ERROR));
            }
        }
    }

    EH_UNWIND:
        return MI_RESULT_OK;
}
MI_Result ResolvePath(_Outptr_opt_result_maybenull_z_ MI_Char **envResolvedPath,
                      _Outptr_opt_result_maybenull_z_ MI_Char **searchPath,
                      _In_z_ const MI_Char *envPath,
                      _In_z_ const MI_Char *searchPattern,
                      _Outptr_result_maybenull_ MI_Instance **extendedError)
{
    MI_Uint32 dwReturnSizeInitial = 0, dwReturnSize = (MI_Uint32) (Tcslen(envPath)+1);
    int result = 0;
    const MI_Char *pathToUse = envPath;

    if (extendedError == NULL)
    {
        return MI_RESULT_INVALID_PARAMETER;
    }
    *extendedError = NULL;  // Explicitly set *extendedError to NULL as _Outptr_ requires setting this at least once.

    if( searchPath)
    {
        *searchPath = NULL;
    }

    if( envResolvedPath != NULL )
    {
#if defined(_MSC_VER)
        dwReturnSizeInitial = ExpandEnvironmentStrings(envPath, NULL, 0);
#else
        dwReturnSizeInitial = Tcslen(envPath) + 1;
#endif

        *envResolvedPath = (MI_Char*)DSC_malloc(dwReturnSizeInitial* sizeof(MI_Char), NitsHere());
        if( *envResolvedPath == NULL)
        {
            return GetCimMIError(MI_RESULT_SERVER_LIMITS_EXCEEDED, extendedError, ID_LCMHELPER_MEMORY_ERROR);
        }

#if defined(_MSC_VER)
        dwReturnSize = ExpandEnvironmentStrings(envPath, *envResolvedPath, dwReturnSizeInitial);
        if( dwReturnSize == 0 || (dwReturnSize >  dwReturnSizeInitial ) || NitsShouldFault(NitsHere(), NitsAutomatic))
        {
            //memory error
            DSC_free(*envResolvedPath);
            *envResolvedPath = NULL;
            return GetCimMIError(MI_RESULT_SERVER_LIMITS_EXCEEDED, extendedError, ID_LCMHELPER_EXPANDENV_FAILED);
        }
#else
        memcpy(*envResolvedPath, envPath, dwReturnSizeInitial * sizeof(MI_Char));
#endif
        pathToUse = *envResolvedPath;
    }

    if( searchPath != NULL)
    {

        dwReturnSize += (MI_Uint32) (Tcslen(searchPattern) + 1);// %s\\%s

        /* Create Search Path*/
        *searchPath = (MI_Char*)DSC_malloc(dwReturnSize* sizeof(MI_Char), NitsHere()); // %s\\%s
        if( *searchPath == NULL)
        {
            if( envResolvedPath != NULL )
            {
                DSC_free(*envResolvedPath);
                *envResolvedPath = NULL;
            }
            return GetCimMIError(MI_RESULT_SERVER_LIMITS_EXCEEDED, extendedError, ID_LCMHELPER_MEMORY_ERROR);
        }
#if defined(_MSC_VER)
        result = Stprintf(*searchPath, dwReturnSize, MI_T("%T\\%T"), pathToUse, searchPattern);
#else
        result = Stprintf(*searchPath, dwReturnSize, MI_T("%T/%T"), pathToUse, searchPattern);
#endif

        if( result <= 0 || NitsShouldFault(NitsHere(), NitsAutomatic))
        {
            if( envResolvedPath != NULL )
            {
                DSC_free(*envResolvedPath);
                *envResolvedPath = NULL;
            }

            DSC_free(*searchPath);
            return GetCimMIError(MI_RESULT_FAILED, extendedError, ID_LCMHELPER_PRINTF_ERROR);
        }
    }
    return MI_RESULT_OK;
}
Exemplo n.º 9
0
MI_Result ValidateProviderRegistrationAgainstSchema(_In_ MI_ClassA *miClassArray,
                                                    _In_ MI_InstanceA *miRegistrationArray,
                                                    _Outptr_result_maybenull_ MI_Instance **extendedError)

{
    MI_Result r = MI_RESULT_OK;
    MI_Uint32 xCount=0 , yCount = 0;
    MI_Uint32 registrationFoundCount = 0, schemaFoundCount = 0;
    MI_Value value;

    if (extendedError == NULL)
    {        
        return MI_RESULT_INVALID_PARAMETER; 
    }
    *extendedError = NULL;  // Explicitly set *extendedError to NULL as _Outptr_ requires setting this at least once.   

    DSC_EventWriteValidatingProviderRegistration(miClassArray->size,miRegistrationArray->size);

    //Test1 : only 1 registration per class
    //Test2 : no class left out without registration(except for meta config), also validates that registration not targeting more than 1 class.
    //Test3: no registration instance left out without class
    //Test4 : no two classes with same name    

    for (xCount = 0 ; xCount < miClassArray->size ; xCount++)
    {
        if (miClassArray->data[xCount]->classDecl->superClass &&
            Tcscasecmp(miClassArray->data[xCount]->classDecl->superClass, BASE_RESOURCE_CLASSNAME) == 0)
        {
            schemaFoundCount++;
        }

        //Test4
        for (yCount = xCount + 1 ; yCount <  miClassArray->size ; yCount++)
        {
            if (Tcscasecmp(miClassArray->data[yCount]->classDecl->name, miClassArray->data[xCount]->classDecl->name) == 0  || NitsShouldFault(NitsHere(), NitsAutomatic))
            {
                return GetCimMIError(MI_RESULT_INVALID_PARAMETER, extendedError, ID_MODMAN_VALIDATE_PROVREG_MULTI);  
            }
        }
    }

    for (xCount = 0 ; xCount < miRegistrationArray->size ; xCount++)
    {
        for (yCount = 0 ; yCount < miClassArray->size ; yCount++)
        {
            if ((miClassArray->data[yCount]->classDecl->superClass &&
                 Tcscasecmp(miClassArray->data[yCount]->classDecl->superClass, BASE_RESOURCE_CLASSNAME) == 0) ||
                 Tcscasecmp(miClassArray->data[xCount]->classDecl->name, METACONFIG_CLASSNAME) == 0)
            {
                r = DSC_MI_Instance_GetElement(miRegistrationArray->data[xCount], MSFT_BaseConfigurationProviderRegistration_ClassName, 
                    &value, NULL, NULL, NULL); 
                if (r != MI_RESULT_OK )
                {
                    return GetCimMIError(r, extendedError, ID_MODMAN_VALIDATE_PROVREG_MANDATORY);
                }

                if (Tcscasecmp(value.string, miClassArray->data[yCount]->classDecl->name) == 0 )
                {
                    // Test1
                    registrationFoundCount++;
                    break;
                }
            }
        }

        // Test3
        if (yCount == miClassArray->size  || NitsShouldFault(NitsHere(), NitsAutomatic))
        {
            return GetCimMIError(MI_RESULT_INVALID_PARAMETER, extendedError, ID_MODMAN_VALIDATE_PROVREG_NOCLASS);    
        }
    }

    // Test2
    if (registrationFoundCount != schemaFoundCount  || NitsShouldFault(NitsHere(), NitsAutomatic))
    {
        return GetCimMIError(MI_RESULT_INVALID_PARAMETER, extendedError, ID_MODMAN_VALIDATE_PROVREG_NOREG);
    }

    return r;
}
MI_Result UpdateTask(
    _In_z_ MI_Char* taskName,
    _In_z_ MI_Char* taskTime,
    _In_ MI_Uint32 refreshFrequencyInSeconds,
    _Outptr_result_maybenull_ MI_Instance **extendedError)
{
    MI_Result r = MI_RESULT_OK;
    PROCESS_INFORMATION ProcInfo;
    STARTUPINFO si;
    HRESULT hr = S_OK;
    MI_Uint32 dwExitCode = 0;
    BOOL bRes = MI_TRUE;
    UINT retVal = 0;
    HANDLE hXmlFileHandle = NULL;
    BOOL bHandleUsageSuccess = FALSE;
    const char BOM [] = {0xFF, 0xFE};
    MI_Uint32 dwWmiMethodArg = 0;
    size_t sFormattedXMLFileLength = 0;

    // The task scheduler filename
    // This will double as the buffer for GetTempPath and for the command
    wchar_t wSchedTaskPath[MAX_PATH];
    wchar_t wTmpFilePath[MAX_PATH];
    wchar_t wSchedTaskFile[(sizeof(LocalConfigManagerTaskXMLFormatString)+sizeof(L"2013-04-11T18:10:48")+sizeof("2678400"))/sizeof(wchar_t)];
    wchar_t wSchedTaskParam[LCM_MAX_PATH];
    MI_Uint32 len = 0;

    LPWSTR wCommandFormat = NULL;

    if (extendedError == NULL)
    {
        return MI_RESULT_INVALID_PARAMETER;
    }
    *extendedError = NULL;  // Explicitly set *extendedError to NULL as _Outptr_ requires setting this at least once.

    wSchedTaskPath[0] = L'\0';
    wTmpFilePath[0] = L'\0';
    wSchedTaskFile[0] = L'\0';
    wSchedTaskParam[0] = L'\0';
    memset(&si,0,sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);
    si.dwFlags = STARTF_FORCEOFFFEEDBACK;

    if (refreshFrequencyInSeconds > THIRTY_ONE_DAYS_IN_SECONDS)
    {
        refreshFrequencyInSeconds = THIRTY_ONE_DAYS_IN_SECONDS;
    }
    if (refreshFrequencyInSeconds < FIFTEEN_MINUTES_IN_SECONDS)
    {
        refreshFrequencyInSeconds = THIRTY_ONE_DAYS_IN_SECONDS;
    }



    wCommandFormat = LocalConfigManagerTaskConsistencyCommand;
    dwWmiMethodArg = 1;

    retVal = GetTempPath(MAX_PATH, wSchedTaskPath);
    if (!retVal)
    {
        hr = E_FAIL;
        return GetCimError(hr, extendedError, ID_LCMHELPER_GETTEMPPATH_ERROR);
    }

    // 0 here signifies our willingness to let the system create and close the file for us
    // This means we cannot specify FILE_ATTRIBUTE_TEMPORARY to CreateFile
    // but in return we can be sure that nobody will take our filename in the microsecond before we use it
    retVal = GetTempFileName(wSchedTaskPath, L"LCM", 0u, wTmpFilePath);
    if (!retVal)
    {
        hr = E_FAIL;
        return GetCimError(hr, extendedError, ID_LCMHELPER_GETTEMPFILENAME_ERROR);
    }

    hr = StringCchPrintf(wSchedTaskParam, sizeof(wSchedTaskParam)/sizeof(wchar_t), wCommandFormat, wTmpFilePath);
    if (FAILED(hr) || NitsShouldFault(NitsHere(), NitsAutomatic))
    {
        if (SUCCEEDED(hr)) hr = E_FAIL;
        return GetCimError(hr, extendedError, ID_LCMHELPER_PRINTF_ERROR);
    }

    if (GetEnvironmentVariable(L"windir", wSchedTaskPath, MAX_PATH) ==0 )
    {
        return  GetCimWin32Error(GetLastError(), extendedError, ID_MODMAN_WINDIRENV_FAILED);
    }

    hr = StringCchCatW(wSchedTaskPath, MAX_PATH, L"\\system32\\schtasks.exe");
    if (FAILED(hr))
    {
        return GetCimError(hr, extendedError, ID_ENGINEHELPER_CAT_ERROR);
    }

    hr = StringCchPrintf(wSchedTaskFile, sizeof(wSchedTaskFile)/sizeof(wchar_t), LocalConfigManagerTaskXMLFormatString, refreshFrequencyInSeconds, taskTime, dwWmiMethodArg);
    if (FAILED(hr) || NitsShouldFault(NitsHere(), NitsAutomatic))
    {
        if( SUCCEEDED(hr)) hr = E_FAIL;
        return GetCimError(hr, extendedError, ID_LCMHELPER_PRINTF_ERROR);
    }

    hr = StringCchLength(wSchedTaskFile, STRSAFE_MAX_CCH, &sFormattedXMLFileLength);
    if (FAILED(hr) || NitsShouldFault(NitsHere(), NitsAutomatic))
    {
        if( SUCCEEDED(hr)) hr = E_FAIL;
        return GetCimError(hr, extendedError, ID_LCMHELPER_STRLEN_ERROR);
    }

    // We've done everything we can do ahead of time. Now we actually start changing the system

    hXmlFileHandle = CreateFile(wTmpFilePath, GENERIC_WRITE, 0 /* Prevent sharing */, NULL /* Children don't inherit */, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL /* No template */);
    if (hXmlFileHandle == INVALID_HANDLE_VALUE)
    {
        return GetCimWin32Error(GetLastError(), extendedError, ID_ENGINEHELPER_OPENFILE_ERROR);
    }

    bHandleUsageSuccess = WriteFile(hXmlFileHandle, BOM, sizeof(BOM), (LPDWORD)&len, NULL);
    if (!bHandleUsageSuccess)
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        CloseHandle(hXmlFileHandle);
        DeleteFile(wTmpFilePath);
        return GetCimError(hr, extendedError, ID_LCMHELPER_WRITEFILE_ERROR);
    }

    bHandleUsageSuccess = WriteFile(hXmlFileHandle, wSchedTaskFile, (DWORD)(sFormattedXMLFileLength*sizeof(wchar_t)), (LPDWORD)&len, NULL);
    if (!bHandleUsageSuccess)
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        CloseHandle(hXmlFileHandle);
        DeleteFile(wTmpFilePath);
        return GetCimError(hr, extendedError, ID_LCMHELPER_WRITEFILE_ERROR);
    }

    bHandleUsageSuccess = CloseHandle(hXmlFileHandle);
    if (!bHandleUsageSuccess)
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        DeleteFile(wTmpFilePath);
        return GetCimError(hr, extendedError, ID_LCMHELPER_CLOSEHANDLE_ERROR);
    }

    bRes = CreateProcess(wSchedTaskPath, wSchedTaskParam, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &ProcInfo);
    if (!bRes)
    {
        CloseHandle(hXmlFileHandle);
        DeleteFile(wTmpFilePath);
        return GetCimWin32Error(GetLastError(), extendedError, ID_ENGINEHELPER_CREATEPROCESS_ERROR);
    }

    WaitForSingleObject(ProcInfo.hProcess, INFINITE);
    if (GetExitCodeProcess(ProcInfo.hProcess,(LPDWORD)&dwExitCode) && dwExitCode != 0)
    {
        r = GetCimMIError(MI_RESULT_FAILED, extendedError, ID_ENGINEHELPER_CREATEPROCESS_ERROR);
    }

    bHandleUsageSuccess = DeleteFile(wTmpFilePath);
    if (!bHandleUsageSuccess && r == MI_RESULT_OK)
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        return GetCimError(hr, extendedError, ID_LCMHELPER_DELETEFILE_ERROR);
    }

    CloseHandle(ProcInfo.hThread);
    CloseHandle(ProcInfo.hProcess);

    return r;
}
MI_Result RegisterStartAtBootTask(
    _In_ MI_Boolean bregisterTask,
    _Outptr_result_maybenull_ MI_Instance **extendedError)
{
    MI_Result r = MI_RESULT_OK;
    PROCESS_INFORMATION ProcInfo;
    STARTUPINFO si;
    HRESULT hr = S_OK;
    MI_Uint32 dwExitCode = 0;
    BOOL bRes = MI_TRUE;
    wchar_t param[LCM_MAX_PATH] ;
    wchar_t wExe[LCM_MAX_PATH];
    DSC_EventWriteMessageScheduleTaskAfterReboot();

    if (extendedError == NULL)
    {
        return MI_RESULT_INVALID_PARAMETER;
    }
    *extendedError = NULL;  // Explicitly set *extendedError to NULL as _Outptr_ requires setting this at least once.

    wExe[0] = L'\0';
    param[0] = L'\0';
    memset(&si,0,sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);
    si.dwFlags = STARTF_FORCEOFFFEEDBACK;

    if (bregisterTask)
    {
        hr = StringCchPrintf(param, LCM_MAX_PATH, L" /Create /SC ONSTART /TN \"%s\" /RU System /F /TR \"PowerShell.exe -NonInt -Window Hidden -Command \'Invoke-CimMethod -Namespace root/Microsoft/Windows/DesiredStateConfiguration -ClassName MSFT_DSCLocalConfigurationManager -MethodName PerformRequiredConfigurationChecks -Arg @{Flags = [System.UInt32]2 }\'\"",
                             DSC_RESTART_BOOTUP_TASK);
    }
    else
    {
        hr = StringCchPrintf(param, LCM_MAX_PATH, L" /Delete /F /TN \"%s\" ", DSC_RESTART_BOOTUP_TASK);
    }


    if (FAILED(hr) || NitsShouldFault(NitsHere(), NitsAutomatic))
    {
        if (SUCCEEDED(hr)) hr = E_FAIL;
        return GetCimError(hr, extendedError, ID_LCMHELPER_PRINTF_ERROR);
    }
    if(GetEnvironmentVariable(L"windir", wExe, LCM_MAX_PATH) ==0 )
    {
        return  GetCimWin32Error(GetLastError(), extendedError, ID_MODMAN_WINDIRENV_FAILED);
    }
    hr = StringCchCatW(wExe, LCM_MAX_PATH, L"\\system32\\schtasks.exe");
    if( FAILED(hr))
    {
        return GetCimError(hr, extendedError, ID_ENGINEHELPER_CAT_ERROR);
    }

    bRes = CreateProcess(wExe, param,
                         NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &ProcInfo);
    if (!bRes)
    {
        return  GetCimWin32Error(GetLastError(), extendedError, ID_ENGINEHELPER_CREATEPROCESS_ERROR);
    }

    WaitForSingleObject( ProcInfo.hProcess, INFINITE);
    if (GetExitCodeProcess(ProcInfo.hProcess,(LPDWORD)&dwExitCode) && dwExitCode != 0)
    {
        r = GetCimMIError(MI_RESULT_FAILED, extendedError, ID_ENGINEHELPER_CREATEPROCESS_ERROR);
    }

    CloseHandle(ProcInfo.hThread);
    CloseHandle(ProcInfo.hProcess);

    return r;
}
MI_Result RepudicationHelper(
    _In_opt_ MI_Context* context,
    _In_ HANDLE token,
    _In_z_ const MI_Char* methodName,
    _Outptr_result_maybenull_ MI_Instance **cimErrorDetails)
{
    MI_Type type;
    MI_Value value;
    MI_Result result;
    size_t computerLength;
    DWORD sidLength;
    MI_Char* pComputerName=NULL;
    BOOL success = FALSE;
    PWSTR pstrUserSid = NULL;
    PTOKEN_USER userInformation = NULL;
    LCMProviderContext lcmContext = {0};

    if (context)
    {
        result = MI_Context_GetCustomOption(context,DSCCOMPUTERNAME, &type, &value);
        if (result == MI_RESULT_OK && type == MI_STRING)
        {
            computerLength = Tcslen(value.string)+1;
            pComputerName = (MI_Char*)DSC_malloc(computerLength* sizeof(wchar_t), NitsHere());
            if (pComputerName == NULL)
            {
                return GetCimMIError(MI_RESULT_SERVER_LIMITS_EXCEEDED, cimErrorDetails, ID_LCMHELPER_MEMORY_ERROR);
            }

            memcpy(pComputerName, value.string, computerLength * sizeof(wchar_t));
        }
    }

    GetTokenInformation(token, TokenUser, userInformation, 0, &sidLength);
    if (GetLastError() != ERROR_INSUFFICIENT_BUFFER || NitsShouldFault(NitsHere(), NitsAutomatic))
    {
        if (pComputerName != NULL)
        {
            DSC_free(pComputerName);
        }

        return GetCimMIError(MI_RESULT_FAILED, cimErrorDetails, ID_LCMHELPER_COMPUTERNAMECONTEXT_ERROR);
    }

    userInformation = (PTOKEN_USER)DSC_malloc(sidLength, NitsHere());
    if (userInformation == NULL)
    {
        if (pComputerName != NULL)
        {
            DSC_free(pComputerName);
        }

        return GetCimMIError(MI_RESULT_SERVER_LIMITS_EXCEEDED, cimErrorDetails, ID_LCMHELPER_MEMORY_ERROR);
    }

    success = GetTokenInformation(token, TokenUser, userInformation, sidLength, &sidLength);
    if (!success || NitsShouldFault(NitsHere(), NitsAutomatic))
    {
        if (pComputerName != NULL)
        {
            DSC_free(pComputerName);
        }

        DSC_free(userInformation);

        if (success)
        {
            // Pass through a bogus error if we've faulted in an error otherwise success will be returned.
            SetLastError(ERROR_ACCESS_DENIED);
        }
        return GetCimWin32Error(MI_RESULT_FAILED, cimErrorDetails, GetLastError());
    }

    success = ConvertSidToStringSidW(userInformation->User.Sid, &pstrUserSid);
    DSC_free(userInformation);
    if (!success || NitsShouldFault(NitsHere(), NitsAutomatic))
    {
        if (pComputerName != NULL)
        {
            DSC_free(pComputerName);
        }
        if (pstrUserSid != NULL)
        {
            LocalFree(pstrUserSid);
        }

        if (success)
        {
            // Pass through a bogus error if we've faulted in an error otherwise success will be returned.
            SetLastError(ERROR_ACCESS_DENIED);
        }
        return GetCimWin32Error(MI_RESULT_FAILED, cimErrorDetails, GetLastError());
    }

    lcmContext.executionMode = (LCM_EXECUTIONMODE_OFFLINE | LCM_EXECUTIONMODE_ONLINE);
    lcmContext.context = (void*)context;
    LCM_WriteMessageInfo(&lcmContext, pComputerName, MI_WRITEMESSAGE_CHANNEL_VERBOSE, pstrUserSid);
    LocalFree(pstrUserSid);
    if (pComputerName != NULL)
    {
        DSC_free(pComputerName);
    }

    return MI_RESULT_OK;
}