blob: 1ce78567d5f7655518ff90677c5728332ef60ca5 [file] [log] [blame]
/* **********************************************************
* Copyright (c) 2013-2014 Google, Inc. All rights reserved.
* **********************************************************/
/*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of Google, Inc. nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE, INC. OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*/
#ifndef _DR_FRONTEND_LIB_H_
#define _DR_FRONTEND_LIB_H_
#include "globals_shared.h" /* For bool type */
/* XXX i#1079: we may want to share the define block with DR's libutil/our_tchar.h
* b/c we'll want something similar for drdeploy and drinject libs and tools
*/
/* DR_API EXPORT TOFILE dr_frontend.h */
/* DR_API EXPORT BEGIN */
/****************************************************************************
* Tool front-end API
*/
/**
* @file dr_frontend.h
* @brief Tool front-end API. Use these functions to search for and query
* the properties of a target application file, check environment variables,
* and perform other common actions in a tool front-end executable.
* The library provides cross-platform utilities that support internationalization.
*
* The general usage model is for the front-end executable to always deal with
* UTF-8 strings and let this front-end library perform conversion back and
* forth to UTF-16 when interacting with Windows library. The executable should
* declare its main routine as follows:
*
* int _tmain(int argc, TCHAR *targv[])
*
* And then invoke drfront_convert_args() to convert them to UTF-8. All further
* references to the arguments should use the UTF-8 versions.
* On Linux or MacOS, _tmain and TCHAR will turn into regular symbols.
*/
#ifdef WINDOWS
# include <tchar.h>
#else
# define TCHAR char
# define _tmain main
# define _tcslen strlen
# define _tcsstr strstr
# define _tcscmp strcmp
# define _tcsnicmp strnicmp
# define _tcsncpy strncpy
# define _tcscat_s strcat
# define _tcsrchr strrchr
# define _snprintf snprintf
# define _sntprintf snprintf
# define _ftprintf fprintf
# define _tfopen fopen
# define _T(s) s
#endif
/* DR_API EXPORT VERBATIM */
#ifdef _UNICODE
# define TSTR_FMT "%S"
#else
# define TSTR_FMT "%s"
#endif
/* DR_API EXPORT END */
/** Status code for each DRFront operation */
typedef enum {
DRFRONT_SUCCESS, /**< Operation succeeded */
DRFRONT_ERROR, /**< Operation failed */
DRFRONT_ERROR_INVALID_PARAMETER, /**< Operation failed: invalid parameter */
DRFRONT_ERROR_INVALID_SIZE, /**< Operation failed: invalid size */
DRFRONT_ERROR_FILE_EXISTS, /**< Operation failed: dir or file already
* exists */
DRFRONT_ERROR_INVALID_PATH, /**< Operation failed: wrong path */
DRFRONT_ERROR_ACCESS_DENIED, /**< Operation failed: access denied */
DRFRONT_ERROR_LIB_UNSUPPORTED, /**< Operation failed: old version
* or invalid library */
} drfront_status_t;
/** Permission modes for drfront_access() */
typedef enum {
DRFRONT_EXIST = 0x00, /**< Test existence */
DRFRONT_EXEC = 0x01, /**< Test for execute access */
DRFRONT_WRITE = 0x02, /**< Test for write access */
DRFRONT_READ = 0x04, /**< Test for read access */
} drfront_access_mode_t;
/**
* Checks \p fname for the permssions specified by \p mode.
*
* \note DRFRONT_EXEC is ignored on Windows because _waccess doesn't test it.
*
* @param[in] fname The filename to test permission to.
* @param[in] mode The permission to test the file for.
* @param[out] ret True iff \p fname has the permission specified by \p mode.
*/
drfront_status_t
drfront_access(const char *fname, drfront_access_mode_t mode, OUT bool *ret);
/**
* Implements a normal path search for \p fname on the paths in \p env_var.
* Resolves symlinks.
*
* @param[in] fname The filename to search for.
* @param[in] env_var The environment variable that contains the paths to
* search for \p fname.
* Paths are ;-separated on Windows and :-separated on UNIX.
* @param[out] full_path The full path of \p fname if it is found.
* @param[in] full_path_size The maximum size of \p full_path.
* @param[out] ret True iff \p fname is found.
*/
drfront_status_t
drfront_searchenv(const char *fname, const char *env_var, OUT char *full_path,
const size_t full_path_size, OUT bool *ret);
/**
* Concatenate onto a buffer. The buffer is not resized if the content does not fit.
*
* @param[in,out] buf The buffer to concatenate onto.
* @param[in] bufsz The allocated size of \p buf.
* @param[in,out] sofar The number of bytes added so far. Cumulative between calls.
* @param[out] len The number of bytes sucessfully written to \p buf this call.
* @param[in] fmt The format string to be added to \p buf.
* @param[in] ... Any data needed for the format string.
*/
drfront_status_t
drfront_bufprint(INOUT char *buf, size_t bufsz, INOUT size_t *sofar,
OUT ssize_t *len, char *fmt, ...);
/**
* Converts from UTF-16 to UTF-8.
*
* \note On UNIX the information is simply copied from \p wstr to \p buf.
*
* \note Always null-terminates.
*
* @param[in] wstr The UTF-16 string to be converted to UTF-8.
* @param[out] buf The destination of the new UTF-8 string.
* @param[in] buflen The allocated size of \p buf in elements.
*/
drfront_status_t
drfront_tchar_to_char(const TCHAR *wstr, OUT char *buf, size_t buflen/*# elements*/);
/**
* Gets the necessary size of a UTF-8 buffer to hold the content in \p wstr.
*
* \note needed includes the terminating null character.
*
* @param[in] wstr The UTF-16 string to be converted later.
* @param[out] needed The size a buffer has to be to hold \p wstr in UTF-8.
*/
drfront_status_t
drfront_tchar_to_char_size_needed(const TCHAR *wstr, OUT size_t *needed);
/**
* Converts from UTF-8 to UTF-16.
*
* \note On UNIX the information is simply copied from \p str to \p wbuf.
*
* \note Always null-terminates.
*
* @param[in] str The UTF-8 string to be converted to UTF-16.
* @param[out] wbuf The destination of the new UTF-16 string.
* @param[in] wbuflen The allocated size of \p wbuf in elements.
*/
drfront_status_t
drfront_char_to_tchar(const char *str, OUT TCHAR *wbuf, size_t wbuflen/*# elements*/);
/**
* Stores the contents of the environment variable \p name in \p buf.
*
* @param[in] name The name of the environment variable.
* @param[out] buf The destination to store the contents of \p name.
* @param[in] buflen The allocated size of \p buf in elements.
*/
drfront_status_t
drfront_get_env_var(const char *name, OUT char *buf, size_t buflen/*# elements*/);
/**
* Gets the absolute path of \p src.
*
* @param[in] src The path to expand.
* @param[out] buf The buffer to place the absolute path in.
* @param[in] buflen The allocated size of \p buf in elements.
*/
drfront_status_t
drfront_get_absolute_path(const char *src, OUT char *buf, size_t buflen/*# elements*/);
/**
* Gets the full path of \p app, which is located by searching the PATH if necessary.
*
* @param[in] app The executable to get the full path of.
* @param[out] buf The buffer to place the full path in if found.
* @param[in] buflen The allocated size of \p buf in elements.
*/
drfront_status_t
drfront_get_app_full_path(const char *app, OUT char *buf, size_t buflen/*# elements*/);
/**
* Reads the file header to determine if \p exe is a 64-bit application.
*
* @param[in] exe The executable to check for the 64-bit flag.
* @param[out] is_64 True if \p exe is a 64-bit application.
*/
drfront_status_t
drfront_is_64bit_app(const char *exe, OUT bool *is_64);
/**
* Reads the PE header to determine if \p exe has a GUI.
*
* \note This function always returns false on UNIX because it is not relevant.
*
* @param[in] exe The executable to check the subsystem of.
* @param[out] is_graphical True if \p exe's subsystem is graphical.
*/
drfront_status_t
drfront_is_graphical_app(const char *exe, OUT bool *is_graphical);
/**
* Converts the command-line arguments to UTF-8.
*
* \note This function allocates memory on the heap that must be freed by
* calling drfront_cleanup_args().
*
* \note On UNIX the data is simply copied.
*
* @param[in] targv The original command-line arguments.
* @param[out] argv The original command-line arguments in UTF-8.
* @param[in] argc The number of command-line arguments.
*/
drfront_status_t
drfront_convert_args(const TCHAR **targv, OUT char ***argv, int argc);
/**
* Frees the UTF-8 array of command-line arguments.
*
* @param[in] argv The array of command-line arguments.
* @param[in] argc The number of command-line arguments.
*/
drfront_status_t
drfront_cleanup_args(char **argv, int argc);
/**
* If a tool is installed into a "Program Files" directory on Windows,
* or into "/usr/..." on Linux, it needs to store its log files
* elsewhere. This utility function helps to select that alternative
* location. First, it checks whether \p root is in a location where
* log files should not be created, and returns that result in \p
* use_root. If \p use_root is false, this function returns a
* suggested alternative directory for log files in \p buf. It looks
* in standard locations such as "$APPDATA" or
* "$USERPROFILE/Application Data" on Windows or in temp directories
* if those fail or if on Linux. It appends \p subdir to the base
* application data or temp directory. It is up to the caller to
* create the returned directory if it does not exist.
*
* @param[in] root The location where the tool's binaries are installed.
* @param[in] subdir A directory to append to the application data directory
* to form a result in \p buf.
* @param[out] use_root Returns whether \p root is suitable for storing log files.
* @param[out] buf If \p use_root is false, this buffer is filled with a
* suggested directory for storing log files. The directory
* ends with \p subdir.
* If \p use_root is true, \p buf's contents are undefined.
* @param[in] buflen The maximum capacity of \p buf, in elements.
*/
drfront_status_t
drfront_appdata_logdir(const char *root, const char *subdir,
OUT bool *use_root,
OUT char *buf, size_t buflen/*# elements*/);
/**
* Replace occurences of \p old_char with \p new_char in \p str. Typically used to
* canonicalize Windows paths into using forward slashes.
*
* @param[out] str The string whose characters should be replaced.
* @param[in] old_char Old character to be replaced.
* @param[in] new_char New character to use.
*/
void
drfront_string_replace_character(OUT char *str, char old_char, char new_char);
/**
* Replace occurences of \p old_char with \p new_char in TCHAR \p str.
* Typically used to canonicalize Windows paths into using forward slashes.
*
* @param[out] str A string whose characters should be replaced.
* @param[in] old_char Old character to be replaced.
* @param[in] new_char New character to use.
*/
void
drfront_string_replace_character_wide(OUT TCHAR *str, TCHAR old_char, TCHAR new_char);
/**
* Sets the environment variable _NT_SYMBOL_PATH and the dbghelp
* search path for symbol lookup in a client, without any network
* symbol server component (such components are unsafe in a client).
*
* If the _NT_SYMBOL_PATH is already specified, this routine validates it and
* if invalid replaces it.
*
* This routine also takes the client symbol lookup path and adds the Microsoft
* symbol server for use in a frontend itself (not in a client) and returns that
* path in \p symsrv_path. The frontend can enable use of this path by calling
* drfront_set_symbol_search_path().
*
* drfront_sym_init() must be called before calling this routine.
*
* \note This routine requires DbgHelp.dll 6.0 or later.
*
* \warning This routine will fail when using the system copy of dbghelp.dll on
* Windows XP or 2003. The client should use its own copy of dbghelp.dll
* version 6.0 or later.
*
* @param[in] symdir A local symbol cache directory.
* It can be passed without srv* prepended.
* It will have "/symbols" appended to it.
* @param[in] ignore_env If TRUE, any existing _NT_SYMBOL_PATH value is ignored.
* @param[out] symsrv_path Returns a symbol path that includes the Microsoft
* symbol server.
* @param[in] symsrv_path_sz The maximum length, in characters, of \p symsrv_path.
*/
drfront_status_t
drfront_set_client_symbol_search_path(const char *symdir, bool ignore_env,
OUT char *symsrv_path, size_t symsrv_path_sz);
/**
* Sets the symbol search path for this frontend process to the specified value.
* Typically this would be used with the output value from
* drfront_set_client_symbol_search_path().
*
* drfront_sym_init() must be called before calling this routine.
*
* \note The routine requires DbgHelp.dll 6.0 or later.
*
* \warning The routine will fail when using the system copy of dbghelp.dll on
* Windows XP or 2003. The client should use its own copy of dbghelp.dll
* version 6.0 or later.
*
* @param[in] symsrv_path The symbol search path to use.
*/
drfront_status_t
drfront_set_symbol_search_path(const char *symsrv_path);
/**
* This routine initializes the symbol handler for the current process. Should be called
* before drfront_set_symbol_search_path() and drfront_fetch_module_symbols().
*
* \note The routine requires DbgHelp.dll 6.0 or later.
*
* \warning The routine will fail when using the system copy of dbghelp.dll on
* Windows XP or 2003. The client should use its own copy of dbghelp.dll
* version 6.0 or later.
*
* @param[in] wsymsrv_path The path, or series of paths separated by a semicolon (;),
* that is used to search for symbol files. If this parameter
* is NULL, the library attempts to form a symbol path from
* the following sources: the current working directory,
* _NT_SYMBOL_PATH, _NT_ALTERNATE_SYMBOL_PATH.
* @param[in] dbghelp_path The path to dbghelp.dll. If the string specifies a full
* path, the routine looks only in that path for the module.
* If the string specifies a relative path or a module name
* without a path, the function uses a standard Windows library
* search strategy to find the module.
*/
drfront_status_t
drfront_sym_init(const char *wsymsrv_path, const char *dbghelp_path);
/**
* This routine deallocates all symbol-related resources associated with the current
* process.
*/
drfront_status_t
drfront_sym_exit(void);
/**
* This routine tries to fetch all missed symbols for module specified in \p modpath
* using _NT_SYMBOL_PATH environment var. User should call \p drfront_sym_init,
* drfront_sym_set_search_path() and drfront_sym_set_search_path() before calling
* this routine. If success function returns full path to fetched symbol file in
* \p symbol_path.
*
* \note The routine will fetch symbols from remote MS Symbol Server only if symbols
* don't exist in the search paths and _NT_SYMBOL_PATH has right srv* path & link.
* The routine requires DbgHelp.dll 6.0 or later.
*
* \warning The routine will fail when using the system copy of dbghelp.dll on
* Windows XP or 2003. The client should use its own copy of dbghelp.dll
* version 6.0 or later.
*
* @param[in] modpath The name of the image to be loaded. This name can contain
* a partial path, a full path, or no path at all. If the file
* cannot be located by the name provided, the routine returns
* DRFRONT_OBJ_NOEXIST.
* @param[in] symbol_path The full path to fetched symbols file.
* @param[in] symbol_path_sz Size of \p symbol_path argument in characters.
*/
drfront_status_t
drfront_fetch_module_symbols(const char *modpath, OUT char *symbol_path,
size_t symbol_path_sz);
/**
* This routine creates the directory specified in \p dir.
*
* @param[in] dir New directory name.
*/
drfront_status_t
drfront_create_dir(const char *dir);
/**
* This routine removes the empty directory specified in \p dir.
*
* @param[in] dir Name of directory to remove.
*/
drfront_status_t
drfront_remove_dir(const char *dir);
/**
* This routine checks whether \p path is a valid directory.
*
* @param[in] path The path to be checked
* @param[out] is_dir Returns whether \p path is a valid directory.
*/
drfront_status_t
drfront_dir_exists(const char *path, OUT bool *is_dir);
/* DR_API EXPORT END */
#endif