mirror of
https://github.com/ValveSoftware/Proton.git
synced 2025-01-14 15:48:11 +03:00
steam_helper: Create a thread to signal DIPC objects.
CW-Bug-Id: #15930
This commit is contained in:
parent
5b7de85bdf
commit
7d37e79328
@ -32,7 +32,10 @@
|
||||
* a small subset of the actual Steam functionality for games that expect
|
||||
* Windows version of Steam running. */
|
||||
|
||||
#include "ntstatus.h"
|
||||
#define WIN32_NO_STATUS
|
||||
#include <windows.h>
|
||||
#include <winternl.h>
|
||||
#include <shlobj.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
@ -1172,6 +1175,94 @@ static void setup_steam_files(void)
|
||||
WINE_ERR("Could not write %s.\n", wine_dbgstr_w(libraryfolders_nameW));
|
||||
}
|
||||
|
||||
#ifndef DIRECTORY_QUERY
|
||||
#define DIRECTORY_QUERY 0x0001
|
||||
#endif
|
||||
|
||||
static HANDLE find_ack_event(void)
|
||||
{
|
||||
static const WCHAR steam_ack_event[] = L"STEAM_START_ACK_EVENT";
|
||||
static const WCHAR name[] = L"\\BaseNamedObjects\\Session\\1";
|
||||
DIRECTORY_BASIC_INFORMATION *di;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
HANDLE dir, ret = NULL;
|
||||
ULONG context, size;
|
||||
UNICODE_STRING str;
|
||||
char buffer[1024];
|
||||
NTSTATUS status;
|
||||
|
||||
di = (DIRECTORY_BASIC_INFORMATION *)buffer;
|
||||
|
||||
RtlInitUnicodeString(&str, name);
|
||||
InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
|
||||
status = NtOpenDirectoryObject( &dir, DIRECTORY_QUERY, &attr );
|
||||
if (status)
|
||||
{
|
||||
WINE_WARN("Failed to open directory %s, status %#x.\n", wine_dbgstr_w(name), status);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
status = NtQueryDirectoryObject(dir, di, sizeof(buffer), TRUE, TRUE, &context, &size);
|
||||
while (!status)
|
||||
{
|
||||
if (!strncmpW(di->ObjectName.Buffer, steam_ack_event, ARRAY_SIZE(steam_ack_event) - 1))
|
||||
{
|
||||
WINE_TRACE("Found event %s.\n", wine_dbgstr_w(di->ObjectName.Buffer));
|
||||
ret = OpenEventW(SYNCHRONIZE, FALSE, di->ObjectName.Buffer);
|
||||
if (!ret)
|
||||
WINE_WARN("Failed to create event, err %u.\n", GetLastError());
|
||||
break;
|
||||
}
|
||||
status = NtQueryDirectoryObject(dir, di, sizeof(buffer), TRUE, FALSE, &context, &size);
|
||||
}
|
||||
if (status && status != STATUS_NO_MORE_ENTRIES)
|
||||
WINE_WARN("NtQueryDirectoryObject failed, status %#x.\n", status);
|
||||
WINE_TRACE("ret %p.\n", ret);
|
||||
|
||||
CloseHandle(dir);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static DWORD WINAPI steam_drm_thread(void *arg)
|
||||
{
|
||||
HANDLE consume, produce;
|
||||
HANDLE start_ack = NULL;
|
||||
HANDLE child = arg;
|
||||
DWORD pid;
|
||||
LONG prev;
|
||||
|
||||
consume = CreateSemaphoreA(NULL, 0, 512, "STEAM_DIPC_CONSUME");
|
||||
if (!consume)
|
||||
{
|
||||
WINE_ERR("Failed to create consume semaphore, err %u.\n", GetLastError());
|
||||
return -1;
|
||||
}
|
||||
produce = CreateSemaphoreA(NULL, 1, 512, "SREAM_DIPC_PRODUCE");
|
||||
if (!produce)
|
||||
{
|
||||
CloseHandle(consume);
|
||||
WINE_ERR("Failed to create produce semaphore, err %u.\n", GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
pid = GetProcessId(child);
|
||||
|
||||
WINE_TRACE("Child pid %04x.\n", pid);
|
||||
|
||||
while (WaitForSingleObject(consume, INFINITE) == WAIT_OBJECT_0)
|
||||
{
|
||||
WINE_TRACE("Got event.\n");
|
||||
|
||||
if (!start_ack)
|
||||
start_ack = find_ack_event();
|
||||
if (start_ack)
|
||||
SetEvent(start_ack);
|
||||
ReleaseSemaphore(produce, 1, &prev);
|
||||
WINE_TRACE("prev %d.\n", prev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
HANDLE wait_handle = INVALID_HANDLE_VALUE;
|
||||
@ -1240,6 +1331,9 @@ int main(int argc, char *argv[])
|
||||
else
|
||||
CloseHandle(child);
|
||||
}
|
||||
|
||||
if (game_process)
|
||||
CreateThread(NULL, 0, steam_drm_thread, child, 0, NULL);
|
||||
}
|
||||
|
||||
if(wait_handle != INVALID_HANDLE_VALUE)
|
||||
|
Loading…
x
Reference in New Issue
Block a user