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; }
DWORD RegCStringDuplicate( OUT PSTR* ppszNewString, IN PCSTR pszOriginalString ) { return RegNtStatusToWin32Error( LwRtlCStringDuplicate(ppszNewString, pszOriginalString) ); }
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; }
NTSTATUS RegStrDupOrNull( PCSTR pszInputString, PSTR *ppszOutputString ) { if (pszInputString == NULL) { *ppszOutputString = NULL; return STATUS_SUCCESS; } else { return LwRtlCStringDuplicate(ppszOutputString, pszInputString); } }
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; }
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; }
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(¤tFileName, 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; }
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; }