Beispiel #1
0
NTSTATUS
NtRegOpenConfig(
    PCSTR pszConfigKey,
    PCSTR pszPolicyKey,
    PLWREG_CONFIG_REG *ppReg
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    PLWREG_CONFIG_REG pReg = NULL;

    ntStatus = LW_RTL_ALLOCATE(
                   (PVOID*)&pReg, 
                   LWREG_CONFIG_REG, 
                   sizeof(LWREG_CONFIG_REG));
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = LwRtlCStringDuplicate(&pReg->pszConfigKey, pszConfigKey);
    BAIL_ON_NT_STATUS(ntStatus);

    if (pszPolicyKey)
    {
        ntStatus = LwRtlCStringDuplicate(&pReg->pszPolicyKey, pszPolicyKey);
        BAIL_ON_NT_STATUS(ntStatus);
    }

    ntStatus = NtRegOpenServer(&pReg->hConnection);
    BAIL_ON_NT_STATUS(ntStatus);

    ntStatus = NtRegOpenKeyExA(
            pReg->hConnection,
            NULL,
            HKEY_THIS_MACHINE,
            0,
            KEY_READ,
            &(pReg->hKey));
    BAIL_ON_NT_STATUS(ntStatus);

cleanup:

    *ppReg = pReg;

    return ntStatus;

error:

    NtRegCloseConfig(pReg);
    pReg = NULL;

    goto cleanup;
}
static
DWORD
LsaPstorepInitializePlugin(
    OUT PLSA_PSTORE_PLUGIN_INFO PluginInfo,
    IN PCSTR PluginName
    )
{
    DWORD dwError = 0;
    int EE = 0;
    LSA_PSTORE_PLUGIN_INITIALIZE_FUNCTION initFunction = NULL;

    dwError = LwNtStatusToWin32Error(LwRtlCStringDuplicate(&PluginInfo->Name, PluginName));
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

    dwError = LsaPstorepGetPluginPath(PluginInfo->Name, &PluginInfo->Path);
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);
    
    dwError = LsaPstorepOpenPlugin(
                    PluginInfo->Path,
                    LSA_PSTORE_PLUGIN_INITIALIZE_FUNCTION_NAME,
                    &PluginInfo->LibraryHandle,
                    OUT_PPVOID(&initFunction));
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

    dwError = initFunction(LSA_PSTORE_PLUGIN_VERSION,
                           PluginInfo->Name,
                           &PluginInfo->Dispatch,
                           &PluginInfo->Context);
    GOTO_CLEANUP_ON_WINERROR_EE(dwError, EE);

    if (!PluginInfo->Dispatch)
    {
        LW_RTL_LOG_ERROR("LSA pstore plugin %s is missing a dispatch table",
                         PluginInfo->Name);
        dwError = ERROR_DLL_INIT_FAILED;
        GOTO_CLEANUP_EE(EE);
    }

    if (!PluginInfo->Dispatch->Cleanup)
    {
        LW_RTL_LOG_ERROR("LSA pstore plugin %s is missing the Cleanup function",
                         PluginInfo->Name);
        dwError = ERROR_DLL_INIT_FAILED;
        GOTO_CLEANUP_EE(EE);
    }

    LW_RTL_LOG_VERBOSE("Loaded LSA pstore plugin %s from %s",
                       PluginInfo->Name, PluginInfo->Path);

cleanup:
    if (dwError)
    {
        LsaPstorepCleanupPlugin(PluginInfo);
    }

    LSA_PSTORE_LOG_LEAVE_ERROR_EE(dwError, EE);
    return dwError;
}
Beispiel #3
0
DWORD
RegCStringDuplicate(
    OUT PSTR* ppszNewString,
    IN PCSTR pszOriginalString
    )
{
	return RegNtStatusToWin32Error(
			LwRtlCStringDuplicate(ppszNewString, pszOriginalString)
			);
}
Beispiel #4
0
DWORD
IDMAllocateStringA(
    PSTR  pszString,
    PSTR* ppszString
    )
{
    DWORD dwError = 0;
    PSTR  pszNewString = NULL;

    if (!pszString || !ppszString)
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_ERROR(dwError);
    }
#ifdef _WIN32
{
    SIZE_T len = 0;
    len = strlen(pszString);

    dwError = IDMAllocateMemory(
                    len + 1,
                    (PVOID*)&pszNewString);
    BAIL_ON_ERROR(dwError);

    strcpy_s(pszNewString, len+1, pszString);
}
#else

    dwError = LwRtlCStringDuplicate(&pszNewString, pszString);
    BAIL_ON_ERROR(dwError);

#endif

    *ppszString = pszNewString;

cleanup:

    return dwError;

error:

    if (ppszString)
    {
        *ppszString = NULL;
    }

    IDM_SAFE_FREE_MEMORY(pszNewString);

    goto cleanup;
}
Beispiel #5
0
NTSTATUS
RegStrDupOrNull(
    PCSTR pszInputString,
    PSTR *ppszOutputString
    )
{
    if (pszInputString == NULL)
    {
        *ppszOutputString = NULL;
        return STATUS_SUCCESS;
    }
    else
    {
        return LwRtlCStringDuplicate(ppszOutputString, pszInputString);
    }
}
Beispiel #6
0
VOID
PvfsNotifyScheduleFullReport(
    PPVFS_FCB pFcb,
    FILE_NOTIFY_CHANGE Filter,
    FILE_ACTION Action,
    PCSTR pszFilename
    )
{
    NTSTATUS ntError = STATUS_UNSUCCESSFUL;
    PPVFS_NOTIFY_REPORT_RECORD pReport = NULL;

    BAIL_ON_INVALID_PTR(pFcb, ntError);

    ntError = PvfsAllocateMemory(
                  OUT_PPVOID(&pReport),
                  sizeof(PVFS_NOTIFY_REPORT_RECORD),
                  FALSE);
    BAIL_ON_NT_STATUS(ntError);

    pReport->pFcb = PvfsReferenceFCB(pFcb);
    pReport->Filter = Filter;
    pReport->Action = Action;

    ntError = LwRtlCStringDuplicate(&pReport->pszFilename, pszFilename);
    BAIL_ON_NT_STATUS(ntError);

    ntError = LwRtlQueueWorkItem(
                  gPvfsDriverState.ThreadPool,
                  PvfsNotifyProcessEvent,
                  pReport,
                  0);
    BAIL_ON_NT_STATUS(ntError);

error:
    if (!NT_SUCCESS(ntError))
    {
        if (pReport)
        {
            PvfsNotifyFullReportCtxFree(&pReport);
        }
    }

    return;
}
Beispiel #7
0
NTSTATUS
PvfsSysOpenByFileName(
    OUT int *pFd,
    OUT PBOOLEAN pbCreateOwnerFile,
    IN PPVFS_FILE_NAME pFileName,
    IN int iFlags,
    IN mode_t Mode
)
{
    NTSTATUS ntError = STATUS_SUCCESS;
    int fd = -1;
    int unixerr = 0;
    PSTR pszFilename = NULL;
    PVFS_STAT Stat = {0};
    int Ownerfd = -1;
    PSTR pszStreamDirectoryName = NULL;
    PSTR pszMetadataPath = NULL;
    BOOLEAN bCreateOwnerFile = FALSE;

    // Need make sure the object (file/directory) exists
    // Before non-default stream objects can be created
    if (!PvfsIsDefaultStreamName(pFileName))
    {
        ntError = PvfsSysStat(pFileName->FileName, &Stat);
        if (LW_STATUS_OBJECT_NAME_NOT_FOUND == ntError)
        {
            ntError = PvfsSysOpen(
                          &Ownerfd,
                          pFileName->FileName,
                          iFlags,
                          Mode);
            if (STATUS_SUCCESS == ntError)
            {
                bCreateOwnerFile = TRUE;
            }
        }
        BAIL_ON_NT_STATUS(ntError);

        ntError = PvfsLookupStreamDirectoryPath(&pszStreamDirectoryName,
                                                pFileName);
        BAIL_ON_NT_STATUS(ntError);

        ntError = PvfsFileDirname(&pszMetadataPath,
                                  pszStreamDirectoryName);
        BAIL_ON_NT_STATUS(ntError);

        ntError = PvfsSysOpenDir(pszMetadataPath, NULL);
        if (LW_STATUS_OBJECT_NAME_NOT_FOUND == ntError)
        {
            // create meta data directory
            ntError = PvfsSysMkDir(
                          pszMetadataPath,
                          (mode_t)gPvfsDriverConfig.CreateDirectoryMode);
            BAIL_ON_NT_STATUS(ntError);
        }
        BAIL_ON_NT_STATUS(ntError);

        ntError = PvfsSysOpenDir(pszStreamDirectoryName, NULL);
        if (LW_STATUS_OBJECT_NAME_NOT_FOUND == ntError)
        {
            // create stream directory for an object
            ntError = PvfsSysMkDir(
                          pszStreamDirectoryName,
                          (mode_t)gPvfsDriverConfig.CreateDirectoryMode);
            BAIL_ON_NT_STATUS(ntError);
        }
        BAIL_ON_NT_STATUS(ntError);

        ntError = LwRtlCStringAllocatePrintf(
                      &pszFilename,
                      "%s/%s",
                      pszStreamDirectoryName,
                      PvfsGetCStringBaseStreamName(pFileName));
        BAIL_ON_NT_STATUS(ntError);
    }
    else
    {
        ntError = LwRtlCStringDuplicate(&pszFilename,
                                        PvfsGetCStringBaseFileName(pFileName));
        BAIL_ON_NT_STATUS(ntError);
    }

    if ((fd = open(pszFilename, iFlags, Mode)) == -1) {
        PVFS_BAIL_ON_UNIX_ERROR(unixerr, ntError);
    }

    *pFd = fd;
    *pbCreateOwnerFile = bCreateOwnerFile;

cleanup:

    if (pszFilename)
    {
        LwRtlCStringFree(&pszFilename);
    }
    if (pszStreamDirectoryName)
    {
        LwRtlCStringFree(&pszStreamDirectoryName);
    }
    if (pszMetadataPath)
    {
        LwRtlCStringFree(&pszMetadataPath);
    }

    if (Ownerfd != -1)
    {
        PvfsSysClose(Ownerfd);
    }

    return ntError;

error:
    if (fd != -1)
    {
        PvfsSysClose(fd);
    }

    goto cleanup;
}
Beispiel #8
0
NTSTATUS
PvfsRenameFCB(
    PPVFS_FCB pFcb,
    PPVFS_CCB pCcb,
    PPVFS_FILE_NAME pNewFilename
    )
{
    NTSTATUS ntError = STATUS_SUCCESS;
    PPVFS_CB_TABLE fcbTable = &gPvfsDriverState.FcbTable;
    PPVFS_FCB pNewParentFcb = NULL;
    PPVFS_FCB pOldParentFcb = NULL;
    PPVFS_FCB pTargetFcb = NULL;
    PPVFS_CB_TABLE_ENTRY pTargetBucket = NULL;
    PPVFS_CB_TABLE_ENTRY pCurrentBucket = NULL;
    BOOLEAN currentFcbControl = FALSE;
    BOOLEAN targetFcbListLocked = FALSE;
    BOOLEAN targetBucketLocked = FALSE;
    BOOLEAN currentBucketLocked = FALSE;
    BOOLEAN fcbRwLocked = FALSE;
    BOOLEAN renameLock = FALSE;
    PPVFS_FILE_NAME currentFileName = NULL;

    /* If the target has an existing SCB, remove it from the Table and let
       the existing ref counters play out (e.g. pending change notifies. */

    BAIL_ON_INVALID_PTR(pNewFilename, ntError);

    ntError = PvfsFindParentFCB(&pNewParentFcb, pNewFilename->FileName);
    BAIL_ON_NT_STATUS(ntError);

    ntError = PvfsAllocateFileNameFromScb(&currentFileName, pCcb->pScb);
    BAIL_ON_NT_STATUS(ntError);

    // Obtain all locks for the rename
    LWIO_LOCK_RWMUTEX_EXCLUSIVE(renameLock, &fcbTable->rwLock);
    LWIO_LOCK_MUTEX(currentFcbControl, &pFcb->BaseControlBlock.Mutex);

    pCurrentBucket = pFcb->BaseControlBlock.pBucket;

    ntError = PvfsCbTableGetBucket(
                  &pTargetBucket,
                  fcbTable,
                  pNewFilename->FileName);
    BAIL_ON_NT_STATUS(ntError);

    LWIO_LOCK_RWMUTEX_EXCLUSIVE(currentBucketLocked, &pCurrentBucket->rwLock);
    if (pCurrentBucket != pTargetBucket)
    {
        LWIO_LOCK_RWMUTEX_EXCLUSIVE(targetBucketLocked, &pTargetBucket->rwLock);
    }

    // Do the rename work now
    ntError = PvfsCbTableLookup_inlock(
                  (PPVFS_CONTROL_BLOCK*)OUT_PPVOID(&pTargetFcb),
                  pTargetBucket,
                  pNewFilename->FileName);
    if (ntError == STATUS_SUCCESS)
    {
        if (pTargetFcb != pFcb)
        {
            // Remove an existing FCB for the target file/stream (if one exists)
            // But make sure it is a different FCB

            LWIO_LOCK_RWMUTEX_SHARED(targetFcbListLocked, &pTargetFcb->rwScbLock);

            if (pTargetFcb->OpenHandleCount > 0 )
            {
                // if TargetScb has open handles cannot rename
                // This except in the batch-oplock case
                ntError = STATUS_INVALID_PARAMETER;
                BAIL_ON_NT_STATUS(ntError);
            }

            LWIO_UNLOCK_RWMUTEX(targetFcbListLocked, &pTargetFcb->rwScbLock);

            // TODO - How to get the Control Mutex without violating the
            // lock heirarchy?  Does it matter at all ?

            ntError = PvfsRemoveStreamObjects(pTargetFcb);
            LWIO_ASSERT(STATUS_SUCCESS == ntError);

            ntError = PvfsCbTableRemove_inlock(
                          (PPVFS_CONTROL_BLOCK)pTargetFcb,
                          pTargetFcb->pszFilename);
            LWIO_ASSERT(STATUS_SUCCESS == ntError);
        }
    }

    ntError = PvfsSysRenameByFileName(currentFileName, pNewFilename);
    // Ignore the error here and continue

    ntError = PvfsPathCacheRemove(currentFileName);
    // Ignore the error here and continue

    /* Remove the SCB from the table, update the lookup key, and then re-add.
       Otherwise you will get memory corruption as a freed pointer gets left
       in the Table because if cannot be located using the current (updated)
       filename. Another reason to use the dev/inode pair instead if we could
       solve the "Create New File" issue. */

    // Remove FCB
    ntError = PvfsCbTableRemove_inlock(
                  (PPVFS_CONTROL_BLOCK)pFcb,
                  pFcb->pszFilename);
    LWIO_ASSERT(STATUS_SUCCESS == ntError);

    // Rename FCB & Update parent links
    LWIO_LOCK_RWMUTEX_EXCLUSIVE(fcbRwLocked, &pFcb->BaseControlBlock.RwLock);
    LwRtlCStringFree(&pFcb->pszFilename);

    ntError = LwRtlCStringDuplicate(&pFcb->pszFilename, pNewFilename->FileName);
    BAIL_ON_NT_STATUS(ntError);

    if (pNewParentFcb != pFcb->pParentFcb)
    {
        pOldParentFcb = pFcb->pParentFcb;
        pFcb->pParentFcb = pNewParentFcb;
        pNewParentFcb = NULL;
    }
    LWIO_UNLOCK_RWMUTEX(fcbRwLocked, &pFcb->BaseControlBlock.RwLock);

    // Re-Add SCB
    ntError = PvfsCbTableAdd_inlock(
                  pTargetBucket,
                  pFcb->pszFilename,
                  (PPVFS_CONTROL_BLOCK)pFcb);
    BAIL_ON_NT_STATUS(ntError);

error:

    // Release all locks .. Whew!
    LWIO_UNLOCK_RWMUTEX(targetFcbListLocked, &pTargetFcb->rwScbLock);
    LWIO_UNLOCK_RWMUTEX(targetBucketLocked, &pTargetBucket->rwLock);
    LWIO_UNLOCK_RWMUTEX(currentBucketLocked, &pCurrentBucket->rwLock);
    LWIO_UNLOCK_RWMUTEX(fcbRwLocked, &pFcb->BaseControlBlock.RwLock);
    LWIO_UNLOCK_MUTEX(currentFcbControl, &pFcb->BaseControlBlock.Mutex);
    LWIO_UNLOCK_RWMUTEX(renameLock, &fcbTable->rwLock);

    if (pNewParentFcb)
    {
        PvfsReleaseFCB(&pNewParentFcb);
    }
    if (pOldParentFcb)
    {
        PvfsReleaseFCB(&pOldParentFcb);
    }
    if (pTargetFcb)
    {
        PvfsReleaseFCB(&pTargetFcb);
    }
    if (currentFileName)
    {
        PvfsFreeFileName(currentFileName);
    }

    return ntError;
}
Beispiel #9
0
NTSTATUS
NtRegReadConfigString(
    PLWREG_CONFIG_REG pReg,
    PCSTR   pszName,
    BOOLEAN bUsePolicy,
    PSTR    *ppszValue,
    PDWORD  pdwSize
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    BOOLEAN bGotValue = FALSE;
    PSTR pszValue = NULL;
    char szValue[MAX_VALUE_LENGTH];
    DWORD dwType;
    DWORD dwSize;

    if ( bUsePolicy )
    {
        if (!pReg->pszPolicyKey)
        {
            ntStatus = STATUS_INVALID_PARAMETER;
            BAIL_ON_NT_STATUS(ntStatus);
        }

        dwSize = sizeof(szValue);
        memset(szValue, 0, dwSize);
        ntStatus = NtRegGetValueA(
                    pReg->hConnection,
                    pReg->hKey,
                    pReg->pszPolicyKey,
                    pszName,
                    RRF_RT_REG_SZ,
                    &dwType,
                    szValue,
                    &dwSize);
        if (!ntStatus)
        {
            bGotValue = TRUE;
        }
    }

    if (!bGotValue )
    {
        dwSize = sizeof(szValue);
        memset(szValue, 0, dwSize);
        ntStatus = NtRegGetValueA(
                    pReg->hConnection,
                    pReg->hKey,
                    pReg->pszConfigKey,
                    pszName,
                    RRF_RT_REG_SZ,
                    &dwType,
                    szValue,
                    &dwSize);
        if (!ntStatus)
        {
            bGotValue = TRUE;
        }
    }

    if (bGotValue)
    {
        ntStatus = LwRtlCStringDuplicate(&pszValue, szValue);
        BAIL_ON_NT_STATUS(ntStatus);

        LwRtlCStringFree(ppszValue);
        *ppszValue = pszValue;
        pszValue = NULL;

        if (pdwSize)
        {
            *pdwSize = dwSize;
        }
    }

    ntStatus = 0;

cleanup:
    LwRtlCStringFree(&pszValue);
    return ntStatus;

error:
    goto cleanup;
}