ADVERTISEMENT

userport.zip

zmiana sofciku na systemie Win XP potrzebe jakies pliki?

znalazem :) ... wrzuce opisik dla przyszlych szulkajacych :użytkownicy Windows 2000/XP chcac flashować swoje fony przy użyciu Nokia DCT3 np flasher by Rolis v 4.79 musza skopiowac plik userport.sys do folderu windows/system32/drivers, nastepnie uruchomic User Port, kliknac "Start" i dopiero potem uruchomić np Flasher Rolisa 4.79 ... wrzucam takze programik :)


Download file - link to post
  • userport.zip
    • IOPort.h
    • IOPort.pas
    • IOPort.c


userport.zip > IOPort.h

#ifndef IOPORTH
#define IOPORTH

#ifdef __cplusplus
extern " C " {
#endif

void outport(UINT portid, UINT value);
void outportb(UINT portid, BYTE value);
BYTE inportb(UINT portid);
UINT inport(UINT portid);
BOOL StartUpIoPorts(UINT PortToAccess, BOOL bShowMessageBox, HWND hParentWnd);

#ifdef __cplusplus
}
#endif

#endif


userport.zip > UserPort.pdf

UserPort Documentation
1 Summary
UserPort.SYS is a kernel mode driver for Windows NT/2000 that gives usermode programs access to I/O
Ports. This makes it possible to access hardware directly from a normal executable in the same way as under
Windows 95/98/ME. This driver does not work on Windows 95/98/ME and there is really no need to run it
anyway because I/O ports are always granted to usermode programs on these operating systems.
The driver can be used for the following purposes:
• To run software on Windows NT/2000 that normally only runs on Windows 95/98/ME.
• To easily access hardware like the parallel port and other I/O ports.
So what’s the drawbacks with this wonderful software? Microsoft has for security reasons prohibited usermode
access to I/O ports. Opening up I/O ports creates a big security hole in your system. You should therefore
carefully set the grant lists to only give usermode access to the specific I/O ports you need. The default values
opens up a wide range of I/O ports and you should narrow it down.
If you are writing your own software you should only grant access through the file “\\.\UserPort”. Access is then
given to your program when you open the file “\\.\UserPort”. Other programs that don’t open “\\.\UserPort” will
not have access to these I/O ports.

2 Installation
The driver can be installed in the following two ways:
• Copy UserPort.SYS to %WINDIR%\SYSTEM32\DRIVERS
Start UserPort.EXE and add the addresses you want and remove
the others and click on start.
• Run UserPort.EXE with the driver filename and path as an argument
i.e. run UserPort.EXE X:\YOURDIR\UserPort.SYS
Add the addresses you want and remove the others and click on start.
You should now have usermode access to the addresses you have chosen.

3 Examples
Port instructions are not included in development environments (such as Visual C++ and Delphi) because direct
I/O access isn’t allowed by the operating system. You will therefore need to include a portion of assembler code
into your software in order to access your hardware, see Figure 2, 3 and 4.
BYTE inportb(UINT portid)
{
unsigned char value;
__asm mov edx,portid
__asm in al,dx
__asm mov value,al
return value;

void outportb(UINT portid,
BYTE value)
{
__asm mov edx,portid
__asm mov al,value
__asm out dx,al
}

}

Figure 2: Read I/O port
if (inportb(0x379) & 0x10) {
outportb(0x378,'A');
outportb(0x37a,inportb(0x37a) | 0x01);
Sleep(1);
outportb(0x37a,inportb(0x37a) & 0xfe);
}

Figure 3: Write I/O port
//
//
//
//
//

Check ”Select” pin
Write character ‘A’ to printer
Set “strobe”
Wait 1ms
Clear ”Strobe” pin

Figure 4: Print ’A’ example using direct I/O access
Figure 4 shows how simple it now is to access hardware from a usermode program. The UserPort package
should contain the files IOPort.c, IOPort.h and IOPort.pas to be when developing C, C++ and Delphi programs.

4 Technical Description
The driver gives user mode program access to selected ports by changing the x86-processors IOPM (I/O
Permission Map). Figure 1 shows how the driver works. For a detailed description on the TSS see Intel
proccessor handbooks.
Task State Segment
GDT-reg

+

Task-register

0x66

TSS-descriptor

0x88

Base-address

Limit

IOPM offset
IOPM for processes
that opens
”\\.\UserPort”

0x20ab
0x20ad

IOPM for all processes

0x2135
Figure 1: 80x86 TSS description
The original size of the TSS is 0x20ab and the driver extends it to 0x2135. The default IOPM offset is 0x20ad
and this value is rewritten by the OS on every task switch. The IOPM offset must therefore be changed with the
undocumented function Ke386IoSetAccessProcess, which sets the IOPM offset to 0x88. The
AllProcessesIOPM is written to 0x20ad because this is the default IOPM offset for all processes and the
ThroughCreateFileIOPM is written to 0x88 because the Ke386IoSetAccessProcess function sets the
IOPM offset to 0x88. The Ke386IoSetAccessProcess function is called when a user mode program opens
the file “\\.\UserPort”. The driver loads the two IOPM:s from:
HKEY_LOCAL_MACHINE\Software\UserPort\AllProcessesIOPM
HKEY_LOCAL_MACHINE\Software\UserPort\ThroughCreateFileIOPM
It will use default values below if these doesn't exist.
This driver is influenced and inspired by an article written by Dale Roberts 8/30/95, published in May 96 Dr
Dobbs Journal, see www.ddj.com.
Tomas Franzon
tomas_franzon@hotmail.com


userport.zip > IOPort.c

#include & lt; windows.h & gt;
static BOOL bPrivException = FALSE;

void outport(UINT portid, UINT value)
{
__asm mov edx,portid;
__asm mov eax,value;
__asm out dx,ax;
}
void outportb(UINT portid, BYTE value)
{
__asm mov edx,portid
__asm mov al,value
__asm out dx,al
}

BYTE inportb(UINT portid)
{
unsigned char value;

__asm mov edx,portid
__asm in al,dx
__asm mov value,al
return value;
}

UINT inport(UINT portid)
{
int value=0;
__asm mov edx,portid
__asm in ax,dx
__asm mov value,eax
return value;
}

LONG WINAPI HandlerExceptionFilter ( EXCEPTION_POINTERS *pExPtrs )
{

if (pExPtrs- & gt; ExceptionRecord- & gt; ExceptionCode == EXCEPTION_PRIV_INSTRUCTION)
{
pExPtrs- & gt; ContextRecord- & gt; Eip ++; // Skip the OUT or IN instruction that caused the exception
bPrivException = TRUE;
return EXCEPTION_CONTINUE_EXECUTION;
}
else
return EXCEPTION_CONTINUE_SEARCH;
}

BOOL StartUpIoPorts(UINT PortToAccess, BOOL bShowMessageBox, HWND hParentWnd)
{
HANDLE hUserPort;

hUserPort = CreateFile( " \\\\.\\UserPort " , GENERIC_READ, 0, NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
CloseHandle(hUserPort); // Activate the driver
Sleep(100); // We must make a process switch

SetUnhandledExceptionFilter(HandlerExceptionFilter);

bPrivException = FALSE;
inportb(PortToAccess); // Try to access the given port address

if (bPrivException)
{
if (bShowMessageBox)
{
MessageBox(hParentWnd, " Privileged instruction exception has occured!\r\n\r\n "
" To use this program under Windows NT or Windows 2000\r\n "
" you need to install the driver 'UserPort.SYS' and grant\r\n "
" access to the ports used by this program. " ,
NULL,MB_OK);
}
return FALSE;
}
return TRUE;
}


userport.zip > resource.h

//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by UserPort.rc
//
#define IDD_USERPORT 101
#define IDI_APP 102
#define IDC_AUMP_LIST_GRANTS 1000
#define IDC_AUMP_EDIT_ADD 1001
#define IDC_AUMP_BUTTON_ADD 1002
#define IDC_AUMP_BUTTON_REMOVE 1003
#define IDC_TCF_EDIT_ADD 1004
#define IDC_BUTTON_UPDATE 1009
#define IDC_BUTTON_START 1010
#define IDC_TCF_LIST_GRANTS 1011
#define IDC_TCF_BUTTON_ADD 1012
#define IDC_BUTTON_STOP 1013
#define IDC_AUMP_BUTTON_DEFAULTS 1016
#define IDC_TCF_BUTTON_REMOVE 1017
#define IDC_TCF_BUTTON_DEFAULTS 1018

// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 103
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1017
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif


userport.zip > UserPort.C

/*********************************************************************

Author: Tomas Franzon
Date: 11/09/2000
Program: UserPort.SYS
Compile: Use DDK BUILD facility

Purpose: Give direct port I/O access to user mode programs.

This driver is influenced by an article written by Dale Roberts 8/30/95,
published in May 96 Dr Dobbs Journal, see www.ddj.com.
The driver gives user mode program access to selected ports by changing
the x86-processors IOPM (I/O Permission Map). The driver has one separate
map for all procsesses (AllProcessesIOPM) and one separate map
(ThroughCreateFileIOPM) for processes that opens the file " \\.\UserPort "

The driver tries to read the registry keys:
HKEY_LOCAL_MACHINE\Software\UserPort\AllProcessesIOPM
HKEY_LOCAL_MACHINE\Software\UserPort\ThroughCreateFileIOPM
It will use the default values below if these doesn't exist.

*********************************************************************/
#include & lt; ntddk.h & gt;

/*
* Make sure our structure is packed properly, on byte boundary, not
* on the default doubleword boundary.
*/
#pragma pack(push,1)

/*
* Structures for manipulating the GDT register and a GDT segment
* descriptor entry. Documented in Intel processor handbooks.
*/
typedef struct {
unsigned limit : 16;
unsigned baselo : 16;
unsigned basemid : 8;
unsigned type : 4;
unsigned system : 1;
unsigned dpl : 2;
unsigned present : 1;
unsigned limithi : 4;
unsigned available : 1;
unsigned zero : 1;
unsigned size : 1;
unsigned granularity : 1;
unsigned basehi : 8;
} GDTENT;

typedef struct {
unsigned short limit;
GDTENT *base;
} GDTREG;

#pragma pack(pop)
/*
* The name of our device driver.
*/
#define DEVICE_NAME_STRING L " UserPort "

/*
OriginalMapCopy is used to restore the IOPM when the driver exists.
CurrentMap points to NULL or to the place where the processors IOPM is located.
Accessmap is the IOPM that is used by the driver.
Every port address has one cooresponding bit in the IOPM. The driver supports
addresses from 0x000 to 0x3FF and the IOPM size is then 0x3ff / 8 = 0x80.
*/

UCHAR OriginalAllProcIOPMCopy[0x80];
UCHAR OriginalThroughCreateFileIOPMCopy[0x80];
const UCHAR DefaultMap[0x80]=
/*0x000*/ {0xFF,0xFF,
/*0x010*/ 0xFF,0xFF,
/*0x020*/ 0xFF,0xFF,
/*0x030*/ 0xFF,0xFF,
/*0x040*/ 0xFF,0xFF,
/*0x050*/ 0xFF,0xFF,
/*0x060*/ 0xFF,0xFF,
/*0x070*/ 0xFF,0xFF,
/*0x080*/ 0xFF,0xFF,
/*0x090*/ 0xFF,0xFF,
/*0x0A0*/ 0xFF,0xFF,
/*0x0B0*/ 0xFF,0xFF,
/*0x0C0*/ 0xFF,0xFF,
/*0x0D0*/ 0xFF,0xFF,
/*0x0E0*/ 0xFF,0xFF,
/*0x0F0*/ 0xFF,0xFF,
/*0x100*/ 0xFF,0xFF,
/*0x110*/ 0xFF,0xFF,
/*0x120*/ 0xFF,0xFF,
/*0x130*/ 0xFF,0xFF,
/*0x140*/ 0xFF,0xFF,
/*0x150*/ 0xFF,0xFF,
/*0x160*/ 0xFF,0xFF,
/*0x170*/ 0xFF,0xFF,
/*0x180*/ 0xFF,0xFF,
/*0x190*/ 0xFF,0xFF,
/*0x1A0*/ 0xFF,0xFF,
/*0x1B0*/ 0xFF,0xFF,
/*0x1C0*/ 0xFF,0xFF,
/*0x1D0*/ 0xFF,0xFF,
/*0x1E0*/ 0xFF,0xFF,
/*0x1F0*/ 0xFF,0xFF,
/*0x200*/ 0x00,0x00,
/*0x210*/ 0x00,0x00,
/*0x220*/ 0x00,0x00,
/*0x230*/ 0x00,0x00,
/*0x240*/ 0x00,0x00,
/*0x250*/ 0x00,0x00,
/*0x260*/ 0x00,0x00,
/*0x270*/ 0x00,0x00,
/*0x280*/ 0x00,0x00,
/*0x290*/ 0x00,0x00,
/*0x2A0*/ 0x00,0x00,
/*0x2B0*/ 0x00,0x00,
/*0x2C0*/ 0x00,0x00,
/*0x2D0*/ 0x00,0x00,
/*0x2E0*/ 0x00,0x00,
/*0x2F0*/ 0x00,0x00,
/*0x300*/ 0x00,0x00,
/*0x310*/ 0x00,0x00,
/*0x320*/ 0x00,0x00,
/*0x330*/ 0x00,0x00,
/*0x340*/ 0x00,0x00,
/*0x350*/ 0x00,0x00,
/*0x360*/ 0x00,0x00,
/*0x370*/ 0x00,0x00,
/*0x380*/ 0xFF,0xFF,
/*0x390*/ 0xFF,0xFF,
/*0x3A0*/ 0xFF,0xFF,
/*0x3B0*/ 0xFF,0x0F,
/*0x3C0*/ 0xFF,0xFF,
/*0x3D0*/ 0xFF,0xFF,
/*0x3E0*/ 0xFF,0x00,
/*0x3F0*/ 0x00,0x00};

unsigned OrgGDTSize; // The original sise of the TSS

/*
Ke386IoSetAccessProcess() adjusts the IOPM offset pointer to the IOPM at 0x88
Ke386IoSetAccessProcess() is located in NTOSKRNL.EXE but is not included in any
header file or documented anywhere...
*/

void Ke386IoSetAccessProcess(PEPROCESS, int);

/*********************************************************************
Service handler for a CreateFile() user mode call.

This routine is entered in the driver object function call table by
the DriverEntry() routine. When the user mode application calls
CreateFile(), this routine gets called while still in the context of
the user mode application, but with the CPL (the processor's Current
Privelege Level) set to 0. This allows us to do kernel mode
operations. UserPort() is called to give the calling process I/O
access. All the user mode application needs do to obtain I/O access
is open this device with CreateFile(). No other operations are
required.
*********************************************************************/
NTSTATUS CreateFileDispatch(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
// Give the current process IO access
Ke386IoSetAccessProcess(PsGetCurrentProcess(), 1);

Irp- & gt; IoStatus.Information = 0;
Irp- & gt; IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}

// remove the link \\.\UserPort and restore the IOPM
void UserPortUnload(IN PDRIVER_OBJECT DriverObject)
{
WCHAR DOSNameBuffer[] = L " \\DosDevices\\ " DEVICE_NAME_STRING;
UNICODE_STRING uniDOSString;
GDTREG gdtreg;
GDTENT *g;
short TaskSeg;
UCHAR *TSSAllProcessesIOPM;
UCHAR *TSSThroughCreateFileIOPM;
unsigned i;
UCHAR *TSSbase;

_asm cli;
_asm sgdt gdtreg;
_asm str TaskSeg;
g = gdtreg.base + (TaskSeg & gt; & gt; 3);
g- & gt; limit = OrgGDTSize;
g- & gt; type = 9;
_asm ltr TaskSeg;
_asm sti;

TSSbase = (UCHAR *) (g- & gt; baselo | (g- & gt; basemid & lt; & lt; 16) | (g- & gt; basehi & lt; & lt; 24));
TSSAllProcessesIOPM = *((USHORT *)(TSSbase + 0x66)) + TSSbase;
TSSThroughCreateFileIOPM = TSSbase + 0x88;

// Restore to the original map
for (i=0;i & lt; sizeof(DefaultMap);i++)
{
TSSAllProcessesIOPM[i] = OriginalAllProcIOPMCopy[i];
TSSThroughCreateFileIOPM[i] = OriginalThroughCreateFileIOPMCopy[i];
}

RtlInitUnicodeString( & uniDOSString, DOSNameBuffer);
IoDeleteSymbolicLink ( & uniDOSString);
IoDeleteDevice(DriverObject- & gt; DeviceObject);
}

// This routine is the entrypoint of the driver.
// This routine reads the AllProcessesIOPM and ThroughCreateFileIOPM from registry and start the driver
NTSTATUS DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
PDEVICE_OBJECT deviceObject;
NTSTATUS status;
WCHAR NameBuffer[] = L " \\Device\\ " DEVICE_NAME_STRING;
WCHAR DOSNameBuffer[] = L " \\DosDevices\\ " DEVICE_NAME_STRING;
UNICODE_STRING uniNameString, uniDOSString;
GDTREG gdtreg;
GDTENT *g;
short TaskSeg;
UCHAR *TSSAllProcessesIOPM;
UCHAR *TSSThroughCreateFileIOPM;
const UCHAR *AllProcessesIOPM = DefaultMap;
const UCHAR *ThroughCreateFileIOPM = DefaultMap;
unsigned i;
UCHAR *TSSbase;
UCHAR InformationBuffer1[sizeof(DefaultMap)+sizeof(KEY_VALUE_PARTIAL_INFORMATION)];
PKEY_VALUE_PARTIAL_INFORMATION Information1 = (PKEY_VALUE_PARTIAL_INFORMATION)InformationBuffer1;
UCHAR InformationBuffer2[sizeof(DefaultMap)+sizeof(KEY_VALUE_PARTIAL_INFORMATION)];
PKEY_VALUE_PARTIAL_INFORMATION Information2 = (PKEY_VALUE_PARTIAL_INFORMATION)InformationBuffer2;
ULONG ResultLength;
HANDLE KeyHandle;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING ThroughCreateFileIOPMString,AllProcessesIOPMString,RegPathString;

RtlInitUnicodeString( & AllProcessesIOPMString, L " AllProcessesIOPM " );
RtlInitUnicodeString( & ThroughCreateFileIOPMString, L " ThroughCreateFileIOPM " );
RtlInitUnicodeString( & RegPathString,L " \\Registry\\Machine\\Software\\UserPort " );

InitializeObjectAttributes( & ObjectAttributes, & RegPathString,OBJ_CASE_INSENSITIVE,NULL,NULL);

if (STATUS_SUCCESS == ZwOpenKey( & KeyHandle, KEY_QUERY_VALUE, & ObjectAttributes))
{
if (STATUS_SUCCESS == ZwQueryValueKey(KeyHandle, & ThroughCreateFileIOPMString,KeyValuePartialInformation,Information1,sizeof(InformationBuffer1), & ResultLength))
ThroughCreateFileIOPM = Information1- & gt; Data;
if (STATUS_SUCCESS == ZwQueryValueKey(KeyHandle, & AllProcessesIOPMString,KeyValuePartialInformation,Information2,sizeof(InformationBuffer2), & ResultLength))
AllProcessesIOPM = Information2- & gt; Data;
ZwClose(KeyHandle);
}

_asm cli; // don't get interrupted!
_asm str TaskSeg; // get the TSS selector
_asm sgdt gdtreg; // get the GDT address
g = gdtreg.base + (TaskSeg & gt; & gt; 3); // get the TSS descript
// get the TSS address
OrgGDTSize = g- & gt; limit;
g- & gt; limit += 0x082; // modify TSS segment limit
g- & gt; type = 9; // mark TSS as " not busy "
_asm ltr TaskSeg; // reload task register (TR)
_asm sti; // let interrupts continue*/

TSSbase = (UCHAR *) (g- & gt; baselo | (g- & gt; basemid & lt; & lt; 16) | (g- & gt; basehi & lt; & lt; 24));
TSSAllProcessesIOPM = *((USHORT *)(TSSbase + 0x66)) + TSSbase;
TSSThroughCreateFileIOPM = TSSbase + 0x88;

// Copy the AccessMap to TSSbase + 0x20ad and save the original map
for (i=0;i & lt; sizeof(DefaultMap);i++)
{
OriginalAllProcIOPMCopy[i] = TSSAllProcessesIOPM[i];
TSSAllProcessesIOPM[i] = AllProcessesIOPM[i];
OriginalThroughCreateFileIOPMCopy[i] = TSSThroughCreateFileIOPM[i];
TSSThroughCreateFileIOPM[i] = TSSThroughCreateFileIOPM[i] & ThroughCreateFileIOPM[i];
}

//
// Set up device driver name and device object.
// Make the driver accessable though the file \\.\UserPort

RtlInitUnicodeString( & uniNameString, NameBuffer);
RtlInitUnicodeString( & uniDOSString, DOSNameBuffer);

status = IoCreateDevice(DriverObject, 0,
& uniNameString,
FILE_DEVICE_UNKNOWN,
0, FALSE, & deviceObject);

if(!NT_SUCCESS(status))
return status;

status = IoCreateSymbolicLink ( & uniDOSString, & uniNameString);

if (!NT_SUCCESS(status))
return status;

//
// Initialize the Driver Object with driver's entry points.
// All we require are the Create and Unload operations.
//
DriverObject- & gt; MajorFunction[IRP_MJ_CREATE] = CreateFileDispatch;

DriverObject- & gt; DriverUnload = UserPortUnload;

return STATUS_SUCCESS;
}


