Can't get inpout32.dll run

My x64 port of InpOut32
Post Reply
aj0123
New User
Posts: 2
Joined: Tue Aug 09, 2011 1:39 pm

Can't get inpout32.dll run

Post by aj0123 »

Hello, I have been trying to get my code run from the past week but I don't know how to install this DLL file and sys files. I am totally confused and mixed up as I have seen so many websites for this purpose. I'm using Windows 7 Professional 64 Bit and Visual Studio 2010. For now I will be using VC++ 2010 for my coding. Kindly guide me through a step by step process of using inpout32.dll in my code. Also tell about the linking of lib files. Kindly elaborate the whole procedure step by step. Kindly reply soon... I'm awaiting reply to get out of this confusion I'm stuck in. Thanks.
User avatar
phil
Site Admin
Posts: 7664
Joined: Sun Apr 06, 2003 11:12 pm

Re: Can't get inpout32.dll run

Post by phil »

Is the example on my download site not enough - I guess not for C++ :(

Anyway its relatively easy :) I recommend that your don't statically link the dll (i.e. at compile time) but rather use runtime linking as that's the most flexible, you can swap out for different versions so long as the C interface does not change (and that's not likely).

You don't need to worry about the .sys that is installed automatically when you load the DLL, however it does men that the first time you load the DLL you have to be running with elevated permissions (so run it from an installer, or use the InstallDriver.exe supplied.

Make sure your using the latest version from my website as the x64 compatible links on http://www.logix4u.net (the original author) are out of date and do not work.

If you are writing a 32bit app, you must use the InpOut32.dll (even on x64 windows).
If your writing a 64bit (x64) C++ application use InpOutx64.dll.

Then put the DLL in the same folder as your compiled exe (or anywhere in the system path) and use something like the following (really basic 32bit) code (that I just wrote):

Code: Select all

// InpoutTest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "stdio.h"

typedef void	(__stdcall *lpOut32)(short, short);
typedef short	(__stdcall *lpInp32)(short);
typedef BOOL	(__stdcall *lpIsInpOutDriverOpen)(void);
typedef BOOL	(__stdcall *lpIsXP64Bit)(void);

//Some global function pointers (messy but fine for an example)
lpOut32 gfpOut32;
lpInp32 gfpInp32;
lpIsInpOutDriverOpen gfpIsInpOutDriverOpen;
lpIsXP64Bit gfpIsXP64Bit;

void Beep(unsigned int freq)
{
	gfpOut32(0x43, 0xB6);
	gfpOut32(0x42, (freq & 0xFF));
	gfpOut32(0x42, (freq >> 9));
	Sleep(10);
	gfpOut32(0x61, gfpInp32(0x61) | 0x03);
}

void StopBeep()
{
	gfpOut32(0x61, (gfpInp32(0x61) & 0xFC));
}

int main(int argc, char* argv[])
{
	if(argc<3)
	{
		//too few command line arguments, show usage
		printf("Error : too few arguments\n\n***** Usage *****\n\nInpoutTest read <ADDRESS> \nor \nInpoutTest write <ADDRESS> <DATA>\n\n\n\n\n");
	} 
	else
	{
		//Dynamically load the DLL at runtime (not linked at compile time)
		HINSTANCE hInpOutDll ;
		hInpOutDll = LoadLibrary ( "InpOut32.DLL" ) ;	//The 32bit DLL. If we are building x64 C++ 
														//applicaiton then use InpOutx64.dll
		if ( hInpOutDll != NULL )
		{
			gfpOut32 = (lpOut32)GetProcAddress(hInpOutDll, "Out32");
			gfpInp32 = (lpInp32)GetProcAddress(hInpOutDll, "Inp32");
			gfpIsInpOutDriverOpen = (lpIsInpOutDriverOpen)GetProcAddress(hInpOutDll, "IsInpOutDriverOpen");
			gfpIsXP64Bit = (lpIsXP64Bit)GetProcAddress(hInpOutDll, "IsXP64Bit");

			if (gfpIsInpOutDriverOpen())
			{
				//Make some noise through the PC Speaker - hey it can do more that a single beep using InpOut32
				Beep(2000);
				Sleep(200);
				Beep(1000);
				Sleep(300);
				Beep(2000);
				Sleep(250);
				StopBeep();

				if(!strcmp(argv[1],"read"))
				{
					short iPort = atoi(argv[2]);
					WORD wData = gfpInp32(iPort);	//Read the port
					printf("Data read from address %s is %d \n\n\n\n", argv[2], wData);
				}
				else if(!strcmp(argv[1],"write"))
				{
					if(argc<4)
					{
						printf("Error in arguments supplied");
						printf("\n***** Usage *****\n\nInpoutTest read <ADDRESS> \nor \nInpoutTest write <ADDRESS> <DATA>\n\n\n\n\n");
					}
					else
					{
						short iPort = atoi(argv[2]);
						WORD wData = atoi(argv[3]);
						gfpOut32(iPort, wData);
						printf("data written to %s\n\n\n", argv[2]);
					}
				}
			}
			else
			{
				printf("Unable to open InpOut32 Driver!\n");
			}

			//All done
			FreeLibrary ( hInpOutDll ) ;
			return 0;
		}
		else
		{
			printf("Unable to load InpOut32 DLL!\n");
			return -1;
		}
	}
	return -2;
}
--[ Phil ]--
--[ Administrator & XMBC Author ]--
Logitech G9/G604/M720/MX518, Microsoft Intellimouse, Trust 16341 BT Mouse
Windows 10 x64, AMD Ryzen 5900x, MSI x570 Tomahawk, 32GB DDR4,
nVidia RTX 2070s, Evo 970 1Tb NVME, 2x2TB WD Black (RAID1)
User avatar
phil
Site Admin
Posts: 7664
Joined: Sun Apr 06, 2003 11:12 pm

Re: Can't get inpout32.dll run

Post by phil »

In case it was not clear, the above example does not use the .lib to link (at compile time) it uses runtime linkage, i.e., manually loading the DLL and looking up the relevant functions in it.

Using the lib might be "easier" once you figure out what to do but your tied in to that DLL can cant easily replace it like you can with the runtime linking.

Thanks,
Phil
--[ Phil ]--
--[ Administrator & XMBC Author ]--
Logitech G9/G604/M720/MX518, Microsoft Intellimouse, Trust 16341 BT Mouse
Windows 10 x64, AMD Ryzen 5900x, MSI x570 Tomahawk, 32GB DDR4,
nVidia RTX 2070s, Evo 970 1Tb NVME, 2x2TB WD Black (RAID1)
User avatar
phil
Site Admin
Posts: 7664
Joined: Sun Apr 06, 2003 11:12 pm

Re: Can't get inpout32.dll run

Post by phil »

Ive added the above code, in the full VC++ solution (vs2005 but should convert to vs2010) on my InpOut32 page as another sample project.
--[ Phil ]--
--[ Administrator & XMBC Author ]--
Logitech G9/G604/M720/MX518, Microsoft Intellimouse, Trust 16341 BT Mouse
Windows 10 x64, AMD Ryzen 5900x, MSI x570 Tomahawk, 32GB DDR4,
nVidia RTX 2070s, Evo 970 1Tb NVME, 2x2TB WD Black (RAID1)
aj0123
New User
Posts: 2
Joined: Tue Aug 09, 2011 1:39 pm

Re: Can't get inpout32.dll run

Post by aj0123 »

Thanks Phil. I compiled and executed both C++ and .NET examples. Just one more thing. In the C++ code you have declared all the functions in the start of the code. Where are their implementations? In the DLL file? And also explain that why are we using pointers to call these functions? Can't we make direct calls like Inp32(var), and Out32(var1,var2)?

Now I will try to run my code... see if it works... I will let you now... Thanks
User avatar
phil
Site Admin
Posts: 7664
Joined: Sun Apr 06, 2003 11:12 pm

Re: Can't get inpout32.dll run

Post by phil »

As I said, the example is using dynamic runtime DLL linking. That means it loads the DLL (LoadLibrary()) and then gets the address of the function (GetProcAddress()), hence the pointer that points to the function (yes implemented in the DLL!)...

This is the same principle as in the .NET code where it imports the functions at the start of the code. Its just how you do it in C++

If you need more detail, I suggest you read up a bit on DLL linking here:
http://en.wikipedia.org/wiki/Dynamic-li ... me_linking

To use compile time linking (and thus call the functions directly (without the pointers)) you would need to link to the .LIB file provided. And that means your more tightly locked in to that version of the DLL. It can be done and it should be easier than runtime linking. Just include the lib in the additional linker library (project properties, linker->Input->Additional Dependancies) or you can just add the .LIB (supplied in the binaries pack) to your VS project and it should automatically link to it. Then include the header supplied with the binaries in your code - it should be that easy!

Thanks,
Phil
--[ Phil ]--
--[ Administrator & XMBC Author ]--
Logitech G9/G604/M720/MX518, Microsoft Intellimouse, Trust 16341 BT Mouse
Windows 10 x64, AMD Ryzen 5900x, MSI x570 Tomahawk, 32GB DDR4,
nVidia RTX 2070s, Evo 970 1Tb NVME, 2x2TB WD Black (RAID1)
Post Reply