S
Sam (Deleted User)
Guest
Dontrel would be proud.
ok no seriously, why is this extension function I wrote not working?
Download the 2.3.x yyp project and source code here.
Create:
Alarm 0:
Draw GUI:
Global Left Mouse Down:
Mouse Wheel Up:
Mouse Wheel Down:
Enter Key Pressed:
Escape Key Pressed:
Space Key Pressed:
'R' Key Pressed:
'S' Key Pressed
- 1x1 game window with full scale game option. though not relevant to issue
- uses my dialog module and border toggle extensions though not relevant to issue
- let's try to break down one problem at a time, and I'll let you know what i figure out
- most of the code above does not work, and on windows it doesn't even draw text
- on mac it does draw text, but all the variables are as though not being set
- dll/dylib on github along with source code for those see this link right here
libxproc.yy:
and last but not least here's what I managed to narrow down so far, and we'll take this one issue at a time so bear with me.
Create Event (narrowed down):
I hope someone will be willing to halp me I need to be saved from the great white shark
Yes, this post is serious, well, mostly.
Samuel
ok no seriously, why is this extension function I wrote not working?
Download the 2.3.x yyp project and source code here.
Create:
GML:
procId = 0; parentProcId = 0;
widget_set_system(ws_x11_kdialog);
exefname = ""; cwddname = ""; cmdstr = "";
widget_set_owner(string(int64(window_handle())));
pause = false; window_set_showborder(false);
var i = 0; var list = ProcListCreate();
var size = ProcessInfoLength(list);
if (size) {
if (i < size) {
var info = ProcessInfo(list, i);
var ppid = ParentProcessId(info);
var exe = ExecutableImageFilePath(info);
var cwd = CurrentWorkingDirectory(info);
procId = ProcessId(info); parentProcId = ppid;
exefname = (exe != 0) ? exe : "<undefined>";
cwddname = (cwd != 0) ? cwd : "<undefined>";
var ii = 0; cmdstr = "";
var cmdsize = CommandLineLength(info);
if (cmdsize) {
for (ii = 0; ii < cmdsize; ii++) {
tmpstr = string_replace_all(CommandLine(info, i), @'\', @'\\');
cmdstr += @'"' + string_replace_all(tmpstr, @'"', @'\"') + @'" ';
}
cmdstr = string_copy(cmdstr, 0, string_length(cmdstr) - 1);
}
FreeProcInfo(info);
}
FreeProcList(list);
i++; j = i;
alarm[0] = 10;
}
GML:
if (!pause) {
var list = ProcListCreate();
var size = ProcessInfoLength(list);
if (size) {
if (j < size) {
var info = ProcessInfo(list, j);
var ppid = ParentProcessId(info);
var exe = ExecutableImageFilePath(info);
var cwd = CurrentWorkingDirectory(info);
procId = ProcessId(info); parentProcId = ppid;
exefname = (exe != 0) ? exe : "<undefined>";
cwddname = (cwd != 0) ? cwd : "<undefined>";
var ii = 0; cmdstr = "";
var cmdsize = CommandLineLength(info);
if (cmdsize) {
for (ii = 0; ii < cmdsize; ii++) {
tmpstr = string_replace_all(CommandLine(info, j), @'\', @'\\');
cmdstr += @'"' + string_replace_all(tmpstr, @'"', @'\"') + @'" ';
}
cmdstr = string_copy(cmdstr, 0, string_length(cmdstr) - 1);
}
FreeProcInfo(info);
} else {
FreeProcList(list);
room_restart();
exit;
}
FreeProcList(list);
j++;
alarm[0] = 10;
}
}
GML:
draw_set_color(c_white);
draw_set_font(fnt_example);
display_set_gui_size(window_get_width(), window_get_height());
var str = "press <space> to " + string(!pause ? "pause" : "resume") + " enumeration, or press <enter> to inspect" +
"\nthe environment variables belonging to the process identifier.\n" +
"\npid=" + string(procId) +
"\nppid=" + string(parentProcId) +
"\nexe=" + ((!file_exists(exefname)) ? "<undefined>": exefname) +
"\ncwd=" + ((!directory_exists(cwddname)) ? "<undefined>": cwddname) +
"\ncmd=" + ((!ProcIdExists(procId) || cmdstr == "") ? "<undefined>": cmdstr);
display_set_gui_size(string_width(str) + 64, string_height(str) + 64);
draw_set_color(c_black);
draw_rectangle(16, 16, string_width(str) + 48, string_height(str) + 48, 0);
draw_set_color(c_white);
draw_text(32, 32, str);
draw_set_color(c_black);
draw_rectangle(0, 0, string_width(str) + 64, string_height(str) + 64, 1);
draw_rectangle(1, 1, string_width(str) + 63, string_height(str) + 63, 1);
window_set_size(string_width(str) + 64, string_height(str) + 64);
if (!pause) window_center();
draw_set_color(c_white);
GML:
if (pause) {
window_set_position(display_mouse_get_x() - (window_get_width() / 2), display_mouse_get_y() - (window_get_height() / 2));
if (window_get_cursor() == cr_arrow) window_set_cursor(cr_drag);
}
GML:
if (!pause) {
var list = ProcListCreate();
var size = ProcessInfoLength(list);
if (size) {
j++; if (j > size - 1) j = 0;
if (j < size) {
var info = ProcessInfo(list, j);
var ppid = ParentProcessId(info);
var exe = ExecutableImageFilePath(info);
var cwd = CurrentWorkingDirectory(info);
procId = ProcessId(info); parentProcId = ppid;
exefname = (exe != 0) ? exe : "<undefined>";
cwddname = (cwd != 0) ? cwd : "<undefined>";
var ii = 0; cmdstr = "";
var cmdsize = CommandLineLength(info);
if (cmdsize) {
for (ii = 0; ii < cmdsize; ii++) {
tmpstr = string_replace_all(CommandLine(info, j), @'\', @'\\');
cmdstr += @'"' + string_replace_all(tmpstr, @'"', @'\"') + @'" ';
}
cmdstr = string_copy(cmdstr, 0, string_length(cmdstr) - 1);
}
FreeProcInfo(info);
}
FreeProcList(list);
}
}
GML:
if (!pause) {
var list = ProcListCreate();
var size = ProcessInfoLength(list);
if (size) {
j--; if (j < 0) j = size - 1;
if (j < size) {
var info = ProcessInfo(list, j);
var ppid = ParentProcessId(info);
var exe = ExecutableImageFilePath(info);
var cwd = CurrentWorkingDirectory(info);
procId = ProcessId(info); parentProcId = ppid;
exefname = (exe != 0) ? exe : "<undefined>";
cwddname = (cwd != 0) ? cwd : "<undefined>";
var ii = 0; cmdstr = "";
var cmdsize = CommandLineLength(info);
if (cmdsize) {
for (ii = 0; ii < cmdsize; ii++) {
tmpstr = string_replace_all(CommandLine(info, j), @'\', @'\\');
cmdstr += @'"' + string_replace_all(tmpstr, @'"', @'\"') + @'" ';
}
cmdstr = string_copy(cmdstr, 0, string_length(cmdstr) - 1);
}
FreeProcInfo(info);
}
FreeProcList(list);
}
}
GML:
widget_set_caption("PEB Inspector");
var list = ProcListCreate();
if (ProcessInfoLength(list)) {
for (var i = 0; i < ProcessInfoLength(list); i++) {
var info = ProcessInfo(info, i)
var env = 0; var envsize = 0; Environment(info, i);
if (EnvironmentLength(info)) {
if (ProcIdExists(procId)) {
for (var jj = 0; jj < envsize; jj++) {
var q = show_question("Continue environment iteration?\n\n" + string(env[jj]));
keyboard_clear(keyboard_lastkey);
if (!q) { FreeProcInfo(list); exit; }
}
}
} else {
show_message("No environment to iterate.\n\n<undefined>");
keyboard_clear(keyboard_lastkey);
}
FreeProcInfo(info);
}
}
GML:
game_end();
GML:
pause = !pause;
if (!pause) {
alarm[0] = 10;
}
GML:
if (!keyboard_check(vk_control)) exit;
widget_set_caption("Run");
var command = get_string("Execute command:", "");
keyboard_clear(keyboard_lastkey);
ProcessExecuteAsync(command);
GML:
if (!keyboard_check(vk_control)) exit;
widget_set_caption("Save procfs?");
q = show_question("Save the current process information state to filesystem? The output files' contents will be NULL character separated; view the output files in Notepad++ to see all characters after the first NULL byte.");
keyboard_clear(keyboard_lastkey);
if (q) {
var dname = get_directory_alt("Choose a directory to save output filesystem tree...", working_directory);
keyboard_clear(keyboard_lastkey);
if (dname != "") {
directory_create(dname + "/proc");
var procList = ProcListCreate();
if (ProcessInfoLength(procList)) {
for (var iii = 0; iii < ProcessInfoLength(procList); iii++) {
var procInfo = ProcessInfo(procList, iii);
directory_create(dname + "/proc/" + string(ProcessId(procInfo)));
if (string_length(ExecutableImageFilePath(procInfo))) {
if (file_exists(ExecutableImageFilePath(procInfo))) {
file_delete(dname + "/proc/" + string(ProcessId(procInfo)) + "/exe");
var f = file_text_open_append(dname + "/proc/" + string(ProcessId(procInfo)) + "/exe");
file_text_write_string(f, string(ExecutableImageFilePath(procInfo)) + chr(0));
file_text_close(f);
}
}
if (string_length(CurrentWorkingDirectory(procInfo))) {
if (directory_exists(CurrentWorkingDirectory(procInfo))) {
file_delete(dname + "/proc/" + string(ProcessId(procInfo)) + "/cwd");
var f = file_text_open_append(dname + "/proc/" + string(ProcessId(procInfo)) + "/cwd");
file_text_write_string(f, string(CurrentWorkingDirectory(procInfo)) + chr(0));
file_text_close(f);
}
}
if (CommandLineLength(procInfo)) {
file_delete(dname + "/proc/" + string(ProcessId(procInfo)) + "/cmdline");
for (var jjj = 0; jjj < CommandLineLength(procInfo); jjj++) {
var f = file_text_open_append(dname + "/proc/" + string(ProcessId(procInfo)) + "/cmdline");
file_text_write_string(f, string(CommandLine(procInfo, jjj) + chr(0)));
file_text_close(f);
}
var f = file_text_open_append(dname + "/proc/" + string(ProcessId(procInfo)) + "/cmdline");
file_text_write_string(f, chr(0));
file_text_close(f);
}
if (EnvironmentLength(procInfo)) {
file_delete(dname + "/proc/" + string(ProcessId(procInfo)) + "/environ");
for (var jjj = 0; jjj < EnvironmentLength(procInfo); jjj++) {
var f = file_text_open_append(dname + "/proc/" + string(ProcessId(procInfo)) + "/environ");
file_text_write_string(f, string(Environment(procInfo, jjj) + chr(0)));
file_text_close(f);
}
var f = file_text_open_append(dname + "/proc/" + string(ProcessId(procInfo)) + "/environ");
file_text_write_string(f, chr(0));
file_text_close(f);
}
FreeProcInfo(procInfo);
}
FreeProcList(procList);
}
widget_set_caption("Complete!");
show_message("Done!");
keyboard_clear(keyboard_lastkey);
}
}
- uses my dialog module and border toggle extensions though not relevant to issue
- let's try to break down one problem at a time, and I'll let you know what i figure out
- most of the code above does not work, and on windows it doesn't even draw text
- on mac it does draw text, but all the variables are as though not being set
- dll/dylib on github along with source code for those see this link right here
libxproc.yy:
JSON:
{
"optionsFile": "options.json",
"options": [],
"exportToGame": true,
"supportedTargets": -1,
"extensionVersion": "0.0.1",
"packageId": "",
"productId": "",
"author": "",
"date": "2021-06-09T06:32:23.3229009-04:00",
"license": "",
"description": "",
"helpfile": "",
"iosProps": false,
"tvosProps": false,
"androidProps": false,
"installdir": "",
"files": [
{"filename":"libxproc.dll","origname":"","init":"","final":"","kind":1,"uncompress":false,"functions":[
{"externalName":"ProcessExecute","kind":1,"help":"ProcessExecute(command)","hidden":false,"returnType":2,"argCount":0,"args":[
1,
],"resourceVersion":"1.0","name":"ProcessExecute","tags":[],"resourceType":"GMExtensionFunction",},
{"externalName":"ProcessExecuteAsync","kind":1,"help":"ProcessExecuteAsync(command)","hidden":false,"returnType":2,"argCount":0,"args":[
1,
],"resourceVersion":"1.0","name":"ProcessExecuteAsync","tags":[],"resourceType":"GMExtensionFunction",},
{"externalName":"CompletionStatusFromExecutedProcess","kind":1,"help":"CompletionStatusFromExecutedProcess(procIndex)","hidden":false,"returnType":2,"argCount":0,"args":[
2,
],"resourceVersion":"1.0","name":"CompletionStatusFromExecutedProcess","tags":[],"resourceType":"GMExtensionFunction",},
{"externalName":"ExecutedProcessWriteToStandardInput","kind":1,"help":"ExecutedProcessWriteToStandardInput(procId,input)","hidden":false,"returnType":2,"argCount":0,"args":[
2,
1,
],"resourceVersion":"1.0","name":"ExecutedProcessWriteToStandardInput","tags":[],"resourceType":"GMExtensionFunction",},
{"externalName":"ExecutedProcessReadFromStandardOutput","kind":1,"help":"ExecutedProcessReadFromStandardOutput(procId)","hidden":false,"returnType":1,"argCount":0,"args":[
2,
],"resourceVersion":"1.0","name":"ExecutedProcessReadFromStandardOutput","tags":[],"resourceType":"GMExtensionFunction",},
{"externalName":"ProcIdExists","kind":1,"help":"ProcIdExists(procId)","hidden":false,"returnType":2,"argCount":0,"args":[
2,
],"resourceVersion":"1.0","name":"ProcIdExists","tags":[],"resourceType":"GMExtensionFunction",},
{"externalName":"ProcIdKill","kind":1,"help":"ProcIdKill(procId)","hidden":false,"returnType":2,"argCount":0,"args":[
2,
],"resourceVersion":"1.0","name":"ProcIdKill","tags":[],"resourceType":"GMExtensionFunction",},
{"externalName":"ProcListCreate","kind":1,"help":"ProcListCreate()","hidden":false,"returnType":1,"argCount":0,"args":[],"resourceVersion":"1.0","name":"ProcListCreate","tags":[],"resourceType":"GMExtensionFunction",},
{"externalName":"ProcessInfo","kind":1,"help":"ProcessInfo(procList,i)","hidden":false,"returnType":1,"argCount":0,"args":[
1,
2,
],"resourceVersion":"1.0","name":"ProcessInfo","tags":[],"resourceType":"GMExtensionFunction",},
{"externalName":"ProcessInfoLength","kind":1,"help":"ProcessInfoLength(procList)","hidden":false,"returnType":2,"argCount":0,"args":[
1,
],"resourceVersion":"1.0","name":"ProcessInfoLength","tags":[],"resourceType":"GMExtensionFunction",},
{"externalName":"FreeProcInfo","kind":1,"help":"FreeProcInfo(procInfo)","hidden":false,"returnType":2,"argCount":0,"args":[
1,
],"resourceVersion":"1.0","name":"FreeProcInfo","tags":[],"resourceType":"GMExtensionFunction",},
{"externalName":"FreeProcList","kind":1,"help":"FreeProcList(procList)","hidden":false,"returnType":2,"argCount":0,"args":[
1,
],"resourceVersion":"1.0","name":"FreeProcList","tags":[],"resourceType":"GMExtensionFunction",},
{"externalName":"ProcessId","kind":1,"help":"ProcessId(procInfo)","hidden":false,"returnType":2,"argCount":0,"args":[
1,
],"resourceVersion":"1.0","name":"ProcessId","tags":[],"resourceType":"GMExtensionFunction",},
{"externalName":"ExecutableImageFilePath","kind":1,"help":"ExecutableImageFilePath(procInfo)","hidden":false,"returnType":2,"argCount":0,"args":[
1,
],"resourceVersion":"1.0","name":"ExecutableImageFilePath","tags":[],"resourceType":"GMExtensionFunction",},
{"externalName":"CurrentWorkingDirectory","kind":1,"help":"CurrentWorkingDirectory(procInfo)","hidden":false,"returnType":2,"argCount":0,"args":[
1,
],"resourceVersion":"1.0","name":"CurrentWorkingDirectory","tags":[],"resourceType":"GMExtensionFunction",},
{"externalName":"ParentProcessId","kind":1,"help":"ParentProcessId(procInfo)","hidden":false,"returnType":2,"argCount":0,"args":[
1,
],"resourceVersion":"1.0","name":"ParentProcessId","tags":[],"resourceType":"GMExtensionFunction",},
{"externalName":"ChildProcessId","kind":1,"help":"ChildProcessId(procInfo,i)","hidden":false,"returnType":2,"argCount":0,"args":[
1,
2,
],"resourceVersion":"1.0","name":"ChildProcessId","tags":[],"resourceType":"GMExtensionFunction",},
{"externalName":"ChildProcessIdLength","kind":1,"help":"ChildProcessIdLength(procInfo)","hidden":false,"returnType":2,"argCount":0,"args":[
1,
],"resourceVersion":"1.0","name":"ChildProcessIdLength","tags":[],"resourceType":"GMExtensionFunction",},
{"externalName":"CommandLine","kind":1,"help":"CommandLine(procInfo,i)","hidden":false,"returnType":1,"argCount":0,"args":[
1,
2,
],"resourceVersion":"1.0","name":"CommandLine","tags":[],"resourceType":"GMExtensionFunction",},
{"externalName":"CommandLineLength","kind":1,"help":"CommandLineLength(procInfo)","hidden":false,"returnType":2,"argCount":0,"args":[
1,
],"resourceVersion":"1.0","name":"CommandLineLength","tags":[],"resourceType":"GMExtensionFunction",},
{"externalName":"Environment","kind":1,"help":"Environment(procInfo,i)","hidden":false,"returnType":1,"argCount":0,"args":[
1,
2,
],"resourceVersion":"1.0","name":"Environment","tags":[],"resourceType":"GMExtensionFunction",},
{"externalName":"EnvironmentLength","kind":1,"help":"EnvironmentLength(procInfo)","hidden":false,"returnType":2,"argCount":0,"args":[
1,
],"resourceVersion":"1.0","name":"EnvironmentLength","tags":[],"resourceType":"GMExtensionFunction",},
{"externalName":"OwnedWindowId","kind":1,"help":"OwnedWindowId(procInfo,i)","hidden":false,"returnType":1,"argCount":0,"args":[
1,
2,
],"resourceVersion":"1.0","name":"OwnedWindowId","tags":[],"resourceType":"GMExtensionFunction",},
{"externalName":"OwnedWindowIdLength","kind":1,"help":"OwnedWindowIdLength(procInfo)","hidden":false,"returnType":2,"argCount":0,"args":[
1,
],"resourceVersion":"1.0","name":"OwnedWindowIdLength","tags":[],"resourceType":"GMExtensionFunction",},
{"externalName":"WindowIdExists","kind":1,"help":"WindowIdExists(winId)","hidden":false,"returnType":2,"argCount":0,"args":[
1,
],"resourceVersion":"1.0","name":"WindowIdExists","tags":[],"resourceType":"GMExtensionFunction",},
{"externalName":"WindowIdKill","kind":1,"help":"WindowIdKill(winId)","hidden":false,"returnType":2,"argCount":0,"args":[
1,
],"resourceVersion":"1.0","name":"WindowIdKill","tags":[],"resourceType":"GMExtensionFunction",},
],"constants":[],"ProxyFiles":[
{"TargetMask":1,"resourceVersion":"1.0","name":"libxproc.dylib","tags":[],"resourceType":"GMProxyFile",},
],"copyToTargets":194,"order":[
{"name":"ProcessExecute","path":"extensions/libxproc/libxproc.yy",},
{"name":"ProcessExecuteAsync","path":"extensions/libxproc/libxproc.yy",},
{"name":"CompletionStatusFromExecutedProcess","path":"extensions/libxproc/libxproc.yy",},
{"name":"ExecutedProcessWriteToStandardInput","path":"extensions/libxproc/libxproc.yy",},
{"name":"ExecutedProcessReadFromStandardOutput","path":"extensions/libxproc/libxproc.yy",},
{"name":"ProcIdExists","path":"extensions/libxproc/libxproc.yy",},
{"name":"ProcIdKill","path":"extensions/libxproc/libxproc.yy",},
{"name":"ProcListCreate","path":"extensions/libxproc/libxproc.yy",},
{"name":"ProcessInfo","path":"extensions/libxproc/libxproc.yy",},
{"name":"ProcessInfoLength","path":"extensions/libxproc/libxproc.yy",},
{"name":"FreeProcInfo","path":"extensions/libxproc/libxproc.yy",},
{"name":"FreeProcList","path":"extensions/libxproc/libxproc.yy",},
{"name":"ProcessId","path":"extensions/libxproc/libxproc.yy",},
{"name":"ExecutableImageFilePath","path":"extensions/libxproc/libxproc.yy",},
{"name":"CurrentWorkingDirectory","path":"extensions/libxproc/libxproc.yy",},
{"name":"ParentProcessId","path":"extensions/libxproc/libxproc.yy",},
{"name":"ChildProcessId","path":"extensions/libxproc/libxproc.yy",},
{"name":"ChildProcessIdLength","path":"extensions/libxproc/libxproc.yy",},
{"name":"CommandLine","path":"extensions/libxproc/libxproc.yy",},
{"name":"CommandLineLength","path":"extensions/libxproc/libxproc.yy",},
{"name":"Environment","path":"extensions/libxproc/libxproc.yy",},
{"name":"EnvironmentLength","path":"extensions/libxproc/libxproc.yy",},
{"name":"OwnedWindowId","path":"extensions/libxproc/libxproc.yy",},
{"name":"OwnedWindowIdLength","path":"extensions/libxproc/libxproc.yy",},
{"name":"WindowIdExists","path":"extensions/libxproc/libxproc.yy",},
{"name":"WindowIdKill","path":"extensions/libxproc/libxproc.yy",},
],"resourceVersion":"1.0","name":"","tags":[],"resourceType":"GMExtensionFile",},
],
"classname": "",
"tvosclassname": null,
"tvosdelegatename": null,
"iosdelegatename": "",
"androidclassname": "",
"sourcedir": "",
"androidsourcedir": "",
"macsourcedir": "",
"maccompilerflags": "",
"tvosmaccompilerflags": "",
"maclinkerflags": "",
"tvosmaclinkerflags": "",
"iosplistinject": null,
"tvosplistinject": null,
"androidinject": null,
"androidmanifestinject": null,
"androidactivityinject": null,
"gradleinject": null,
"iosSystemFrameworkEntries": [],
"tvosSystemFrameworkEntries": [],
"iosThirdPartyFrameworkEntries": [],
"tvosThirdPartyFrameworkEntries": [],
"IncludedResources": [],
"androidPermissions": [],
"copyToTargets": 194,
"iosCocoaPods": "",
"tvosCocoaPods": "",
"iosCocoaPodDependencies": "",
"tvosCocoaPodDependencies": "",
"parent": {
"name": "Extensions",
"path": "folders/Extensions.yy",
},
"resourceVersion": "1.2",
"name": "libxproc",
"tags": [],
"resourceType": "GMExtension",
}
Create Event (narrowed down):
GML:
var i = 0; var list = ProcListCreate();
var size = ProcessInfoLength(list);
if (size) {
if (i < size) {
....
size
is returning undefined
. so ProcessInfoLength()
isn't behaving like it should. Oddly enough when I use it in a empty C++ main() function with std::cout << the result << std::endl;
it returns the number of processes in counting that are running on my current user session, which is the expected behavior. Though in GM i can only seem to get it to spit out undefined in the return value.ProcListCreate();
however is working ok because when i show_message() to see what it returns it is giving me the correct pointer address stored in a formatted string, which is expected behavior in GM with this function in particular. Both work in C++ and other game engines I've tried it in, or rather all of my functions work in anything I try them in besides GM. Not sure why? It's really weird, and I don't know what to make of it. Now for relevant C++ code isolated out here...
C++:
...
#if !defined(_WIN32)
typedef int PROCID; // POSIX pid_t
#else
typedef unsigned long PROCID; // Win32 DWORD
#endif
...
typedef char *PROCLIST; // address space of process vector
typedef char *PROCINFO; // address space of procinfo struct
typedef struct {
PROCID ProcessId;
char *ExecutableImageFilePath;
char *CurrentWorkingDirectory;
PROCID ParentProcessId;
PROCID *ChildProcessId;
int ChildProcessIdLength;
char **CommandLine;
int CommandLineLength;
char **Environment;
int EnvironmentLength;
#if defined(XPROCESS_GUIWINDOW_IMPL)
WINDOWID *OwnedWindowId;
int OwnedWindowIdLength;
#endif
} _PROCINFO; // struct for internal use on C++ side
...
void ProcIdEnumerate(PROCID **procId, int *size) {
std::vector<PROCID> vec; int i = 0;
#if defined(_WIN32)
HANDLE hp = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 pe = { 0 };
pe.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(hp, &pe)) {
do {
vec.push_back(pe.th32ProcessID); i++;
} while (Process32Next(hp, &pe));
}
CloseHandle(hp);
#elif (defined(__APPLE__) && defined(__MACH__))
if (ProcIdExists(0)) { vec.push_back(0); i++; }
int cntp = proc_listpids(PROC_ALL_PIDS, 0, nullptr, 0);
std::vector<PROCID> proc_info(cntp);
std::fill(proc_info.begin(), proc_info.end(), 0);
proc_listpids(PROC_ALL_PIDS, 0, &proc_info[0], sizeof(PROCID) * cntp);
for (int j = cntp - 1; j >= 0; j--) {
if (proc_info[j] == 0) { continue; }
vec.push_back(proc_info[j]); i++;
}
#elif (defined(__linux__) && !defined(__ANDROID__))
if (ProcIdExists(0)) { vec.push_back(0); i++; }
PROCTAB *proc = openproc(PROC_FILLMEM | PROC_FILLSTAT | PROC_FILLSTATUS);
while (proc_t *proc_info = readproc(proc, nullptr)) {
vec.push_back(proc_info->tgid); i++;
freeproc(proc_info);
}
closeproc(proc);
#elif defined(__FreeBSD__)
int cntp; if (kinfo_proc *proc_info = kinfo_getallproc(&cntp)) {
for (int j = 0; j < cntp; j++) {
vec.push_back(proc_info[j].ki_pid); i++;
}
free(proc_info);
}
#endif
*procId = (PROCID *)malloc(sizeof(PROCID) * vec.size());
if (procId) {
std::copy(vec.begin(), vec.end(), *procId);
*size = i;
}
}
void FreeProcId(PROCID *procId) {
if (procId) {
free(procId);
}
}
...
PROCINFO ProcInfoFromInternalProcInfo(_PROCINFO *procInfo) {
static std::string res;
const void *address = static_cast<const void *>(procInfo);
std::stringstream ss; ss << address;
res = ss.str();
return (PROCINFO)res.c_str();
}
_PROCINFO *InternalProcInfoFromProcInfo(PROCINFO procInfo) {
void *address; sscanf(procInfo, "%p", &address);
_PROCINFO *res = (_PROCINFO *)address;
return res;
}
PROCLIST ProcListFromProcId(PROCID *procInfo) {
static std::string res;
const void *address = static_cast<const void *>(procInfo);
std::stringstream ss; ss << address;
res = ss.str();
return (PROCLIST)res.c_str();
}
PROCID *ProcIdFromProcList(PROCLIST procInfo) {
void *address; sscanf(procInfo, "%p", &address);
PROCID *res = (PROCID *)address;
return res;
}
_PROCINFO *InternalProcInfoFromProcId(PROCID procId) {
char *exe = nullptr; ExeFromProcId(procId, &exe);
char *cwd = nullptr; CwdFromProcId(procId, &cwd);
PROCID ppid; ParentProcIdFromProcId(procId, &ppid);
PROCID *pid = nullptr; int pidsize;
ProcIdFromParentProcId(procId, &pid, &pidsize);
char **cmd = nullptr; int cmdsize;
CmdlineFromProcId(procId, &cmd, &cmdsize);
char **env = nullptr; int envsize;
EnvironFromProcId(procId, &env, &envsize);
#if defined(XPROCESS_GUIWINDOW_IMPL)
WINDOWID *wid = nullptr; int widsize;
WindowIdFromProcId(procId, &wid, &widsize);
#endif
_PROCINFO *procInfo = new _PROCINFO();
procInfo->ProcessId = procId;
procInfo->ExecutableImageFilePath = exe;
procInfo->CurrentWorkingDirectory = cwd;
procInfo->ParentProcessId = ppid;
procInfo->ChildProcessId = pid;
procInfo->ChildProcessIdLength = pidsize;
procInfo->CommandLine = cmd;
procInfo->CommandLineLength = cmdsize;
procInfo->Environment = env;
procInfo->EnvironmentLength = envsize;
#if defined(XPROCESS_GUIWINDOW_IMPL)
procInfo->OwnedWindowId = wid;
procInfo->OwnedWindowIdLength = widsize;
#endif
return procInfo;
}
...
/* random memory freeing helper functions here,
not posted; too much content in this post as-is */
...
static std::unordered_map<PROCLIST, int> procListSize;
PROCLIST ProcListCreate() { // create process iteration vector
PROCID *procId; int size; ProcIdEnumerate(&procId, &size);
PROCLIST procList = ProcListFromProcId(procId);
procListSize[procList] = size; return procList;
}
// get process info from process vector at index
PROCINFO ProcessInfo(PROCLIST procList, int i) {
PROCID *procId = ProcIdFromProcList(procList);
return ProcInfoFromProcId(procId[i]);
}
// get size of vector, i.e. number of items
int ProcessInfoLength(PROCLIST procList) {
return procListSize[procList];
}
// free from memory, crashes game iirc but not in c++
void FreeProcList(PROCLIST procList) {
procListSize.erase(procList);
FreeProcId(ProcIdFromProcList(procList));
}
...
// create a list for all process info
char *ProcListCreate() {
return CrossProcess::ProcListCreate();
}
// get process info pointer based on process list at index
char *ProcessInfo(char *procList, double i) {
return CrossProcess::ProcessInfo((PROCLIST)procList, (int)i);
}
// get the amount of process info available for iteration
double ProcessInfoLength(char *procList) {
return CrossProcess::ProcessInfoLength((PROCLIST)procList);
}
...
Yes, this post is serious, well, mostly.
Samuel
Last edited by a moderator: