BlindEyeSoftworks / BlindEye.XInput

A managed and feature-rich wrapper over the unmanaged XInput API.
Other
17 stars 0 forks source link

Woudl like to try this but can;t figure it out. #3

Closed ulao closed 1 year ago

ulao commented 1 year ago

Not sure if anyone maintains this but it looks interesting. I'm curios how this works. I imagine it builds a dll? And with that Dll I can make an app that uses xImput with hidden calls?

I tried to build it with VS 11 an was yelled at fo r "Error 2 The modifier 'readonly' is not valid for this item BlindEye.XInput-main\src\XInput\VibrationInformation.cs 19 " for 10 items. Removing the read only cry's about a body since it is not abstract.

BL1NDX3N0N commented 1 year ago

This project is a C# binding for the XInput API, XInput 1.4 specifically, and will be compiled as a DLL per the project's configuration. The project targets the .NET Framework and can be compiled against versions 2.0-4.8. I was able to verify that the solution was able to be compiled on numerous environments running Visual Studio 2022 Community including Visual Studio 2013 Professional. Please ensure you are using the latest version of C#.

ulao commented 1 year ago

I'm trying with 4.8. Not sure about a c# version, I know c had a few versions but was unaware c# did, is there some standard way f checking this? I will see if I can get 2013 or 2022 installed.

ulao commented 1 year ago

yes 2022 worked.

So if I build this, and wanted to make a project based on xinput, I'd put this dll in place of the one I reference in the project? And this also means I need to ship this dll with the compiled application?

BL1NDX3N0N commented 1 year ago

yes 2022 worked.

So if I build this, and wanted to make a project based on xinput, I'd put this dll in place of the one I reference in the project?

You can import it as a reference when compiled yes.

And this also means I need to ship this dll with the compiled application?

Correct. If you would like to integrate the source code into your project you have my permission to do so, that way you can ship just your executable. There are solutions out there for embedding DLLs as resources, but I do not recommend those as it could result in being flagged by an AV which I would rather not be associated with. Due to this, I request people ignore the license and integrate the source code into their project instead.

ulao commented 1 year ago

ok one more question about building.

I'm using cpp because there are no c# libraries for xinput, other then the managed projects like sharpx. . So I'm a bit confused why this blind eye is a c# project? So I used C++ with the dll.

my existing project (cpp) does calls to the normal lib

include

pragma comment(lib,"xinput.lib")

I added the dll as reference and since you didt give a lib I just used the exiting one. and for runtime swap out the 1.4 dll with blind eye

but I get image

the real xinput is 140k where the new one is only 12k

I know what you mean by integrating the source but I'm not that great with VS, if I breath on it it gets mad at me. Mixed # and c++ never goes well. For simplicity, is there any way to just use the dll? I'm just trying to make a very simple tool here.


Aside from the building here, I was looking at the source and I see mainly xinput related functions. I wanted to see the list of undocumented functions but I get that is not written up anywhere as an API reference. I see tings in the files like " /// Note that these force-feedback features beyond rumble (i.e. impulse triggers and /// other haptics) are not currently supported by the XInput API on Windows and can be /// found exclusively in the GameInput API as well for the Windows.Gaming.Input /// namespace for developers targeting the Universal Windows Platform (UWP). " but was hoping they were all listed somewhere. I was specifically hoping to find the calls to the security but that maybe not possible.

BL1NDX3N0N commented 1 year ago

I'm using cpp because there are no c# libraries for xinput, other then the managed projects like sharpx. . So I'm a bit confused why this blind eye is a c# project?

The reason is because this is a managed binding for the XInput API, to my knowledge none of the frameworks in the .NET ecosystem provide input handling support for XInput peripherals. Due to such, the GameInput API is the next best option since it is compatible with versions of Windows as early as Windows 7 and I have also updated documentation on Microsoft's end to illustrate such. However, after attempting to reverse engineer GameInput binaries I was not able to confirm whether the API defers calls to XInput for backward compatibility scenarios in lieu of accessing legacy drivers directly. There were also a couple minor problems I found with Microsoft's approach to deprecating XInput which includes lack of documentation at the time, compatibility issues with Windows IoT, and intuitive bindings only being provided for C#/WinRT projects where said bindings are implemented as stubs defined in WinMD files for language projection and unmanaged code generation purposes. This makes sense given that WinRT applications developed with C# are transpiled with .NET Native but it also makes it less trivial to create your own bindings for platforms that don't support WinRT applications which includes a lot of factory control systems. I'm also fairly certain that GameInput is served through COM as well given the evidence of vtables. Another problem being legacy versions of Windows where XInput is only supported and/or did not ship with GameInput. XInput has shipped with Windows since XP due to Microsoft pushing Windows as a gaming platform since Windows 95, DirectX succeeding WinG, and the development of the Xbox. Lastly, for game engines with compilers and scripting runtimes lacking COM ABI support this will also serve as a viable fallback.

Therefore, due to the above, you can rely on XInput being existent when GameInput is not, nor do you have to panic about redistributing it--making it and this binding important for legacy systems and applications. Needless to say, I am not really interested in using the GameInput API, other technologies provided in Microsoft's GDK, or UWP due to me finding them unnecessary for my projects. I still highly recommend you check them out though just to see where they may be of use for you and those you know.

So I used C++ with the dll.

C++ compilers do not have FFIs for managed code interop aside from MSVC, in order for execution to take place the bytecode needs the runtime to execute on. Because of this, you would have to register your own COM object which will serve what you need, the runtime will automatically be inserted into the process or via whatever subsystem Windows uses for such. My advice is do not do this especially for input handling, you will be generating an unnecessary amount of overhead especially from runtime marshalling. Authoring your project in such a way means you are creating an unmanaged executable to invoke unmanaged functions via managed code and COM, results being served through the COM layer. Under-the-hood the flow of execution would look roughly like such:

First time initialization: unmanaged COM client requests COM object/server -> SCM locates and creates an instance of the COM object/server -> runtime creation COM server interop: runtime loads the XInput DLL -> managed code execution signals FFI -> FFI invokes the unmanaged function -> result returned to runtime -> runtime transfers control and result to the caller -> COM server transfers control and result to COM client

You are better off cutting out the middleman by including the necessary header files yourself. My code was intentionally authored to be extremely close to the XInput API so it should be easy to translate to C++, applying the same knowledge you already do when consuming any Win32 API. This will ensure your code and underlying loop is performant while also drastically reducing code and redistribution complexity.

I'm not that great with VS, if I breath on it it gets mad at me

Is there a specific problem with Visual Studio you are experiencing? This will allow me to better understand how you are using it and what your workflow is.

For simplicity, is there any way to just use the dll?

Create a .NET project and import it directly.

I'm just trying to make a very simple tool here.

Depending on your definition of simple I am willing to develop that utility for you as a C# project for free, no license or credit required. This should allow you to get a better understanding of working with .NET.

I wanted to see the list of undocumented functions but I get that is not written up anywhere as an API reference

I don't build a list of undocumented functions, nor do I feel those details are necessary unless going into the project with a reverse engineering mindset. Once again, this binding is almost 1:1 with the XInput API so an easy heuristic to determine what functions are undocumented would be comparing methods in this binding against documented functions.

but was hoping they were all listed somewhere

To get a list you would need to decompile the XInput DLL, inspect function tables with programs such as Dependency Walker, or inspect symbol files from Microsoft's symbol server. Microsoft did not export the functions, hence the binding specifying function entry points via their respective ordinal value. However, their names are still referenced in the binary itself which you can inspect by dumping the image's string table. This is why you cannot search or garner meaningful information for such aside from Guide Button polling, unfortunately I am the first to fully reverse engineer the API which was the basis of this project. Due to such I made extra sure to provide documentation over undocumented functions. As for force-feedback features beyond palm rumble, XInput does not support such--nor do Xbox 360 peripheral drivers either since those devices were manufactured with two motors maximum. Force-feedback features such as impulse triggers are exclusive to Xbox One and newer peripherals, impulse triggers being implemented as 2 additional motors which are individually integrated into both trigger assemblies. To access those features, you need to use newer input APIs beyond XInput 1.4 as well for having the necessary drivers which XInput is also incapable of calling into due to only targeting legacy drivers.

