/******************************************************************************/ /* */ /* IoExample for PortTalk V2.1 */ /* Version 2.1, 12th January 2002 */ /* http://www.beyondlogic.org */ /* */ /* Copyright © 2002 Craig Peacock. Craig.Peacock@beyondlogic.org */ /* Any publication or distribution of this code in source form is prohibited */ /* without prior written permission of the copyright holder. This source code */ /* is provided "as is", without any guarantee made as to its suitability or */ /* fitness for any particular use. Permission is herby granted to modify or */ /* enhance this sample code to produce a derivative program which may only be */ /* distributed in compiled object form only. */ /******************************************************************************/ #include <stdio.h> #include <windows.h> #include <winioctl.h> #include "PortTalk_IOCTL.h" unsigned char OpenPortTalk(void); void ClosePortTalk(void); void outportb(unsigned short PortAddress, unsigned char byte); unsigned char inportb(unsigned short PortAddress); void InstallPortTalkDriver(void); unsigned char StartPortTalkDriver(void); #define inp(PortAddress) inportb(PortAddress) #define outp(PortAddress, Value) outportb(PortAddress, Value) HANDLE PortTalk_Handle; /* Handle for PortTalk Driver */ void outportb(unsigned short PortAddress, unsigned char byte) { unsigned int error; DWORD BytesReturned; unsigned char Buffer[3]; unsigned short * pBuffer; pBuffer = (unsigned short *)&Buffer[0]; *pBuffer = PortAddress; Buffer[2] = byte; error = DeviceIoControl(PortTalk_Handle, IOCTL_WRITE_PORT_UCHAR, &Buffer, 3, NULL, 0, &BytesReturned, NULL); if (!error) printf("Error occured during outportb while talking to PortTalk driver %d\n",GetLastError()); } unsigned char inportb(unsigned short PortAddress) { unsigned int error; DWORD BytesReturned; unsigned char Buffer[3]; unsigned short * pBuffer; pBuffer = (unsigned short *)&Buffer; *pBuffer = PortAddress; error = DeviceIoControl(PortTalk_Handle, IOCTL_READ_PORT_UCHAR, &Buffer, 2, &Buffer, 1, &BytesReturned, NULL); if (!error) printf("Error occured during inportb while talking to PortTalk driver %d\n",GetLastError()); return(Buffer[0]); } unsigned char OpenPortTalk(void) { /* Open PortTalk Driver. If we cannot open it, try installing and starting it */ PortTalk_Handle = CreateFile("\\\\.\\PortTalk", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(PortTalk_Handle == INVALID_HANDLE_VALUE) { /* Start or Install PortTalk Driver */ StartPortTalkDriver(); /* Then try to open once more, before failing */ PortTalk_Handle = CreateFile("\\\\.\\PortTalk", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(PortTalk_Handle == INVALID_HANDLE_VALUE) { printf("PortTalk: Couldn't access PortTalk Driver, Please ensure driver is loaded.\n\n"); return -1; } } return 0; } void ClosePortTalk(void) { CloseHandle(PortTalk_Handle); } unsigned char StartPortTalkDriver(void) { SC_HANDLE SchSCManager; SC_HANDLE schService; BOOL ret; DWORD err; /* Open Handle to Service Control Manager */ SchSCManager = OpenSCManager (NULL, /* machine (NULL == local) */ NULL, /* database (NULL == default) */ SC_MANAGER_ALL_ACCESS); /* access required */ if (SchSCManager == NULL) if (GetLastError() == ERROR_ACCESS_DENIED) { /* We do not have enough rights to open the SCM, therefore we must */ /* be a poor user with only user rights. */ printf("PortTalk: You do not have rights to access the Service Control Manager and\n"); printf("PortTalk: the PortTalk driver is not installed or started. Please ask \n"); printf("PortTalk: your administrator to install the driver on your behalf.\n"); return(0); } do { /* Open a Handle to the PortTalk Service Database */ schService = OpenService(SchSCManager, /* handle to service control manager database */ "PortTalk", /* pointer to name of service to start */ SERVICE_ALL_ACCESS); /* type of access to service */ if (schService == NULL) switch (GetLastError()){ case ERROR_ACCESS_DENIED: printf("PortTalk: You do not have rights to the PortTalk service database\n"); return(0); case ERROR_INVALID_NAME: printf("PortTalk: The specified service name is invalid.\n"); return(0); case ERROR_SERVICE_DOES_NOT_EXIST: printf("PortTalk: The PortTalk driver does not exist. Installing driver.\n"); printf("PortTalk: This can take up to 30 seconds on some machines . .\n"); InstallPortTalkDriver(); break; } } while (schService == NULL); /* Start the PortTalk Driver. Errors will occur here if PortTalk.SYS file doesn't exist */ ret = StartService (schService, /* service identifier */ 0, /* number of arguments */ NULL); /* pointer to arguments */ if (ret) printf("PortTalk: The PortTalk driver has been successfully started.\n"); else { err = GetLastError(); if (err == ERROR_SERVICE_ALREADY_RUNNING) printf("PortTalk: The PortTalk driver is already running.\n"); else { printf("PortTalk: Unknown error while starting PortTalk driver service.\n"); printf("PortTalk: Does PortTalk.SYS exist in your \\System32\\Drivers Directory?\n"); return(0); } } /* Close handle to Service Control Manager */ CloseServiceHandle (schService); return(TRUE); } void InstallPortTalkDriver(void) { SC_HANDLE SchSCManager; SC_HANDLE schService; DWORD err; CHAR DriverFileName[80]; /* Get Current Directory. Assumes PortTalk.SYS driver is in this directory. */ /* Doesn't detect if file exists, nor if file is on removable media - if this */ /* is the case then when windows next boots, the driver will fail to load and */ /* a error entry is made in the event viewer to reflect this */ /* Get System Directory. This should be something like c:\windows\system32 or */ /* c:\winnt\system32 with a Maximum Character lenght of 20. As we have a */ /* buffer of 80 bytes and a string of 24 bytes to append, we can go for a max */ /* of 55 bytes */ if (!GetSystemDirectory(DriverFileName, 55)) { printf("PortTalk: Failed to get System Directory. Is System Directory Path > 55 Characters?\n"); printf("PortTalk: Please manually copy driver to your system32/driver directory.\n"); } /* Append our Driver Name */ lstrcat(DriverFileName,"\\Drivers\\PortTalk.sys"); printf("PortTalk: Copying driver to %s\n",DriverFileName); /* Copy Driver to System32/drivers directory. This fails if the file doesn't exist. */ if (!CopyFile("PortTalk.sys", DriverFileName, FALSE)) { printf("PortTalk: Failed to copy driver to %s\n",DriverFileName); printf("PortTalk: Please manually copy driver to your system32/driver directory.\n"); } /* Open Handle to Service Control Manager */ SchSCManager = OpenSCManager (NULL, /* machine (NULL == local) */ NULL, /* database (NULL == default) */ SC_MANAGER_ALL_ACCESS); /* access required */ /* Create Service/Driver - This adds the appropriate registry keys in */ /* HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services - It doesn't */ /* care if the driver exists, or if the path is correct. */ schService = CreateService (SchSCManager, /* SCManager database */ "PortTalk", /* name of service */ "PortTalk", /* name to display */ SERVICE_ALL_ACCESS, /* desired access */ SERVICE_KERNEL_DRIVER, /* service type */ SERVICE_DEMAND_START, /* start type */ SERVICE_ERROR_NORMAL, /* error control type */ "System32\\Drivers\\PortTalk.sys", /* service's binary */ NULL, /* no load ordering group */ NULL, /* no tag identifier */ NULL, /* no dependencies */ NULL, /* LocalSystem account */ NULL /* no password */ ); if (schService == NULL) { err = GetLastError(); if (err == ERROR_SERVICE_EXISTS) printf("PortTalk: Driver already exists. No action taken.\n"); else printf("PortTalk: Unknown error while creating Service.\n"); } else printf("PortTalk: Driver successfully installed.\n"); /* Close Handle to Service Control Manager */ CloseServiceHandle (schService); }