https://github.com/LeonB/wineshm-go
Unfortuantely I don't know Go, but I have a pretty good understanding of the C wrappers in the project.
Even without looking at the code in the project it should be possible to figure out what I'm not understanding. I'll provide more background with code snippets that contain code that I added where I'm just trying anything I can think of, regardless of how much sense it makes.
snippet one compiles a windows exe:
Code: Select all
// +build none
#include <windows.h>
#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include "acdata.h"
int main(int argc, char** argv) {
char *access_mode;
DWORD access = 0;
STARTUPINFO si;
PROCESS_INFORMATION pi;
HANDLE maph;
if (argc < 4) {
fprintf(stderr, "not enough arguments\n");
return 1;
}
access_mode = argv[2];
while (*access_mode) {
switch(*access_mode) {
case 'r': access |= FILE_MAP_READ; break;
case 'w': access |= FILE_MAP_WRITE; break;
}
access_mode++;
}
maph = OpenFileMapping(access, TRUE, argv[1]);
/* printf("maph: %p\n", maph); */
if (maph == NULL) {
fprintf(stderr, "failed to open mapping %s: %s\n", argv[1], strerror(GetLastError()));
return 1;
}
SetStdHandle(STD_INPUT_HANDLE, maph);
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
fprintf(stderr, "mmf handle: %p\n", maph);
/*
freopen(NULL, "fb", maph);
*/
struct SPageFilePhysics* b = malloc(sizeof(struct SPageFilePhysics));
read(maph, b, sizeof(struct SPageFilePhysics));
//fread(b, sizeof(struct SPageFilePhysics), 1, maph);
fprintf(stderr, "buf contains: %i\n", b->packetId);
fprintf(stderr, "buf contains: %f\n", b->fuel);
fprintf(stderr, "buf contains: %i\n", b->gear);
/* We can't wait for the helper to exit, since waiting for a spawned unix
* process does not work:
* https://bugs.winehq.org/show_bug.cgi?id=22338 */
if (!CreateProcess(argv[3], NULL, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) {
fprintf(stderr, "failed to launch second helper process: %s\n", strerror(GetLastError()));
}
return 0;
}
Code: Select all
// +build none
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include "acdata.h"
#define SOCKET_FD 1
#define SEND_FD 0
int main(int argc, char** argv) {
/* Send FD 0 over the open socket in FD 1 */
struct msghdr msg = {0};
struct cmsghdr *cmsg;
char buf[CMSG_SPACE(sizeof(int))];
int *fdptr;
msg.msg_control = buf;
msg.msg_controllen = sizeof(buf);
cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
cmsg->cmsg_len = CMSG_LEN(sizeof(int));
fdptr = (int *) CMSG_DATA(cmsg);
fdptr[0] = SEND_FD;
msg.msg_controllen = cmsg->cmsg_len;
//if (sendmsg(SOCKET_FD, &msg, 0) < 0)
//perror("sendmsg");
int duplicated_stdin = dup(0);
fprintf(stderr, "duplicated to: %i\n", duplicated_stdin);
freopen(NULL, "fb", stdin);
char e[25];
char h[25];
readlink("/proc/self/fd/0", &e, sizeof(e));
readlink("/proc/self/fd/3", &e, sizeof(h));
fprintf(stderr, "fd 0 link: %s\n", e);
fprintf(stderr, "fd 3 link: %s\n", h);
struct SPageFilePhysics* b = malloc(sizeof(struct SPageFilePhysics));
fread(b, sizeof(struct SPageFilePhysics), 1, stdin);
fprintf(stderr, "buf contains: %i\n", b->packetId);
fprintf(stderr, "buf contains: %f\n", b->fuel);
fprintf(stderr, "buf contains: %i\n", b->gear);
read(duplicated_stdin, b, sizeof(struct SPageFilePhysics));
fprintf(stderr, "buf contains: %i\n", b->packetId);
fprintf(stderr, "buf contains: %f\n", b->fuel);
fprintf(stderr, "buf contains: %i\n", b->gear);
int g = 0;
//lseek(stdin, sizeof(int)*4, SEEK_SET);
fread(&g, sizeof(int), 1, stdin);
fprintf(stderr, "read: %i\n", g);
return 0;
}
[code
protontricks --no-runtime --background-wineserver -c "wine /home/racedev/git/wineshm-go/assets/shmwrapper1.exe 'acpmf_physics' rw /home/racedev/git/wineshm-go/assets/shmwrapper2.bin" 244210
mmf handle: 00000040
buf contains: 0
buf contains: 0.000000
buf contains: 0
duplicated to: 3
fd 0 link: /dev/null
fd 3 link:
buf contains: 0
buf contains: 0.000000
buf contains: 0
buf contains: 0
buf contains: 0.000000
buf contains: 0
read: 0
05d8:fixme:ver:GetCurrentPackageId (000000000073FDB0 0000000000000000): stub
/home/racedev/.cache/protontricks/proton/Proton 6.3/bin/wineserver-keepalive: line 29: DEBUG warning: wait_for: recursively setting old_sigint_handler to wait_sigint_handler: running_trap = 1
[/code]
I feel like it must not be working since readlink shows that stdin is /dev/null. It should somehow point me to the memory mapped file from the window exe.
With that in mind i'm going to research why either SetStdHandle(STD_INPUT_HANDLE, maph); isn't working or why CreateProcess isn't sending over stdin correctly. This was written 7 years ago, so there could be new security bits that need to be enabled in wine, etc that weren't there before.
but if there's something else i'm not seeing, i don't know nearly enough about the Windows or Wine internals.