diff options
Diffstat (limited to 'win32')
-rw-r--r-- | win32/process.c | 107 |
1 files changed, 89 insertions, 18 deletions
diff --git a/win32/process.c b/win32/process.c index d6176ca23..3219fcad4 100644 --- a/win32/process.c +++ b/win32/process.c | |||
@@ -1,5 +1,6 @@ | |||
1 | #include "libbb.h" | 1 | #include "libbb.h" |
2 | #include <tlhelp32.h> | 2 | #include <tlhelp32.h> |
3 | #include <psapi.h> | ||
3 | 4 | ||
4 | int waitpid(pid_t pid, int *status, int options) | 5 | int waitpid(pid_t pid, int *status, int options) |
5 | { | 6 | { |
@@ -406,6 +407,79 @@ static inline long long filetime_to_ticks(const FILETIME *ft) | |||
406 | HNSEC_PER_TICK; | 407 | HNSEC_PER_TICK; |
407 | } | 408 | } |
408 | 409 | ||
410 | /* | ||
411 | * Attempt to get the applet name from another instance of busybox.exe. | ||
412 | * This will only work if the other process is using the same binary | ||
413 | * as the current process. If anything goes wrong just give up. | ||
414 | */ | ||
415 | static char *get_applet_name(DWORD pid, char *exe) | ||
416 | { | ||
417 | HANDLE proc; | ||
418 | HMODULE mlist[32]; | ||
419 | DWORD needed; | ||
420 | void *address; | ||
421 | char *my_base; | ||
422 | char buffer[128]; | ||
423 | char *name = NULL; | ||
424 | int i; | ||
425 | |||
426 | if (!(proc=OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, | ||
427 | FALSE, pid))) { | ||
428 | return NULL; | ||
429 | } | ||
430 | |||
431 | /* | ||
432 | * Search for the module that matches the name of the executable. | ||
433 | * The values returned in mlist are actually the base address of | ||
434 | * the module in the other process (as noted in the documentation | ||
435 | * for the MODULEINFO structure). | ||
436 | */ | ||
437 | if (!EnumProcessModules(proc, mlist, sizeof(mlist), &needed)) { | ||
438 | goto finish; | ||
439 | } | ||
440 | |||
441 | for (i=0; i<needed/sizeof(HMODULE); ++i) { | ||
442 | char modname[MAX_PATH]; | ||
443 | if (GetModuleFileNameEx(proc, mlist[i], modname, sizeof(modname))) { | ||
444 | if (strcasecmp(bb_basename(modname), exe) == 0) { | ||
445 | break; | ||
446 | } | ||
447 | } | ||
448 | } | ||
449 | |||
450 | if (i == needed/sizeof(HMODULE)) { | ||
451 | goto finish; | ||
452 | } | ||
453 | |||
454 | /* attempt to read the BusyBox version string */ | ||
455 | my_base = (char *)GetModuleHandle(NULL); | ||
456 | address = (char *)mlist[i] + ((char *)bb_banner - my_base); | ||
457 | if (!ReadProcessMemory(proc, address, buffer, 128, NULL)) { | ||
458 | goto finish; | ||
459 | } | ||
460 | |||
461 | if (memcmp(buffer, bb_banner, strlen(bb_banner)) != 0) { | ||
462 | /* version mismatch (or not BusyBox at all) */ | ||
463 | goto finish; | ||
464 | } | ||
465 | |||
466 | /* attempt to read the applet name */ | ||
467 | address = (char *)mlist[i] + ((char *)bb_applet_name - my_base); | ||
468 | if (!ReadProcessMemory(proc, address, buffer, 128, NULL)) { | ||
469 | goto finish; | ||
470 | } | ||
471 | |||
472 | /* check that the string really is an applet name */ | ||
473 | buffer[31] = '\0'; | ||
474 | if (find_applet_by_name(buffer) >= 0) { | ||
475 | name = auto_string(xstrdup(buffer)); | ||
476 | } | ||
477 | |||
478 | finish: | ||
479 | CloseHandle(proc); | ||
480 | return name; | ||
481 | } | ||
482 | |||
409 | /* POSIX version in libbb/procps.c */ | 483 | /* POSIX version in libbb/procps.c */ |
410 | procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags | 484 | procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags |
411 | #if !ENABLE_FEATURE_PS_TIME && !ENABLE_FEATURE_PS_LONG | 485 | #if !ENABLE_FEATURE_PS_TIME && !ENABLE_FEATURE_PS_LONG |
@@ -414,7 +488,8 @@ UNUSED_PARAM | |||
414 | ) | 488 | ) |
415 | { | 489 | { |
416 | PROCESSENTRY32 pe; | 490 | PROCESSENTRY32 pe; |
417 | const char *comm; | 491 | const char *comm, *name; |
492 | BOOL ret; | ||
418 | 493 | ||
419 | pe.dwSize = sizeof(pe); | 494 | pe.dwSize = sizeof(pe); |
420 | if (!sp) { | 495 | if (!sp) { |
@@ -424,18 +499,16 @@ UNUSED_PARAM | |||
424 | free(sp); | 499 | free(sp); |
425 | return NULL; | 500 | return NULL; |
426 | } | 501 | } |
427 | if (!Process32First(sp->snapshot, &pe)) { | 502 | ret = Process32First(sp->snapshot, &pe); |
428 | CloseHandle(sp->snapshot); | ||
429 | free(sp); | ||
430 | return NULL; | ||
431 | } | ||
432 | } | 503 | } |
433 | else { | 504 | else { |
434 | if (!Process32Next(sp->snapshot, &pe)) { | 505 | ret = Process32Next(sp->snapshot, &pe); |
435 | CloseHandle(sp->snapshot); | 506 | } |
436 | free(sp); | 507 | |
437 | return NULL; | 508 | if (!ret) { |
438 | } | 509 | CloseHandle(sp->snapshot); |
510 | free(sp); | ||
511 | return NULL; | ||
439 | } | 512 | } |
440 | 513 | ||
441 | memset(&sp->vsz, 0, sizeof(*sp) - offsetof(procps_status_t, vsz)); | 514 | memset(&sp->vsz, 0, sizeof(*sp) - offsetof(procps_status_t, vsz)); |
@@ -478,19 +551,17 @@ UNUSED_PARAM | |||
478 | sp->pid = pe.th32ProcessID; | 551 | sp->pid = pe.th32ProcessID; |
479 | sp->ppid = pe.th32ParentProcessID; | 552 | sp->ppid = pe.th32ParentProcessID; |
480 | 553 | ||
481 | comm = pe.szExeFile; | ||
482 | if (sp->pid == GetProcessId(GetCurrentProcess())) { | 554 | if (sp->pid == GetProcessId(GetCurrentProcess())) { |
483 | comm = applet_name; | 555 | comm = applet_name; |
484 | } | 556 | } |
557 | else if ((name=get_applet_name(pe.th32ProcessID, pe.szExeFile)) != NULL) { | ||
558 | comm = name; | ||
559 | } | ||
485 | else { | 560 | else { |
486 | char name[32], *value; | 561 | comm = pe.szExeFile; |
487 | |||
488 | sprintf(name, "BB_APPLET_%d", sp->pid); | ||
489 | if ((value=getenv(name)) != NULL) { | ||
490 | comm = value; | ||
491 | } | ||
492 | } | 562 | } |
493 | safe_strncpy(sp->comm, comm, COMM_LEN); | 563 | safe_strncpy(sp->comm, comm, COMM_LEN); |
564 | |||
494 | return sp; | 565 | return sp; |
495 | } | 566 | } |
496 | 567 | ||