Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cf4ff64f authored by Spencer Low's avatar Spencer Low Committed by Elliott Hughes
Browse files

adb: win32: Unicode path names, env vars, some console support

Initial support for Unicode file/dir names. Unicode paths can be passed
on the command line, directory enumeration can enumerate Unicode paths,
Unicode paths are used for file access, and Unicode paths can be output
on the console correctly.

Also Unicode environment variable access.

Initial support for Unicode output from adb shell (which uses
adb_fwrite()). This is partial because the corner case of an
adb_fwrite() call with an incomplete UTF-8 multi-byte sequence does not
output correctly, but this should be uncommon, is better than what we
had before (*always* incorrect UTF-8 multi-byte sequences) and can be
fixed in the future.

Calls to Windows APIs with char strings were changed to pass wchar_t
strings to the FooW() variants.

For more details, see the giant comment in sysdeps_win32.cpp.

https://code.google.com/p/android/issues/detail?id=8185



Change-Id: I7ebf6713bb635638b986ccee97b354428837c9c5
Signed-off-by: default avatarSpencer Low <CompareAndSwap@gmail.com>
parent cf4dba5a
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -179,6 +179,8 @@ ifeq ($(HOST_OS),darwin)
endif

ifeq ($(HOST_OS),windows)
    # Use wmain instead of main
    LOCAL_LDFLAGS += -municode
    LOCAL_LDLIBS += -lws2_32 -lgdi32
    EXTRA_STATIC_LIBS := AdbWinApi
endif
+15 −6
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@
#include <unordered_map>

#include <base/logging.h>
#include <base/macros.h>
#include <base/stringprintf.h>
#include <base/strings.h>

@@ -557,9 +558,9 @@ int launch_server(int server_port)
    HANDLE                pipe_read, pipe_write;
    HANDLE                stdout_handle, stderr_handle;
    SECURITY_ATTRIBUTES   sa;
    STARTUPINFO           startup;
    STARTUPINFOW          startup;
    PROCESS_INFORMATION   pinfo;
    char                  program_path[ MAX_PATH ];
    WCHAR                 program_path[ MAX_PATH ];
    int                   ret;

    sa.nLength = sizeof(sa);
