Exemple #1
0
DWORD
RegGetErrorMessageForLoggingEvent(
    DWORD dwErrCode,
    PSTR* ppszErrorMsg
    )
{
    DWORD dwErrorBufferSize = 0;
    DWORD dwError = 0;
    DWORD dwLen = 0;
    PSTR  pszErrorMsg = NULL;
    PSTR  pszErrorBuffer = NULL;

    dwErrorBufferSize = LwRegGetErrorString(dwErrCode, NULL, 0);

    if (!dwErrorBufferSize)
        goto cleanup;

    dwError = LW_RTL_ALLOCATE((PVOID*)&pszErrorBuffer, CHAR,
    		                  sizeof(*pszErrorBuffer) * dwErrorBufferSize);
    BAIL_ON_REG_ERROR(dwError);

    dwLen = LwRegGetErrorString(dwErrCode, pszErrorBuffer, dwErrorBufferSize);

    if ((dwLen == dwErrorBufferSize) && !IsNullOrEmptyString(pszErrorBuffer))
    {
        dwError = RegCStringAllocatePrintf(
                     &pszErrorMsg,
                     "Error: %s [error code: %d]",
                     pszErrorBuffer,
                     dwErrCode);
        BAIL_ON_REG_ERROR(dwError);
    }

    *ppszErrorMsg = pszErrorMsg;

cleanup:

    LWREG_SAFE_FREE_STRING(pszErrorBuffer);

    return dwError;

error:

    LWREG_SAFE_FREE_STRING(pszErrorMsg);

    *ppszErrorMsg = NULL;

    goto cleanup;
}
Exemple #2
0
NTSTATUS
RegByteArrayToHexStr(
    IN UCHAR* pucByteArray,
    IN DWORD dwByteArrayLength,
    OUT PSTR* ppszHexString
    )
{
    NTSTATUS status = 0;
    DWORD i = 0;
    PSTR pszHexString = NULL;

    status = LW_RTL_ALLOCATE((PVOID*)&pszHexString, CHAR,
            		          sizeof(*pszHexString)* (dwByteArrayLength*2 + 1));
    BAIL_ON_NT_STATUS(status);

    for (i = 0; i < dwByteArrayLength; i++)
    {
        sprintf(pszHexString+(2*i), "%.2X", pucByteArray[i]);
    }

    *ppszHexString = pszHexString;

cleanup:

    return status;

error:
    LWREG_SAFE_FREE_STRING(pszHexString);

    *ppszHexString = NULL;
    goto cleanup;
}
Exemple #3
0
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;
}
Exemple #4
0
DWORD
RegGetCurrentDirectoryPath(
    PSTR* ppszPath
    )
{
    DWORD dwError = 0;
    CHAR szBuf[PATH_MAX+1];
    PSTR pszPath = NULL;

    if (getcwd(szBuf, PATH_MAX) == NULL) {
        dwError = errno;
        BAIL_ON_REG_ERROR(dwError);
    }

    dwError = RegCStringDuplicate(&pszPath, szBuf);
    BAIL_ON_REG_ERROR(dwError);

    *ppszPath = pszPath;

    return dwError;

error:

    LWREG_SAFE_FREE_STRING(pszPath);

    return dwError;
}
Exemple #5
0
VOID
RegPrintError(
    IN OPTIONAL PCSTR pszErrorPrefix,
    IN DWORD dwError
    )
{
    PCSTR pszUseErrorPrefix = NULL;
    size_t size = 0;
    PSTR pszErrorString = NULL;
    PCSTR pszWinError = NULL;

    if (dwError)
    {
        pszUseErrorPrefix = pszErrorPrefix;
        if (!pszUseErrorPrefix)
        {
            pszUseErrorPrefix = "LWREG ERROR: ";
        }

        size = LwRegGetErrorString(dwError, NULL, 0);
        if (size)
        {
            pszErrorString = malloc(size);
            if (pszErrorString)
            {
            	LwRegGetErrorString(dwError, pszErrorString, size);
            }
        }

        pszWinError = LW_PRINTF_STRING(RegWin32ExtErrorToName(dwError));

        if (!pszWinError)
        {
            pszWinError = "";
        }

        if (LW_IS_NULL_OR_EMPTY_STR(pszErrorString))
        {
            fprintf(stderr,
                    "%s (error = %u%s%s)\n",
                     pszUseErrorPrefix,
                     dwError,
                     *pszWinError ? " - " : "",
                     pszWinError);
        }
        else
        {
            fprintf(stderr,
                    "%s (error = %u%s%s)\n%s\n",
                    pszUseErrorPrefix,
                    dwError,
                    *pszWinError ? " - " : "",
                    pszWinError,
                    pszErrorString);
        }
    }
    LWREG_SAFE_FREE_STRING(pszErrorString);
}
Exemple #6
0
VOID
RegFreeSysLogInfo(
    PREG_SYS_LOG pSysLog
    )
{
    if (pSysLog->bOpened)
    {
        /* close connection to syslog */
        closelog();
    }

    LWREG_SAFE_FREE_STRING(pSysLog->pszIdentifier);

    RegMemoryFree(pSysLog);
}
Exemple #7
0
DWORD
RegGetDirectoryFromPath(
    IN PCSTR pszPath,
    OUT PSTR* ppszDir
    )
{
    PCSTR pszLastSlash = NULL;
    PSTR pszDir = NULL;
    DWORD dwError = 0;

    BAIL_ON_INVALID_POINTER(pszPath);

    pszLastSlash = strrchr(pszPath, '/');
    if (pszLastSlash == pszPath)
    {
        //Include the trailing / since this is the root directory ( / )
        pszLastSlash++;
    }

    if (pszLastSlash == NULL)
    {
        dwError = RegCStringDuplicate(
                        &pszDir, ".");
        BAIL_ON_REG_ERROR(dwError);
    }
    else
    {
        dwError = RegStrndup(
                        pszPath,
                        pszLastSlash - pszPath,
                        &pszDir);
        BAIL_ON_REG_ERROR(dwError);
    }

    *ppszDir = pszDir;

cleanup:

    return dwError;

error:

    LWREG_SAFE_FREE_STRING(pszDir);
    *ppszDir = NULL;
    goto cleanup;
}
Exemple #8
0
DWORD
RegGetSymlinkTarget(
   PCSTR pszPath,
   PSTR* ppszTargetPath
   )
{
    DWORD dwError = 0;
    CHAR szBuf[PATH_MAX+1];
    PSTR pszTargetPath = NULL;

    memset(szBuf, 0, sizeof(szBuf));

    while (1) {

       if (readlink(pszPath, szBuf, PATH_MAX) < 0) {
          if (errno == EINTR)
             continue;

          dwError = errno;
          BAIL_ON_REG_ERROR(dwError);
       }

       break;
    }

    dwError = RegCStringDuplicate(
                    &pszTargetPath,
                    szBuf);
    BAIL_ON_REG_ERROR(dwError);

    *ppszTargetPath = pszTargetPath;

cleanup:

    return dwError;

error:

    *ppszTargetPath = NULL;

    LWREG_SAFE_FREE_STRING(pszTargetPath);

    goto cleanup;
}
Exemple #9
0
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;
}
Exemple #10
0
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(&regItem, 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 *) &regItem.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(&regItem, 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 *) &regItem.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(
                          &regItem,
                          &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(&regItem, 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(
                          &regItem,
                          &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;
}
Exemple #11
0
DWORD
RegSrvStartListenThread(
    void
    )
{
    PSTR pszCachePath = NULL;
    PSTR pszCommPath = NULL;
    BOOLEAN bDirExists = FALSE;
    DWORD dwError = 0;
    static LWMsgTime idleTimeout = {30, 0};

    dwError = RegSrvGetCachePath(&pszCachePath);
    BAIL_ON_REG_ERROR(dwError);

    dwError = RegCheckDirectoryExists(pszCachePath, &bDirExists);
    BAIL_ON_REG_ERROR(dwError);

    if (!bDirExists)
    {
        // Directory should be RWX for root and accessible to all
        // (so they can see the socket.
        mode_t mode = S_IRWXU | S_IRGRP| S_IXGRP | S_IROTH | S_IXOTH;
        dwError = RegCreateDirectory(pszCachePath, mode);
        BAIL_ON_REG_ERROR(dwError);
    }


    dwError = LwRtlCStringAllocatePrintf(&pszCommPath, "%s/%s",
                                      pszCachePath, REG_SERVER_FILENAME);
    BAIL_ON_REG_ERROR(dwError);

    dwError = MAP_LWMSG_ERROR(lwmsg_context_new(NULL, &gpContext));
    BAIL_ON_REG_ERROR(dwError);

    lwmsg_context_set_log_function(gpContext, RegSrvLogIpc, NULL);

    /* Set up IPC protocol object */
    dwError = MAP_LWMSG_ERROR(lwmsg_protocol_new(gpContext, &gpProtocol));
    BAIL_ON_REG_ERROR(dwError);

    dwError = MAP_LWMSG_ERROR(lwmsg_protocol_add_protocol_spec(
                              gpProtocol,
                              RegIPCGetProtocolSpec()));
    BAIL_ON_REG_ERROR(dwError);

    /* Set up IPC server object */
    dwError = MAP_LWMSG_ERROR(lwmsg_peer_new(gpContext, gpProtocol, &gpServer));
    BAIL_ON_REG_ERROR(dwError);

    dwError = MAP_LWMSG_ERROR(lwmsg_peer_add_dispatch_spec(
                              gpServer,
                              RegSrvGetDispatchSpec()));
    BAIL_ON_REG_ERROR(dwError);

    dwError = MAP_LWMSG_ERROR(lwmsg_peer_add_listen_endpoint(
                              gpServer,
                              LWMSG_ENDPOINT_DIRECT,
                              "lwreg",
                              0));
    BAIL_ON_REG_ERROR(dwError);

    dwError = MAP_LWMSG_ERROR(lwmsg_peer_add_listen_endpoint(
                              gpServer,
                              LWMSG_ENDPOINT_LOCAL,
                              pszCommPath,
                              0666));
    BAIL_ON_REG_ERROR(dwError);

    dwError = MAP_LWMSG_ERROR(lwmsg_peer_set_max_listen_clients(
                                  gpServer,
                                  MAX_CLIENTS));
    BAIL_ON_REG_ERROR(dwError);

    dwError = MAP_LWMSG_ERROR(lwmsg_peer_set_max_listen_backlog(
                                  gpServer,
                                  REG_MAX(5, MAX_CLIENTS / 4)));
    BAIL_ON_REG_ERROR(dwError);

    dwError = MAP_LWMSG_ERROR(lwmsg_peer_set_timeout(
                                  gpServer,
                                  LWMSG_TIMEOUT_IDLE,
                                  &idleTimeout));
    BAIL_ON_REG_ERROR(dwError);

    dwError = MAP_LWMSG_ERROR(lwmsg_peer_set_listen_session_functions(
                                  gpServer,
                                  RegSrvIpcConstructSession,
                                  RegSrvIpcDestructSession,
                                  NULL));
    BAIL_ON_REG_ERROR(dwError);

    dwError = MAP_LWMSG_ERROR(lwmsg_peer_start_listen(gpServer));

error:

    LWREG_SAFE_FREE_STRING(pszCachePath);
    LWREG_SAFE_FREE_STRING(pszCommPath);

    if (dwError)
    {
        if (gpServer)
        {
            lwmsg_peer_stop_listen(gpServer);
            lwmsg_peer_delete(gpServer);
            gpServer = NULL;
        }
    }

    return dwError;
}
Exemple #12
0
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;
}