DWORD RegStrndup( PCSTR pszInputString, size_t size, PSTR * ppszOutputString ) { DWORD dwError = 0; size_t copylen = 0; PSTR pszOutputString = NULL; if (!pszInputString || !ppszOutputString){ dwError = EINVAL; BAIL_ON_REG_ERROR(dwError); } for (copylen = 0; copylen < size && pszInputString[copylen]; copylen++); dwError = RegAllocateMemory(copylen+1, (PVOID*)&pszOutputString); BAIL_ON_REG_ERROR(dwError); memcpy(pszOutputString, pszInputString, copylen); pszOutputString[copylen] = 0; *ppszOutputString = pszOutputString; cleanup: return dwError; error: LWREG_SAFE_FREE_STRING(pszOutputString); goto cleanup; }
DWORD RegWC16StringArraysAllocateFromCStringArraysWithNullTerminator( IN PSTR* ppszStrings, OUT PWSTR** pppwszStrings ) { DWORD dwError = 0; PWSTR* ppwszStrings = NULL; int i = 0; if (!ppszStrings || !ppszStrings[0]) { goto cleanup; } while (ppszStrings[i++]); dwError = RegAllocateMemory(sizeof(*ppwszStrings)*i, (PVOID*)&ppwszStrings); BAIL_ON_REG_ERROR(dwError); i = 0; while (ppszStrings[i]) { dwError = RegWC16StringAllocateFromCString( &ppwszStrings[i], ppszStrings[i]); BAIL_ON_REG_ERROR(dwError); i++; } *pppwszStrings = ppwszStrings; cleanup: return dwError; error: if (ppwszStrings) { RegFreeWC16StringArrayWithNullTerminator(ppwszStrings); } *pppwszStrings = NULL; goto cleanup; }
DWORD RegLexOpen( PREGLEX_ITEM *ppLexHandle) { DWORD dwError = 0; DWORD indx = 0; PREGLEX_ITEM pLexHandle; dwError = RegAllocateMemory(sizeof(*pLexHandle), (LW_PVOID*)&pLexHandle); BAIL_ON_REG_ERROR(dwError); memset(pLexHandle, 0, sizeof(REGLEX_ITEM)); /* Initialize table of function pointers to parsing routines */ for (indx=0; indx<256; indx++) { pLexHandle->parseFuncArray[indx] = RegLexParseDefaultState; } pLexHandle->parseFuncArray[REGLEX_CHAR_INDEX('[')] = RegLexParseOpenBracket; pLexHandle->parseFuncArray[REGLEX_CHAR_INDEX(']')] = RegLexParseCloseBracket; pLexHandle->parseFuncArray[REGLEX_CHAR_INDEX('{')] = RegLexParseOpenBrace; pLexHandle->parseFuncArray[REGLEX_CHAR_INDEX('}')] = RegLexParseCloseBrace; pLexHandle->parseFuncArray[REGLEX_CHAR_INDEX('"')] = RegLexParseQuote; pLexHandle->parseFuncArray[REGLEX_CHAR_INDEX('-')] = RegLexParseDash; pLexHandle->parseFuncArray[REGLEX_CHAR_INDEX('@')] = RegLexParseAt; pLexHandle->parseFuncArray[REGLEX_CHAR_INDEX('=')] = RegLexParseEquals; pLexHandle->parseFuncArray[REGLEX_CHAR_INDEX(',')] = RegLexParseComma; pLexHandle->parseFuncArray[REGLEX_CHAR_INDEX('\\')] = RegLexParseBackslash; pLexHandle->parseFuncArray[REGLEX_CHAR_INDEX(':')] = RegLexParseColon; pLexHandle->parseFuncArray[REGLEX_CHAR_INDEX('\r')] = RegLexParseNewline; pLexHandle->parseFuncArray[REGLEX_CHAR_INDEX('\n')] = RegLexParseNewline; pLexHandle->parseFuncArray[REGLEX_CHAR_INDEX(' ')] = RegLexParseWhitespace; pLexHandle->parseFuncArray[REGLEX_CHAR_INDEX('\t')] = RegLexParseWhitespace; pLexHandle->parseFuncArray[REGLEX_CHAR_INDEX('#')] = RegLexParseComment; *ppLexHandle = pLexHandle; cleanup: return dwError; error: LWREG_SAFE_FREE_MEMORY(pLexHandle); goto cleanup; }
DWORD RegDuplicateValueAttributes( LWREG_VALUE_ATTRIBUTES pAttr, PLWREG_VALUE_ATTRIBUTES* ppAttr ) { DWORD dwError = 0; PLWREG_VALUE_ATTRIBUTES pAttr = NULL; dwError = RegAllocateMemory(sizeof(*pAttr),(PVOID*)&pAttr); BAIL_ON_REG_ERROR(dwError); pAttr->DefaultValueLen = pAttr.DefaultValueLen; pAttr->Hint = attrA.Hint; pAttr->RangeType = attrA.RangeType; switch (pAttr->RangeType) { case LWREG_VALUE_RANGE_TYPE_ENUM: dwError = RegWC16StringArraysAllocateFromCStringArraysWithNullTerminator( attrA.Range.ppszRangeEnumStrings, &pAttr->Range.ppwszRangeEnumStrings); BAIL_ON_REG_ERROR(dwError); break; case LWREG_VALUE_RANGE_TYPE_INTEGER: pAttr->Range.RangeInteger.Min = attrA.Range.RangeInteger.Min; pAttr->Range.RangeInteger.Max = attrA.Range.RangeInteger.Max; break; case LWREG_VALUE_RANGE_TYPE_BOOLEAN: pAttr->Range.RangeInteger.Min = 0; pAttr->Range.RangeInteger.Max = 1; break; default: dwError = ERROR_INVALID_PARAMETER; BAIL_ON_REG_ERROR(dwError); } if (attrA.pszDocString) { dwError = RegWC16StringAllocateFromCString( &pAttr->pwszDocString, attrA.pszDocString ); BAIL_ON_REG_ERROR(dwError); } pAttr->ValueType = attrA.ValueType; dwError = RegCopyValueAToW(pAttr->ValueType, attrA.pDefaultValue, attrA.DefaultValueLen, &pAttr->pDefaultValue, &pAttr->DefaultValueLen); BAIL_ON_REG_ERROR(dwError); *ppAttrW = pAttr; cleanup: return dwError; error: RegSafeFreeValueAttributes(&pAttr); goto cleanup; }
DWORD RegCopyValueAToW( IN REG_DATA_TYPE dwType, IN PVOID pData, IN DWORD cbData, OUT PVOID* ppOutData, OUT PDWORD pcbOutDataLen ) { DWORD dwError = 0; PVOID pOutData = NULL; DWORD cbOutDataLen = 0; BOOLEAN bIsStrType = FALSE; if (dwType == REG_MULTI_SZ) { if (!pData) { pData = (PBYTE) ""; } if (cbData == 0) { cbData = 1; } } if (pData) { if (REG_MULTI_SZ == dwType) { dwError = RegConvertByteStreamA2W((PBYTE)pData, cbData, (PBYTE*)&pOutData, &cbOutDataLen); BAIL_ON_REG_ERROR(dwError); bIsStrType = TRUE; } else if (REG_SZ == dwType) { /* Verify correct null termination of input data */ if (strlen((char *) pData) != (cbData-1)) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_REG_ERROR(dwError); } dwError = RegWC16StringAllocateFromCString((PWSTR*)&pOutData, pData); BAIL_ON_REG_ERROR(dwError); cbOutDataLen = (mbstrlen((const char*) pData)+1) * sizeof(WCHAR); bIsStrType = TRUE; } } if (!bIsStrType && cbData) { dwError = RegAllocateMemory(cbData, &pOutData); BAIL_ON_REG_ERROR(dwError); if (pData) { memcpy(pOutData, pData, cbData); cbOutDataLen = cbData; } } *ppOutData = pOutData; *pcbOutDataLen = cbOutDataLen; cleanup: return dwError; error: LWREG_SAFE_FREE_MEMORY(pOutData); *ppOutData = NULL; *pcbOutDataLen = 0; goto cleanup; }
DWORD RegOpenSyslog( PCSTR pszIdentifier, RegLogLevel maxAllowedLogLevel, DWORD dwOptions, DWORD dwFacility, PHANDLE phLog ) { DWORD dwError = 0; PREG_SYS_LOG pSyslog = NULL; dwError = RegAllocateMemory(sizeof(*pSyslog), (PVOID*)&pSyslog); if (dwError) { goto error; } dwError = RegCStringDuplicate( &pSyslog->pszIdentifier, (IsNullOrEmptyString(pszIdentifier) ? "registry" : pszIdentifier)); if (dwError) { goto error; } pSyslog->dwOptions = dwOptions; pSyslog->dwFacility = dwFacility; openlog( pSyslog->pszIdentifier, pSyslog->dwOptions, pSyslog->dwFacility); pSyslog->bOpened = TRUE; RegSetSyslogMask(maxAllowedLogLevel); dwError = RegSetupLogging( (HANDLE)pSyslog, maxAllowedLogLevel, &RegLogToSyslog); if (dwError) { goto error; } *phLog = (HANDLE)pSyslog; cleanup: return dwError; error: *phLog = (HANDLE)NULL; if (pSyslog) { RegFreeSysLogInfo(pSyslog); } goto cleanup; }
DWORD RegShellUtilExport( HANDLE hReg, PREG_EXPORT_STATE pExportState, HKEY hKey, PCSTR pszKeyName, DWORD dwNumSubKeys, DWORD dwMaxSubKeyLen ) { DWORD dwError = 0; REG_DATA_TYPE prevType = REG_NONE; SECURITY_INFORMATION SecInfoAll = OWNER_SECURITY_INFORMATION |GROUP_SECURITY_INFORMATION |DACL_SECURITY_INFORMATION |SACL_SECURITY_INFORMATION; PBYTE pSecDescRel = NULL; ULONG ulSecDescLen = SECURITY_DESCRIPTOR_RELATIVE_MAX_SIZE; PSTR pszStringSecurityDescriptor = NULL; dwError = RegGetKeySecurity(hReg, hKey, SecInfoAll, NULL, &ulSecDescLen); BAIL_ON_REG_ERROR(dwError); dwError = RegAllocateMemory(ulSecDescLen, (PVOID)&pSecDescRel); BAIL_ON_REG_ERROR(dwError); dwError = RegGetKeySecurity(hReg, hKey, SecInfoAll, (PSECURITY_DESCRIPTOR_RELATIVE)pSecDescRel, &ulSecDescLen); BAIL_ON_REG_ERROR(dwError); if (LwRtlCStringIsEqual(pszKeyName,HKEY_THIS_MACHINE,TRUE) || ulSecDescLen != pExportState->ulRootKeySecDescLen || !LwRtlEqualMemory(pSecDescRel, pExportState->pRootKeySecDescRel, ulSecDescLen)) { dwError = RegNtStatusToWin32Error( RtlAllocateSddlCStringFromSecurityDescriptor( &pszStringSecurityDescriptor, (PSECURITY_DESCRIPTOR_RELATIVE)pSecDescRel, SDDL_REVISION_1, SecInfoAll) ); BAIL_ON_REG_ERROR(dwError); } if (hKey) { dwError = ProcessExportedKeyInfo(hReg, pExportState, hKey, pszKeyName, pExportState->dwExportFormat == 1 ? NULL : pszStringSecurityDescriptor, &prevType); BAIL_ON_REG_ERROR(dwError); } if (hKey && dwNumSubKeys != 0) { dwError = ProcessSubKeys(hReg, pExportState, hKey, pszKeyName, dwNumSubKeys, dwMaxSubKeyLen); BAIL_ON_REG_ERROR(dwError); } else if (hKey == NULL && dwNumSubKeys == 0) { dwError = ProcessRootKeys(hReg, pExportState); BAIL_ON_REG_ERROR(dwError); } else if (hKey == NULL && dwNumSubKeys != 0) { dwError = ERROR_INTERNAL_ERROR; BAIL_ON_REG_ERROR(dwError); } cleanup: if (pszStringSecurityDescriptor) { RegFreeString(pszStringSecurityDescriptor); } LWREG_SAFE_FREE_MEMORY(pSecDescRel); if (pSecDescRel) { RegMemoryFree(pSecDescRel); pSecDescRel = NULL; } return dwError; error: goto cleanup; }
DWORD RegLexGetToken( HANDLE ioHandle, PREGLEX_ITEM lexHandle, PREGLEX_TOKEN pRetToken, PBOOLEAN pEof) { DWORD dwError = 0; CHAR inC = 0; BOOLEAN eof = FALSE; BAIL_ON_INVALID_HANDLE(ioHandle); BAIL_ON_INVALID_HANDLE(lexHandle); BAIL_ON_INVALID_HANDLE(pRetToken); *pRetToken = REGLEX_FIRST; if (lexHandle->isToken && lexHandle->curToken.token != REGLEX_HEXPAIR && lexHandle->curToken.token != REGLEX_REG_BINARY) { if ( lexHandle->curToken.token == REGLEX_REG_DWORD) { lexHandle->state = (REGLEX_STATE)REGLEX_FIRST; } lexHandle->isToken = FALSE; lexHandle->curToken.token = REGLEX_FIRST; lexHandle->curToken.valueCursor = 0; } /* Return pushed back token, if one is present */ if (lexHandle->prevToken.token != REGLEX_FIRST) { lexHandle->curToken = lexHandle->prevToken; lexHandle->prevToken.token = REGLEX_FIRST; *pRetToken = lexHandle->curToken.token; return dwError; } if (lexHandle->state == REGLEX_STATE_INIT || lexHandle->curToken.token == REGLEX_HEXPAIR || lexHandle->curToken.token == REGLEX_HEXPAIR_END) { lexHandle->curToken.valueCursor = 0; } if (!lexHandle->curToken.pszValue) { /* Extra byte for string termination */ LWREG_SAFE_FREE_MEMORY(lexHandle->curToken.pszValue); dwError = RegAllocateMemory(REGLEX_DEFAULT_SZ_LEN + 1, (LW_PVOID) &lexHandle->curToken.pszValue); BAIL_ON_REG_ERROR(dwError); lexHandle->curToken.valueCursor = 0; lexHandle->curToken.valueSize = REGLEX_DEFAULT_SZ_LEN; } do { lexHandle->isToken = FALSE; dwError = RegIOGetChar(ioHandle, &inC, &eof); if (eof) { if (lexHandle->curToken.token != REGLEX_FIRST && lexHandle->curToken.valueCursor > 0) { lexHandle->isToken = TRUE; *pRetToken = lexHandle->curToken.token; } else { if (lexHandle->state == REGLEX_STATE_IN_QUOTE) { dwError = LWREG_ERROR_UNEXPECTED_TOKEN; } else if (lexHandle->state == REGLEX_STATE_IN_KEY) { lexHandle->isToken = TRUE; lexHandle->curToken.token = REGLEX_REG_KEY; lexHandle->state = REGLEX_STATE_INIT; *pRetToken = lexHandle->curToken.token; *pEof = 0; break; } *pEof = eof; } break; } dwError = lexHandle->parseFuncArray[REGLEX_CHAR_INDEX(inC)]( lexHandle, ioHandle, inC); BAIL_ON_REG_ERROR(dwError); if (lexHandle->isToken) { *pRetToken = lexHandle->curToken.token; break; } } while (dwError == ERROR_SUCCESS); cleanup: return dwError; error: goto cleanup; }
static DWORD ProcessSubKeys( HANDLE hReg, PREG_EXPORT_STATE pExportState, HKEY hKey, PCSTR pszFullKeyName, DWORD dwNumSubKeys, DWORD dwMaxSubKeyLen ) { DWORD dwError = 0; int iCount = 0; DWORD dwSubKeyLen = dwMaxSubKeyLen+1; PWSTR pwszSubKey = NULL; // buffer for subkey name PSTR pszSubKey = NULL; PSTR pszFullSubKeyName = NULL; HKEY hSubKey = NULL; DWORD dwNumSubSubKeys = 0; DWORD dwMaxSubSubKeyLen = 0; // Get the subkeys and values under this key from registry for (iCount = 0; iCount < dwNumSubKeys; iCount++) { dwSubKeyLen = dwMaxSubKeyLen+1; dwError = RegAllocateMemory(sizeof(*pwszSubKey) * dwSubKeyLen, (PVOID*)&pwszSubKey); BAIL_ON_REG_ERROR(dwError); dwError = RegEnumKeyExW((HANDLE)hReg, hKey, iCount, pwszSubKey, &dwSubKeyLen, NULL, NULL, NULL, NULL); BAIL_ON_REG_ERROR(dwError); dwError = RegOpenKeyExW( hReg, hKey, pwszSubKey, 0, KEY_READ, &hSubKey); BAIL_ON_REG_ERROR(dwError); dwError = RegQueryInfoKeyA( (HANDLE) hReg, hSubKey, NULL, NULL, NULL, &dwNumSubSubKeys, &dwMaxSubSubKeyLen, NULL, NULL, NULL, NULL, NULL, NULL); BAIL_ON_REG_ERROR(dwError); // Get the pszFullSubKeyName dwError = RegCStringAllocateFromWC16String(&pszSubKey, pwszSubKey); BAIL_ON_REG_ERROR(dwError); dwError = RegCStringAllocatePrintf( &pszFullSubKeyName, "%s\\%s", pszFullKeyName, pszSubKey); BAIL_ON_REG_ERROR(dwError); dwError = RegShellUtilExport( hReg, pExportState, hSubKey, pszFullSubKeyName, dwNumSubSubKeys, dwMaxSubSubKeyLen); BAIL_ON_REG_ERROR(dwError); if (hSubKey) { dwError = RegCloseKey((HANDLE) hReg, hSubKey); BAIL_ON_REG_ERROR(dwError); hSubKey = NULL; } LWREG_SAFE_FREE_STRING(pszFullSubKeyName); LWREG_SAFE_FREE_STRING(pszSubKey); LWREG_SAFE_FREE_MEMORY(pwszSubKey); dwNumSubSubKeys = 0; dwMaxSubSubKeyLen = 0; pszFullSubKeyName = NULL; pszSubKey = NULL; pwszSubKey = NULL; } cleanup: if (hSubKey) { RegCloseKey((HANDLE) hReg, hSubKey); hSubKey = NULL; } LWREG_SAFE_FREE_STRING(pszFullSubKeyName); LWREG_SAFE_FREE_STRING(pszSubKey); LWREG_SAFE_FREE_MEMORY(pwszSubKey); dwNumSubKeys = 0; return dwError; error: goto cleanup; }
static DWORD ProcessExportedKeyInfo( IN HANDLE hReg, PREG_EXPORT_STATE pExportState, IN HKEY hKey, IN PCSTR pszFullKeyName, IN OPTIONAL PCSTR pszSddlCstring, IN OUT PREG_DATA_TYPE pPrevType ) { DWORD dwError = 0; DWORD dwError2 = 0; DWORD dwValueNameLen = MAX_KEY_LENGTH; WCHAR pwszValueName[MAX_KEY_LENGTH]; // buffer for subkey name WCHAR format PSTR pszValueName = NULL; // buffer for subkey name PSTR pszValueNameEscaped = NULL; // buffer for subkey name PSTR pszValue = NULL; REG_DATA_TYPE dataType = REG_NONE; BYTE *value = NULL; DWORD dwValueLen = 0; DWORD dwValueNameEscapedLen = 0; DWORD dwValueLenMax = 0; int iCount = 0; DWORD dwValuesCount = 0; PVOID pValue = NULL; PLWREG_VALUE_ATTRIBUTES pValueAttributes = NULL; PSTR pszAttrDump = NULL; DWORD pszAttrDumpLen = 0; PLWREG_CURRENT_VALUEINFO pCurrValueInfo = NULL; REG_PARSE_ITEM regItem = {0}; FILE *fp = pExportState->fp; BOOLEAN bValueSet = FALSE; dwError = PrintToRegFile( fp, pszFullKeyName, pszSddlCstring, REG_KEY, NULL, REG_KEY, FALSE, NULL, 0, pPrevType); BAIL_ON_REG_ERROR(dwError); dwError = RegQueryInfoKeyW( hReg, hKey, NULL, NULL, NULL, NULL, NULL, NULL, &dwValuesCount, NULL, &dwValueLenMax, NULL, NULL); BAIL_ON_REG_ERROR(dwError); if (!dwValuesCount) { goto cleanup; } dwError = RegAllocateMemory(dwValueLenMax, (PVOID*)&value); BAIL_ON_REG_ERROR(dwError); for (iCount = 0; iCount < dwValuesCount; iCount++) { memset(pwszValueName, 0, MAX_KEY_LENGTH); dwValueNameLen = MAX_KEY_LENGTH; memset(value, 0, dwValueLenMax); dwValueLen = dwValueLenMax; RegSafeFreeCurrentValueInfo(&pCurrValueInfo); dwError = RegEnumValueW((HANDLE)hReg, hKey, iCount, pwszValueName, &dwValueNameLen, NULL, &dataType, value, &dwValueLen); BAIL_ON_REG_ERROR(dwError); LWREG_SAFE_FREE_STRING(pszValueName); LWREG_SAFE_FREE_STRING(pszValueNameEscaped); dwError = RegCStringAllocateFromWC16String( &pszValueName, pwszValueName); BAIL_ON_REG_ERROR(dwError); dwError = RegShellUtilEscapeString( pszValueName, &pszValueNameEscaped, &dwValueNameEscapedLen); BAIL_ON_REG_ERROR(dwError); if (dataType == REG_SZ) { LWREG_SAFE_FREE_STRING(pszValue); dwError2 = RegCStringAllocateFromWC16String( &pszValue, (PWSTR) value); BAIL_ON_REG_ERROR(dwError2); pValue = pszValue; } else { pValue = value; } LWREG_SAFE_FREE_MEMORY(pszAttrDump); dwError = LwRegGetValueAttributesW( hReg, hKey, NULL, pwszValueName, &pCurrValueInfo, &pValueAttributes); if (pExportState->dwExportFormat == REGSHELL_EXPORT_LEGACY) { bValueSet = pCurrValueInfo || (dwError && dwValueLen) ? FALSE : TRUE; /* Export "legacy" format */ dwError = PrintToRegFile( fp, pszFullKeyName, NULL, REG_SZ, pszValueNameEscaped, dataType, bValueSet, pValue, dwValueLen, pPrevType); } else if (pExportState->dwExportFormat == REGSHELL_EXPORT_VALUES) { /* Export only values that override default */ if ((dwError == 0 && pCurrValueInfo) || (dwError && dwValueLen)) { memset(®Item, 0, sizeof(regItem)); regItem.type = REG_SZ; regItem.valueName = pszValueNameEscaped; if (pCurrValueInfo) { dataType = pCurrValueInfo->dwType; pValue = pCurrValueInfo->pvData; dwValueLen = pCurrValueInfo->cbData; } else { pValue = value; } regItem.valueType = dataType; regItem.regAttr.ValueType = regItem.valueType; if (dataType == REG_SZ) { if (pValue) { dwError = RegCStringAllocateFromWC16String( (PSTR *) ®Item.value, (PWSTR) pValue); BAIL_ON_REG_ERROR(dwError); regItem.valueLen = strlen(regItem.value); } pValue = regItem.value; dwValueLen = strlen((PSTR) value); } else { regItem.value = pValue; regItem.valueLen = dwValueLen; } /* Export "legacy" format */ dwError = PrintToRegFile( fp, pszFullKeyName, NULL, REG_SZ, pszValueNameEscaped, dataType, FALSE, pValue, dwValueLen, pPrevType); } else { /* * Don't care if there isn't a schema entry when * exporting values, so ignore error from * RegGetValueAttributesW(). */ dwError = 0; } } else if (dwError == 0) { /* Export value and attribute information */ memset(®Item, 0, sizeof(regItem)); regItem.type = REG_SZ; regItem.valueName = pszValueNameEscaped; regItem.valueType = dataType; if (pValueAttributes) { regItem.regAttr = *pValueAttributes; } /* Might have to do something with MULTI_SZ */ if (dataType == REG_SZ) { if (regItem.regAttr.pDefaultValue) { dwError = RegCStringAllocateFromWC16String( (PSTR *) ®Item.regAttr.pDefaultValue, (PWSTR) regItem.regAttr.pDefaultValue); BAIL_ON_REG_ERROR(dwError); regItem.regAttr.DefaultValueLen = strlen(regItem.regAttr.pDefaultValue); regItem.value = pCurrValueInfo ? pValue : NULL; } } else { regItem.value = pCurrValueInfo ? value : NULL; regItem.valueLen = dwValueLen; } dwError = RegExportAttributeEntries( ®Item, &pszAttrDump, &pszAttrDumpLen); BAIL_ON_REG_ERROR(dwError); LWREG_SAFE_FREE_STRING(regItem.regAttr.pDefaultValue); fprintf(fp, "%*s\n", pszAttrDumpLen, pszAttrDump); } else { /* * Create a "fake" PITEM, populate it with legacy * valueName=dataValue information, and use * RegExportAttributeEntries() to generate the export data. */ memset(®Item, 0, sizeof(regItem)); regItem.type = REG_SZ; regItem.valueName = pszValueNameEscaped; regItem.valueType = dataType; regItem.regAttr.ValueType = dataType; regItem.value = pValue; regItem.valueLen = dwValueLen; dwError = RegExportAttributeEntries( ®Item, &pszAttrDump, &pszAttrDumpLen); BAIL_ON_REG_ERROR(dwError); fprintf(fp, "%*s\n", pszAttrDumpLen, pszAttrDump); } } cleanup: LWREG_SAFE_FREE_MEMORY(pszAttrDump); LWREG_SAFE_FREE_MEMORY(pszValue); LWREG_SAFE_FREE_STRING(pszValueName); LWREG_SAFE_FREE_STRING(pszValueNameEscaped); LWREG_SAFE_FREE_STRING(pszValue); LWREG_SAFE_FREE_STRING(regItem.regAttr.pDefaultValue); RegSafeFreeCurrentValueInfo(&pCurrValueInfo); memset(value, 0, dwValueLenMax); LWREG_SAFE_FREE_MEMORY(value); return dwError; error: goto cleanup; }
static DWORD RegCreateDirectoryRecursive( PSTR pszCurDirPath, PSTR pszTmpPath, PSTR *ppszTmp, DWORD dwFileMode, DWORD dwWorkingFileMode, int iPart ) { DWORD dwError = 0; PSTR pszDirPath = NULL; BOOLEAN bDirCreated = FALSE; BOOLEAN bDirExists = FALSE; CHAR szDelimiters[] = "/"; PSTR pszToken = strtok_r((iPart ? NULL : pszTmpPath), szDelimiters, ppszTmp); if (pszToken != NULL) { dwError = RegAllocateMemory(strlen(pszCurDirPath)+strlen(pszToken)+2, (PVOID*)&pszDirPath); BAIL_ON_REG_ERROR(dwError); sprintf(pszDirPath, "%s/%s", (!strcmp(pszCurDirPath, "/") ? "" : pszCurDirPath), pszToken); dwError = RegCheckDirectoryExists(pszDirPath, &bDirExists); BAIL_ON_REG_ERROR(dwError); if (!bDirExists) { if (mkdir(pszDirPath, dwWorkingFileMode) < 0) { dwError = errno; BAIL_ON_REG_ERROR(dwError); } bDirCreated = TRUE; } dwError = RegChangeDirectory(pszDirPath); BAIL_ON_REG_ERROR(dwError); dwError = RegCreateDirectoryRecursive( pszDirPath, pszTmpPath, ppszTmp, dwFileMode, dwWorkingFileMode, iPart+1 ); BAIL_ON_REG_ERROR(dwError); } if (bDirCreated && (dwFileMode != dwWorkingFileMode)) { dwError = RegChangePermissions(pszDirPath, dwFileMode); BAIL_ON_REG_ERROR(dwError); } if (pszDirPath) { RegMemoryFree(pszDirPath); } return dwError; error: if (bDirCreated) { RegRemoveDirectory(pszDirPath); } if (pszDirPath) { RegMemoryFree(pszDirPath); } return dwError; }
DWORD RegGetMatchingFilePathsInFolder( PCSTR pszDirPath, PCSTR pszFileNameRegExp, PSTR** pppszHostFilePaths, PDWORD pdwNPaths ) { typedef struct __PATHNODE { PSTR pszPath; struct __PATHNODE *pNext; } *PPATHNODE; DWORD dwError = 0; DIR* pDir = NULL; struct dirent* pDirEntry = NULL; regex_t rx; BOOLEAN rxAllocated = FALSE; regmatch_t* pResult = NULL; size_t nMatch = 1; DWORD dwNPaths = 0; DWORD iPath = 0; PSTR* ppszHostFilePaths = NULL; CHAR szBuf[PATH_MAX+1]; struct stat statbuf; PPATHNODE pPathList = NULL; PPATHNODE pPathNode = NULL; BOOLEAN bDirExists = FALSE; dwError = RegCheckDirectoryExists(pszDirPath, &bDirExists); BAIL_ON_REG_ERROR(dwError); if(!bDirExists) { dwError = ENOENT; BAIL_ON_REG_ERROR(dwError); } if (regcomp(&rx, pszFileNameRegExp, REG_EXTENDED) != 0) { dwError = LWREG_ERROR_REGEX_COMPILE_FAILED; BAIL_ON_REG_ERROR(dwError); } rxAllocated = TRUE; dwError = RegAllocateMemory(sizeof(*pResult), (PVOID*)&pResult); BAIL_ON_REG_ERROR(dwError); pDir = opendir(pszDirPath); if (!pDir) { dwError = errno; BAIL_ON_REG_ERROR(dwError); } while ((pDirEntry = readdir(pDir)) != NULL) { int copied = snprintf( szBuf, sizeof(szBuf), "%s/%s", pszDirPath, pDirEntry->d_name); if (copied >= sizeof(szBuf)) { //Skip pathnames that are too long continue; } memset(&statbuf, 0, sizeof(struct stat)); if (lstat(szBuf, &statbuf) < 0) { if(errno == ENOENT) { //This occurs when there is a symbolic link pointing to a //location that doesn't exist, because stat looks at the final //file, not the link. Since this file doesn't exist anyway, //just skip it. continue; } dwError = errno; BAIL_ON_REG_ERROR(dwError); } /* * For now, we are searching only for regular files * This may be enhanced in the future to support additional * file system entry types */ if (((statbuf.st_mode & S_IFMT) == S_IFREG) && (regexec(&rx, pDirEntry->d_name, nMatch, pResult, 0) == 0)) { dwNPaths++; dwError = RegAllocateMemory(sizeof(*pPathNode), (PVOID*)&pPathNode); BAIL_ON_REG_ERROR(dwError); dwError = RegCStringDuplicate(&pPathNode->pszPath, szBuf); BAIL_ON_REG_ERROR(dwError); pPathNode->pNext = pPathList; pPathList = pPathNode; pPathNode = NULL; } } if (pPathList) { dwError = RegAllocateMemory(sizeof(*ppszHostFilePaths)*dwNPaths, (PVOID*)&ppszHostFilePaths); BAIL_ON_REG_ERROR(dwError); /* * The linked list is in reverse. * Assign values in reverse to get it right */ iPath = dwNPaths-1; pPathNode = pPathList; while (pPathNode) { *(ppszHostFilePaths+iPath) = pPathNode->pszPath; pPathNode->pszPath = NULL; pPathNode = pPathNode->pNext; iPath--; } } *pppszHostFilePaths = ppszHostFilePaths; *pdwNPaths = dwNPaths; cleanup: if (pPathNode) { LWREG_SAFE_FREE_STRING(pPathNode->pszPath); RegMemoryFree(pPathNode); } while(pPathList) { pPathNode = pPathList; pPathList = pPathList->pNext; LWREG_SAFE_FREE_STRING(pPathNode->pszPath); RegMemoryFree(pPathNode); } if (rxAllocated) { regfree(&rx); } LWREG_SAFE_FREE_MEMORY(pResult); if (pDir) { closedir(pDir); } return dwError; error: if (ppszHostFilePaths) { RegFreeStringArray(ppszHostFilePaths, dwNPaths); } goto cleanup; }
int main(int argc, char *argv[]) { PIV_CONVERT_CTX ivHandle = NULL; PCHAR strDefaultList[] = { "1: Now is the time", "2: For all good people", "3: All work and no play", "4: Makes Jack a dull boy", NULL, }; PCHAR *argcList = NULL; PCHAR *multiStringList = strDefaultList; PBYTE multiString = NULL; ssize_t multiStringLen = 0; PSTR exportString = NULL; DWORD exportStringLen = 0; DWORD dwError = 0; DWORD count = 0; if (argc > 1) { dwError = RegAllocateMemory(sizeof(PCHAR) * argc, (PVOID*)&argcList); BAIL_ON_REG_ERROR(dwError); for (count=1; count < argc; count++) { argcList[count-1] = argv[count]; } multiStringList = argcList; } RegIconvConvertOpen(&ivHandle, "ucs-2le", "utf-8"); RegMultiStrsToByteArray(multiStringList, &multiString, &multiStringLen); RegExportEntry("HKLM_LINUX/likewise/registry/devel", NULL, 0, NULL, REG_KEY, NULL, 0, &exportString, &exportStringLen); printf("%s\n", exportString); RegExportEntry(NULL, NULL, 0, "testkey1", REG_MULTI_SZ, multiString, multiStringLen, &exportString, &exportStringLen); printf("%s\n", exportString); RegIconvConvertClose(ivHandle); cleanup: return dwError; error: goto cleanup; }