@@ -635,10 +636,18 @@ int launch_server(int server_port)
    ZeroMemory( &pinfo, sizeof(pinfo) );

    /* get path of current program */
    GetModuleFileName( NULL, program_path, sizeof(program_path) );
    char args[64];
    snprintf(args, sizeof(args), "adb -P %d fork-server server",  server_port);
    ret = CreateProcess(
    DWORD module_result = GetModuleFileNameW(NULL, program_path,
                                             arraysize(program_path));
    if ((module_result == arraysize(program_path)) || (module_result == 0)) {
        // String truncation or some other error.
        fprintf(stderr, "GetModuleFileNameW() failure, error %ld\n",
                GetLastError());
        return -1;
    }
    WCHAR args[64];
    snwprintf(args, arraysize(args),
              L"adb -P %d fork-server server", server_port);
    ret = CreateProcessW(
            program_path,                              /* program path  */
            args,
                                    /* the fork-server argument will set the
+7 −3
Original line number Diff line number Diff line
@@ -301,11 +301,15 @@ static int get_user_keyfilepath(char *filename, size_t len)
    char android_dir[PATH_MAX];
    struct stat buf;
#ifdef _WIN32
    char path[PATH_MAX];
    std::string home_str;
    home = getenv("ANDROID_SDK_HOME");
    if (!home) {
        SHGetFolderPath(NULL, CSIDL_PROFILE, NULL, 0, path);
        home = path;
        WCHAR path[MAX_PATH];
        if (FAILED(SHGetFolderPathW(NULL, CSIDL_PROFILE, NULL, 0, path))) {
            return -1;
        }
        home_str = narrow(path);
        home = home_str.c_str();
    }
    format = "%s\\%s";
#else
+37 −10
Original line number Diff line number Diff line
@@ -82,21 +82,22 @@ static BOOL WINAPI ctrlc_handler(DWORD type) {

static std::string GetLogFilePath() {
    const char log_name[] = "adb.log";
    char temp_path[MAX_PATH - sizeof(log_name) + 1];
    WCHAR temp_path[MAX_PATH];

    // https://msdn.microsoft.com/en-us/library/windows/desktop/aa364992%28v=vs.85%29.aspx
    DWORD nchars = GetTempPath(sizeof(temp_path), temp_path);
    CHECK_LE(nchars, sizeof(temp_path));
    if (nchars == 0) {
        // TODO(danalbert): Log the error message from FormatError().
        // Windows unfortunately has two errnos, errno and GetLastError(), so
        // I'm not sure what to do about PLOG here. Probably better to just
        // ignore it and add a simplified version of FormatError() for use in
        // log messages.
    DWORD nchars = GetTempPathW(arraysize(temp_path), temp_path);
    if ((nchars >= arraysize(temp_path)) || (nchars == 0)) {
        // If string truncation or some other error.
        // TODO(danalbert): Log the error message from
        // FormatMessage(GetLastError()). Pure Windows APIs only touch
        // GetLastError(), C Runtime APIs touch errno, so maybe there should be
        // WPLOG or PLOGW (which would read GetLastError() instead of errno),
        // in addition to PLOG, or maybe better to just ignore it and add a
        // simplified version of FormatMessage() for use in log messages.
        LOG(ERROR) << "Error creating log file";
    }

    return std::string(temp_path) + log_name;
    return narrow(temp_path) + log_name;
}
#else
static const char kNullFileName[] = "/dev/null";
@@ -189,9 +190,35 @@ int adb_main(int is_daemon, int server_port) {
    return 0;
}

#ifdef _WIN32
static bool _argv_is_utf8 = false;
#endif

int main(int argc, char** argv) {
#ifdef _WIN32
    if (!_argv_is_utf8) {
        fatal("_argv_is_utf8 is not set, suggesting that wmain was not "
              "called. Did you forget to link with -municode?");
    }
#endif

    adb_sysdeps_init();
    adb_trace_init(argv);
    D("Handling commandline()\n");
    return adb_commandline(argc - 1, const_cast<const char**>(argv + 1));
}

#ifdef _WIN32

extern "C"
int wmain(int argc, wchar_t **argv) {
    // Set diagnostic flag to try to detect if the build system was not
    // configured to call wmain.
    _argv_is_utf8 = true;

    // Convert args from UTF-16 to UTF-8 and pass that to main().
    NarrowArgs narrow_args(argc, argv);
    return main(argc, narrow_args.data());
}

#endif
+20 −8
Original line number Diff line number Diff line
@@ -14,21 +14,33 @@
 * limitations under the License.
 */

#include "sysdeps.h"

#include <assert.h>
#include <limits.h>
#include <windows.h>

#include <base/macros.h>

#include "adb.h"

void get_my_path(char *exe, size_t maxLen)
{
    char  *r;
// This is not currently called on Windows. Code that only runs on Windows
// should probably deal with UTF-16 WCHAR/wchar_t since Windows APIs natively
// work in that format.
void get_my_path(char *exe, size_t maxLen) {
    WCHAR wexe[MAX_PATH];

    DWORD module_result = GetModuleFileNameW(NULL, wexe, arraysize(wexe));
    if ((module_result == arraysize(wexe)) || (module_result == 0)) {
        // String truncation or other error.
        wexe[0] = '\0';
    }

    // Convert from UTF-16 to UTF-8.
    const std::string exe_str(narrow(wexe));

    /* XXX: should be GetModuleFileNameA */
    if (GetModuleFileName(NULL, exe, maxLen) > 0) {
        r = strrchr(exe, '\\');
        if (r != NULL)
            *r = '\0';
    if (exe_str.length() + 1 <= maxLen) {
        strcpy(exe, exe_str.c_str());
    } else {
        exe[0] = '\0';
    }
Loading