I was specifically hoping to find the calls to the security but that maybe not possible.

XInput doesn't really provide any security mechanisms and if they are implemented they would most likely be part of ETW integration which isn't particularly useful for you nor is it part of the public API. Do understand that XInput API functions are going to be called from a user mode application where virtual memory and other protections via the kernel and your CPU are employed, it isn't until NTDLL or drivers get involved that system calls or CSRSS signaling via ALPC are performed. I am unsure what your goal is, but if security is an issue then I recommend digital certificates specific for protected processes which is what many media and AV software vendors use for implementing DRM and protecting against out of process manipulation.

ulao commented 1 year ago

I do appreciate the answers. but the one that could get me working was skipped. Thought leading on from Depending on your definition of simple I am willing to develop that utility for you as a C# project for free, no license or credit required. This should allow you to get a better understanding of working with .NET.

I have two projects.

1) a c++ sample project where I replaced BlindEye dll with xinput 1.4 and I get that dll error. 2) a c# project with both sharp xinput and the Blind Eye project.

The first project takes no effort to work but the fact running it blows up, I'm at a loss. I think this would be best for me. I just need the application to do testing, its not for use by anyone but me anyways.

The second, albeit more to your recommendation, its super crazy because the two api's are so different. The sharp is written like a class and the the regular c++ is un class like.

If I wanted to make the sharp xinput work, I'd need it's source to add the blind eye functions, but since they are not documented I guess I'd have to add them as I go? And somehow figure out how the sharp xinput was written and compiled.

I guess there might be a way to doBlindEyeDllCall ( getsharpX.id )

normal xinput XInputGetState( i, &g_Controllers[i].state );

sharp,xinput controller.GetState();

so XInputGetState( controller._soWyToGetTheRealObject )

I can share what I have here but the xinput samples were taken from the net. If I could use the Blind Eye dll in-place of the real 1.4 xinput dll, I maybe could take it from there. Is the blind eye dll expected to be so small in comparison ? "the real xinput is 140k where the new one is only 12k"

thx again for the help.

BL1NDX3N0N commented 1 year ago

I think I understand the issue now, do not attempt to replace the XInput DLL. This binding calls into the XInput DLL and it is expected to exist in any location defined by system search order policies. This is an XInput binding, not an XInput replacement.

ulao commented 1 year ago

If that is the case I guess it works, can you give me one function I can test to ensure its using your code? A function the normal xinput does not have?

BL1NDX3N0N commented 1 year ago

WaitForGuideButton and CancelWaitForGuideButton being excellent examples that will provide visual results by suspending the application's message pump if called from the primary thread. Some of the functions to request device and bus information are pretty fun to poke around as well. Microsoft also tends to have extended functions throughout various Win32 APIs and XInput is no exception to that, I use all of said extended functions over their limited variants which you'll eventually find out by using them or comparing method signatures.

ulao commented 1 year ago

thx for this.

So I'm unfortunately still a touch bit confused on how this works. I guess I'm used to using polished API's so I do apologize here. I looked for this "WaitForGuideButton " in the blind eye code and found nothing. There maybe a few misconceptions here and I maybe completely missing the point to this. but I thought bind eye exposed access to hidden functions? Though best I can tell I see none. Perhaps I just make a "blind" call (pun was intended here). To access a xinput function I need to know the name, like get state. XInputGetState ( ... ) but I have no way of knowing ( based on my knowledge of how this works) how to call WaitForGuideButton. I do not possess the knowledge on how to rip apart a dll and pull the names out if that is what is expected here. And also I fail to see the need in using blindeye if that needs to be done. Again, it's possible its just my understanding that is short here. Would it be possible to get an example of how this one function is used? then I could replicate the same process of any others?