b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * IPRT - Debugging Configuration.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * Copyright (C) 2013 Oracle Corporation
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * available from http://www.virtualbox.org. This file is free software;
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * you can redistribute it and/or modify it under the terms of the GNU
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * General Public License (GPL) as published by the Free Software
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * The contents of this file may alternatively be used under the terms
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * of the Common Development and Distribution License Version 1.0
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * VirtualBox OSE distribution, in which case the provisions of the
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * CDDL are applicable instead of those of the GPL.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * You may elect to license modified versions of this file under the
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * terms and conditions of either the GPL or the CDDL or both.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync/*******************************************************************************
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync* Header Files *
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync*******************************************************************************/
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync/*******************************************************************************
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync* Structures and Typedefs *
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync*******************************************************************************/
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * String list entry.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync /** List entry. */
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync /** Domain specific flags. */
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync /** The length of the string. */
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync /** The string. */
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync/** Pointer to a string list entry. */
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * Configuration instance.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync /** The magic value (RTDBGCFG_MAGIC). */
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync /** Reference counter. */
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync /** Flags, see RTDBGCFG_FLAGS_XXX. */
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync /** List of paths to search for debug files and executable images. */
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync /** List of debug file suffixes. */
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync /** List of paths to search for source files. */
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync /** The _NT_ALT_SYMBOL_PATH and _NT_SYMBOL_PATH combined. */
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync /** The _NT_EXECUTABLE_PATH. */
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync /** The _NT_SOURCE_PATH. */
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync /** Log callback function. */
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync /** User argument to pass to the log callback. */
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync /** Critical section protecting the instance data. */
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * Mnemonics map entry for a 64-bit unsigned property value.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync /** The flags to set or clear. */
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync /** The mnemonic. */
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync /** The length of the mnemonic. */
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync /** If @c true, the bits in fFlags will be set, if @c false they will be
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * cleared. */
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync/** Pointer to a read only mnemonic map entry for a uint64_t property. */
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsynctypedef RTDBGCFGU64MNEMONIC const *PCRTDBGCFGU64MNEMONIC;
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync/** @name Open flags.
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync/** The operative system mask. The values are RT_OPSYS_XXX. */
fa6dbd9c9e9645298cca864aa561382469907905vboxsync/** The files may be compressed MS styled. */
fa6dbd9c9e9645298cca864aa561382469907905vboxsync#define RTDBGCFG_O_MAYBE_COMPRESSED_MS RT_BIT_32(26)
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync/** Whether to make a recursive search. */
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync/** We're looking for a separate debug file. */
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync/** We're looking for an executable image. */
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync/** The file search should be done in an case insensitive fashion. */
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync/** Use Windbg style symbol servers when encountered in the path. */
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync/*******************************************************************************
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync* Defined Constants And Macros *
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync*******************************************************************************/
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync/** Validates a debug module handle and returns rc if not valid. */
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync AssertReturn((pThis)->u32Magic == RTDBGCFG_MAGIC, (rc)); \
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync } while (0)
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync/*******************************************************************************
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync* Global Variables *
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync*******************************************************************************/
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync/** Mnemonics map for RTDBGCFGPROP_FLAGS. */
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync { RTDBGCFG_FLAGS_DEFERRED, RT_STR_TUPLE("deferred"), true },
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync { RTDBGCFG_FLAGS_DEFERRED, RT_STR_TUPLE("nodeferred"), false },
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync { RTDBGCFG_FLAGS_NO_SYM_SRV, RT_STR_TUPLE("symsrv"), false },
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync { RTDBGCFG_FLAGS_NO_SYM_SRV, RT_STR_TUPLE("nosymsrv"), true },
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync { RTDBGCFG_FLAGS_NO_SYSTEM_PATHS, RT_STR_TUPLE("syspaths"), false },
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync { RTDBGCFG_FLAGS_NO_SYSTEM_PATHS, RT_STR_TUPLE("nosyspaths"), true },
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync { RTDBGCFG_FLAGS_NO_RECURSIV_SEARCH, RT_STR_TUPLE("rec"), false },
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync { RTDBGCFG_FLAGS_NO_RECURSIV_SEARCH, RT_STR_TUPLE("norec"), true },
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync { RTDBGCFG_FLAGS_NO_RECURSIV_SRC_SEARCH, RT_STR_TUPLE("recsrc"), false },
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync { RTDBGCFG_FLAGS_NO_RECURSIV_SRC_SEARCH, RT_STR_TUPLE("norecsrc"), true },
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync { 0, NULL, 0, false }
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync/** Interesting bundle suffixes. */
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync ".framework",
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync ".component",
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync ".caction",
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync ".sourcebundle",
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync ".monitorpanel",
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync ".scripting",
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync ".prefPane",
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync ".qlgenerator",
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync ".brailledriver",
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync ".SpeechVoice",
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync ".SpeechRecognizer",
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync ".SpeechSynthesizer",
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync ".mdimporter",
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync ".spreporter",
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync/** Debug bundle suffixes. (Same as above + .dSYM) */
e0d6f087507011df5f570f6800a2c332f8970e58vboxsyncstatic const char * const g_apszDSymBundleSuffixes[] =
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync ".kext.dSYM",
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync ".app.dSYM",
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync ".framework.dSYM",
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync ".component.dSYM",
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync ".action.dSYM",
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync ".caction.dSYM",
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync ".bundle.dSYM",
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync ".sourcebundle.dSYM",
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync ".menu.dSYM",
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync ".plugin.dSYM",
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync ".ppp.dSYM",
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync ".monitorpanel.dSYM",
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync ".scripting.dSYM",
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync ".prefPane.dSYM",
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync ".qlgenerator.dSYM",
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync ".brailledriver.dSYM",
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync ".saver.dSYM",
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync ".SpeechVoice.dSYM",
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync ".SpeechRecognizer.dSYM",
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync ".SpeechSynthesizer.dSYM",
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync ".mdimporter.dSYM",
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync ".spreporter.dSYM",
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync ".xpc.dSYM",
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * Runtime logging, level 1.
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * @param pThis The debug config instance data.
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * @param pszFormat The message format string.
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * @param ... Arguments references in the format string.
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsyncstatic void rtDbgCfgLog1(PRTDBGCFGINT pThis, const char *pszFormat, ...)
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync if (LogIsEnabled() || (pThis && pThis->pfnLogCallback))
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync pThis->pfnLogCallback(pThis, 1, pszMsg, pThis->pvLogUser);
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * Runtime logging, level 2.
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * @param pThis The debug config instance data.
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * @param pszFormat The message format string.
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * @param ... Arguments references in the format string.
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsyncstatic void rtDbgCfgLog2(PRTDBGCFGINT pThis, const char *pszFormat, ...)
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync if (LogIs2Enabled() || (pThis && pThis->pfnLogCallback))
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync pThis->pfnLogCallback(pThis, 2, pszMsg, pThis->pvLogUser);
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * Checks if the file system at the given path is case insensitive or not.
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * @returns true / false
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * @param pszPath The path to query about.
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsyncstatic int rtDbgCfgIsFsCaseInsensitive(const char *pszPath)
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * Worker that does case sensitive file/dir searching.
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * @returns true / false.
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync * @param pszPath The path buffer containing an existing directory and
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync * at @a offLastComp the name we're looking for.
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync * RTPATH_MAX in size. On success, this last component
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync * will have the correct case. On failure, the last
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync * component is stripped off.
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * @param offLastComp The offset of the last component (for chopping it
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * @param enmType What kind of thing we're looking for.
9ec22033341c104cf895501e1c2347b15a21ec1evboxsyncstatic bool rtDbgCfgIsXxxxAndFixCaseWorker(char *pszPath, size_t offLastComp, RTDIRENTRYTYPE enmType)
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync /** @todo IPRT should generalize this so we can use host specific tricks to
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * speed it up. */
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync /* Return straight away if the name isn't case foldable. */
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync return false;
fa6dbd9c9e9645298cca864aa561382469907905vboxsync * Try some simple case folding games.
fa6dbd9c9e9645298cca864aa561382469907905vboxsync return true;
fa6dbd9c9e9645298cca864aa561382469907905vboxsync return true;
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * Open the directory and check each entry in it.
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync return false;
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync /* Read the next entry. */
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync RTDirQueryUnknownType(pszPath, true /*fFollowSymlinks*/, &u.Entry.enmType);
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync return true;
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync return false;
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * Appends @a pszSubDir to @a pszPath and check whether it exists and is a
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * directory.
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * If @a fCaseInsensitive is set, we will do a case insensitive search for a
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * matching sub directory.
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * @returns true / false
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * @param pszPath The path buffer containing an existing
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * directory. RTPATH_MAX in size.
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * @param pszSubDir The sub directory to append.
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * @param fCaseInsensitive Whether case insensitive searching is required.
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsyncstatic bool rtDbgCfgIsDirAndFixCase(char *pszPath, const char *pszSubDir, bool fCaseInsensitive)
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync /* Save the length of the input path so we can restore it in the case
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync insensitive branch further down. */
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * Append the sub directory and check if we got a hit.
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync int rc = RTPathAppend(pszPath, RTPATH_MAX, pszSubDir);
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync return false;
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync return true;
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * Do case insensitive lookup if requested.
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync return rtDbgCfgIsXxxxAndFixCaseWorker(pszPath, cchPath, RTDIRENTRYTYPE_DIRECTORY);
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync return false;
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync * Appends @a pszSubDir1 and @a pszSuffix to @a pszPath and check whether it
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync * exists and is a directory.
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync * If @a fCaseInsensitive is set, we will do a case insensitive search for a
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync * matching sub directory.
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync * @returns true / false
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync * @param pszPath The path buffer containing an existing
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync * directory. RTPATH_MAX in size.
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync * @param pszSubDir The sub directory to append.
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync * @param fCaseInsensitive Whether case insensitive searching is required.
e0d6f087507011df5f570f6800a2c332f8970e58vboxsyncstatic bool rtDbgCfgIsDirAndFixCase2(char *pszPath, const char *pszSubDir, const char *pszSuffix, bool fCaseInsensitive)
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync /* Save the length of the input path so we can restore it in the case
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync insensitive branch further down. */
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync * Append the subdirectory and suffix, then check if we got a hit.
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync int rc = RTPathAppend(pszPath, RTPATH_MAX, pszSubDir);
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync return true;
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync * Do case insensitive lookup if requested.
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync return rtDbgCfgIsXxxxAndFixCaseWorker(pszPath, cchPath, RTDIRENTRYTYPE_DIRECTORY);
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync return false;
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * Appends @a pszFilename to @a pszPath and check whether it exists and is a
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * directory.
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * If @a fCaseInsensitive is set, we will do a case insensitive search for a
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * matching filename.
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * @returns true / false
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * @param pszPath The path buffer containing an existing
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * directory. RTPATH_MAX in size.
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync * @param pszFilename The filename to append.
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync * @param pszSuffix Optional filename suffix to append.
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * @param fCaseInsensitive Whether case insensitive searching is required.
fa6dbd9c9e9645298cca864aa561382469907905vboxsync * @param fMsCompressed Whether to look for the MS compressed file name
fa6dbd9c9e9645298cca864aa561382469907905vboxsync * @param pfProbablyCompressed This is set to true if a MS compressed
fa6dbd9c9e9645298cca864aa561382469907905vboxsync * filename variant is returned. Optional.
9ec22033341c104cf895501e1c2347b15a21ec1evboxsyncstatic bool rtDbgCfgIsFileAndFixCase(char *pszPath, const char *pszFilename, const char *pszSuffix, bool fCaseInsensitive,
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync /* Save the length of the input path so we can restore it in the case
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync insensitive branch further down. */
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync * Append the filename and optionally suffix, then check if we got a hit.
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync int rc = RTPathAppend(pszPath, RTPATH_MAX, pszFilename);
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync return false;
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync return false;
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync return true;
fa6dbd9c9e9645298cca864aa561382469907905vboxsync * Do case insensitive file lookup if requested.
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync if (rtDbgCfgIsXxxxAndFixCaseWorker(pszPath, cchPath, RTDIRENTRYTYPE_FILE))
fa6dbd9c9e9645298cca864aa561382469907905vboxsync return true;
fa6dbd9c9e9645298cca864aa561382469907905vboxsync * Look for MS compressed file if requested.
fa6dbd9c9e9645298cca864aa561382469907905vboxsync && (unsigned char)pszFilename[strlen(pszFilename) - 1] < 0x7f)
fa6dbd9c9e9645298cca864aa561382469907905vboxsync rc = RTPathAppend(pszPath, RTPATH_MAX, pszFilename);
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync && rtDbgCfgIsXxxxAndFixCaseWorker(pszPath, cchPath, RTDIRENTRYTYPE_FILE) ))
fa6dbd9c9e9645298cca864aa561382469907905vboxsync return true;
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync return false;
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsyncstatic int rtDbgCfgTryOpenDir(PRTDBGCFGINT pThis, char *pszPath, PRTPATHSPLIT pSplitFn, uint32_t fFlags,
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2)
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync /* If the directory doesn't exist, just quit immediately.
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync Note! Our case insensitivity doesn't extend to the search dirs themselfs,
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync only to the bits under neath them. */
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync rtDbgCfgLog2(pThis, "Dir does not exist: '%s'\n", pszPath);
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync /* Figure out whether we have to do a case sensitive search or not.
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync Note! As a simplification, we don't ask for case settings in each
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync directory under the user specified path, we assume the file
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync systems that mounted there have compatible settings. Faster
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync that way. */
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync bool const fCaseInsensitive = (fFlags & RTDBGCFG_O_CASE_INSENSITIVE)
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * Look for the file with less and less of the original path given.
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync for (unsigned i = RTPATH_PROP_HAS_ROOT_SPEC(pSplitFn->fProps); i < pSplitFn->cComps; i++)
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync for (unsigned j = i; j < pSplitFn->cComps - 1U && RT_SUCCESS(rc2); j++)
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync if (!rtDbgCfgIsDirAndFixCase(pszPath, pSplitFn->apszComps[i], fCaseInsensitive))
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync if (rtDbgCfgIsFileAndFixCase(pszPath, pSplitFn->apszComps[pSplitFn->cComps - 1], NULL /*pszSuffix*/,
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync rc2 = pfnCallback(pThis, pszPath, pvUser1, pvUser2);
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync if (rc2 == VINF_CALLBACK_RETURN || rc2 == VERR_CALLBACK_RETURN)
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync rtDbgCfgLog1(pThis, "Error opening '%s'.\n", pszPath);
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync rtDbgCfgLog1(pThis, "Error %Rrc opening '%s'.\n", rc2, pszPath);
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * Do a recursive search if requested.
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync && !(pThis->fFlags & RTDBGCFG_FLAGS_NO_RECURSIV_SEARCH) )
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync /** @todo Recursive searching will be done later. */
fa6dbd9c9e9645298cca864aa561382469907905vboxsyncstatic int rtDbgCfgUnpackMsCacheFile(PRTDBGCFGINT pThis, char *pszPath, const char *pszFilename)
fa6dbd9c9e9645298cca864aa561382469907905vboxsync rtDbgCfgLog2(pThis, "Unpacking '%s'...\n", pszPath);
fa6dbd9c9e9645298cca864aa561382469907905vboxsync * Duplicate the source file path, just for simplicity and restore the
fa6dbd9c9e9645298cca864aa561382469907905vboxsync * final character in the orignal. We cheerfully ignorining any
fa6dbd9c9e9645298cca864aa561382469907905vboxsync * possibility of multibyte UTF-8 sequences just like the caller did when
fa6dbd9c9e9645298cca864aa561382469907905vboxsync * setting it to '_'.
fa6dbd9c9e9645298cca864aa561382469907905vboxsync pszPath[strlen(pszPath) - 1] = RT_C_TO_LOWER(pszFilename[strlen(pszFilename) - 1]);
fa6dbd9c9e9645298cca864aa561382469907905vboxsync * Figuring out the argument list for the platform specific unpack util.
fa6dbd9c9e9645298cca864aa561382469907905vboxsync "expand.exe",
fa6dbd9c9e9645298cca864aa561382469907905vboxsync "cabextract",
fa6dbd9c9e9645298cca864aa561382469907905vboxsync * Do the unpacking.
fa6dbd9c9e9645298cca864aa561382469907905vboxsync int rc = RTProcCreate(papszArgs[0], papszArgs, RTENV_DEFAULT,
fa6dbd9c9e9645298cca864aa561382469907905vboxsync RTPROC_FLAGS_NO_WINDOW | RTPROC_FLAGS_HIDDEN | RTPROC_FLAGS_SEARCH_PATH,
fa6dbd9c9e9645298cca864aa561382469907905vboxsync rc = RTProcWait(hChild, RTPROCWAIT_FLAGS_BLOCK, &ProcStatus);
fa6dbd9c9e9645298cca864aa561382469907905vboxsync if ( ProcStatus.enmReason == RTPROCEXITREASON_NORMAL
fa6dbd9c9e9645298cca864aa561382469907905vboxsync rtDbgCfgLog1(pThis, "Successfully unpacked '%s' to '%s'.\n", pszSrcArchive, pszPath);
fa6dbd9c9e9645298cca864aa561382469907905vboxsync rtDbgCfgLog1(pThis, "Successfully ran unpacker on '%s', but '%s' is missing!\n", pszSrcArchive, pszPath);
fa6dbd9c9e9645298cca864aa561382469907905vboxsync rtDbgCfgLog2(pThis, "Unpacking '%s' failed: iStatus=%d enmReason=%d\n",
fa6dbd9c9e9645298cca864aa561382469907905vboxsync pszSrcArchive, ProcStatus.iStatus, ProcStatus.enmReason);
fa6dbd9c9e9645298cca864aa561382469907905vboxsync rtDbgCfgLog1(pThis, "Error waiting for process: %Rrc\n", rc);
fa6dbd9c9e9645298cca864aa561382469907905vboxsync rtDbgCfgLog1(pThis, "Error starting unpack process '%s': %Rrc\n", papszArgs[0], rc);
9ec22033341c104cf895501e1c2347b15a21ec1evboxsyncstatic int rtDbgCfgTryDownloadAndOpen(PRTDBGCFGINT pThis, const char *pszServer, char *pszPath,
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync const char *pszCacheSubDir, const char *pszUuidMappingSubDir,
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync PRTPATHSPLIT pSplitFn, const char *pszCacheSuffix, uint32_t fFlags,
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2)
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync NOREF(pszUuidMappingSubDir); /** @todo do we bother trying pszUuidMappingSubDir? */
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync NOREF(pszCacheSuffix); /** @todo do we bother trying pszUuidMappingSubDir? */
0109a2240391a89f6556b1545e6cc57f9efab060vboxsync * Create the path.
fa6dbd9c9e9645298cca864aa561382469907905vboxsync Log(("Error creating cache dir '%s': %Rrc\n", pszPath, rc));
0109a2240391a89f6556b1545e6cc57f9efab060vboxsync const char *pszFilename = pSplitFn->apszComps[pSplitFn->cComps - 1];
fa6dbd9c9e9645298cca864aa561382469907905vboxsync rc = RTPathAppend(pszPath, RTPATH_MAX, pszFilename);
0109a2240391a89f6556b1545e6cc57f9efab060vboxsync rc = RTPathAppend(pszPath, RTPATH_MAX, pszCacheSubDir);
0109a2240391a89f6556b1545e6cc57f9efab060vboxsync /* Prepare the destination file name while we're here. */
0109a2240391a89f6556b1545e6cc57f9efab060vboxsync rc = RTPathAppend(pszPath, RTPATH_MAX, pszFilename);
0109a2240391a89f6556b1545e6cc57f9efab060vboxsync * Download the file.
0109a2240391a89f6556b1545e6cc57f9efab060vboxsync "User-Agent: Microsoft-Symbol-Server/6.6.0999.9",
fa6dbd9c9e9645298cca864aa561382469907905vboxsync "Pragma: no-cache",
0109a2240391a89f6556b1545e6cc57f9efab060vboxsync rc = RTHttpSetHeaders(hHttp, RT_ELEMENTS(s_apszHeaders), s_apszHeaders);
0109a2240391a89f6556b1545e6cc57f9efab060vboxsync RTStrPrintf(szUrl, sizeof(szUrl), "%s/%s/%s/%s", pszServer, pszFilename, pszCacheSubDir, pszFilename);
fa6dbd9c9e9645298cca864aa561382469907905vboxsync /** @todo Use some temporary file name and rename it after the operation
fa6dbd9c9e9645298cca864aa561382469907905vboxsync * since not all systems support read-deny file sharing
fa6dbd9c9e9645298cca864aa561382469907905vboxsync * settings. */
fa6dbd9c9e9645298cca864aa561382469907905vboxsync rtDbgCfgLog2(pThis, "Downloading '%s' to '%s'...\n", szUrl, pszPath);
fa6dbd9c9e9645298cca864aa561382469907905vboxsync rtDbgCfgLog1(pThis, "%Rrc on URL '%s'\n", rc, pszPath);
fa6dbd9c9e9645298cca864aa561382469907905vboxsync /* Try the compressed version of the file. */
fa6dbd9c9e9645298cca864aa561382469907905vboxsync rtDbgCfgLog2(pThis, "Downloading '%s' to '%s'...\n", szUrl, pszPath);
fa6dbd9c9e9645298cca864aa561382469907905vboxsync rc = rtDbgCfgUnpackMsCacheFile(pThis, pszPath, pszFilename);
fa6dbd9c9e9645298cca864aa561382469907905vboxsync rtDbgCfgLog1(pThis, "%Rrc on URL '%s'\n", rc, pszPath);
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync * Succeeded in downloading it. Add UUID mapping?
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync /** @todo UUID mapping when downloading. */
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync * Give the file a try.
fa6dbd9c9e9645298cca864aa561382469907905vboxsync rc = pfnCallback(pThis, pszPath, pvUser1, pvUser2);
fa6dbd9c9e9645298cca864aa561382469907905vboxsync rtDbgCfgLog1(pThis, "Error opening '%s'.\n", pszPath);
fa6dbd9c9e9645298cca864aa561382469907905vboxsync rtDbgCfgLog1(pThis, "Error %Rrc opening '%s'.\n", rc, pszPath);
097353c82eb03cb665f4129ef5ace4aa984abf70vboxsync#else /* !IPRT_WITH_HTTP */
097353c82eb03cb665f4129ef5ace4aa984abf70vboxsync#endif /* !IPRT_WITH_HTTP */
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsyncstatic int rtDbgCfgCopyFileToCache(PRTDBGCFGINT pThis, char const *pszSrc, const char *pchCache, size_t cchCache,
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync const char *pszCacheSubDir, const char *pszUuidMappingSubDir, PRTPATHSPLIT pSplitFn)
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync /** @todo copy to cache */
9ec22033341c104cf895501e1c2347b15a21ec1evboxsyncstatic int rtDbgCfgTryOpenCache(PRTDBGCFGINT pThis, char *pszPath, size_t cchCachePath,
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync const char *pszCacheSubDir, const char *pszUuidMappingSubDir,
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync PCRTPATHSPLIT pSplitFn, const char *pszCacheSuffix, uint32_t fFlags,
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2)
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * If the cache doesn't exist, fail right away.
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync rtDbgCfgLog2(pThis, "Cache does not exist: '%s'\n", pszPath);
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync * If we got a UUID mapping option, try it first as we can hopefully
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync * dispense with case folding.
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync int rc = RTPathAppend(pszPath, RTPATH_MAX, pszUuidMappingSubDir);
445c121df5de5b7c7593483999aef85863847f9avboxsync /* Try resolve the path before presenting it to the client, a
445c121df5de5b7c7593483999aef85863847f9avboxsync 12 digit filename is of little worth. */
445c121df5de5b7c7593483999aef85863847f9avboxsync /* Do the callback thing. */
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync int rc2 = pfnCallback(pThis, pszPath, pvUser1, pvUser2);
445c121df5de5b7c7593483999aef85863847f9avboxsync rtDbgCfgLog1(pThis, "Found '%s' via uuid mapping.\n", pszPath);
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync rtDbgCfgLog1(pThis, "Error opening '%s'.\n", pszPath);
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync rtDbgCfgLog1(pThis, "Error %Rrc opening '%s'.\n", rc2, pszPath);
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync if (rc2 == VINF_CALLBACK_RETURN || rc2 == VERR_CALLBACK_RETURN)
445c121df5de5b7c7593483999aef85863847f9avboxsync /* Failed, restore the cache path. */
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * Carefully construct the cache path with case insensitivity in mind.
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync bool const fCaseInsensitive = (fFlags & RTDBGCFG_O_CASE_INSENSITIVE)
fa6dbd9c9e9645298cca864aa561382469907905vboxsync const char *pszFilename = pSplitFn->apszComps[pSplitFn->cComps - 1];
fa6dbd9c9e9645298cca864aa561382469907905vboxsync if (!rtDbgCfgIsDirAndFixCase(pszPath, pszFilename, fCaseInsensitive))
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync if (!rtDbgCfgIsDirAndFixCase(pszPath, pszCacheSubDir, fCaseInsensitive))
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync if (!rtDbgCfgIsFileAndFixCase(pszPath, pszFilename, pszCacheSuffix, fCaseInsensitive,
fa6dbd9c9e9645298cca864aa561382469907905vboxsync RT_BOOL(fFlags & RTDBGCFG_O_MAYBE_COMPRESSED_MS), &fProbablyCompressed))
fa6dbd9c9e9645298cca864aa561382469907905vboxsync int rc = rtDbgCfgUnpackMsCacheFile(pThis, pszPath, pszFilename);
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync int rc2 = pfnCallback(pThis, pszPath, pvUser1, pvUser2);
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync rtDbgCfgLog1(pThis, "Error opening '%s'.\n", pszPath);
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync rtDbgCfgLog1(pThis, "Error %Rrc opening '%s'.\n", rc2, pszPath);
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsyncstatic int rtDbgCfgTryOpenList(PRTDBGCFGINT pThis, PRTLISTANCHOR pList, PRTPATHSPLIT pSplitFn, const char *pszCacheSubDir,
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync const char *pszUuidMappingSubDir, uint32_t fFlags, char *pszPath,
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2)
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync rtDbgCfgLog2(pThis, "Path list entry: '%s'\n", pszDir);
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync /* This is very simplistic, but we have a unreasonably large path
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync buffer, so it'll work just fine and simplify things greatly below. */
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * Process the path according to it's type.
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * Symbol server.
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync const char *pszServer = (const char *)memchr(pszDir, '*', cchDir);
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync /* We don't have any default cache directory, so skip if the cache is missing. */
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync /* Search the cache first (if we haven't already done so). */
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync rcCache = rc2 = rtDbgCfgTryOpenCache(pThis, pszPath, cchCache, pszCacheSubDir, pszUuidMappingSubDir,
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync pSplitFn, NULL /*pszCacheSuffix*/, fFlags, pfnCallback, pvUser1, pvUser2);
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync if (rc2 == VINF_CALLBACK_RETURN || rc2 == VERR_CALLBACK_RETURN)
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync /* Try downloading the file. */
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync rc2 = rtDbgCfgTryDownloadAndOpen(pThis, pszServer, pszPath, pszCacheSubDir, pszUuidMappingSubDir,
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync pSplitFn, NULL /*pszCacheSuffix*/, fFlags, pfnCallback, pvUser1, pvUser2);
fa6dbd9c9e9645298cca864aa561382469907905vboxsync if (rc2 == VINF_CALLBACK_RETURN || rc2 == VERR_CALLBACK_RETURN)
fd7f945d04fb69c4ab017a5185cfe8718c023b83vboxsync else if (!RTStrNICmp(pszDir, RT_STR_TUPLE("cache*")))
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * Cache directory.
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync rcCache = rc2 = rtDbgCfgTryOpenCache(pThis, pszPath, cchCache, pszCacheSubDir, pszUuidMappingSubDir,
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync pSplitFn, NULL /*pszCacheSuffix*/, fFlags, pfnCallback, pvUser1, pvUser2);
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync if (rc2 == VINF_CALLBACK_RETURN || rc2 == VERR_CALLBACK_RETURN)
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * Normal directory. Check for our own 'rec*' and 'norec*' prefix
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * flags governing recursive searching.
fd7f945d04fb69c4ab017a5185cfe8718c023b83vboxsync else if (!RTStrNICmp(pszDir, RT_STR_TUPLE("norec*")))
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync /* Copy the path into the buffer and do the searching. */
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync rc2 = rtDbgCfgTryOpenDir(pThis, pszPath, pSplitFn, fFlagsDir, pfnCallback, pvUser1, pvUser2);
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync if (rc2 == VINF_CALLBACK_RETURN || rc2 == VERR_CALLBACK_RETURN)
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync rtDbgCfgCopyFileToCache(pThis, pszPath, pchCache, cchCache,
fa6dbd9c9e9645298cca864aa561382469907905vboxsync /* Propagate errors. */
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * Common worker routine for Image and debug info opening.
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * This will not search using for suffixes.
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * @returns IPRT status code.
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync * @param hDbgCfg The debugging configuration handle.
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync * NIL_RTDBGCFG is accepted, but the result is
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync * that no paths will be searched beyond the
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync * given and the current directory.
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync * @param pszFilename The filename to search for. This may or may
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync * not include a full or partial path.
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync * @param pszCacheSubDir The cache subdirectory to look in.
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync * @param pszUuidMappingSubDir UUID mapping subdirectory to check, NULL if
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync * no mapping wanted.
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync * @param fFlags Flags and hints.
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync * @param pfnCallback The open callback routine.
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync * @param pvUser1 User parameter 1.
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync * @param pvUser2 User parameter 2.
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsyncstatic int rtDbgCfgOpenWithSubDir(RTDBGCFG hDbgCfg, const char *pszFilename, const char *pszCacheSubDir,
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2)
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * Do a little validating first.
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync RTDBGCFG_VALID_RETURN_RC(pThis, VERR_INVALID_HANDLE);
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync AssertPtrReturn(pszFilename, VERR_INVALID_POINTER);
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync AssertPtrReturn(pszCacheSubDir, VERR_INVALID_POINTER);
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync AssertPtrReturn(pfnCallback, VERR_INVALID_POINTER);
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * Do some guessing as to the way we should parse the filename and whether
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * it's case exact or not.
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync || RT_OPSYS_USES_DOS_PATHS(fFlags & RTDBGCFG_O_OPSYS_MASK)
fa6dbd9c9e9645298cca864aa561382469907905vboxsync rtDbgCfgLog2(pThis, "Looking for '%s' w/ cache subdir '%s' and %#x flags...\n", pszFilename, pszCacheSubDir, fFlags);
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync rc2 = RTPathSplitA(pszFilename, &pSplitFn, fDosPath ? RTPATH_STR_F_STYLE_DOS : RTPATH_STR_F_STYLE_UNIX);
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync AssertReturnStmt(pSplitFn->fProps & RTPATH_PROP_FILENAME, RTPathSplitFree(pSplitFn), VERR_IS_A_DIRECTORY);
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * Try the stored file name first if it has a kind of absolute path.
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync rc2 = RTPathSplitReassemble(pSplitFn, RTPATH_STR_F_STYLE_HOST, szPath, sizeof(szPath));
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync rc2 = pfnCallback(pThis, szPath, pvUser1, pvUser2);
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync rtDbgCfgLog1(pThis, "Error opening '%s'.\n", szPath);
b1eb97eca02d27edf670107fb160f4a06e055f1evboxsync rtDbgCfgLog1(pThis, "Error %Rrc opening '%s'.\n", rc2, szPath);
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * Try the current directory (will take cover relative paths
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * skipped above).
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync rc2 = rtDbgCfgTryOpenDir(pThis, szPath, pSplitFn, fFlags, pfnCallback, pvUser1, pvUser2);
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * Run the applicable lists.
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync rc2 = rtDbgCfgTryOpenList(pThis, &pThis->PathList, pSplitFn, pszCacheSubDir,
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync pszUuidMappingSubDir, fFlags, szPath, pfnCallback, pvUser1, pvUser2);
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync && !(pThis->fFlags & RTDBGCFG_FLAGS_NO_SYSTEM_PATHS) )
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync rc2 = rtDbgCfgTryOpenList(pThis, &pThis->NtExecutablePathList, pSplitFn, pszCacheSubDir,
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync pszUuidMappingSubDir, fFlags, szPath, pfnCallback, pvUser1, pvUser2);
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync && !(pThis->fFlags & RTDBGCFG_FLAGS_NO_SYSTEM_PATHS) )
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync rc2 = rtDbgCfgTryOpenList(pThis, &pThis->NtSymbolPathList, pSplitFn, pszCacheSubDir,
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync pszUuidMappingSubDir, fFlags, szPath, pfnCallback, pvUser1, pvUser2);
daa94352f51be2329ac8660f70396e03a7cb983bvboxsyncRTDECL(int) RTDbgCfgOpenPeImage(RTDBGCFG hDbgCfg, const char *pszFilename, uint32_t cbImage, uint32_t uTimestamp,
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2)
fa6dbd9c9e9645298cca864aa561382469907905vboxsync RTStrPrintf(szSubDir, sizeof(szSubDir), "%08X%x", uTimestamp, cbImage);
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync return rtDbgCfgOpenWithSubDir(hDbgCfg, pszFilename, szSubDir, NULL,
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync RT_OPSYS_WINDOWS /* approx */ | RTDBGCFG_O_SYMSRV | RTDBGCFG_O_CASE_INSENSITIVE
fa6dbd9c9e9645298cca864aa561382469907905vboxsync | RTDBGCFG_O_MAYBE_COMPRESSED_MS | RTDBGCFG_O_EXECUTABLE_IMAGE,
daa94352f51be2329ac8660f70396e03a7cb983bvboxsyncRTDECL(int) RTDbgCfgOpenPdb70(RTDBGCFG hDbgCfg, const char *pszFilename, PCRTUUID pUuid, uint32_t uAge,
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2)
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync /* Stringify the UUID and remove the dashes. */
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync int rc2 = RTUuidToStr(pUuid, szSubDir, sizeof(szSubDir));
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync RTStrPrintf(pszDst, &szSubDir[sizeof(szSubDir)] - pszDst, "%X", uAge);
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync return rtDbgCfgOpenWithSubDir(hDbgCfg, pszFilename, szSubDir, NULL,
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync RT_OPSYS_WINDOWS /* approx */ | RTDBGCFG_O_SYMSRV | RTDBGCFG_O_CASE_INSENSITIVE
fa6dbd9c9e9645298cca864aa561382469907905vboxsync | RTDBGCFG_O_MAYBE_COMPRESSED_MS | RTDBGCFG_O_EXT_DEBUG_FILE,
daa94352f51be2329ac8660f70396e03a7cb983bvboxsyncRTDECL(int) RTDbgCfgOpenPdb20(RTDBGCFG hDbgCfg, const char *pszFilename, uint32_t cbImage, uint32_t uTimestamp, uint32_t uAge,
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2)
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync /** @todo test this! */
fa6dbd9c9e9645298cca864aa561382469907905vboxsync RTStrPrintf(szSubDir, sizeof(szSubDir), "%08X%x", uTimestamp, uAge);
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync return rtDbgCfgOpenWithSubDir(hDbgCfg, pszFilename, szSubDir, NULL,
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync RT_OPSYS_WINDOWS /* approx */ | RTDBGCFG_O_SYMSRV | RTDBGCFG_O_CASE_INSENSITIVE
fa6dbd9c9e9645298cca864aa561382469907905vboxsync | RTDBGCFG_O_MAYBE_COMPRESSED_MS | RTDBGCFG_O_EXT_DEBUG_FILE,
daa94352f51be2329ac8660f70396e03a7cb983bvboxsyncRTDECL(int) RTDbgCfgOpenDbg(RTDBGCFG hDbgCfg, const char *pszFilename, uint32_t cbImage, uint32_t uTimestamp,
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2)
fa6dbd9c9e9645298cca864aa561382469907905vboxsync RTStrPrintf(szSubDir, sizeof(szSubDir), "%08X%x", uTimestamp, cbImage);
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync return rtDbgCfgOpenWithSubDir(hDbgCfg, pszFilename, szSubDir, NULL,
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync RT_OPSYS_WINDOWS /* approx */ | RTDBGCFG_O_SYMSRV | RTDBGCFG_O_CASE_INSENSITIVE
fa6dbd9c9e9645298cca864aa561382469907905vboxsync | RTDBGCFG_O_MAYBE_COMPRESSED_MS | RTDBGCFG_O_EXT_DEBUG_FILE,
daa94352f51be2329ac8660f70396e03a7cb983bvboxsyncRTDECL(int) RTDbgCfgOpenDwo(RTDBGCFG hDbgCfg, const char *pszFilename, uint32_t uCrc32,
daa94352f51be2329ac8660f70396e03a7cb983bvboxsync PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2)
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync RTStrPrintf(szSubDir, sizeof(szSubDir), "%08x", uCrc32);
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync return rtDbgCfgOpenWithSubDir(hDbgCfg, pszFilename, szSubDir, NULL,
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync * D a r w i n . d S Y M b u n d l e s
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync * D a r w i n . d S Y M b u n d l e s
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync * D a r w i n . d S Y M b u n d l e s
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync * Very similar to rtDbgCfgTryOpenDir.
e0d6f087507011df5f570f6800a2c332f8970e58vboxsyncstatic int rtDbgCfgTryOpenDsymBundleInDir(PRTDBGCFGINT pThis, char *pszPath, PRTPATHSPLIT pSplitFn,
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync const char * const *papszSuffixes, uint32_t fFlags,
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2)
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync /* If the directory doesn't exist, just quit immediately.
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync Note! Our case insensitivity doesn't extend to the search dirs themselfs,
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync only to the bits under neath them. */
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync rtDbgCfgLog2(pThis, "Dir does not exist: '%s'\n", pszPath);
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync /* Figure out whether we have to do a case sensitive search or not.
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync Note! As a simplification, we don't ask for case settings in each
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync directory under the user specified path, we assume the file
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync systems that mounted there have compatible settings. Faster
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync that way. */
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync bool const fCaseInsensitive = (fFlags & RTDBGCFG_O_CASE_INSENSITIVE)
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync * Look for the file with less and less of the original path given.
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync * Also try out typical bundle extension variations.
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync const char *pszName = pSplitFn->apszComps[pSplitFn->cComps - 1];
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync for (unsigned i = RTPATH_PROP_HAS_ROOT_SPEC(pSplitFn->fProps); i < pSplitFn->cComps; i++)
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync for (unsigned j = i; j < pSplitFn->cComps - 1U && RT_SUCCESS(rc2); j++)
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync if (!rtDbgCfgIsDirAndFixCase(pszPath, pSplitFn->apszComps[i], fCaseInsensitive))
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync size_t cchCurPath = cchPath + strlen(&pszPath[cchPath]);
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync for (uint32_t iSuffix = 0; papszSuffixes[iSuffix]; iSuffix++)
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync if ( !rtDbgCfgIsDirAndFixCase2(pszPath, pszName, papszSuffixes[iSuffix], fCaseInsensitive)
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync && !rtDbgCfgIsDirAndFixCase(pszPath, "Contents", fCaseInsensitive)
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync && !rtDbgCfgIsDirAndFixCase(pszPath, "Resources", fCaseInsensitive)
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync && !rtDbgCfgIsDirAndFixCase(pszPath, "DWARF", fCaseInsensitive))
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync if (rtDbgCfgIsFileAndFixCase(pszPath, pszName, NULL /*pszSuffix*/, fCaseInsensitive, false, NULL))
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync rc2 = pfnCallback(pThis, pszPath, pvUser1, pvUser2);
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync if (rc2 == VINF_CALLBACK_RETURN || rc2 == VERR_CALLBACK_RETURN)
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync rtDbgCfgLog1(pThis, "Error opening '%s'.\n", pszPath);
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync rtDbgCfgLog1(pThis, "Error %Rrc opening '%s'.\n", rc2, pszPath);
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync * Do a recursive search if requested.
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync && !(pThis->fFlags & RTDBGCFG_FLAGS_NO_RECURSIV_SEARCH) )
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync /** @todo Recursive searching will be done later. */
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync * Very similar to rtDbgCfgTryOpenList.
e0d6f087507011df5f570f6800a2c332f8970e58vboxsyncstatic int rtDbgCfgTryOpenBundleInList(PRTDBGCFGINT pThis, PRTLISTANCHOR pList, PRTPATHSPLIT pSplitFn,
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync const char * const *papszSuffixes, const char *pszCacheSubDir,
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync const char *pszCacheSuffix, const char *pszUuidMappingSubDir,
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2)
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync rtDbgCfgLog2(pThis, "Path list entry: '%s'\n", pszDir);
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync /* This is very simplistic, but we have a unreasonably large path
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync buffer, so it'll work just fine and simplify things greatly below. */
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync * Process the path according to it's type.
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync * Symbol server.
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync const char *pszServer = (const char *)memchr(pszDir, '*', cchDir);
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync /* We don't have any default cache directory, so skip if the cache is missing. */
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync /* Search the cache first (if we haven't already done so). */
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync rcCache = rc2 = rtDbgCfgTryOpenCache(pThis, pszPath, cchCache, pszCacheSubDir, pszUuidMappingSubDir,
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync pSplitFn, pszCacheSuffix, fFlags, pfnCallback, pvUser1, pvUser2);
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync if (rc2 == VINF_CALLBACK_RETURN || rc2 == VERR_CALLBACK_RETURN)
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync /* Try downloading the file. */
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync rc2 = rtDbgCfgTryDownloadAndOpen(pThis, pszServer, pszPath, pszCacheSubDir, pszUuidMappingSubDir,
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync pSplitFn, pszCacheSuffix, fFlags, pfnCallback, pvUser1, pvUser2);
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync if (rc2 == VINF_CALLBACK_RETURN || rc2 == VERR_CALLBACK_RETURN)
fd7f945d04fb69c4ab017a5185cfe8718c023b83vboxsync else if (!RTStrNICmp(pszDir, RT_STR_TUPLE("cache*")))
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync * Cache directory.
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync rcCache = rc2 = rtDbgCfgTryOpenCache(pThis, pszPath, cchCache, pszCacheSubDir, pszUuidMappingSubDir,
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync pSplitFn, pszCacheSuffix, fFlags, pfnCallback, pvUser1, pvUser2);
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync if (rc2 == VINF_CALLBACK_RETURN || rc2 == VERR_CALLBACK_RETURN)
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync * Normal directory. Check for our own 'rec*' and 'norec*' prefix
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync * flags governing recursive searching.
fd7f945d04fb69c4ab017a5185cfe8718c023b83vboxsync else if (!RTStrNICmp(pszDir, RT_STR_TUPLE("norec*")))
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync /* Copy the path into the buffer and do the searching. */
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync rc2 = rtDbgCfgTryOpenDsymBundleInDir(pThis, pszPath, pSplitFn, papszSuffixes, fFlagsDir,
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync if (rc2 == VINF_CALLBACK_RETURN || rc2 == VERR_CALLBACK_RETURN)
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync rtDbgCfgCopyFileToCache(pThis, pszPath, pchCache, cchCache,
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync /* Propagate errors. */
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync * Creating a UUID mapping subdirectory path for use in caches.
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync * @returns IPRT status code.
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync * @param pszSubDir The output buffer.
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync * @param cbSubDir The size of the output buffer. (Top dir length +
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync * slash + UUID string len + extra dash.)
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync * @param pszTopDir The top level cache directory name. No slashes
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync * or other directory separators, please.
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync * @param pUuid The UUID.
9ec22033341c104cf895501e1c2347b15a21ec1evboxsyncstatic int rtDbgCfgConstructUuidMappingSubDir(char *pszSubDir, size_t cbSubDir, const char *pszTopDir, PCRTUUID pUuid)
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync if (cchTopDir + 1 + 1 + RTUUID_STR_LENGTH + 1 > cbSubDir)
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync /* ed5a8336-35c2-4892-9122-21d5572924a3 -> ED5A/8336/35C2/4892/9122/21D5572924A3 */
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync int rc = RTUuidToStr(pUuid, pszSubDir + 1, cbSubDir - 1); AssertRCReturn(rc, rc);
e0d6f087507011df5f570f6800a2c332f8970e58vboxsyncstatic int rtDbgCfgOpenBundleFile(RTDBGCFG hDbgCfg, const char *pszImage, const char * const *papszSuffixes,
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync const char *pszBundleSubDir, PCRTUUID pUuid, const char *pszUuidMapDirName,
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2)
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync * Bundles are directories, means we can forget about sharing code much
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync * with the other RTDbgCfgOpenXXX methods. Thus we're duplicating a lot of
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync * code from rtDbgCfgOpenWithSubDir with .dSYM/.kext/.dylib/.app/.* related
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync * adjustments, so, a bug found here or there probably means the other
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync * version needs updating.
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync * Do a little validating first.
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync RTDBGCFG_VALID_RETURN_RC(pThis, VERR_INVALID_HANDLE);
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync AssertPtrReturn(pfnCallback, VERR_INVALID_POINTER);
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync * Set up rtDbgCfgOpenWithSubDir and uuid map parameters.
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync uint32_t fFlags = RTDBGCFG_O_EXT_DEBUG_FILE | RT_OPSYS_DARWIN;
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync /* Since Mac debuggers uses UUID mappings, we just the slashing default
9ec22033341c104cf895501e1c2347b15a21ec1evboxsync UUID string representation instead of stripping dashes like for PDB. */
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync RTUuidToStr(pUuid, szCacheSubDir, sizeof(szCacheSubDir));
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync rc2 = rtDbgCfgConstructUuidMappingSubDir(szUuidMappingSubDir, sizeof(szUuidMappingSubDir), pszUuidMapDirName, pUuid);
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync * Do some guessing as to the way we should parse the filename and whether
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync * it's case exact or not.
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync || RT_OPSYS_USES_DOS_PATHS(fFlags & RTDBGCFG_O_OPSYS_MASK)
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync rtDbgCfgLog2(pThis, "Looking for '%s' with %#x flags...\n", pszImage, fFlags);
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync rc2 = RTPathSplitA(pszImage, &pSplitFn, fDosPath ? RTPATH_STR_F_STYLE_DOS : RTPATH_STR_F_STYLE_UNIX);
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync AssertReturnStmt(pSplitFn->fProps & RTPATH_PROP_FILENAME, RTPathSplitFree(pSplitFn), VERR_IS_A_DIRECTORY);
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync * Try the image directory first.
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync rc2 = RTPathSplitReassemble(pSplitFn, RTPATH_STR_F_STYLE_HOST, szPath, sizeof(szPath));
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync rc2 = RTStrCat(szPath, sizeof(szPath), papszSuffixes[0]);
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync rc2 = RTStrCat(szPath, sizeof(szPath), pszBundleSubDir);
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync rc2 = RTPathAppend(szPath, sizeof(szPath), pSplitFn->apszComps[pSplitFn->cComps - 1]);
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync rc2 = pfnCallback(pThis, szPath, pvUser1, pvUser2);
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync rtDbgCfgLog1(pThis, "Error opening '%s'.\n", szPath);
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync rtDbgCfgLog1(pThis, "Error %Rrc opening '%s'.\n", rc2, szPath);
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync * Try the current directory (will take cover relative paths
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync * skipped above).
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync rc2 = rtDbgCfgTryOpenDsymBundleInDir(pThis, szPath, pSplitFn, g_apszDSymBundleSuffixes,
6ba706e9f431401d425d16817fdcd6316f83b584vboxsync * Run the applicable lists.
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync rc2 = rtDbgCfgTryOpenBundleInList(pThis, &pThis->PathList, pSplitFn, g_apszDSymBundleSuffixes,
e0d6f087507011df5f570f6800a2c332f8970e58vboxsyncRTDECL(int) RTDbgCfgOpenDsymBundle(RTDBGCFG hDbgCfg, const char *pszImage, PCRTUUID pUuid,
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2)
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync return rtDbgCfgOpenBundleFile(hDbgCfg, pszImage, g_apszDSymBundleSuffixes,
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync "Contents" RTPATH_SLASH_STR "Resources" RTPATH_SLASH_STR "DWARF",
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync pUuid, RTDBG_CACHE_UUID_MAP_DIR_DSYMS, RTDBG_CACHE_DSYM_FILE_SUFFIX, false /* fOpenImage */,
e0d6f087507011df5f570f6800a2c332f8970e58vboxsyncRTDECL(int) RTDbgCfgOpenMachOImage(RTDBGCFG hDbgCfg, const char *pszImage, PCRTUUID pUuid,
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync PFNDBGCFGOPEN pfnCallback, void *pvUser1, void *pvUser2)
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync return rtDbgCfgOpenBundleFile(hDbgCfg, pszImage, g_apszBundleSuffixes,
e0d6f087507011df5f570f6800a2c332f8970e58vboxsync pUuid, RTDBG_CACHE_UUID_MAP_DIR_IMAGES, NULL /*pszCacheSuffix*/, true /* fOpenImage */,
d6f8b76ab3b2ec0c270c96f9db6e2568fc41b5fevboxsyncRTDECL(int) RTDbgCfgSetLogCallback(RTDBGCFG hDbgCfg, PFNRTDBGCFGLOG pfnCallback, void *pvUser)
d6f8b76ab3b2ec0c270c96f9db6e2568fc41b5fevboxsync RTDBGCFG_VALID_RETURN_RC(pThis, VERR_INVALID_HANDLE);
d6f8b76ab3b2ec0c270c96f9db6e2568fc41b5fevboxsync AssertPtrNullReturn(pfnCallback, VERR_INVALID_POINTER);
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * Frees a string list.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param pList The list to free.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsyncstatic void rtDbgCfgFreeStrList(PRTLISTANCHOR pList)
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync RTListForEachSafe(pList, pCur, pNext, RTDBGCFGSTR, ListEntry)
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * Make changes to a string list, given a semicolon separated input string.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @returns VINF_SUCCESS, VERR_FILENAME_TOO_LONG, VERR_NO_MEMORY
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param pThis The config instance.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param enmOp The change operation.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param pszValue The input strings separated by semicolon.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param fPaths Indicates that this is a path list and that we
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * should look for srv and cache prefixes.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param pList The string list anchor.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsyncstatic int rtDbgCfgChangeStringList(PRTDBGCFGINT pThis, RTDBGCFGOP enmOp, const char *pszValue, bool fPaths,
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync /* Skip separators. */
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync /* Find the end of this path. */
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * Remove all occurences.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync RTListForEachSafe(pList, pCur, pNext, RTDBGCFGSTR, ListEntry)
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * We're adding a new one.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync PRTDBGCFGSTR pNew = (PRTDBGCFGSTR)RTMemAlloc(RT_OFFSETOF(RTDBGCFGSTR, sz[cchPath + 1]));
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * Make changes to a 64-bit value
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @returns VINF_SUCCESS, VERR_DBG_CFG_INVALID_VALUE.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param pThis The config instance.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param enmOp The change operation.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param pszValue The input value.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param pszMnemonics The mnemonics map for this value.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param puValue The value to change.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsyncstatic int rtDbgCfgChangeStringU64(PRTDBGCFGINT pThis, RTDBGCFGOP enmOp, const char *pszValue,
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync PCRTDBGCFGU64MNEMONIC paMnemonics, uint64_t *puValue)
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync uint64_t uNew = enmOp == RTDBGCFGOP_SET ? 0 : *puValue;
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync /* skip whitespace and separators */
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync while (RT_C_IS_SPACE(ch) || RT_C_IS_CNTRL(ch) || ch == ';' || ch == ':')
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync int rc = RTStrToUInt64Ex(pszValue, (char **)&pszValue, 0, &uTmp);
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync /* A mnemonic, find the end of it. */
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync while (ch && !RT_C_IS_SPACE(ch) && !RT_C_IS_CNTRL(ch) && ch != ';' && ch != ':');
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync /* Look it up in the map and apply it. */
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync unsigned i = 0;
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync && !memcmp(pszMnemonic, paMnemonics[i].pszMnemonic, cchMnemonic))
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync if (paMnemonics[i].fSet ? enmOp != RTDBGCFGOP_REMOVE : enmOp == RTDBGCFGOP_REMOVE)
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsyncRTDECL(int) RTDbgCfgChangeString(RTDBGCFG hDbgCfg, RTDBGCFGPROP enmProp, RTDBGCFGOP enmOp, const char *pszValue)
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync RTDBGCFG_VALID_RETURN_RC(pThis, VERR_INVALID_HANDLE);
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync AssertReturn(enmProp > RTDBGCFGPROP_INVALID && enmProp < RTDBGCFGPROP_END, VERR_INVALID_PARAMETER);
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync AssertReturn(enmOp > RTDBGCFGOP_INVALID && enmOp < RTDBGCFGOP_END, VERR_INVALID_PARAMETER);
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync rc = rtDbgCfgChangeStringU64(pThis, enmOp, pszValue, g_aDbgCfgFlags, &pThis->fFlags);
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync rc = rtDbgCfgChangeStringList(pThis, enmOp, pszValue, true, &pThis->PathList);
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync rc = rtDbgCfgChangeStringList(pThis, enmOp, pszValue, false, &pThis->SuffixList);
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync rc = rtDbgCfgChangeStringList(pThis, enmOp, pszValue, true, &pThis->SrcPathList);
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsyncRTDECL(int) RTDbgCfgChangeUInt(RTDBGCFG hDbgCfg, RTDBGCFGPROP enmProp, RTDBGCFGOP enmOp, uint64_t uValue)
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync RTDBGCFG_VALID_RETURN_RC(pThis, VERR_INVALID_HANDLE);
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync AssertReturn(enmProp > RTDBGCFGPROP_INVALID && enmProp < RTDBGCFGPROP_END, VERR_INVALID_PARAMETER);
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync AssertReturn(enmOp > RTDBGCFGOP_INVALID && enmOp < RTDBGCFGOP_END, VERR_INVALID_PARAMETER);
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * Querys a string list as a single string (semicolon separators).
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @returns VINF_SUCCESS, VERR_BUFFER_OVERFLOW.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param pThis The config instance.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param pList The string list anchor.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param pszValue The output buffer.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param cbValue The size of the output buffer.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsyncstatic int rtDbgCfgQueryStringList(RTDBGCFG hDbgCfg, PRTLISTANCHOR pList,
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * Check the length first.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * Construct the string list in the buffer.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * Querys the string value of a 64-bit unsigned int.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @returns VINF_SUCCESS, VERR_BUFFER_OVERFLOW.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param pThis The config instance.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param uValue The value to query.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param pszMnemonics The mnemonics map for this value.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param pszValue The output buffer.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * @param cbValue The size of the output buffer.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsyncstatic int rtDbgCfgQueryStringU64(RTDBGCFG hDbgCfg, uint64_t uValue, PCRTDBGCFGU64MNEMONIC paMnemonics,
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * If no mnemonics, just return the hex value.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync size_t cch = RTStrPrintf(szTmp, sizeof(szTmp), "%#x", uValue);
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * Check that there is sufficient buffer space first.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync for (unsigned i = 0; paMnemonics[i].pszMnemonic; i++)
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync cbReq += (cbReq != 1) + paMnemonics[i].cchMnemonic;
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * Construct the string.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync for (unsigned i = 0; paMnemonics[i].pszMnemonic; i++)
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync memcpy(psz, paMnemonics[i].pszMnemonic, paMnemonics[i].cchMnemonic);
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsyncRTDECL(int) RTDbgCfgQueryString(RTDBGCFG hDbgCfg, RTDBGCFGPROP enmProp, char *pszValue, size_t cbValue)
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync RTDBGCFG_VALID_RETURN_RC(pThis, VERR_INVALID_HANDLE);
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync AssertReturn(enmProp > RTDBGCFGPROP_INVALID && enmProp < RTDBGCFGPROP_END, VERR_INVALID_PARAMETER);
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync int rc = RTCritSectRwEnterShared(&pThis->CritSect);
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync rc = rtDbgCfgQueryStringU64(pThis, pThis->fFlags, g_aDbgCfgFlags, pszValue, cbValue);
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync rc = rtDbgCfgQueryStringList(pThis, &pThis->PathList, pszValue, cbValue);
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync rc = rtDbgCfgQueryStringList(pThis, &pThis->SuffixList, pszValue, cbValue);
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync rc = rtDbgCfgQueryStringList(pThis, &pThis->SrcPathList, pszValue, cbValue);
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsyncRTDECL(int) RTDbgCfgQueryUInt(RTDBGCFG hDbgCfg, RTDBGCFGPROP enmProp, uint64_t *puValue)
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync RTDBGCFG_VALID_RETURN_RC(pThis, VERR_INVALID_HANDLE);
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync AssertReturn(enmProp > RTDBGCFGPROP_INVALID && enmProp < RTDBGCFGPROP_END, VERR_INVALID_PARAMETER);
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync int rc = RTCritSectRwEnterShared(&pThis->CritSect);
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * Last reference - free all memory.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync ASMAtomicWriteU32(&pThis->u32Magic, ~RTDBGCFG_MAGIC);
0109a2240391a89f6556b1545e6cc57f9efab060vboxsyncRTDECL(int) RTDbgCfgCreate(PRTDBGCFG phDbgCfg, const char *pszEnvVarPrefix, bool fNativePaths)
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * Validate input.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync AssertPtrReturn(pszEnvVarPrefix, VERR_INVALID_POINTER);
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync AssertReturn(*pszEnvVarPrefix, VERR_INVALID_PARAMETER);
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * Allocate and initialize a new instance.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync PRTDBGCFGINT pThis = (PRTDBGCFGINT)RTMemAllocZ(sizeof(*pThis));
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * Read configurtion from the environment if requested to do so.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync char *pszEnvVar = (char *)RTMemTmpAlloc(cbEnvVar + cbEnvVal);
0109a2240391a89f6556b1545e6cc57f9efab060vboxsync static struct
0109a2240391a89f6556b1545e6cc57f9efab060vboxsync const char *pszVar;
0109a2240391a89f6556b1545e6cc57f9efab060vboxsync for (unsigned i = 0; i < RT_ELEMENTS(s_aProps); i++)
0109a2240391a89f6556b1545e6cc57f9efab060vboxsync size_t cchEnvVar = RTStrPrintf(pszEnvVar, cbEnvVar, "%s_%s", pszEnvVarPrefix, s_aProps[i].pszVar);
0109a2240391a89f6556b1545e6cc57f9efab060vboxsync rc = RTEnvGetEx(RTENV_DEFAULT, pszEnvVar, pszEnvVal, cbEnvVal, NULL);
0109a2240391a89f6556b1545e6cc57f9efab060vboxsync rc = RTDbgCfgChangeString(pThis, s_aProps[i].enmProp, RTDBGCFGOP_SET, pszEnvVal);
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync * Pick up system specific search paths.
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync const char *pszVar;
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync { &pThis->NtExecutablePathList, "_NT_EXECUTABLE_PATH", ';' },
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync { &pThis->NtSymbolPathList, "_NT_ALT_SYMBOL_PATH", ';' },
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync { &pThis->NtSymbolPathList, "_NT_SYMBOL_PATH", ';' },
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync Assert(aNativePaths[i].chSep == ';'); /* fix when needed */
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync rc = RTEnvGetEx(RTENV_DEFAULT, aNativePaths[i].pszVar, pszEnvVal, cbEnvVal, NULL);
9af7167fa39f1f139899c989da973e59b9cccc3fvboxsync rc = rtDbgCfgChangeStringList(pThis, RTDBGCFGOP_APPEND, pszEnvVal, true, aNativePaths[i].pList);
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * Error, bail out.
b7a07b07543924f45c1fffd2f90de582038b8ba6vboxsync * Returns successfully.