userport.zip > UserPort.c

#include & lt; windows.h & gt;
#include & lt; string.h & gt;
#include " resource.h "

char szDriverFileName[MAX_PATH];
char DriverName[]= " UserPort " ;
HWND hDlg;

unsigned Chars2Hex (char ch, unsigned oldval)
{
int nHex;

if ((ch & gt; ='0') & & (ch & lt; ='9'))
nHex=ch-'0';
else if ((ch & gt; ='a') & & (ch & lt; ='f'))
nHex=ch-'a'+10;
else if ((ch & gt; ='A') & & (ch & lt; ='F'))
nHex=ch-'A'+10;
else
return oldval;
return oldval*16+nHex;
}

void UpperString(char *Str)
{
int i,Len;

Len=strlen(Str);
for (i=0;i & lt; Len;i++)
if (Str[i] & gt; 'Z')
Str[i]-=32;
}

BOOL StopDriver()
{
SC_HANDLE schService;
SC_HANDLE schSCManager;
SERVICE_STATUS serviceStatus;


schSCManager = OpenSCManager (NULL, // machine (NULL == local)
NULL, // database (NULL == default)
SC_MANAGER_ALL_ACCESS // access required
);
if (schSCManager == NULL)
{
return FALSE;
}

schService = OpenService (schSCManager,
DriverName,
SERVICE_ALL_ACCESS
);

if (schService == NULL)
{
CloseServiceHandle (schSCManager);
return FALSE;
}

ControlService (schService, SERVICE_CONTROL_STOP, & serviceStatus);

DeleteService (schService);

CloseServiceHandle (schService);
CloseServiceHandle (schSCManager);
return TRUE;
}

