[os2/process]: Implement retrieving command args in process info

This commit is contained in:
flysand7
2024-07-15 07:27:43 +11:00
parent c1f5d8f006
commit 5d6e0bc793
+57 -2
View File
@@ -165,6 +165,12 @@ _process_info :: proc(pid: int, selection: Process_Info_Fields, allocator: runti
defer if .Command_Line in info.fields && err != nil { defer if .Command_Line in info.fields && err != nil {
delete(info.command_line, allocator) delete(info.command_line, allocator)
} }
defer if .Command_Args in selection && err != nil {
for arg in info.command_args {
delete(arg, allocator)
}
delete(info.command_args, allocator)
}
if need_peb { if need_peb {
ntdll_lib := windows.LoadLibraryW(windows.L("ntdll.dll")) ntdll_lib := windows.LoadLibraryW(windows.L("ntdll.dll"))
if ntdll_lib == nil { if ntdll_lib == nil {
@@ -208,13 +214,14 @@ _process_info :: proc(pid: int, selection: Process_Info_Fields, allocator: runti
err = _get_platform_error() err = _get_platform_error()
return return
} }
if .Command_Line in selection { if .Command_Line in selection || .Command_Args in selection {
TEMP_ALLOCATOR_GUARD() TEMP_ALLOCATOR_GUARD()
cmdline_w := make([]u16, process_params.CommandLine.Length, temp_allocator()) cmdline_w := make([]u16, process_params.CommandLine.Length, temp_allocator())
if !read_slice(ph, process_params.CommandLine.Buffer, cmdline_w, &bytes_read) { if !read_slice(ph, process_params.CommandLine.Buffer, cmdline_w, &bytes_read) {
err = _get_platform_error() err = _get_platform_error()
return return
} }
if .Command_Line in selection {
cmdline, cmdline_err := windows.utf16_to_utf8(cmdline_w, allocator) cmdline, cmdline_err := windows.utf16_to_utf8(cmdline_w, allocator)
if cmdline_err != nil { if cmdline_err != nil {
err = cmdline_err err = cmdline_err
@@ -223,6 +230,16 @@ _process_info :: proc(pid: int, selection: Process_Info_Fields, allocator: runti
info.fields |= {.Command_Line} info.fields |= {.Command_Line}
info.command_line = cmdline info.command_line = cmdline
} }
if .Command_Args in selection {
args, args_err := _parse_argv(raw_data(cmdline_w), allocator)
if args_err != nil {
err = args_err
return
}
info.fields += {.Command_Args}
info.command_args = args
}
}
if .Environment in selection { if .Environment in selection {
TEMP_ALLOCATOR_GUARD() TEMP_ALLOCATOR_GUARD()
env_len := process_params.EnvironmentSize / 2 env_len := process_params.EnvironmentSize / 2
@@ -312,8 +329,9 @@ _current_process_info :: proc(selection: Process_Info_Fields, allocator: runtime
defer if .Executable_Path in selection && err != nil { defer if .Executable_Path in selection && err != nil {
delete(info.executable_path, allocator) delete(info.executable_path, allocator)
} }
if .Command_Line in selection { if .Command_Line in selection || .Command_Args in selection {
command_line_w := windows.GetCommandLineW() command_line_w := windows.GetCommandLineW()
if .Command_Line in selection {
command_line, command_line_err := windows.wstring_to_utf8(command_line_w, -1, allocator) command_line, command_line_err := windows.wstring_to_utf8(command_line_w, -1, allocator)
if command_line_err != nil { if command_line_err != nil {
err = command_line_err err = command_line_err
@@ -322,9 +340,25 @@ _current_process_info :: proc(selection: Process_Info_Fields, allocator: runtime
info.fields += {.Command_Line} info.fields += {.Command_Line}
info.command_line = command_line info.command_line = command_line
} }
if .Command_Args in selection {
args, args_err := _parse_argv(command_line_w, allocator)
if args_err != nil {
err = args_err
return
}
info.fields += {.Command_Args}
info.command_args = args
}
}
defer if .Command_Line in selection && err != nil { defer if .Command_Line in selection && err != nil {
delete(info.command_line, allocator) delete(info.command_line, allocator)
} }
defer if .Command_Args in selection && err != nil {
for arg in info.command_args {
delete(arg, allocator)
}
delete(info.command_args, allocator)
}
if .Environment in selection { if .Environment in selection {
env_block := windows.GetEnvironmentStringsW() env_block := windows.GetEnvironmentStringsW()
envs, envs_err := _parse_environment_block(env_block, allocator) envs, envs_err := _parse_environment_block(env_block, allocator)
@@ -407,6 +441,27 @@ _get_process_user :: proc(process_handle: windows.HANDLE, allocator: runtime.All
return full_name, nil return full_name, nil
} }
@(private)
_parse_argv :: proc(cmd_line_w: [^]u16, allocator: runtime.Allocator) -> ([]string, Error) {
argc: i32 = ---
argv_w := windows.CommandLineToArgvW(cmd_line_w, &argc)
if argv_w == nil {
return nil, _get_platform_error()
}
argv, argv_err := make([]string, argc, allocator)
if argv_err != nil {
return nil, argv_err
}
for arg_w, i in argv_w[:argc] {
arg, arg_err := windows.wstring_to_utf8(arg_w, -1, allocator)
if arg_err != nil {
return nil, arg_err
}
argv[i] = arg
}
return argv, nil
}
@(private) @(private)
_parse_environment_block :: proc(block: [^]u16, allocator: runtime.Allocator) -> ([]string, Error) { _parse_environment_block :: proc(block: [^]u16, allocator: runtime.Allocator) -> ([]string, Error) {
zt_count := 0 zt_count := 0