NTSTATUS MemDeleteKeyValue( IN HANDLE Handle, IN HKEY hKey, IN OPTIONAL PCWSTR pSubKey, IN OPTIONAL PCWSTR pValueName ) { NTSTATUS status = 0; PREG_KEY_HANDLE pKeyHandle = (PREG_KEY_HANDLE) hKey; PMEMREG_NODE hSubKey = NULL; BOOLEAN bInLock = FALSE; hSubKey = pKeyHandle->pKey->hNode; LWREG_LOCK_RWMUTEX_EXCLUSIVE(bInLock, &MemRegRoot()->lock); if (pSubKey) { status = MemRegStoreFindNode( hSubKey, pSubKey, &hSubKey); BAIL_ON_NT_STATUS(status); } status = MemRegStoreDeleteNodeValue( hSubKey, pValueName); MemDbExportEntryChanged(); error: LWREG_UNLOCK_RWMUTEX(bInLock, &MemRegRoot()->lock); return status; }
NTSTATUS SqliteCacheUpdateValuesInfo( DWORD dwOffSet, IN OUT PREG_KEY_CONTEXT pKeyResult, OUT size_t* psNumValues ) { NTSTATUS status = STATUS_SUCCESS; BOOLEAN bInLock = FALSE; BAIL_ON_NT_INVALID_POINTER(pKeyResult); LWREG_LOCK_RWMUTEX_EXCLUSIVE(bInLock, &pKeyResult->mutex); status = SqliteCacheUpdateValuesInfo_inlock(dwOffSet, pKeyResult, psNumValues); BAIL_ON_NT_STATUS(status); cleanup: LWREG_UNLOCK_RWMUTEX(bInLock, &pKeyResult->mutex); return status; error: goto cleanup; }
VOID MemCloseKey( IN HKEY hKey ) { BOOLEAN bInLock = FALSE; if (hKey) { LWREG_LOCK_RWMUTEX_EXCLUSIVE(bInLock, &MemRegRoot()->lock); MemDbCloseKey(hKey); LWREG_UNLOCK_RWMUTEX(bInLock, &MemRegRoot()->lock); } }
VOID MemProvider_Shutdown( PREGPROV_PROVIDER_FUNCTION_TABLE pFnTable ) { REG_DB_CONNECTION regDbConn = {0}; NTSTATUS status = 0; PWSTR pwszRootKey = NULL; BOOLEAN bInLock = FALSE; PREG_DB_CONNECTION pMemRegRoot = MemRegRoot(); MEMDB_FILE_EXPORT_CTX exportCtx = {0}; exportCtx.hNode = pMemRegRoot->pMemReg; LWREG_LOCK_RWMUTEX_EXCLUSIVE(bInLock, &pMemRegRoot->lock); status = MemDbExportToFile(&exportCtx); BAIL_ON_REG_ERROR(status); regDbConn.pMemReg = pMemRegRoot->pMemReg; status = MemDbClose(®DbConn); BAIL_ON_REG_ERROR(status); BAIL_ON_REG_ERROR(RegMapErrnoToLwRegError( pthread_mutex_destroy(&pMemRegRoot->ExportMutex))); BAIL_ON_REG_ERROR(RegMapErrnoToLwRegError( pthread_mutex_destroy(&pMemRegRoot->ExportMutexStop))); BAIL_ON_REG_ERROR(RegMapErrnoToLwRegError( pthread_cond_destroy(&pMemRegRoot->ExportCond))); BAIL_ON_REG_ERROR(RegMapErrnoToLwRegError( pthread_cond_destroy(&pMemRegRoot->ExportCondStop))); LWREG_UNLOCK_RWMUTEX(bInLock, &pMemRegRoot->lock); BAIL_ON_REG_ERROR(RegMapErrnoToLwRegError( pthread_rwlock_destroy(&pMemRegRoot->lock))); cleanup: LWREG_SAFE_FREE_MEMORY(pMemRegRoot->ExportCtx); LWREG_SAFE_FREE_MEMORY(pMemRegRoot); LWREG_SAFE_FREE_MEMORY(pwszRootKey); return; error: goto cleanup; }
NTSTATUS MemDeleteTree( IN HANDLE Handle, IN HKEY hKey, IN OPTIONAL PCWSTR pwszSubKey ) { NTSTATUS status = 0; REG_DB_CONNECTION regDbConn = {0}; PREG_KEY_HANDLE pKeyHandle = (PREG_KEY_HANDLE) hKey; BOOLEAN bInLock = FALSE; regDbConn.pMemReg = pKeyHandle->pKey->hNode; LWREG_LOCK_RWMUTEX_EXCLUSIVE(bInLock, &MemRegRoot()->lock); /* * First determine if any subkey has a non-zero refcount. Refuse * to delete the tree if this is true. */ status = MemDbRecurseRegistry( Handle, ®DbConn, pwszSubKey, pfMemRegSubTreeRefCount, NULL); BAIL_ON_NT_STATUS(status); /* No keys are open, so proceed with the deletion of the subtree. */ status = MemDbRecurseDepthFirstRegistry( Handle, ®DbConn, pwszSubKey, pfDeleteNodeCallback, NULL); MemDbExportEntryChanged(); cleanup: LWREG_UNLOCK_RWMUTEX(bInLock, &MemRegRoot()->lock); return status; error: goto cleanup; }
NTSTATUS MemSetValueEx( IN HANDLE Handle, IN HKEY hKey, IN OPTIONAL PCWSTR pValueName, IN DWORD dwReserved, IN DWORD dwType, IN const BYTE *pData, DWORD cbData ) { NTSTATUS status = 0; REG_DB_CONNECTION regDbConn = {0}; PREG_KEY_HANDLE pKeyHandle = (PREG_KEY_HANDLE) hKey; BOOLEAN bInLock = FALSE; if (pValueName && wc16slen(pValueName) > MEMREG_MAX_VALUENAME_LEN) { status = STATUS_INVALID_BLOCK_LENGTH; BAIL_ON_NT_STATUS(status); } regDbConn.pMemReg = pKeyHandle->pKey->hNode; LWREG_LOCK_RWMUTEX_EXCLUSIVE(bInLock, &MemRegRoot()->lock); status = MemDbSetValueEx( Handle, ®DbConn, pValueName, dwReserved, dwType, pData, cbData); BAIL_ON_NT_STATUS(status); MemDbExportEntryChanged(); cleanup: LWREG_UNLOCK_RWMUTEX(bInLock, &MemRegRoot()->lock); return status; error: goto cleanup; }
NTSTATUS SqliteCacheKeyDefaultValuesInfo( IN OUT PREG_KEY_CONTEXT pKeyResult ) { NTSTATUS status = STATUS_SUCCESS; BOOLEAN bInLock = FALSE; BAIL_ON_NT_INVALID_POINTER(pKeyResult); LWREG_LOCK_RWMUTEX_EXCLUSIVE(bInLock, &pKeyResult->mutex); status = SqliteCacheKeyDefaultValuesInfo_inlock(pKeyResult); BAIL_ON_NT_STATUS(status); cleanup: LWREG_UNLOCK_RWMUTEX(bInLock, &pKeyResult->mutex); return status; error: goto cleanup; }
NTSTATUS MemDeleteValue( IN HANDLE Handle, IN HKEY hKey, IN OPTIONAL PCWSTR pValueName ) { NTSTATUS status = 0; PREG_KEY_HANDLE pKeyHandle = (PREG_KEY_HANDLE) hKey; PMEMREG_VALUE pRegValue = NULL; BOOLEAN bInLock = FALSE; LWREG_LOCK_RWMUTEX_EXCLUSIVE(bInLock, &MemRegRoot()->lock); status = MemRegStoreFindNodeValue( pKeyHandle->pKey->hNode, pValueName, &pRegValue); BAIL_ON_NT_STATUS(status); if (!pRegValue->Data) { status = STATUS_CANNOT_DELETE; BAIL_ON_NT_STATUS(status); } LWREG_SAFE_FREE_MEMORY(pRegValue->Data); pRegValue->DataLen = 0; MemDbExportEntryChanged(); cleanup: LWREG_UNLOCK_RWMUTEX(bInLock, &MemRegRoot()->lock); return status; error: goto cleanup; }
NTSTATUS MemDeleteKey( IN HANDLE Handle, IN HKEY hKey, IN PCWSTR pSubKey ) { NTSTATUS status = 0; PREG_KEY_HANDLE pKeyHandle = (PREG_KEY_HANDLE) hKey; PMEMREG_NODE hParentKey = NULL; PMEMREG_NODE hRegKey = NULL; PSECURITY_DESCRIPTOR_RELATIVE SecurityDescriptor = NULL; DWORD SecurityDescriptorLen = 0; PREG_SRV_API_STATE pServerState = (PREG_SRV_API_STATE)Handle; ACCESS_MASK AccessGranted = 0; BOOLEAN bInLock = FALSE; if (pKeyHandle && pKeyHandle->pKey->hNode->pNodeSd) { SecurityDescriptor = pKeyHandle->pKey->hNode->pNodeSd->SecurityDescriptor; SecurityDescriptorLen = pKeyHandle->pKey->hNode->pNodeSd->SecurityDescriptorLen; } if (SecurityDescriptor && pServerState && pServerState->pToken) { status = RegSrvAccessCheckKey(pServerState->pToken, SecurityDescriptor, SecurityDescriptorLen, KEY_WRITE, &AccessGranted); } if (STATUS_NO_TOKEN == status) { status = 0; AccessGranted = 0; } BAIL_ON_NT_STATUS(status); if (hKey) { hParentKey = pKeyHandle->pKey->hNode; } else { hParentKey = MemRegRoot()->pMemReg; } LWREG_LOCK_RWMUTEX_EXCLUSIVE(bInLock, &MemRegRoot()->lock); status = MemRegStoreFindNode( hParentKey, pSubKey, &hRegKey); BAIL_ON_NT_STATUS(status); /* Don't delete this node if it has subkeys */ if (hRegKey->NodesLen > 0) { status = STATUS_KEY_HAS_CHILDREN; BAIL_ON_NT_STATUS(status); } /* Don't delete this node if there are still open handles to it */ if (hRegKey->NodeRefCount >= 1) { status = STATUS_RESOURCE_IN_USE; BAIL_ON_NT_STATUS(status); } status = MemRegStoreDeleteNode(hRegKey); BAIL_ON_NT_STATUS(status); MemDbExportEntryChanged(); cleanup: LWREG_UNLOCK_RWMUTEX(bInLock, &MemRegRoot()->lock); return status; error: goto cleanup; }
NTSTATUS MemCreateKeyEx( IN HANDLE Handle, IN HKEY hKey, IN PCWSTR pSubKey, IN DWORD dwReserved, IN OPTIONAL PWSTR pClass, IN DWORD dwOptions, IN ACCESS_MASK AccessDesired, IN OPTIONAL PSECURITY_DESCRIPTOR_RELATIVE pSecDescRel, IN ULONG ulSecDescLength, OUT PHKEY phkResult, OUT OPTIONAL PDWORD pdwDisposition ) { NTSTATUS status = 0; PREG_KEY_HANDLE pKeyHandle = (PREG_KEY_HANDLE)hKey; PMEMREG_NODE hRootKey = NULL; PMEMREG_NODE hSubKey = NULL; REG_DB_CONNECTION regDbConn = {0}; PWSTR pwszRootKey = NULL; PREG_SRV_API_STATE pServerState = (PREG_SRV_API_STATE)Handle; ACCESS_MASK AccessGranted = 0; PSECURITY_DESCRIPTOR_RELATIVE SecurityDescriptor = NULL; DWORD SecurityDescriptorLen = 0; BOOLEAN bInLock = FALSE; LWREG_LOCK_RWMUTEX_EXCLUSIVE(bInLock, &MemRegRoot()->lock); if (!hKey) { status = LwRtlWC16StringAllocateFromCString( &pwszRootKey, HKEY_THIS_MACHINE); BAIL_ON_NT_STATUS(status); // Search for specified root key. If NULL, return HKTM. status = MemDbOpenKey( Handle, NULL, pwszRootKey, AccessDesired, &hRootKey); BAIL_ON_NT_STATUS(status); regDbConn.pMemReg = hRootKey; } else { regDbConn.pMemReg = pKeyHandle->pKey->hNode; } if (!pServerState->pToken) { status = RegSrvCreateAccessToken(pServerState->peerUID, pServerState->peerGID, &pServerState->pToken); BAIL_ON_NT_STATUS(status); } if (pSecDescRel) { SecurityDescriptor = pSecDescRel; SecurityDescriptorLen = ulSecDescLength; } else { SecurityDescriptor = pKeyHandle->pKey->hNode->pNodeSd->SecurityDescriptor; SecurityDescriptorLen = pKeyHandle->pKey->hNode->pNodeSd->SecurityDescriptorLen; } if (SecurityDescriptor) { status = RegSrvAccessCheckKey(pServerState->pToken, SecurityDescriptor, SecurityDescriptorLen, AccessDesired, &AccessGranted); } if (STATUS_NO_TOKEN == status) { status = 0; AccessGranted = 0; } BAIL_ON_NT_STATUS(status); status = MemDbCreateKeyEx( Handle, // Access token is on this handle ®DbConn, pSubKey, 0, // IN DWORD dwReserved NULL, // IN OPTIONAL PWSTR pClass 0, //IN DWORD dwOptions AccessDesired, // IN ACCESS_MASK pSecDescRel, // IN OPTIONAL ulSecDescLength, // IN ULONG &hSubKey, pdwDisposition); BAIL_ON_NT_STATUS(status); status = _MemCreateHkeyReply(hSubKey, phkResult); BAIL_ON_NT_STATUS(status); pKeyHandle->AccessGranted = AccessGranted; hSubKey->NodeRefCount++; MemDbExportEntryChanged(); cleanup: LWREG_UNLOCK_RWMUTEX(bInLock, &MemRegRoot()->lock); LWREG_SAFE_FREE_MEMORY(pwszRootKey); return status; error: if (hRootKey) { // Close open root key } goto cleanup; }