BOOL StartDriver()
{
SC_HANDLE schService = NULL;
SC_HANDLE schSCManager;
HANDLE hDriver;
DWORD LastError;
char szMess[300];
char szTmp[MAX_PATH];

lstrcpy(szTmp,szDriverFileName);
szTmp[12] = '\0';
if (lstrcmpi(szTmp, " \\SystemRoot\\ " )==0)
{
GetWindowsDirectory(szTmp,sizeof(szTmp));
lstrcat(szTmp,szDriverFileName+11);
}
else
lstrcpy(szTmp,szDriverFileName);


hDriver = CreateFile (szTmp,
GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (hDriver==INVALID_HANDLE_VALUE)
{
wsprintf(szMess, " Driver does not exist:\r\n%s " ,szTmp);
MessageBox(hDlg,szMess, " UserPort " ,MB_OK);
return FALSE;
}

CloseHandle(hDriver);

schSCManager = OpenSCManager (NULL, // machine (NULL == local)
NULL, // database (NULL == default)
SC_MANAGER_ALL_ACCESS // access required
);

if (schSCManager == NULL)
{
if (GetLastError() == ERROR_ACCESS_DENIED)
MessageBox(hDlg, " You are not authorized to install drivers.\r\nPlase contact your administrator. " , " UserPort " ,MB_OK);
else
MessageBox(hDlg, " Unable to start driver! " , " UserPort " ,MB_OK);

return FALSE;
}

schService = CreateService (schSCManager, // SCManager database
DriverName, // name of service
DriverName, // name to display
SERVICE_START,//SERVICE_ALL_ACCESS, // desired access
SERVICE_KERNEL_DRIVER, // service type
SERVICE_SYSTEM_START, // start type
SERVICE_ERROR_NORMAL, // error control type
szDriverFileName, // service's binary
NULL, // no load ordering group
NULL, // no tag identifier
NULL, // no dependencies
NULL, // LocalSystem account
NULL // no password
);

if (schService == NULL)
{
LastError = GetLastError();
if (LastError == ERROR_SERVICE_EXISTS)
MessageBox(hDlg, " Driver already started! " , " UserPort " ,MB_OK);
else if (LastError == ERROR_ACCESS_DENIED)
MessageBox(hDlg, " You are not authorized to install drivers.\r\nPlase contact your administrator. " , " UserPort " ,MB_OK);
else
MessageBox(hDlg, " Unable to start driver! " , " UserPort " ,MB_OK);

CloseServiceHandle (schSCManager);
return FALSE;
}

StartService (schService, // service identifier
0, // number of arguments
NULL // pointer to arguments
);

CloseServiceHandle (schService);
CloseServiceHandle (schSCManager);
return TRUE;
}

BOOL GetStartAndStopAddress(char *szStr, unsigned *nStartAddress, unsigned *nStopAddress)
{
unsigned i, nStart = 0, nStop = 0;

for (i=0;(szStr[i]!='\0') & & (szStr[i]!='-');i++)
nStart = Chars2Hex(szStr[i], nStart);

if (szStr[i]=='\0')
return FALSE;

for (i++;(szStr[i]!='\0') & & (szStr[i]!='-');i++)
nStop = Chars2Hex(szStr[i], nStop);

*nStartAddress = nStart;
*nStopAddress = nStop;

if (nStop & lt; nStart)
return FALSE;
if (nStop & gt; 0x3ff)
return FALSE;

return TRUE;
}

BOOL AddAUMPBtn()
{
char szTemp[256];
char szTemp2[256];
unsigned nStartAddress,nStopAddress;

GetDlgItemText(hDlg,IDC_AUMP_EDIT_ADD,szTemp,sizeof(szTemp));

if (!GetStartAndStopAddress(szTemp, & nStartAddress, & nStopAddress))
{
MessageBox(hDlg, " Wrong syntax. Use: \ " startadress - stopaddress\ " (000 - 3ff) " , " UserPort " ,MB_OK);
return FALSE;
}

wsprintf(szTemp2, " %X - %X " ,nStartAddress,nStopAddress);
SendDlgItemMessage(hDlg, IDC_AUMP_LIST_GRANTS,LB_ADDSTRING, 0,(LPARAM)szTemp2);
SetDlgItemText(hDlg,IDC_AUMP_EDIT_ADD, " " );
return TRUE;
}

BOOL AddTCFBtn()
{
char szTemp[256];
char szTemp2[256];
unsigned nStartAddress,nStopAddress;

GetDlgItemText(hDlg,IDC_TCF_EDIT_ADD,szTemp,sizeof(szTemp));

if (!GetStartAndStopAddress(szTemp, & nStartAddress, & nStopAddress))
{
MessageBox(hDlg, " Wrong syntax. Use: \ " startadress - stopaddress\ " (000 - 3ff) " , " UserPort " ,MB_OK);
return FALSE;
}

wsprintf(szTemp2, " %X - %X " ,nStartAddress,nStopAddress);
SendDlgItemMessage(hDlg, IDC_TCF_LIST_GRANTS,LB_ADDSTRING, 0,(LPARAM)szTemp2);
SetDlgItemText(hDlg,IDC_TCF_EDIT_ADD, " " );
return TRUE;
}

BOOL UpdateBtn()
{
HKEY hKey;
DWORD wType;
UCHAR AllProcessesIOPM[0x80];
UCHAR ThroughCreateFileIOPM[0x80];
unsigned nCount,i,j;
char szTemp[256];
unsigned nStartAddress,nStopAddress;

for (i=0;i & lt; sizeof(AllProcessesIOPM);i++)
AllProcessesIOPM[i] = 0xff;

nCount = SendDlgItemMessage(hDlg, IDC_AUMP_LIST_GRANTS,LB_GETCOUNT, 0,0);

for (i=0;i & lt; nCount;i++)
{
SendDlgItemMessage(hDlg, IDC_AUMP_LIST_GRANTS,LB_GETTEXT, i,(LPARAM)szTemp);
if (GetStartAndStopAddress(szTemp, & nStartAddress, & nStopAddress))
{
for (j=nStartAddress;j & lt; =nStopAddress;j++)
AllProcessesIOPM[j & gt; & gt; 3] & = ~(1 & lt; & lt; (j & 7));
}
}

for (i=0;i & lt; sizeof(ThroughCreateFileIOPM);i++)
ThroughCreateFileIOPM[i] = 0xff;

nCount = SendDlgItemMessage(hDlg, IDC_TCF_LIST_GRANTS,LB_GETCOUNT, 0,0);

for (i=0;i & lt; nCount;i++)
{
SendDlgItemMessage(hDlg, IDC_TCF_LIST_GRANTS,LB_GETTEXT, i,(LPARAM)szTemp);
if (GetStartAndStopAddress(szTemp, & nStartAddress, & nStopAddress))
{
for (j=nStartAddress;j & lt; =nStopAddress;j++)
ThroughCreateFileIOPM[j & gt; & gt; 3] & = ~(1 & lt; & lt; (j & 7));
}
}

if (RegCreateKeyEx(HKEY_LOCAL_MACHINE,
" Software\\UserPort " ,0, " " ,
REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,
NULL, & hKey, & wType) == ERROR_SUCCESS)
{
RegSetValueEx(hKey,
" AllProcessesIOPM " ,0,REG_BINARY,
(BYTE *)AllProcessesIOPM,sizeof(AllProcessesIOPM));
RegSetValueEx(hKey,
" ThroughCreateFileIOPM " ,0,REG_BINARY,
(BYTE *)ThroughCreateFileIOPM,sizeof(ThroughCreateFileIOPM));

RegCloseKey(hKey);
if (StopDriver())
{
Sleep(200);
StartDriver();
}
return TRUE;
}

return FALSE;
}

BOOL ReadRegistry()
{
UCHAR AllProcessesIOPM[0x80];
UCHAR ThroughCreateFileIOPM[0x80];
char szTemp[256];
unsigned i,nStartAddress,nStopAddress;

DWORD cb,wType, bResult1 = FALSE, bResult2 = FALSE;
HKEY hKey;

if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
" Software\\UserPort " ,0,KEY_READ,
& hKey) == ERROR_SUCCESS)
{
cb = sizeof(AllProcessesIOPM);
if (RegQueryValueEx(hKey, " AllProcessesIOPM " ,0, & wType,(BYTE *)AllProcessesIOPM, & cb) == ERROR_SUCCESS)
bResult1 = TRUE;
cb = sizeof(ThroughCreateFileIOPM);
if (RegQueryValueEx(hKey, " ThroughCreateFileIOPM " ,0, & wType,(BYTE *)ThroughCreateFileIOPM, & cb) == ERROR_SUCCESS)
bResult2 = TRUE;
RegCloseKey(hKey);
}

