Changeset 108285 in vbox
- Timestamp:
- Feb 19, 2025 10:53:35 AM (3 weeks ago)
- svn:sync-xref-src-repo-rev:
- 167628
- Location:
- trunk/src/VBox/Installer/win/InstallHelper
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Installer/win/InstallHelper/VBoxCommon.cpp
r108071 r108285 36 36 #include <msiquery.h> 37 37 38 #include <iprt/mem.h> 38 39 #include <iprt/string.h> 39 40 #include <iprt/utf16.h> … … 94 95 } 95 96 #endif /* !TESTCASE */ 97 98 /** 99 * Destroys a custom action data entry. 100 * 101 * @param pEntry Custom action data entry to destroy. 102 */ 103 static void vboxMsiCustomActionDataEntryDestroy(PVBOXMSICUSTOMACTIONDATAENTRY pEntry) 104 { 105 if (!pEntry) 106 return; 107 108 RTStrFree(pEntry->pszKey); 109 pEntry->pszKey = NULL; 110 RTStrFree(pEntry->pszVal); 111 pEntry->pszVal = NULL; 112 } 113 114 /** 115 * Queries custom action data entries, extended version. 116 * 117 * @returns VBox status code. 118 * @param hMsi MSI handle to use. 119 * @param pszSep Separator to use for parsing the key=value pairs. 120 * @param ppaEntries Where to return the allocated custom action data entries. 121 Might be NULL if \a pcEntries returns 0. 122 * Must be destroyed using vboxMsiCustomActionDataEntryDestroy(). 123 * @param pcEntries Where to return the number of allocated custom action data entries of \a ppaEntries. 124 * 125 * @note The "CustomActionData" property used is fixed by the MSI engine and must not be changed. 126 */ 127 static int vboxMsiCustomActionDataQueryEx(MSIHANDLE hMsi, const char *pszSep, PVBOXMSICUSTOMACTIONDATAENTRY *ppaEntries, size_t *pcEntries) 128 { 129 char *pszData = NULL; 130 int rc = VBoxMsiQueryPropUtf8(hMsi, "CustomActionData", &pszData); 131 if (RT_FAILURE(rc)) 132 return rc; 133 134 *ppaEntries = NULL; 135 136 char **ppapszPairs; /* key=value pairs. */ 137 size_t cPairs; 138 rc = RTStrSplit(pszData, strlen(pszData) + 1 /* Must include terminator */, pszSep, &ppapszPairs, &cPairs); 139 if ( RT_SUCCESS(rc) 140 && cPairs) 141 { 142 PVBOXMSICUSTOMACTIONDATAENTRY paEntries = 143 (PVBOXMSICUSTOMACTIONDATAENTRY)RTMemAllocZ(cPairs * sizeof(VBOXMSICUSTOMACTIONDATAENTRY)); 144 if (paEntries) 145 { 146 size_t i = 0; 147 for (; i < cPairs; i++) 148 { 149 const char *pszPair = ppapszPairs[i]; 150 151 char **ppapszKeyVal; 152 size_t cKeyVal; 153 rc = RTStrSplit(pszPair, strlen(pszPair) + 1 /* Must include terminator */, "=", &ppapszKeyVal, &cKeyVal); 154 if (RT_SUCCESS(rc)) 155 { 156 if (cKeyVal == 2) /* Exactly one key=val pair. */ 157 { 158 /* paEntries[i] will take ownership of ppapszKeyVal. */ 159 paEntries[i].pszKey = ppapszKeyVal[0]; 160 ppapszKeyVal[0] = NULL; 161 paEntries[i].pszVal = ppapszKeyVal[1]; 162 ppapszKeyVal[1] = NULL; 163 } 164 else 165 rc = VERR_INVALID_PARAMETER; 166 167 for (size_t a = 0; a < cKeyVal; a++) 168 RTStrFree(ppapszKeyVal[a]); 169 RTMemFree(ppapszKeyVal); 170 } 171 172 if (RT_FAILURE(rc)) 173 break; 174 } 175 176 if (RT_FAILURE(rc)) 177 { 178 /* Rollback on failure. */ 179 while (i) 180 vboxMsiCustomActionDataEntryDestroy(&paEntries[i--]); 181 RTMemFree(paEntries); 182 } 183 else 184 { 185 *ppaEntries = paEntries; 186 *pcEntries = cPairs; 187 } 188 } 189 else 190 rc = VERR_NO_MEMORY; 191 192 for (size_t i = 0; i < cPairs; i++) 193 RTStrFree(ppapszPairs[i]); 194 RTMemFree(ppapszPairs); 195 } 196 197 return rc; 198 } 199 200 /** 201 * Queries custom action data entries. 202 * 203 * @returns VBox status code. 204 * @param hMsi MSI handle to use. 205 * @param ppaEntries Where to return the allocated custom action data entries. 206 * Must be destroyed using vboxMsiCustomActionDataEntryDestroy(). 207 * @param pcEntries Where to return the number of allocated custom action data entries of \a ppaEntries. 208 */ 209 static int vboxMsiCustomActionDataQuery(MSIHANDLE hMsi, PVBOXMSICUSTOMACTIONDATAENTRY *ppaEntries, size_t *pcEntries) 210 { 211 return vboxMsiCustomActionDataQueryEx(hMsi, VBOX_MSI_CUSTOMACTIONDATA_SEP_STR, ppaEntries, pcEntries); 212 } 213 214 /** 215 * Frees custom action data. 216 * 217 * @returns VBox status code. 218 * @param pData Custom action data to free. 219 * The pointer will be invalid on return. 220 */ 221 void VBoxMsiCustomActionDataFree(PVBOXMSICUSTOMACTIONDATA pData) 222 { 223 if (!pData) 224 return; 225 226 for (size_t i = 0; i < pData->cEntries; i++) 227 vboxMsiCustomActionDataEntryDestroy(&pData->paEntries[i]); 228 229 RTMemFree(pData); 230 pData = NULL; 231 } 232 233 /** 234 * Queries custom action data, extended version. 235 * 236 * @returns VBox status code. 237 * @param hMsi MSI handle to use. 238 * @param pszSep Separator to use for parsing the key=value pairs. 239 * @param ppData Where to return the allocated custom action data. 240 * Needs to be free'd using VBoxMsiCustomActionDataFree(). 241 */ 242 int VBoxMsiCustomActionDataQueryEx(MSIHANDLE hMsi, const char *pszSep, PVBOXMSICUSTOMACTIONDATA *ppData) 243 { 244 AssertPtrReturn(pszSep, VERR_INVALID_POINTER); 245 AssertPtrReturn(ppData, VERR_INVALID_POINTER); 246 247 PVBOXMSICUSTOMACTIONDATA pData = (PVBOXMSICUSTOMACTIONDATA)RTMemAllocZ(sizeof(VBOXMSICUSTOMACTIONDATA)); 248 AssertPtrReturn(pData, VERR_NO_MEMORY); 249 250 int rc = vboxMsiCustomActionDataQueryEx(hMsi, pszSep, &pData->paEntries, &pData->cEntries); 251 if (RT_SUCCESS(rc)) 252 { 253 *ppData = pData; 254 } 255 else 256 VBoxMsiCustomActionDataFree(pData); 257 258 return rc; 259 } 260 261 /** 262 * Queries custom action data. 263 * 264 * @returns VBox status code. 265 * @param hMsi MSI handle to use. 266 * @param ppData Where to return the allocated custom action data. 267 * Needs to be free'd using VBoxMsiCustomActionDataFree(). 268 */ 269 int VBoxMsiCustomActionDataQuery(MSIHANDLE hMsi, PVBOXMSICUSTOMACTIONDATA *ppData) 270 { 271 return VBoxMsiCustomActionDataQueryEx(hMsi, VBOX_MSI_CUSTOMACTIONDATA_SEP_STR, ppData); 272 } 273 274 /** 275 * Finds a key in custom action data and returns its value. 276 * 277 * @returns Value if found, or NULL if not found. 278 * @param pHaystack Custom action data to search in. 279 * @param pszNeedle Key to search for. Case-sensitive. 280 */ 281 const char *VBoxMsiCustomActionDataFind(PVBOXMSICUSTOMACTIONDATA pHaystack, const char *pszNeedle) 282 { 283 AssertPtrReturn(pHaystack, NULL); 284 AssertPtrReturn(pszNeedle, NULL); 285 286 for (size_t i = 0; i < pHaystack->cEntries; i++) 287 { 288 if (!RTStrICmp(pHaystack->paEntries[i].pszKey, pszNeedle)) 289 return pHaystack->paEntries[i].pszVal; 290 } 291 292 return NULL; 293 } 96 294 97 295 /** -
trunk/src/VBox/Installer/win/InstallHelper/VBoxCommon.h
r108071 r108285 36 36 #endif 37 37 38 /** Struct for keeping a single "CustomActionData" key=value item. */ 39 typedef struct VBOXMSICUSTOMACTIONDATAENTRY 40 { 41 /** Key (name) of the item. */ 42 char *pszKey; 43 /** Value of the item. Always a string but can represent other stuff. Use with care. */ 44 char *pszVal; 45 } VBOXMSICUSTOMACTIONDATAENTRY; 46 /** Pointer to a struct for keeping a single "CustomActionData" key=value item. */ 47 typedef VBOXMSICUSTOMACTIONDATAENTRY *PVBOXMSICUSTOMACTIONDATAENTRY; 48 49 /** Struct for keeping "CustomActionData" entries. */ 50 typedef struct VBOXMSICUSTOMACTIONDATA 51 { 52 /** Array of CustomActionData entries. */ 53 PVBOXMSICUSTOMACTIONDATAENTRY paEntries; 54 /** Number of entries in \a paEntries. */ 55 size_t cEntries; 56 } VBOXMSICUSTOMACTIONDATA; 57 /** Pointer to a struct for keeping "CustomActionData" entries. */ 58 typedef VBOXMSICUSTOMACTIONDATA *PVBOXMSICUSTOMACTIONDATA; 59 60 /** Default separator for custom action data key=value pairs. */ 61 #define VBOX_MSI_CUSTOMACTIONDATA_SEP_STR "##" 62 63 void VBoxMsiCustomActionDataFree(PVBOXMSICUSTOMACTIONDATA pData); 64 int VBoxMsiCustomActionDataQueryEx(MSIHANDLE hMsi, const char *pszSep, PVBOXMSICUSTOMACTIONDATA *ppData); 65 int VBoxMsiCustomActionDataQuery(MSIHANDLE hMsi, PVBOXMSICUSTOMACTIONDATA *ppData); 66 const char *VBoxMsiCustomActionDataFind(PVBOXMSICUSTOMACTIONDATA pHaystack, const char *pszNeedle); 67 38 68 int VBoxMsiQueryProp(MSIHANDLE hMsi, const WCHAR *pwszName, WCHAR *pwszVal, DWORD cwVal); 39 69 int VBoxMsiQueryPropEx(MSIHANDLE hMsi, const WCHAR *pwszName, WCHAR *pwszVal, DWORD *pcwVal); … … 41 71 int VBoxMsiQueryPropInt32(MSIHANDLE hMsi, const char *pszName, DWORD *pdwValue); 42 72 UINT VBoxMsiSetProp(MSIHANDLE hMsi, const WCHAR *pwszName, const WCHAR *pwszValue); 43 int VBoxMsiSetPropUtf8(MSIHANDLE hMsi, const char *pszName, const char *pszValue);73 int VBoxMsiSetPropUtf8(MSIHANDLE hMsi, const char *pszName, const char *pszValue); 44 74 UINT VBoxMsiSetPropDWORD(MSIHANDLE hMsi, const WCHAR *pwszName, DWORD dwVal); 45 int VBoxMsiRegQueryDWORDW(MSIHANDLE hMsi, HKEY hKey, LPCWSTR pwszName, DWORD *pdwValue);46 int VBoxMsiRegQueryDWORD(MSIHANDLE hMsi, HKEY hKey, const char *pszName, DWORD *pdwValue);75 int VBoxMsiRegQueryDWORDW(MSIHANDLE hMsi, HKEY hKey, LPCWSTR pwszName, DWORD *pdwValue); 76 int VBoxMsiRegQueryDWORD(MSIHANDLE hMsi, HKEY hKey, const char *pszName, DWORD *pdwValue); 47 77 48 78 #endif /* !VBOX_INCLUDED_SRC_InstallHelper_VBoxCommon_h */
Note:
See TracChangeset
for help on using the changeset viewer.