| | 1010 | |
|---|
| | 1011 | |
|---|
| | 1012 | /** |
|---|
| | 1013 | * Creates a CFGM tree. |
|---|
| | 1014 | * |
|---|
| | 1015 | * This is intended for creating device/driver configs can be |
|---|
| | 1016 | * passed around and later attached to the main tree in the |
|---|
| | 1017 | * correct location. |
|---|
| | 1018 | * |
|---|
| | 1019 | * @returns Pointer to the root node. |
|---|
| | 1020 | * @param pVM The VM handle. |
|---|
| | 1021 | */ |
|---|
| | 1022 | CFGMR3DECL(PCFGMNODE) CFGMR3CreateTree(PVM pVM) |
|---|
| | 1023 | { |
|---|
| | 1024 | PCFGMNODE pNew = (PCFGMNODE)MMR3HeapAlloc(pVM, MM_TAG_CFGM, sizeof(*pNew)); |
|---|
| | 1025 | if (pNew) |
|---|
| | 1026 | { |
|---|
| | 1027 | pNew->pPrev = NULL; |
|---|
| | 1028 | pNew->pNext = NULL; |
|---|
| | 1029 | pNew->pParent = NULL; |
|---|
| | 1030 | pNew->pFirstChild = NULL; |
|---|
| | 1031 | pNew->pFirstLeaf = NULL; |
|---|
| | 1032 | pNew->pVM = pVM; |
|---|
| | 1033 | pNew->fRestrictedRoot = false; |
|---|
| | 1034 | pNew->cchName = 0; |
|---|
| | 1035 | pNew->szName[0] = 0; |
|---|
| | 1036 | } |
|---|
| | 1037 | return pNew; |
|---|
| | 1038 | } |
|---|
| | 1039 | |
|---|
| | 1040 | |
|---|
| | 1041 | /** |
|---|
| | 1042 | * Insert subtree. |
|---|
| | 1043 | * |
|---|
| | 1044 | * This function inserts (no duplication) a tree created by CFGMR3CreateTree() |
|---|
| | 1045 | * into the main tree. |
|---|
| | 1046 | * |
|---|
| | 1047 | * The root node of the inserted subtree will need to be reallocated, which |
|---|
| | 1048 | * effectually means that the passed in pSubTree handle becomes invalid |
|---|
| | 1049 | * upon successful return. Use the value returned in ppChild instead |
|---|
| | 1050 | * of pSubTree. |
|---|
| | 1051 | * |
|---|
| | 1052 | * @returns VBox status code. |
|---|
| | 1053 | * @returns VERR_CFGM_NODE_EXISTS if the final child node name component exists. |
|---|
| | 1054 | * @param pNode Parent node. |
|---|
| | 1055 | * @param pszName Name or path of the new child node. |
|---|
| | 1056 | * @param pSubTree The subtree to insert. Must be returned by CFGMR3CreateTree(). |
|---|
| | 1057 | * @param ppChild Where to store the address of the new child node. (optional) |
|---|
| | 1058 | */ |
|---|
| | 1059 | CFGMR3DECL(int) CFGMR3InsertSubTree(PCFGMNODE pNode, const char *pszName, PCFGMNODE pSubTree, PCFGMNODE *ppChild) |
|---|
| | 1060 | { |
|---|
| | 1061 | /* |
|---|
| | 1062 | * Validate input. |
|---|
| | 1063 | */ |
|---|
| | 1064 | AssertPtrReturn(pSubTree, VERR_INVALID_POINTER); |
|---|
| | 1065 | AssertReturn(!pSubTree->pParent, VERR_INVALID_PARAMETER); |
|---|
| | 1066 | AssertReturn(pSubTree->pVM, VERR_INVALID_PARAMETER); |
|---|
| | 1067 | AssertReturn(pSubTree->pParent != pSubTree->pVM->cfgm.s.pRoot, VERR_INVALID_PARAMETER); |
|---|
| | 1068 | Assert(!pSubTree->pNext); |
|---|
| | 1069 | Assert(!pSubTree->pPrev); |
|---|
| | 1070 | |
|---|
| | 1071 | /* |
|---|
| | 1072 | * Use CFGMR3InsertNode to create a new node and then |
|---|
| | 1073 | * re-attach the children and leafs of the subtree to it. |
|---|
| | 1074 | */ |
|---|
| | 1075 | PCFGMNODE pNewChild; |
|---|
| | 1076 | int rc = CFGMR3InsertNode(pNode, pszName, &pNewChild); |
|---|
| | 1077 | if (RT_SUCCESS(rc)) |
|---|
| | 1078 | { |
|---|
| | 1079 | Assert(pNewChild->pFirstChild); |
|---|
| | 1080 | pNewChild->pFirstChild = pSubTree->pFirstChild; |
|---|
| | 1081 | Assert(pNewChild->pFirstLeaf); |
|---|
| | 1082 | pNewChild->pFirstLeaf = pSubTree->pFirstLeaf; |
|---|
| | 1083 | if (ppChild) |
|---|
| | 1084 | *ppChild = pNewChild; |
|---|
| | 1085 | |
|---|
| | 1086 | /* free the old subtree root */ |
|---|
| | 1087 | pSubTree->pVM = NULL; |
|---|
| | 1088 | pSubTree->pFirstLeaf = NULL; |
|---|
| | 1089 | pSubTree->pFirstChild = NULL; |
|---|
| | 1090 | MMR3HeapFree(pSubTree); |
|---|
| | 1091 | } |
|---|
| | 1092 | return rc; |
|---|
| | 1093 | } |
|---|