X-Git-Url: http://git.sven.stormbind.net/?p=sven%2Fjattach.git;a=blobdiff_plain;f=src%2Fwindows%2Fjattach.c;fp=src%2Fwindows%2Fjattach.c;h=f25f1d6f049f1f2acac970e02850736e0104d82b;hp=1318a94541a2ef6706bde4d361cc81c4d28385f3;hb=9464f9dff60583eddd012881f62b0c8561e9cf3a;hpb=44105a0f6c4f57785d3a74ef1b88af82e3fe6052 diff --git a/src/windows/jattach.c b/src/windows/jattach.c index 1318a94..f25f1d6 100644 --- a/src/windows/jattach.c +++ b/src/windows/jattach.c @@ -1,5 +1,5 @@ /* - * Copyright 2016 Andrei Pangin + * Copyright jattach authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -85,10 +85,19 @@ static LPVOID allocate_data(HANDLE hProcess, char* pipeName, int argc, char** ar strcpy(data.strJvm, "jvm"); strcpy(data.strEnqueue, "_JVM_EnqueueOperation"); strcpy(data.pipeName, pipeName); + data.args[0][0] = data.args[1][0] = data.args[2][0] = data.args[3][0] = 0; + // jcmd has 2 arguments maximum; merge excessive arguments into one + int cmd_args = argc >= 2 && strcmp(argv[0], "jcmd") == 0 ? 2 : argc >= 4 ? 4 : argc; + + size_t n = 0; int i; - for (i = 0; i < 4; i++) { - strcpy(data.args[i], i < argc ? argv[i] : ""); + for (i = 0; i < argc; i++) { + if (i < cmd_args) { + n = snprintf(data.args[i], sizeof(data.args[i]), "%s", argv[i]); + } else if (n < sizeof(data.args[cmd_args - 1])) { + n += snprintf(data.args[cmd_args - 1] + n, sizeof(data.args[cmd_args - 1]) - n, " %s", argv[i]); + } } LPVOID remoteData = VirtualAllocEx(hProcess, NULL, sizeof(CallData), MEM_COMMIT, PAGE_READWRITE); @@ -203,7 +212,7 @@ static int inject_thread(int pid, char* pipeName, int argc, char** argv) { } // JVM response is read from the pipe and mirrored to stdout -static int read_response(HANDLE hPipe) { +static int read_response(HANDLE hPipe, int print_output) { ConnectNamedPipe(hPipe, NULL); char buf[8192]; @@ -217,14 +226,19 @@ static int read_response(HANDLE hPipe) { buf[bytesRead] = 0; int result = atoi(buf); - do { - fwrite(buf, 1, bytesRead, stdout); - } while (ReadFile(hPipe, buf, sizeof(buf), &bytesRead, NULL)); + if (print_output) { + // Mirror JVM response to stdout + printf("JVM response code = "); + do { + fwrite(buf, 1, bytesRead, stdout); + } while (ReadFile(hPipe, buf, sizeof(buf), &bytesRead, NULL)); + printf("\n"); + } return result; } -int jattach(int pid, int argc, char** argv) { +int jattach(int pid, int argc, char** argv, int print_output) { // When attaching as an Administrator, make sure the target process can connect to our pipe, // i.e. allow read-write access to everyone. For the complete format description, see // https://docs.microsoft.com/en-us/windows/win32/secauthz/security-descriptor-string-format @@ -236,7 +250,7 @@ int jattach(int pid, int argc, char** argv) { sprintf(pipeName, "\\\\.\\pipe\\javatool%d", GetTickCount()); HANDLE hPipe = CreateNamedPipe(pipeName, PIPE_ACCESS_INBOUND, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 1, 4096, 8192, NMPWAIT_USE_DEFAULT_WAIT, &sec); - if (hPipe == NULL) { + if (hPipe == INVALID_HANDLE_VALUE) { print_error("Could not create pipe", GetLastError()); LocalFree(sec.lpSecurityDescriptor); return 1; @@ -249,11 +263,7 @@ int jattach(int pid, int argc, char** argv) { return 1; } - printf("Response code = "); - fflush(stdout); - - int result = read_response(hPipe); - printf("\n"); + int result = read_response(hPipe, print_output); CloseHandle(hPipe); return result; @@ -264,7 +274,6 @@ int jattach(int pid, int argc, char** argv) { int main(int argc, char** argv) { if (argc < 3) { printf("jattach " JATTACH_VERSION " built on " __DATE__ "\n" - "Copyright 2021 Andrei Pangin\n" "\n" "Usage: jattach [args ...]\n" "\n" @@ -281,7 +290,7 @@ int main(int argc, char** argv) { return 1; } - return jattach(pid, argc - 2, argv + 2); + return jattach(pid, argc - 2, argv + 2, 1); } #endif // JATTACH_VERSION