if ((bResult1 == FALSE) || (bResult2 == FALSE))
return FALSE;

for (i=0;i & lt; sizeof(AllProcessesIOPM) & lt; & lt; 3;i++)
{
if ((AllProcessesIOPM[i & gt; & gt; 3] & (1 & lt; & lt; (i & 7))) == 0)
{
nStartAddress = i;
do
{
nStopAddress = i;
i++;
} while ((i & lt; sizeof(AllProcessesIOPM) & lt; & lt; 3) & & ((AllProcessesIOPM[i & gt; & gt; 3] & (1 & lt; & lt; (i & 7))) == 0));
wsprintf(szTemp, " %X - %X " ,nStartAddress,nStopAddress);
SendDlgItemMessage(hDlg, IDC_AUMP_LIST_GRANTS,LB_ADDSTRING, 0,(LPARAM)szTemp);
}
}

for (i=0;i & lt; sizeof(ThroughCreateFileIOPM) & lt; & lt; 3;i++)
{
if ((ThroughCreateFileIOPM[i & gt; & gt; 3] & (1 & lt; & lt; (i & 7))) == 0)
{
nStartAddress = i;
do
{
nStopAddress = i;
i++;
} while ((i & lt; sizeof(ThroughCreateFileIOPM) & lt; & lt; 3) & & ((ThroughCreateFileIOPM[i & gt; & gt; 3] & (1 & lt; & lt; (i & 7))) == 0));
wsprintf(szTemp, " %X - %X " ,nStartAddress,nStopAddress);
SendDlgItemMessage(hDlg, IDC_TCF_LIST_GRANTS,LB_ADDSTRING, 0,(LPARAM)szTemp);
}
}

