Commit 238ec27b authored by Dmitry Timoshkov's avatar Dmitry Timoshkov Committed by Vitaly Lipatov

grdwine: Convert to unixcall interface.

parent 77be3f09
From 7bfa5a40224de7a3f9af4f0be4c862f53d0d5c95 Mon Sep 17 00:00:00 2001
From: Vitaly Lipatov <lav@etersoft.ru>
Date: Sat, 29 Oct 2022 10:21:51 +0300
Subject: [PATCH] don't use DLL_WINE_PREATTACH
To: wine-devel <wine-devel@winehq.org>
---
src/grdwine.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/src/grdwine.c b/src/grdwine.c
index 79747f0..d2613c8 100644
--- a/src/grdwine.c
+++ b/src/grdwine.c
@@ -105,9 +105,6 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
switch (fdwReason)
{
- case DLL_WINE_PREATTACH:
- return FALSE; /* prefer native version */
-
case DLL_PROCESS_ATTACH:
// DisableThreadLibraryCalls(hinstDLL);
break;
--
2.33.4
/* /*
* Copyright (C) 2008 Aktiv Co. (Aleksey Samsonov) * Copyright (C) 2008 Aktiv Co. (Aleksey Samsonov)
* Copyright (C) 2025 Dmitry Timoshkov for Etersoft
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
...@@ -19,12 +20,7 @@ ...@@ -19,12 +20,7 @@
#ifndef GRDIMPL__H__ #ifndef GRDIMPL__H__
#define GRDIMPL__H__ #define GRDIMPL__H__
#ifdef HAVE_CONFIG_H #include "wine/unixlib.h"
#include <config.h>
#endif /* HAVE_CONFIG_H */
#ifdef HAVE_STDDEF_H
#include <stddef.h>
#endif /* HAVE_STDDEF_H */
typedef int __attribute__((ms_abi)) typedef int __attribute__((ms_abi))
(*search_usb_device_callback)(const char* path, void* param); (*search_usb_device_callback)(const char* path, void* param);
...@@ -32,20 +28,50 @@ typedef int __attribute__((ms_abi)) ...@@ -32,20 +28,50 @@ typedef int __attribute__((ms_abi))
/* /*
* Communication to device (which grd_probe_device returned zero). * Communication to device (which grd_probe_device returned zero).
*/ */
int grd_ioctl_device(const char* dev_path, unsigned int prod_id, struct grd_ioctl_device_params
size_t pack_size, void* in, size_t len_in, void* out, size_t len_out); {
const char *dev_path;
ULONG prod_id;
ULONG pack_size;
void *in;
ULONG in_size;
void *out;
ULONG out_size;
};
/* /*
* Check device. * Check device.
* Return zero if device is Guardant Sign/Time or Guardant Code. * Return zero if device is Guardant Sign/Time or Guardant Code.
*/ */
int grd_probe_device(const char* dev_path, unsigned int* prod_id); struct grd_probe_device_params
{
const char *dev_path;
ULONG *prod_id;
};
/* /*
* Search for all USB devices. Call callback function for each USB device. * Search for all USB devices. Call callback function for each USB device.
* Return the count of non-zero values which were returned from callback. * Return the count of non-zero values which were returned from callback.
*/ */
int search_usb_devices(search_usb_device_callback callback, void* param); struct grd_dev_path
{
char path[MAX_PATH];
};
struct grd_search_usb_devices_params
{
struct grd_dev_path *dev_path;
ULONG max_count;
ULONG count;
};
#endif /* !GRDIMPL__H__ */ enum unix_funcs
{
unix_grd_ioctl_device,
unix_grd_probe_device,
unix_grd_search_usb_devices,
unix_funcs_count
};
#define GRD_CALL( func, params ) WINE_UNIX_CALL( unix_ ## func, params )
#endif /* !GRDIMPL__H__ */
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
* on Linux USB Device Filesystem and Linux USB HID Device Interface * on Linux USB Device Filesystem and Linux USB HID Device Interface
* *
* Copyright (C) 2008 Aktiv Co. (Aleksey Samsonov) * Copyright (C) 2008 Aktiv Co. (Aleksey Samsonov)
* Copyright (C) 2025 Dmitry Timoshkov for Etersoft
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
...@@ -19,9 +20,12 @@ ...@@ -19,9 +20,12 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#ifdef HAVE_CONFIG_H #if 0
#pragma makedep unix
#endif
#include <config.h> #include <config.h>
#endif /* HAVE_CONFIG_H */
#include <assert.h> #include <assert.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/time.h> #include <sys/time.h>
...@@ -37,6 +41,9 @@ ...@@ -37,6 +41,9 @@
#include <stdio.h> /* for snprintf */ #include <stdio.h> /* for snprintf */
#include <linux/usbdevice_fs.h> #include <linux/usbdevice_fs.h>
#include <linux/hiddev.h> #include <linux/hiddev.h>
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "grdimpl.h" #include "grdimpl.h"
#define GRD_VENDOR 0x0a89 #define GRD_VENDOR 0x0a89
...@@ -64,7 +71,7 @@ static int create_lock_path(const char* dev_path, char* buf, size_t buf_size) ...@@ -64,7 +71,7 @@ static int create_lock_path(const char* dev_path, char* buf, size_t buf_size)
const char* name_prefix; const char* name_prefix;
const char* slash; const char* slash;
int ret; int ret;
size_t len, i, magic_num = 0; int len, i, magic_num = 0;
name_prefix = getenv(GRD_IPC_NAME_ENV); name_prefix = getenv(GRD_IPC_NAME_ENV);
if (!name_prefix) if (!name_prefix)
...@@ -309,9 +316,16 @@ static int hiddevice_read(int fd, void* buf, size_t len) ...@@ -309,9 +316,16 @@ static int hiddevice_read(int fd, void* buf, size_t len)
return 0; return 0;
} }
int grd_ioctl_device(const char* dev_path, unsigned int prod_id, size_t pack_size, static NTSTATUS grd_ioctl_device(void *args)
void* in, size_t len_in, void* out, size_t len_out)
{ {
struct grd_ioctl_device_params *params = args;
const char *dev_path = params->dev_path;
unsigned int prod_id = params->prod_id;
size_t pack_size = params->pack_size;
void *in = params->in;
size_t len_in = params->in_size;
void *out = params->out;
size_t len_out = params->out_size;
const int ishid = (prod_id == GRD_PRODID_S3S_HID || prod_id == GRD_PRODID_S3C_HID); const int ishid = (prod_id == GRD_PRODID_S3S_HID || prod_id == GRD_PRODID_S3C_HID);
struct lock_descr lock; struct lock_descr lock;
int fd, r; int fd, r;
...@@ -386,8 +400,11 @@ int grd_ioctl_device(const char* dev_path, unsigned int prod_id, size_t pack_siz ...@@ -386,8 +400,11 @@ int grd_ioctl_device(const char* dev_path, unsigned int prod_id, size_t pack_siz
* or device (dev_path eq "GRDHID_PATH_HEAD + N") is * or device (dev_path eq "GRDHID_PATH_HEAD + N") is
* Guardant Sign/Time/Code HID then return 0, else return -1 * Guardant Sign/Time/Code HID then return 0, else return -1
*/ */
int grd_probe_device(const char* dev_path, unsigned int* prod_id) static NTSTATUS grd_probe_device(void *args)
{ {
struct grd_probe_device_params *params = args;
const char *dev_path = params->dev_path;
unsigned int *prod_id = params->prod_id;
unsigned char buf_tmpl[4] = {0x89, 0x0a, 0x00, 0x00}; unsigned char buf_tmpl[4] = {0x89, 0x0a, 0x00, 0x00};
unsigned char buf[16]; unsigned char buf[16];
struct lock_descr lock; struct lock_descr lock;
...@@ -395,12 +412,12 @@ int grd_probe_device(const char* dev_path, unsigned int* prod_id) ...@@ -395,12 +412,12 @@ int grd_probe_device(const char* dev_path, unsigned int* prod_id)
int fd, ret; int fd, ret;
if (!dev_path || !prod_id) if (!dev_path || !prod_id)
return -1; return STATUS_INVALID_PARAMETER;
/* lock process and open usbdev_fs device */ /* lock process and open usbdev_fs device */
fd = open_device(dev_path, &lock); fd = open_device(dev_path, &lock);
if (fd < 0) if (fd < 0)
return -1; return STATUS_DEVICE_NOT_CONNECTED;
if (strncmp(dev_path, GRDHID_PATH_HEAD, sizeof(GRDHID_PATH_HEAD) - 1) == 0) if (strncmp(dev_path, GRDHID_PATH_HEAD, sizeof(GRDHID_PATH_HEAD) - 1) == 0)
{ {
...@@ -437,7 +454,7 @@ int grd_probe_device(const char* dev_path, unsigned int* prod_id) ...@@ -437,7 +454,7 @@ int grd_probe_device(const char* dev_path, unsigned int* prod_id)
ret = -1; ret = -1;
if (ret == 0) if (ret == 0)
*prod_id = id; *prod_id = id;
return ret; return ret == 0 ? STATUS_SUCCESS : STATUS_DEVICE_NOT_CONNECTED;
} }
static int load_usbfs_path(char* buf, size_t size) static int load_usbfs_path(char* buf, size_t size)
...@@ -531,38 +548,131 @@ static size_t search_grdhid_devices(search_usb_device_callback callback, void* p ...@@ -531,38 +548,131 @@ static size_t search_grdhid_devices(search_usb_device_callback callback, void* p
{ {
char dev_path[PATH_MAX]; char dev_path[PATH_MAX];
struct stat buf; struct stat buf;
size_t i; int i;
int ret, count = 0; size_t ret, count = 0;
for (i = 0; i < GRDHID_MAX_COUNT; ++i) for (i = 0; i < GRDHID_MAX_COUNT; ++i)
{ {
ret = snprintf(dev_path, sizeof(dev_path), "%s%d", ret = snprintf(dev_path, sizeof(dev_path), "%s%d",
GRDHID_PATH_HEAD, i); GRDHID_PATH_HEAD, i);
assert(ret > 0 && (size_t)ret < sizeof(dev_path)); if (ret >= sizeof(dev_path))
if (ret < 0 || (size_t)ret >= sizeof(dev_path))
continue; continue;
if (stat(dev_path, &buf) != 0) if (stat(dev_path, &buf) != 0)
continue; continue;
assert(callback);
if (callback(dev_path, param)) if (callback(dev_path, param))
++count; ++count;
} }
return count; return count;
} }
int search_usb_devices(search_usb_device_callback callback, void* param) static int __attribute__((ms_abi)) device_enum_callback(const char *dev_path, void *param)
{
struct grd_search_usb_devices_params *params = param;
if (params->count < params->max_count)
memcpy(params->dev_path[params->count].path, dev_path, min(strlen(dev_path) + 1, sizeof(params->dev_path[0].path)));
params->count++;
return 1;
}
static NTSTATUS grd_search_usb_devices(void *args)
{ {
struct grd_search_usb_devices_params *params = args;
search_usb_device_callback callback = device_enum_callback;
char usbfs_path[PATH_MAX]; char usbfs_path[PATH_MAX];
size_t count; size_t count;
if (!callback)
return -1;
if (load_usbfs_path(usbfs_path, sizeof(usbfs_path)) != 0) if (load_usbfs_path(usbfs_path, sizeof(usbfs_path)) != 0)
return -1; return STATUS_DEVICE_NOT_CONNECTED;
count = search_usbfs_devices(usbfs_path, callback, param); count = search_usbfs_devices(usbfs_path, callback, params);
count += search_grdhid_devices(callback, param); count += search_grdhid_devices(callback, params);
return (int)count; params->count = count;
return count <= params->max_count ? STATUS_SUCCESS : STATUS_BUFFER_TOO_SMALL;
}
const unixlib_entry_t __wine_unix_call_funcs[] =
{
grd_ioctl_device,
grd_probe_device,
grd_search_usb_devices
};
C_ASSERT( ARRAYSIZE(__wine_unix_call_funcs) == unix_funcs_count );
#ifdef _WIN64
typedef ULONG PTR32;
static NTSTATUS wow64_grd_ioctl_device(void *args)
{
struct
{
PTR32 dev_path;
ULONG prod_id;
ULONG pack_size;
PTR32 in;
ULONG in_size;
PTR32 out;
ULONG out_size;
} const *params32 = args;
struct grd_ioctl_device_params params =
{
ULongToPtr(params32->dev_path),
params32->prod_id,
params32->pack_size,
ULongToPtr(params32->in),
params32->in_size,
ULongToPtr(params32->out),
params32->out_size
};
return grd_ioctl_device(&params);
}
static NTSTATUS wow64_grd_probe_device(void *args)
{
struct
{
PTR32 dev_path;
PTR32 prod_id;
} const *params32 = args;
struct grd_probe_device_params params =
{
ULongToPtr(params32->dev_path),
ULongToPtr(params32->prod_id)
};
return grd_probe_device(&params);
}
static NTSTATUS wow64_grd_search_usb_devices(void *args)
{
struct
{
PTR32 dev_path;
ULONG max_count;
ULONG count;
} *params32 = args;
struct grd_search_usb_devices_params params =
{
ULongToPtr(params32->dev_path),
params32->max_count,
params32->count
};
NTSTATUS status;
status = grd_search_usb_devices(&params);
params32->count = params.count;
return status;
} }
const unixlib_entry_t __wine_unix_call_wow64_funcs[] =
{
wow64_grd_ioctl_device,
wow64_grd_probe_device,
wow64_grd_search_usb_devices
};
C_ASSERT( ARRAYSIZE(__wine_unix_call_wow64_funcs) == unix_funcs_count );
#endif /* _WIN64 */
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
* GrdWine - Guardant usb dongle helper library for Wine * GrdWine - Guardant usb dongle helper library for Wine
* *
* Copyright (C) 2008 Aktiv Co. (Aleksey Samsonov) * Copyright (C) 2008 Aktiv Co. (Aleksey Samsonov)
* Copyright (C) 2025 Dmitry Timoshkov for Etersoft
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
...@@ -18,13 +19,11 @@ ...@@ -18,13 +19,11 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif /* HAVE_CONFIG_H */
#ifdef HAVE_STDDEF_H
#include <stddef.h> #include <stddef.h>
#endif /* HAVE_STDDEF_H */
#include <stdarg.h> /* for #include "winbase.h" */ #include <stdarg.h> /* for #include "winbase.h" */
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "windef.h" /* <wine/windows/windef.h> */ #include "windef.h" /* <wine/windows/windef.h> */
#include "winbase.h" /* <wine/windows/winbase.h> */ #include "winbase.h" /* <wine/windows/winbase.h> */
#include "winnt.h" /* <wine/windows/winnt.h> */ #include "winnt.h" /* <wine/windows/winnt.h> */
...@@ -37,78 +36,99 @@ WINE_DEFAULT_DEBUG_CHANNEL(grdwine); ...@@ -37,78 +36,99 @@ WINE_DEFAULT_DEBUG_CHANNEL(grdwine);
typedef BOOL (__attribute__((ms_abi)) * GrdWine_SearchUsbDevices_Callback)(LPCSTR lpDevName, LPVOID lpParam); typedef BOOL (__attribute__((ms_abi)) * GrdWine_SearchUsbDevices_Callback)(LPCSTR lpDevName, LPVOID lpParam);
DWORD WINAPI GrdWine_GetVersion() DWORD WINAPI GrdWine_GetVersion(void)
{ {
TRACE("() Version 0x%x\n", GRD_DRIVER_VERSION); TRACE("() Version 0x%x\n", GRD_DRIVER_VERSION);
return GRD_DRIVER_VERSION; return GRD_DRIVER_VERSION;
} }
DWORD WINAPI GrdWine_SearchUsbDevices(GrdWine_SearchUsbDevices_Callback Func, LPVOID lpParam) DWORD WINAPI GrdWine_SearchUsbDevices(GrdWine_SearchUsbDevices_Callback func, LPVOID param)
{ {
search_usb_device_callback func = (search_usb_device_callback)Func; struct grd_search_usb_devices_params params;
void* param = (void*)lpParam; NTSTATUS status;
ULONG i, count = 0;
int ret; int ret;
TRACE("(%p, %p)\n", (void*)Func, param); TRACE("(%p, %p)\n", func, param);
if (!func || !param) if (!func || !param)
return FALSE; return 0;
params.max_count = 256;
TRACE("Call search_usb_devices(%p, %p)\n", (void*)func, param); for (;;)
ret = search_usb_devices(func, param); {
TRACE("Ret search_usb_devices %d\n", ret); params.count = 0;
params.dev_path = malloc(params.max_count * sizeof(params.dev_path[0]));
if (!params.dev_path) return 0;
TRACE("Call search_usb_devices()\n");
status = GRD_CALL(grd_search_usb_devices, &params);
TRACE("Ret search_usb_devices %#lx\n", status);
if (status != STATUS_BUFFER_TOO_SMALL) break;
free(params.dev_path);
params.max_count = params.count;
}
return ret > 0 ? (DWORD)ret : 0; if (status == STATUS_SUCCESS)
{
for (i = 0; i < params.count; i++)
{
TRACE("Call callback(%s,%p)\n", debugstr_a(params.dev_path[i].path), param);
ret = func(params.dev_path[i].path, param);
if (ret) count++;
TRACE("Ret callback %d\n", ret);
}
free(params.dev_path);
}
return status == STATUS_SUCCESS ? count : 0;
} }
BOOL WINAPI GrdWine_DeviceProbe(LPCSTR lpDevName, LPDWORD pProdId) BOOL WINAPI GrdWine_DeviceProbe(LPCSTR path, LPDWORD prod_id)
{ {
char* path = (char*)lpDevName; struct grd_probe_device_params params = { path, prod_id };
unsigned int* prod_id = (unsigned int*)pProdId; NTSTATUS status;
int ret;
TRACE("(%s, %p)\n", lpDevName, pProdId); TRACE("(%s, %p)\n", debugstr_a(path), prod_id);
if (!path || !prod_id) if (!path || !prod_id)
return FALSE; return FALSE;
TRACE("Call grd_probe_device(%s, %p)\n", path, prod_id); TRACE("Call grd_probe_device(%s, %p)\n", debugstr_a(path), prod_id);
ret = grd_probe_device(path, prod_id); status = GRD_CALL(grd_probe_device, &params);
TRACE("Ret grd_probe_device %d\n", ret); TRACE("Ret grd_probe_device %#lx\n", status);
return ret == 0 ? TRUE : FALSE; return status == STATUS_SUCCESS ? TRUE : FALSE;
} }
BOOL WINAPI GrdWine_DeviceIoctl(LPCSTR lpDevName, DWORD ProdId, DWORD dwPackSize, BOOL WINAPI GrdWine_DeviceIoctl(LPCSTR dev_path, DWORD prod_id, DWORD pack_size,
LPVOID lpIn, DWORD nInSize, LPVOID lpOut, DWORD nOutSize) LPVOID in, DWORD in_size, LPVOID out, DWORD out_size)
{ {
char* path = (char*)lpDevName; NTSTATUS status;
void* in = lpIn, * out = lpOut; struct grd_ioctl_device_params params = { dev_path, prod_id, pack_size, in, in_size, out, out_size };
size_t in_size = (size_t)nInSize, out_size = (size_t)nOutSize;
size_t pack_size = (size_t)dwPackSize;
unsigned int prod_id = (unsigned int)ProdId;
int ret;
TRACE("(%s, %u, %u, %p, %u, %p, %u)\n", lpDevName, ProdId, dwPackSize, lpIn, nInSize, lpOut, nOutSize); TRACE("(%s, %lu, %lu, %p, %lu, %p, %lu)\n", debugstr_a(dev_path), prod_id, pack_size, in, in_size, out, out_size);
if (!path || !in || !out) if (!dev_path || !in || !out)
return FALSE; return FALSE;
TRACE("Call grd_ioctl_device(%s, %u, %u, %p, %u, %p, %u)\n", TRACE("Call grd_ioctl_device(%s, %lu, %lu, %p, %lu, %p, %lu)\n",
path, prod_id, pack_size, in, in_size, out, out_size); debugstr_a(dev_path), prod_id, pack_size, in, in_size, out, out_size);
ret = grd_ioctl_device(path, prod_id, pack_size, in, in_size, out, out_size); status = GRD_CALL(grd_ioctl_device, &params);
TRACE("Ret grd_ioctl_device %d\n", ret); TRACE("Ret grd_ioctl_device %#lx\n", status);
return ret == 0 ? TRUE : FALSE; return status == STATUS_SUCCESS ? TRUE : FALSE;
} }
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{ {
TRACE("(%p, %d, %p)\n", (void*)hinstDLL, fdwReason, lpvReserved); TRACE("(%p, %lu, %p)\n", hinstDLL, fdwReason, lpvReserved);
switch (fdwReason) switch (fdwReason)
{ {
case DLL_PROCESS_ATTACH: case DLL_PROCESS_ATTACH:
// DisableThreadLibraryCalls(hinstDLL); DisableThreadLibraryCalls(hinstDLL);
if (__wine_init_unix_call()) return FALSE;
break; break;
} }
return TRUE; return TRUE;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment