about summary refs log tree commit diff stats
path: root/src/wrapped/wrappedlibusb1.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/wrapped/wrappedlibusb1.c')
-rwxr-xr-xsrc/wrapped/wrappedlibusb1.c196
1 files changed, 196 insertions, 0 deletions
diff --git a/src/wrapped/wrappedlibusb1.c b/src/wrapped/wrappedlibusb1.c
new file mode 100755
index 00000000..9d4b21d4
--- /dev/null
+++ b/src/wrapped/wrappedlibusb1.c
@@ -0,0 +1,196 @@
+#define _GNU_SOURCE         /* See feature_test_macros(7) */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dlfcn.h>
+
+#include "wrappedlibs.h"
+
+#include "debug.h"
+#include "wrapper.h"
+#include "bridge.h"
+#include "librarian/library_private.h"
+#include "x64emu.h"
+#include "emu/x64emu_private.h"
+#include "callback.h"
+#include "librarian.h"
+#include "box64context.h"
+#include "emu/x64emu_private.h"
+#include "myalign.h"
+
+const char* libusb1Name = "libusb-1.0.so.0";
+#define LIBNAME libusb1
+
+typedef void*   (*pFi_t)            (int);
+typedef int     (*iFp_t)            (void*);
+typedef void    (*vFpu_t)           (void*, uint32_t);
+typedef int     (*iFpiiiiippp_t)    (void*, int, int, int, int, int, void*, void*, void*);
+
+static library_t* my_lib = NULL;
+
+#define SUPER() \
+    GO(libusb_hotplug_register_callback, iFpiiiiippp_t) \
+    GO(libusb_alloc_transfer, pFi_t)                    \
+    GO(libusb_submit_transfer, iFp_t)                   \
+    GO(libusb_cancel_transfer, iFp_t)                   \
+
+typedef struct libusb1_my_s {
+    // functions
+    #define GO(A, B)    B   A;
+    SUPER()
+    #undef GO
+} libusb1_my_t;
+
+void* getUsb1My(library_t* lib)
+{
+    libusb1_my_t* my = (libusb1_my_t*)calloc(1, sizeof(libusb1_my_t));
+    #define GO(A, W) my->A = (W)dlsym(lib->priv.w.lib, #A);
+    SUPER()
+    #undef GO
+    return my;
+}
+#undef SUPER
+
+void freeUsb1My(void* lib)
+{
+//    libusb1_my_t *my = (libusb1_my_t *)lib;
+}
+
+#define SUPER() \
+GO(0)   \
+GO(1)   \
+GO(2)   \
+GO(3)   \
+GO(4)   \
+GO(5)   \
+GO(6)   \
+GO(7)   \
+GO(8)   \
+GO(9)   \
+
+
+// hotplug
+#define GO(A)   \
+static uintptr_t my_hotplug_fct_##A = 0;                                                    \
+static int my_hotplug_##A(void* ctx, void* device, int event, void* data)                   \
+{                                                                                           \
+    return (int)RunFunction(my_context, my_hotplug_fct_##A, 4, ctx, device, event, data);   \
+}
+SUPER()
+#undef GO
+static void* findhotplugFct(void* fct)
+{
+    if(!fct) return fct;
+    if(GetNativeFnc((uintptr_t)fct))  return GetNativeFnc((uintptr_t)fct);
+    #define GO(A) if(my_hotplug_fct_##A == (uintptr_t)fct) return my_hotplug_##A;
+    SUPER()
+    #undef GO
+    #define GO(A) if(my_hotplug_fct_##A == 0) {my_hotplug_fct_##A = (uintptr_t)fct; return my_hotplug_##A; }
+    SUPER()
+    #undef GO
+    printf_log(LOG_NONE, "Warning, no more slot for libusb-1.0 hotplug callback (%p)\n", fct);
+    return NULL;
+}
+// transfert
+#define GO(A)   \
+static uintptr_t my_transfert_fct_##A = 0;                      \
+static void my_transfert_##A(void* ctx)                         \
+{                                                               \
+    RunFunction(my_context, my_transfert_fct_##A, 1, ctx);      \
+}
+SUPER()
+#undef GO
+static void* findtransfertFct(void* fct)
+{
+    if(!fct) return fct;
+    #define GO(A) if(my_transfert_##A == fct) return my_transfert_##A;
+    SUPER()
+    #undef GO
+    if(GetNativeFnc((uintptr_t)fct))  return GetNativeFnc((uintptr_t)fct);
+    #define GO(A) if(my_transfert_fct_##A == (uintptr_t)fct) return my_transfert_##A;
+    SUPER()
+    #undef GO
+    #define GO(A) if(my_transfert_fct_##A == 0) {my_transfert_fct_##A = (uintptr_t)fct; return my_transfert_##A; }
+    SUPER()
+    #undef GO
+    printf_log(LOG_NONE, "Warning, no more slot for libusb-1.0 transfert callback (%p)\n", fct);
+    return NULL;
+}
+static void* reverse_transfert_Fct(void* fct)
+{
+    if(!fct) return fct;
+    if(CheckBridged(my_lib->priv.w.bridge, fct))
+        return (void*)CheckBridged(my_lib->priv.w.bridge, fct);
+    #define GO(A) if(my_transfert_##A == fct) return (void*)my_transfert_fct_##A;
+    SUPER()
+    #undef GO
+    return (void*)AddBridge(my_lib->priv.w.bridge, vFp, fct, 0, NULL);
+}
+
+#undef SUPER
+
+EXPORT int my_libusb_hotplug_register_callback(x64emu_t* emu, void* ctx, int event, int flags, int vendor, int product, int dev_class, void* f, void* data, void* handle)
+{
+    libusb1_my_t *my = (libusb1_my_t*)my_lib->priv.w.p2;
+
+    return my->libusb_hotplug_register_callback(ctx, event, flags, vendor, product, dev_class, findhotplugFct(f), data, handle);
+}
+
+struct my_libusb_iso_packet_descriptor {
+    unsigned int length;
+    unsigned int actual_length;
+    int status;
+};
+
+typedef struct my_libusb_transfer_s {
+    void* dev_handle;
+    uint8_t flags;
+    unsigned char endpoint;
+    unsigned char type;
+    unsigned int timeout;
+    int status;
+    int length;
+    int actual_length;
+    void* callback;
+    void* user_data;
+    unsigned char *buffer;
+    int num_iso_packets;
+    struct my_libusb_iso_packet_descriptor iso_packet_desc[0];
+} my_libusb_transfer_t;
+
+EXPORT void* my_libusb_alloc_transfer(x64emu_t* emu, int num)
+{
+    libusb1_my_t *my = (libusb1_my_t*)my_lib->priv.w.p2;
+
+    my_libusb_transfer_t* ret = (my_libusb_transfer_t*)my->libusb_alloc_transfer(num);
+    if(ret)
+        ret->callback = reverse_transfert_Fct(ret->callback);
+    return ret;
+}
+
+EXPORT int my_libusb_submit_transfer(x64emu_t* emu, my_libusb_transfer_t* t)
+{
+    libusb1_my_t *my = (libusb1_my_t*)my_lib->priv.w.p2;
+    
+    t->callback = findtransfertFct(t->callback);
+    return my->libusb_submit_transfer(t); // don't put back callback, it's unknown if it's safe
+} 
+
+EXPORT int my_libusb_cancel_transfer(x64emu_t* emu, my_libusb_transfer_t* t)
+{
+    libusb1_my_t *my = (libusb1_my_t*)my_lib->priv.w.p2;
+    
+    t->callback = findtransfertFct(t->callback);
+    return my->libusb_cancel_transfer(t);
+}
+
+#define CUSTOM_INIT \
+    my_lib = lib;   \
+    lib->priv.w.p2 = getUsb1My(lib);
+
+#define CUSTOM_FINI \
+    freeUsb1My(lib->priv.w.p2); \
+    free(lib->priv.w.p2);
+
+#include "wrappedlib_init.h"
+