return TRUE;
}

BOOL AddAUMPDefaults()
{
int nCount,i;

nCount = SendDlgItemMessage(hDlg, IDC_AUMP_LIST_GRANTS,LB_GETCOUNT, 0,0);

for (i=0;i & lt; nCount;i++)
SendDlgItemMessage(hDlg, IDC_AUMP_LIST_GRANTS,LB_DELETESTRING, 0,0);

SendDlgItemMessage(hDlg, IDC_AUMP_LIST_GRANTS,LB_ADDSTRING, 0,(LPARAM) " 200 - 37F " );
SendDlgItemMessage(hDlg, IDC_AUMP_LIST_GRANTS,LB_ADDSTRING, 0,(LPARAM) " 3BC - 3BF " );
SendDlgItemMessage(hDlg, IDC_AUMP_LIST_GRANTS,LB_ADDSTRING, 0,(LPARAM) " 3E8 - 3FF " );
return TRUE;
}
BOOL AddTCFDefaults()
{
int nCount,i;

nCount = SendDlgItemMessage(hDlg, IDC_TCF_LIST_GRANTS,LB_GETCOUNT, 0,0);

for (i=0;i & lt; nCount;i++)
SendDlgItemMessage(hDlg, IDC_TCF_LIST_GRANTS,LB_DELETESTRING, 0,0);

SendDlgItemMessage(hDlg, IDC_TCF_LIST_GRANTS,LB_ADDSTRING, 0,(LPARAM) " 200 - 37F " );
SendDlgItemMessage(hDlg, IDC_TCF_LIST_GRANTS,LB_ADDSTRING, 0,(LPARAM) " 3BC - 3BF " );
SendDlgItemMessage(hDlg, IDC_TCF_LIST_GRANTS,LB_ADDSTRING, 0,(LPARAM) " 3E8 - 3FF " );
return TRUE;
}

