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 MemRegStoreFindNodeSubkey( IN PMEMREG_NODE hDbNode, IN PCWSTR pwszSubKeyPath, OUT PMEMREG_NODE * phNode) { NTSTATUS status = 0; PWSTR pwszTmpFullPath = NULL; PWSTR pwszSubKey = NULL; PWSTR pwszPtr = NULL; PMEMREG_NODE hParentKey = NULL; PMEMREG_NODE hSubKey = NULL; BOOLEAN bEndOfString = FALSE; BAIL_ON_NT_STATUS(status); if (!pwszSubKeyPath) { pwszSubKeyPath = (PCWSTR) L""; } status = LwRtlWC16StringDuplicate(&pwszTmpFullPath, pwszSubKeyPath); BAIL_ON_NT_STATUS(status); hParentKey = hDbNode; pwszSubKey = pwszTmpFullPath; do { pwszPtr = pwstr_wcschr(pwszSubKey, L'\\'); if (pwszPtr) { *pwszPtr++ = L'\0'; } else { pwszPtr = pwszSubKey; bEndOfString = TRUE; } /* * Iterate over subkeys in \ sepearated path. */ status = MemRegStoreFindNode( hParentKey, pwszSubKey, &hSubKey); hParentKey = hSubKey; pwszSubKey = pwszPtr; } while (status == 0 && !bEndOfString); if (status == 0) { *phNode = hParentKey; } cleanup: LWREG_SAFE_FREE_MEMORY(pwszTmpFullPath); 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; }