www.pudn.com > porttalk22.zip > allowio.c


/******************************************************************************/ 
/*                                                                            */ 
/*                          AllowIO for PortTalk V2.0                         */ 
/*                        Version 2.0, 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  
#include  
#include  
#include  
 
void InstallPortTalkDriver(void); 
unsigned char StartPortTalkDriver(void); 
 
int __cdecl main(int argc, char ** argv) 
{ 
    HANDLE PortTalk_Handle;   /* Handle for PortTalk Driver */ 
    int error;                /* Error Handling for DeviceIoControl() */ 
    int count;                /* Temp Variable to process Auguments */ 
    int value; 
    int offset; 
 
    char filename[80] = {""}; /* Filename of Executable */ 
    DWORD BytesReturned;      /* Bytes Returned for DeviceIoControl() */ 
 
    STARTUPINFO si;           /* Startup Info Structure */ 
    PROCESS_INFORMATION pi;   /* Process Info Structure - Contains Process ID Information */ 
  
    printf("AllowIO for PortTalk V2.0\nCopyright 2002 Craig Peacock\nhttp://www.beyondlogic.org\n"); 
 
    /* No Arguments, Display product info and help */ 
 
    if (argc <= 1) 
        { 
         printf("Grants the specified executable exclusive access to specified I/O Ports\nunder Windows NT/2000/XP\n"); 
         printf("Usage : AllowIO   \n"); 
         printf("Switches : /a - Grants exclusive access to ALL Ports\n"); 
         return 0; 
        } 
     
    /* 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; 
            } 
    } 
 
    /* Once we have successfully opened a handle to the PortTalk Driver, we must fill the */ 
    /* driver's IOPM with 0xFF to restrict access to all ports */ 
 
    error = DeviceIoControl(PortTalk_Handle, 
                            IOCTL_IOPM_RESTRICT_ALL_ACCESS,    
                            NULL, 
                            0,     
                            NULL, 
                            0, 
                            &BytesReturned, 
                            NULL); 
 
    if (!error) printf("PortTalk: error %d occured in IOCTL_IOPM_RESTRICT_ALL_ACCESS\n",GetLastError()); 
     
    /* Now we start processing arguments and sending them to the driver */     
 
    for (count = 1; count < argc; count++) {  
        /* If argument starts with '0x' */ 
        if (argv[count][0] == '0' & argv[count][1] =='x') { 
                sscanf(argv[count],"%x", &value); 
                offset = value / 8; 
                error = DeviceIoControl(PortTalk_Handle, 
                                        IOCTL_SET_IOPM, 
                                        &offset, 
                                        3,     
                                        NULL, 
                                        0, 
                                        &BytesReturned, 
                                        NULL); 
 
                if (!error) printf("Error %d granting access to Address 0x%03X\n",GetLastError(),value); 
                else        printf("Address 0x%03X (IOPM Offset 0x%02X) has been granted access.\n",value,offset); 
        } 
        else if (argv[count][0] == '/' & argv[count][1] =='a') { 
                /*  Set Entire IOPM */ 
                printf("Granting exclusive access to all I/O Ports\n"); 
                error = DeviceIoControl(PortTalk_Handle, 
                                        IOCTL_IOPM_ALLOW_EXCUSIVE_ACCESS, 
                                        NULL, 
                                        0,     
                                        NULL, 
                                        0, 
                                        &BytesReturned, 
                                        NULL); 
        } else { 
                /* Must be a Filename */ 
                if (strlen(filename) + strlen(argv[count]) > 80) {  
                     printf("Command line exceeds 80 Characters\n"); 
                     return 0; 
                    } 
                strcat(filename,argv[count]); 
                strcat(filename," "); 
                } 
    } 
 
    /* Start Executable */ 
    printf("Executing %swith a ",filename); 
 
    ZeroMemory( &si, sizeof(si) ); /* Zero Startup Info */ 
    si.cb = sizeof(si);            /* Set Size */ 
 
    if( !CreateProcess(NULL,       /* No module name (use command line). */ 
                       filename,   /* Command line. */ 
                       NULL,       /* Process handle not inheritable. */ 
                       NULL,       /* Thread handle not inheritable. */ 
                       FALSE,      /* Set handle inheritance to FALSE. */ 
                       0,          /* No creation flags. */ 
                       NULL,       /* Use parent's environment block. */ 
                       NULL,       /* Use parent's starting directory. */ 
                       &si,        /* Pointer to STARTUPINFO structure. */ 
                       &pi)        /* Pointer to PROCESS_INFORMATION structure. */ 
                   ) printf("Error in CreateProcess\n\n");     
 
    printf("ProcessID of %d\n",pi.dwProcessId); 
 
    error = DeviceIoControl(PortTalk_Handle, 
                            IOCTL_ENABLE_IOPM_ON_PROCESSID, 
                            &pi.dwProcessId, 
                            4, 
                            NULL, 
                            0, 
                            &BytesReturned, 
                            NULL); 
 
    if (!error) printf("Error Occured talking to Device Driver %d\n",GetLastError()); 
    else        printf("PortTalk Device Driver has set IOPM for ProcessID %d.\n",pi.dwProcessId); 
 
    CloseHandle(PortTalk_Handle); 
    return 0; 
} 
 
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); 
}