BOOL WINAPI DlgProc(
HWND hWnd, //Handtag till fönster, 16-bitar
UINT msg, //Meddelande, unsigned int
WPARAM wParam, //Parameter (word), unsigned int
LPARAM lParam ) //Parameter (long), unsigned long int
{
char szTemp[256];
int nIndex;
switch (msg)
{
case WM_INITDIALOG:
hDlg=hWnd;
if (!ReadRegistry())
{
AddTCFDefaults();
AddAUMPDefaults();
}
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDCANCEL:
PostQuitMessage ( 0 );
EndDialog(hWnd,FALSE);
break;
case IDC_BUTTON_START:
StartDriver();
break;
case IDC_BUTTON_STOP:
if (!StopDriver())
{
if (GetLastError() == ERROR_ACCESS_DENIED)
MessageBox(hDlg, " You are not authorized to remove drivers.\r\nPlase contact your administrator. " , " UserPort " ,MB_OK);
else
MessageBox(hDlg, " Driver is not installed! " , " UserPort " ,MB_OK);
}
break;
case IDC_AUMP_BUTTON_ADD:
AddAUMPBtn();
break;
case IDC_TCF_BUTTON_ADD:
AddTCFBtn();
break;
case IDC_BUTTON_UPDATE:
UpdateBtn();
break;
case IDC_AUMP_BUTTON_REMOVE:
nIndex = SendDlgItemMessage(hDlg, IDC_AUMP_LIST_GRANTS,LB_GETCURSEL, 0,0);
SendDlgItemMessage(hDlg, IDC_AUMP_LIST_GRANTS,LB_DELETESTRING, nIndex,0);
EnableWindow(GetDlgItem(hWnd,IDC_AUMP_BUTTON_REMOVE), FALSE);
break;
case IDC_TCF_BUTTON_REMOVE:
nIndex = SendDlgItemMessage(hDlg, IDC_TCF_LIST_GRANTS,LB_GETCURSEL, 0,0);
SendDlgItemMessage(hDlg, IDC_TCF_LIST_GRANTS,LB_DELETESTRING, nIndex,0);
EnableWindow(GetDlgItem(hWnd,IDC_TCF_BUTTON_REMOVE), FALSE);
break;
case IDC_AUMP_BUTTON_DEFAULTS:
AddAUMPDefaults();
break;
case IDC_TCF_BUTTON_DEFAULTS:
AddTCFDefaults();
break;
case IDC_AUMP_EDIT_ADD:
GetDlgItemText(hDlg,IDC_AUMP_EDIT_ADD,szTemp,sizeof(szTemp));
EnableWindow(GetDlgItem(hWnd,IDC_AUMP_BUTTON_ADD), szTemp[0]!='\0');
break;
case IDC_TCF_EDIT_ADD:
GetDlgItemText(hDlg,IDC_TCF_EDIT_ADD,szTemp,sizeof(szTemp));
EnableWindow(GetDlgItem(hWnd,IDC_TCF_BUTTON_ADD), szTemp[0]!='\0');
break;
case IDC_AUMP_LIST_GRANTS:
if (HIWORD(wParam) == LBN_SELCHANGE)
{
nIndex = SendDlgItemMessage(hDlg, IDC_AUMP_LIST_GRANTS,LB_GETCURSEL, 0,0);
SendDlgItemMessage(hDlg, IDC_AUMP_LIST_GRANTS,LB_SETCURSEL, nIndex,0);
EnableWindow(GetDlgItem(hWnd,IDC_AUMP_BUTTON_REMOVE), TRUE);
}
break;
case IDC_TCF_LIST_GRANTS:
if (HIWORD(wParam) == LBN_SELCHANGE)
{
nIndex = SendDlgItemMessage(hDlg, IDC_TCF_LIST_GRANTS,LB_GETCURSEL, 0,0);
SendDlgItemMessage(hDlg, IDC_TCF_LIST_GRANTS,LB_SETCURSEL, nIndex,0);
EnableWindow(GetDlgItem(hWnd,IDC_TCF_BUTTON_REMOVE), TRUE);
}
break;
default:
return FALSE;
break;
}
break;
default:
return FALSE;
}
return TRUE;
} //DlgProc

int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpszCmdline,
int nShow )
{
MSG msg;

OSVERSIONINFO osvi;

GetVersionEx( & osvi);

if ((osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) || (osvi.dwPlatformId == VER_PLATFORM_WIN32s))
{
MessageBox(NULL, " UserPort does not work on Windows 3.11/95/98/Me.\r\n\r\nUsermode programs does always have access to ports in Windows 3.11/95/98.\r\nThis program is therefore not needed on these operating systems. " , " UserPort " ,MB_OK);
return 0;
}

if (lpszCmdline[0] != '\0')
lstrcpy(szDriverFileName, lpszCmdline);
else
lstrcpy(szDriverFileName, " \\SystemRoot\\System32\\Drivers\\UserPort.sys " );
CreateDialog(
hInstance,
MAKEINTRESOURCE(IDD_USERPORT),
NULL,
(DLGPROC)DlgProc);

SetClassLong(hDlg,GCL_HICON,(long)LoadIcon ( hInstance, MAKEINTRESOURCE(IDI_APP)));

while ( GetMessage ( & msg, NULL, 0, 0 ) )
{
if (IsDialogMessage(hDlg, & msg))
continue;
TranslateMessage ( & msg );
DispatchMessage ( & msg );
}
return 0;
} //WinMain