MI_Result AppendWMIError1Param( _Inout_ MI_Instance *cimErrorDetails, _In_z_ const MI_Char * pszFormat, _In_z_ const MI_Char * param1 ) { MI_Result r = MI_RESULT_OK; MI_Char *message = NULL; MI_Value value; r = DSC_MI_Instance_GetElement(cimErrorDetails, MSFT_WMIERROR_MESSAGE, &value, NULL, NULL, NULL); if( r == MI_RESULT_OK ) { size_t msgLen = Tcslen(value.string) + Tcslen(param1) + Tcslen(pszFormat) + 1; message = (MI_Char*) DSC_malloc(sizeof(MI_Char) *msgLen, NitsMakeCallSite(-3, NULL, NULL, 0)); if(message) { if( Stprintf(message, msgLen, pszFormat, value.string, param1)) { value.string = message; r = MI_Instance_SetElement(cimErrorDetails, MSFT_WMIERROR_MESSAGE, &value, MI_STRING, 0); } DSC_free(message); } } return r; }
//Logs the Whatif messages that arrive from the provider. void LogCAWhatIfMessage( _In_ void *provContext, _In_z_ const MI_Char *message) { if(message != NULL && provContext != NULL) { ProviderCallbackContext *providerContext = (ProviderCallbackContext *) provContext; LCMProviderContext *lcmContext = providerContext->lcmProviderContext; if((lcmContext->executionMode & LCM_EXECUTIONMODE_ONLINE) && lcmContext->context) { MI_Char *fullMessage = NULL; size_t msgLen; //The message arrived contains whatif : <actualmessage> , and we need to truncate it to the start of the actual message first. const MI_Char * truncatedMsg=(Tcslen(message)<WHATIFMESSAGE_STARTINDEX)?message:message+WHATIFMESSAGE_STARTINDEX; msgLen = Tcslen(truncatedMsg) + Tcslen(providerContext->resourceId) + Tcslen(EMPTY_STRING) +Tcslen(VERBOSE_FORMAT) + Tcslen(g_CAJobInformation.deviceName)+TOKENIZED_MESSAGE_PADDING; fullMessage = (MI_Char*) DSC_malloc(sizeof(MI_Char)*msgLen, NitsHere()); if( fullMessage) { //Full message looks like "What if: [PS3319275115]: [[WindowsFeature]x] Continue with removal?" if(Stprintf(fullMessage, msgLen,VERBOSE_FORMAT , g_CAJobInformation.deviceName, EMPTY_STRING, providerContext->resourceId, truncatedMsg) > 0 ) { MI_Boolean flag; //Changed it from should process to prompt user since shouldprocess is being done within the provider. Here we just output the message. MI_Context_PromptUser((MI_Context*) lcmContext->context,fullMessage, MI_PROMPTTYPE_NORMAL,&flag); } DSC_free(fullMessage); } } } }
void LogCAWarningMessage(_In_ void *provContext,_In_opt_z_ const MI_Char *message) { MI_Result result = MI_RESULT_OK; if(message != NULL && provContext != NULL) { ProviderCallbackContext *providerContext = (ProviderCallbackContext *) provContext; LCMProviderContext *lcmContext = providerContext->lcmProviderContext; if((lcmContext->executionMode & LCM_EXECUTIONMODE_ONLINE) && lcmContext->context) { MI_Char *fullMessage = NULL; size_t msgLen; msgLen = Tcslen(message) + Tcslen(providerContext->resourceId) + Tcslen(VERBOSE_FORMAT)+Tcslen(EMPTY_STRING)+Tcslen(g_CAJobInformation.deviceName)+TOKENIZED_MESSAGE_PADDING; //DeviceName: LCM: \t \t [Package]SQL fullMessage = (MI_Char*) DSC_malloc(sizeof(MI_Char)*msgLen, NitsHere()); if( fullMessage!=NULL) { if(Stprintf(fullMessage, msgLen,VERBOSE_FORMAT , g_CAJobInformation.deviceName, EMPTY_STRING, providerContext->resourceId, message) >0 ) { result = MI_Context_WriteWarning((MI_Context*) lcmContext->context, fullMessage); if(result != MI_RESULT_OK) { // Ignore the failure, this doesn't impact the functionality. } } DSC_free(fullMessage); } } } }
const MI_Char * LogCAVerboseMessage(_In_ void *provContext,_In_opt_z_ const MI_Char *message) { MI_Result result = MI_RESULT_OK; if(message != NULL && provContext != NULL) { ProviderCallbackContext *providerContext = (ProviderCallbackContext *) provContext; LCMProviderContext *lcmContext = providerContext->lcmProviderContext; MI_Boolean whatifEnabled=CAWhatIfEnabled(provContext); if((lcmContext->executionMode & LCM_EXECUTIONMODE_ONLINE) && lcmContext->context) { MI_Char *fullMessage = NULL; size_t msgLen; msgLen = Tcslen(message) + Tcslen(providerContext->resourceId) + Tcslen(VERBOSE_FORMAT) + Tcslen(EMPTY_STRING) + Tcslen(g_CAJobInformation.deviceName) + TOKENIZED_MESSAGE_PADDING; //'ResourceId': <message>\0 fullMessage = (MI_Char*) DSC_malloc(sizeof(MI_Char)*msgLen, NitsHere()); if(fullMessage != NULL) { if (Stprintf(fullMessage, msgLen, VERBOSE_FORMAT,g_CAJobInformation.deviceName, EMPTY_STRING, providerContext->resourceId, message) >0) { if(!whatifEnabled) { result = MI_Context_WriteVerbose((MI_Context*) lcmContext->context, fullMessage); } if(result != MI_RESULT_OK) { // Ignore the failure, this doesn't impact the functionality. } } return fullMessage; } } } return NULL; }
MI_Result FormatServerURLsForDscCache( _In_ RegistrationManager *self, _Outptr_result_maybenull_z_ MI_Char** registeredServerURLs, _Outptr_result_maybenull_ MI_Instance **cimErrorDetails) { MI_Result result = MI_RESULT_OK; size_t totalLengthOfServerURLs = 0; MI_Uint32 i = 0; for (i = 0; i < self->numberOfServerURLs; i++) { totalLengthOfServerURLs += Tcslen(self->serverURLs[i]); // Add 1 for ; between each ServerURL and thumbprint totalLengthOfServerURLs += 1; totalLengthOfServerURLs += Tcslen(self->serverCertificateThumbprints[i]); // Add 1 for ; between each series totalLengthOfServerURLs += 1; } // For '\0' totalLengthOfServerURLs += 1; memset(registeredServerURLs, 0, sizeof(MI_Char)); *registeredServerURLs = (MI_Char*)DSC_malloc(totalLengthOfServerURLs*sizeof(MI_Char), NitsHere()); if (*registeredServerURLs == NULL) { EH_Fail_(GetCimMIError(MI_RESULT_SERVER_LIMITS_EXCEEDED, cimErrorDetails, ID_LCMHELPER_MEMORY_ERROR)); } memset(*registeredServerURLs, 0, totalLengthOfServerURLs); for (i = 0; i < self->numberOfServerURLs; i++) { *registeredServerURLs = Tcscat(*registeredServerURLs, totalLengthOfServerURLs, self->serverURLs[i]); if (*registeredServerURLs == NULL) { EH_Fail_(GetCimMIError(MI_RESULT_FAILED, cimErrorDetails, ID_ENGINEHELPER_CAT_ERROR)); } *registeredServerURLs = Tcscat(*registeredServerURLs, totalLengthOfServerURLs, ";"); if (*registeredServerURLs == NULL) { EH_Fail_(GetCimMIError(MI_RESULT_FAILED, cimErrorDetails, ID_ENGINEHELPER_CAT_ERROR)); } *registeredServerURLs = Tcscat(*registeredServerURLs, totalLengthOfServerURLs, self->serverCertificateThumbprints[i]); if (*registeredServerURLs == NULL) { EH_Fail_(GetCimMIError(MI_RESULT_FAILED, cimErrorDetails, ID_ENGINEHELPER_CAT_ERROR)); } *registeredServerURLs = Tcscat(*registeredServerURLs, totalLengthOfServerURLs, ";"); if (*registeredServerURLs == NULL) { EH_Fail_(GetCimMIError(MI_RESULT_FAILED, cimErrorDetails, ID_ENGINEHELPER_CAT_ERROR)); } } EH_UNWIND: return result; }
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; }
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; }
int StringEndsWith( _In_z_ TChar *self, _In_opt_z_ TChar *stringEndsWith) { size_t len1 =0, len2 = 0, tempLen = 0;; if( stringEndsWith == NULL) return 0; len1 = Tcslen(self); len2 = Tcslen(stringEndsWith); if( len2 > len1 ) return -1; for(;tempLen <len1 && tempLen < len2; tempLen++) { if( toupper(self[len1 - 1 - tempLen]) != toupper(stringEndsWith[len2 - 1 - tempLen]) ) { return -1; } } return 0; }
Internal_Dir* Internal_Dir_Open(_In_z_ const TChar* path, NitsCallSite cs) { #if defined(_MSC_VER) Internal_Dir* dir; wchar_t filespec[PAL_MAX_PATH_SIZE]; /* Allocate and zero-fill struct */ dir = (Internal_Dir*)PAL_CallocCallsite(cs, 1, sizeof(Internal_Dir)); if (!dir) return NULL; /* Build files spec */ { if (Wcslcpy(filespec, path, PAL_MAX_PATH_SIZE) >= PAL_MAX_PATH_SIZE) return NULL; if (Wcslcat(filespec, L"/*", PAL_MAX_PATH_SIZE) >= PAL_MAX_PATH_SIZE) return NULL; } /* Find first file matching the file spec */ dir->handle = _wfindfirst(filespec, &dir->fileinfo); if (dir->handle == -1) { PAL_Free(dir); return NULL; } /* Note that readdir() has not been called yet */ dir->firstTime = 1; return dir; #else Internal_Dir* self = (Internal_Dir*)PAL_CallocCallsite(cs, 1, sizeof(Internal_Dir)); if (!self) return NULL; self->dir = opendir(path); if (!self->dir) { PAL_Free(self); return NULL; } memcpy(self->dirName, path, (Tcslen(path)+1) * sizeof(TChar)); return self; #endif }
ProvRegNamespaceNode* _FindOrCreateNamespace( ProvReg* self, MI_ConstString ns, MI_Boolean extraClass) { ProvRegNamespaceNode* item = _FindNamespace(self,ns, extraClass); if (item) return item; item = (ProvRegNamespaceNode*)Batch_GetClear( &self->batch, sizeof(ProvRegNamespaceNode)); if (item) { if(extraClass) { size_t size; size = Tcslen(ns) + 1; { ZChar* nameSpace = Batch_Get(&self->batch, size * sizeof(ZChar)); if(nameSpace == NULL) { trace_OutOfMemory(); return NULL; } Tcslcpy(nameSpace, ns, size); item->ns = nameSpace; item->next = self->namespacesForExtraClasses; self->namespacesForExtraClasses = item; } } else { item->ns = ns; /* no need to strdup, since it's already in batch*/ item->next = self->namespaces; self->namespaces = item; } } return item; }
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 UpdateTask( _In_z_ MI_Char* taskName, _In_z_ MI_Char* taskTime, _In_ MI_Uint32 refreshFrequencyInSeconds, _Outptr_result_maybenull_ MI_Instance **extendedError) { int retValue = -1; ssize_t read = 0; size_t readLength = 0, writeLength = 0; MI_Char *line = NULL, *lineToWrite = NULL, *taskInCrontab = NULL; FILE *cronFile = NULL, *cronFileTmp = NULL; MI_Uint32 errorCode = 0; if (extendedError == NULL) { return MI_RESULT_INVALID_PARAMETER; } *extendedError = NULL; // Preparation if (refreshFrequencyInSeconds > THIRTY_ONE_DAYS_IN_SECONDS) { refreshFrequencyInSeconds = THIRTY_ONE_DAYS_IN_SECONDS; } if (refreshFrequencyInSeconds < FIFTEEN_MINUTES_IN_SECONDS) { refreshFrequencyInSeconds = FIFTEEN_MINUTES_IN_SECONDS; } // PLAN 1 -- process each line of crontab file to a tmp file and then copy tmp file back // taskTime string is not used in Linux since we can simply register a task with frequency // Allocate memory line = (MI_Char *)DSC_malloc(UNIT_LINE_SIZE * sizeof(MI_Char), NitsHere()); if (line == NULL) { errorCode = ID_LCMHELPER_MEMORY_ERROR; goto ExitWithError; } lineToWrite = (MI_Char *)DSC_malloc(UNIT_LINE_SIZE * sizeof(MI_Char), NitsHere()); if (lineToWrite == NULL) { errorCode = ID_LCMHELPER_MEMORY_ERROR; goto ExitWithError; } taskInCrontab = (MI_Char *)DSC_malloc(UNIT_LINE_SIZE * sizeof(MI_Char), NitsHere()); if (taskInCrontab == NULL) { errorCode = ID_LCMHELPER_MEMORY_ERROR; goto ExitWithError; } // Open files if (File_ExistT(CRON_FILE) != -1) { cronFile = File_OpenT(CRON_FILE, MI_T("r")); if (cronFile == NULL) { // Fail to open existing cron file should lead to error exit errorCode = ID_ENGINEHELPER_OPENFILE_ERROR; goto ExitWithError; } } cronFileTmp = File_OpenT(CRON_FILE_TMP, MI_T("w")); if (cronFileTmp == NULL) { // Fail to create tmp file should lead to error exit errorCode = ID_LCMHELPER_CREATEFILE_ERROR; goto ExitWithError; } // Read and process crontab file if it exists and opens appropriately while (cronFile != NULL && (read = readline(&line, &readLength, cronFile)) != -1) { retValue = TcsStrlcpy(lineToWrite, line, Tcslen(line)+1); retValue = sscanf(line, MI_T("%*s %*s %*s %*s %*s %*s %s"), taskInCrontab); if (retValue == 0) { // Ignore the bad line that does not comply with crontab file format continue; } else { if (Tcsncasecmp(taskName, taskInCrontab, Tcslen(taskName)) == 0) { // Ignore entry that duplicates registration of task continue; } else { // Write the entry to tmp file writeLength = fwrite(lineToWrite, 1, Tcslen(lineToWrite), cronFileTmp); if (writeLength != read) { errorCode = ID_LCMHELPER_WRITEFILE_ERROR; goto ExitWithError; } } } } if (readLength == -1) { // Deal memory failure in readline function errorCode = ID_ENGINEHELPER_READFILE_ERROR; goto ExitWithError; } // Add the task entry retValue = Stprintf(lineToWrite, UNIT_LINE_SIZE, MI_T("*/%d * * * * root %T\n"), refreshFrequencyInSeconds / 60, taskName); if (retValue == -1) { errorCode = ID_LCMHELPER_PRINTF_ERROR; goto ExitWithError; } writeLength = fwrite(lineToWrite, 1, Tcslen(lineToWrite), cronFileTmp); if (writeLength != Tcslen(lineToWrite)) { errorCode = ID_LCMHELPER_WRITEFILE_ERROR; goto ExitWithError; } if (cronFile != NULL) File_Close(cronFile); File_Close(cronFileTmp); File_CopyT(CRON_FILE_TMP, CRON_FILE); File_RemoveT(CRON_FILE_TMP); DSC_free(line); DSC_free(lineToWrite); DSC_free(taskInCrontab); return MI_RESULT_OK; ExitWithError: // Close files and remove temp file if it exists if (cronFile) File_Close(cronFile); if (cronFileTmp) File_Close(cronFileTmp); if (File_ExistT(CRON_FILE_TMP) != -1) File_RemoveT(CRON_FILE_TMP); // Free memory allocations if (line != NULL) DSC_free(line); if (lineToWrite != NULL) DSC_free(lineToWrite); if (taskInCrontab != NULL) DSC_free(taskInCrontab); // Form rich CIM error if (errorCode != 0) return GetCimMIError(MI_RESULT_SERVER_LIMITS_EXCEEDED, extendedError, errorCode); else return MI_RESULT_FAILED; }
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; }
MI_Boolean WQL_MatchLike( _In_z_ const ZChar* pattern, _In_z_ const ZChar* string, ZChar escape) { size_t stringLength; size_t rowLength; const ZChar* orgString; unsigned char* matchState = NULL; unsigned char* currentRow; unsigned char* previousRow; if (!(*pattern) || !(*string)) { /* skip any trailing wildcard characters */ while (*pattern == WILDCARD) pattern++; if (!(*pattern) && !(*string)) return MI_TRUE; return MI_FALSE; } stringLength = Tcslen(string); rowLength = stringLength + 1; orgString = string; if (!_EnsureMatchState(stringLength, &matchState)) return MI_FALSE; currentRow = matchState + rowLength; previousRow = matchState; while (*pattern) { /* Wildcard match. */ if (*pattern == WILDCARD) { size_t c; /* skip any continuous wildcard characters */ while (*(pattern + 1) == WILDCARD) pattern++; for (c = 0; c <= stringLength; c++) { unsigned char match = previousRow[c]; size_t matchedPos; if (match == NO_MATCH) { continue; } /* found a prior pattern char matched, */ /* then mark that the current wildcard */ /* matching the remaining part of target string */ if (match == MATCHED_WITH_ONE_CHAR) { matchedPos = c + 1; /* current wild char still match, but it should be */ /* the same as its preivous pattern char, I.E., */ /* matched one char */ currentRow[c] = MATCHED_WITH_ONE_CHAR; } else { /* if previous one is a wildcard match, */ /* then this wildcard has the same matching result */ /* with preivous char */ matchedPos = c; } for (; matchedPos <= stringLength; matchedPos++) { currentRow[matchedPos] = MATCHED_WITH_WILDCARD_CHAR; } break; } _SwitchRow(rowLength, ¤tRow, &previousRow); pattern++; } /* Set match. */ else if (*pattern == '[') { size_t c; int foundMatch = MI_FALSE; int foundSkip = 0; /* find all matching points based on the */ /* previous matching result */ for (c = 0; c <= stringLength; c++) { unsigned char match = previousRow[c]; int skip; const ZChar* currentString; if (match == NO_MATCH) { continue; } currentString = orgString + c; if (match == MATCHED_WITH_WILDCARD_CHAR) { /* match the current char if preivous is a wildchar match */ /* otherwise match the next char */ currentString --; } else if (c == stringLength) { /* no match since no char left in target string */ break; } if (_MatchSet (pattern, currentString, &skip)) { size_t matchedPos; if (!foundMatch) { foundMatch = MI_TRUE; foundSkip = skip; } /* mark the current pattern char mataching result */ matchedPos = (size_t)(currentString - orgString) + 1; currentRow[matchedPos] = MATCHED_WITH_ONE_CHAR; } } _SwitchRow(rowLength, ¤tRow, &previousRow); /* no match */ if (!foundMatch) { break; } pattern += foundSkip; } /* Single character match. */ else { size_t c; int foundMatch = MI_FALSE; if (escape != '\0' && *pattern == escape) { pattern++; } /* find all matching points based on the */ /* previous matching result */ for (c = 0; c <= stringLength; c++) { unsigned char match = previousRow[c]; const ZChar* currentString; if (match == NO_MATCH) { continue; } currentString = orgString + c; if (match == MATCHED_WITH_WILDCARD_CHAR) { /* match the current char if preivous is a wildchar match, */ /* otherwise match the next char */ currentString --; } else if (c == stringLength) { /* no match since no char left in target string */ break; } if (_Toupper(*pattern) == _Toupper(*currentString) || *pattern == ANYSINGLECHAR) { size_t matchedPos; if (!foundMatch) { foundMatch = MI_TRUE; } /* mark the current pattern char mataching result */ matchedPos = (size_t)(currentString - orgString) + 1; currentRow[matchedPos] = MATCHED_WITH_ONE_CHAR; } } _SwitchRow(rowLength, ¤tRow, &previousRow); /* no match */ if (!foundMatch) { break; } pattern ++; } } /* Matched if the last pattern char mattached the last target string char */ /* NoMatch otherwise */ { MI_Boolean flag = (previousRow[stringLength] != 0) ? MI_TRUE : MI_FALSE; PAL_Free(matchState); return flag; } }
MI_Boolean IsMatchedKeyProperties( _In_ MI_Instance* instance0, _In_ MI_Instance* instance1, _Outptr_result_maybenull_z_ MI_Char** keywords, _Out_ MI_Result* miResult, _Outptr_result_maybenull_ MI_Instance **extendedError) { MI_Uint32 i, j; MI_Result result0, result1; MI_Value value0, value1; MI_Type type0, type1; Intlstr intlstr = Intlstr_Null; MI_Char* tempKeywords = NULL; MI_Char* tempKeywordsBackup = NULL; size_t length; MI_PropertyDecl** properties; if (extendedError == NULL) { return MI_RESULT_INVALID_PARAMETER; } *extendedError = NULL; // Explicitly set *extendedError to NULL as _Outptr_ requires setting this at least once. *miResult = MI_RESULT_OK; *keywords = NULL; properties = (MI_PropertyDecl**)instance0->classDecl->properties; for (i = 0; i < instance0->classDecl->numProperties; i++) { for (j = 0; j < properties[i]->numQualifiers; j++) { if (Tcscasecmp(properties[i]->qualifiers[j]->name, MI_T("Key")) == 0) { result0 = DSC_MI_Instance_GetElement(instance0, properties[i]->name, &value0, &type0, NULL, NULL); result1 = DSC_MI_Instance_GetElement(instance1, properties[i]->name, &value1, &type1, NULL, NULL); if (result0 == MI_RESULT_OK && result1 == MI_RESULT_OK && type0 == type1 && IsSameMiValue(&value0, &value1, type0)) { // key is the same, building keywords list. length = Tcslen(properties[i]->name) + 1; if (tempKeywords == NULL) { // the first keyword. tempKeywords = (MI_Char*)DSC_malloc(length * sizeof (MI_Char), NitsHere()); if (tempKeywords == NULL) { *miResult = CreateMemoryError(extendedError); return MI_TRUE; } memcpy(tempKeywords, properties[i]->name, length * sizeof(MI_Char) ); } else { // the second or more keywords. if (intlstr.str == NULL) { // create separator string once. GetResourceString(ID_CA_COMMA_SEPARATOR, &intlstr); if (intlstr.str == NULL) { *miResult = CreateMemoryError(extendedError); DSC_free(tempKeywords); return MI_TRUE; } } length += Tcslen(tempKeywords) + Tcslen(intlstr.str); tempKeywordsBackup = tempKeywords; tempKeywords = (MI_Char*)DSC_realloc(tempKeywordsBackup, length * sizeof (MI_Char), NitsHere()); if (tempKeywords == NULL) { *miResult = CreateMemoryError(extendedError); DSC_free(tempKeywordsBackup); Intlstr_Free(intlstr); return MI_TRUE; } Stprintf(tempKeywords, length, MI_T("%T%T"), intlstr.str, properties[i]->name); } } else { if (tempKeywords) { DSC_free(tempKeywords); } if (intlstr.str) { Intlstr_Free(intlstr); } if(result0 != MI_RESULT_OK) { *miResult = result0; } else if(result1 != MI_RESULT_OK) { *miResult = result1; } return MI_FALSE; } break; } } } if (intlstr.str) { Intlstr_Free(intlstr); } // at least one key was found, and all matched. if (tempKeywords) { *keywords = tempKeywords; return MI_TRUE; } return MI_FALSE; }
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; }