NTSTATUS SqliteCreateKeyHandle( IN PACCESS_TOKEN pToken, IN ACCESS_MASK AccessDesired, IN PREG_KEY_CONTEXT pKey, OUT PREG_KEY_HANDLE* ppKeyHandle ) { NTSTATUS status = STATUS_SUCCESS; PREG_KEY_HANDLE pKeyHandle = NULL; ACCESS_MASK AccessGranted = 0; BAIL_ON_INVALID_KEY_CONTEXT(pKey); status = RegSrvAccessCheckKey(pToken, pKey->pSecurityDescriptor, pKey->ulSecDescLength, AccessDesired, &AccessGranted); if (STATUS_NO_TOKEN == status) { status = 0; AccessGranted = 0; } BAIL_ON_NT_STATUS(status); status = LW_RTL_ALLOCATE((PVOID*)&pKeyHandle, REG_KEY_HANDLE, sizeof(*pKeyHandle)); BAIL_ON_NT_STATUS(status); pKeyHandle->AccessGranted = AccessGranted; pKeyHandle->pKey = pKey; *ppKeyHandle = pKeyHandle; cleanup: return status; error: LWREG_SAFE_FREE_MEMORY(pKeyHandle); 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; }