Remove 'windows' folder with giveio.sys driver
This commit is contained in:
parent
868895e2e0
commit
60cb548075
|
@ -41,14 +41,13 @@ CLEANFILES = \
|
||||||
|
|
||||||
BUILT_SOURCES = $(CLEANFILES)
|
BUILT_SOURCES = $(CLEANFILES)
|
||||||
|
|
||||||
#SUBDIRS = doc @WINDOWS_DIRS@
|
#SUBDIRS = doc
|
||||||
#DIST_SUBDIRS = doc windows
|
#DIST_SUBDIRS = doc
|
||||||
|
|
||||||
# . lets build this directory before the following in SUBDIRS
|
# . lets build this directory before the following in SUBDIRS
|
||||||
SUBDIRS = .
|
SUBDIRS = .
|
||||||
# doc comes here, and we want to use the built avrdude to generate the parts list
|
# doc comes here, and we want to use the built avrdude to generate the parts list
|
||||||
SUBDIRS += @SUBDIRS_AC@
|
SUBDIRS += @SUBDIRS_AC@
|
||||||
SUBDIRS += @WINDOWS_DIRS@
|
|
||||||
DIST_SUBDIRS = @DIST_SUBDIRS_AC@
|
DIST_SUBDIRS = @DIST_SUBDIRS_AC@
|
||||||
|
|
||||||
AM_YFLAGS = -d
|
AM_YFLAGS = -d
|
||||||
|
|
|
@ -348,7 +348,7 @@ AC_ARG_ENABLE(
|
||||||
esac],
|
esac],
|
||||||
[enabled_linuxspi=no])
|
[enabled_linuxspi=no])
|
||||||
|
|
||||||
DIST_SUBDIRS_AC='doc windows'
|
DIST_SUBDIRS_AC='doc'
|
||||||
|
|
||||||
if test "$enabled_doc" = "yes"; then
|
if test "$enabled_doc" = "yes"; then
|
||||||
SUBDIRS_AC='doc'
|
SUBDIRS_AC='doc'
|
||||||
|
@ -505,15 +505,12 @@ case $target in
|
||||||
LDFLAGS="${LDFLAGS} -static"
|
LDFLAGS="${LDFLAGS} -static"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
WINDOWS_DIRS="windows"
|
|
||||||
CFLAGS="${CFLAGS} -DWIN32NATIVE"
|
CFLAGS="${CFLAGS} -DWIN32NATIVE"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
AC_SUBST(WINDOWS_DIRS,$WINDOWS_DIRS)
|
|
||||||
|
|
||||||
AC_CONFIG_FILES([
|
AC_CONFIG_FILES([
|
||||||
doc/Makefile
|
doc/Makefile
|
||||||
windows/Makefile
|
|
||||||
avrdude.spec
|
avrdude.spec
|
||||||
Makefile
|
Makefile
|
||||||
])
|
])
|
||||||
|
|
|
@ -2108,9 +2108,7 @@ such as @option{--prefix}.
|
||||||
* Windows Installation::
|
* Windows Installation::
|
||||||
* Windows Configuration Files::
|
* Windows Configuration Files::
|
||||||
* Windows Port Names::
|
* Windows Port Names::
|
||||||
* Using the parallel port::
|
|
||||||
* Documentation::
|
* Documentation::
|
||||||
* Credits.::
|
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
@c
|
@c
|
||||||
|
@ -2213,7 +2211,7 @@ The directories that are listed in the PATH environment variable.
|
||||||
@c
|
@c
|
||||||
@c Node
|
@c Node
|
||||||
@c
|
@c
|
||||||
@node Windows Port Names, Using the parallel port, Windows Configuration Files, Windows
|
@node Windows Port Names, Windows Configuration Files, Windows
|
||||||
@subsection Port Names
|
@subsection Port Names
|
||||||
|
|
||||||
@menu
|
@menu
|
||||||
|
@ -2266,70 +2264,7 @@ language notation (i. e., hexadecimal values are prefixed by @code{0x}).
|
||||||
@c
|
@c
|
||||||
@c Node
|
@c Node
|
||||||
@c
|
@c
|
||||||
@node Using the parallel port, Documentation, Windows Port Names, Windows
|
@node Documentation, Windows
|
||||||
@subsection Using the parallel port
|
|
||||||
|
|
||||||
@menu
|
|
||||||
* Windows NT/2K/XP::
|
|
||||||
* Windows 95/98::
|
|
||||||
@end menu
|
|
||||||
|
|
||||||
@c
|
|
||||||
@c Node
|
|
||||||
@c
|
|
||||||
@node Windows NT/2K/XP, Windows 95/98, Using the parallel port, Using the parallel port
|
|
||||||
@subsubsection Windows NT/2K/XP
|
|
||||||
|
|
||||||
@noindent
|
|
||||||
On Windows NT, 2000, and XP user applications cannot directly access the
|
|
||||||
parallel port. However, kernel mode drivers can access the parallel port.
|
|
||||||
giveio.sys is a driver that can allow user applications to set the state
|
|
||||||
of the parallel port pins.
|
|
||||||
|
|
||||||
Before using AVRDUDE, the giveio.sys driver must be loaded. The
|
|
||||||
accompanying command-line program, loaddrv.exe, can do just that.
|
|
||||||
|
|
||||||
To make things even easier there are 3 batch files that are also
|
|
||||||
included:
|
|
||||||
|
|
||||||
@enumerate
|
|
||||||
@item install_giveio.bat
|
|
||||||
Install and start the giveio driver.
|
|
||||||
|
|
||||||
@item status_giveio.bat
|
|
||||||
Check on the status of the giveio driver.
|
|
||||||
|
|
||||||
@item remove_giveio.bat
|
|
||||||
Stop and remove the giveio driver from memory.
|
|
||||||
@end enumerate
|
|
||||||
|
|
||||||
These 3 batch files calls the loaddrv program with various options to
|
|
||||||
install, start, stop, and remove the driver.
|
|
||||||
|
|
||||||
When you first execute install_giveio.bat, loaddrv.exe and giveio.sys
|
|
||||||
must be in the current directory. When install_giveio.bat is executed it
|
|
||||||
will copy giveio.sys from your current directory to your Windows
|
|
||||||
directory. It will then load the driver from the Windows directory. This
|
|
||||||
means that after the first time install_giveio is executed, you should
|
|
||||||
be able to subsequently execute the batch file from any directory and have
|
|
||||||
it successfully start the driver.
|
|
||||||
|
|
||||||
Note that you must have administrator privilege to load the giveio driver.
|
|
||||||
|
|
||||||
@c
|
|
||||||
@c Node
|
|
||||||
@c
|
|
||||||
@node Windows 95/98, , Windows NT/2K/XP, Using the parallel port
|
|
||||||
@subsubsection Windows 95/98
|
|
||||||
|
|
||||||
@noindent
|
|
||||||
On Windows 95 and 98 the giveio.sys driver is not needed.
|
|
||||||
|
|
||||||
|
|
||||||
@c
|
|
||||||
@c Node
|
|
||||||
@c
|
|
||||||
@node Documentation, Credits., Using the parallel port, Windows
|
|
||||||
@subsection Documentation
|
@subsection Documentation
|
||||||
|
|
||||||
@noindent
|
@noindent
|
||||||
|
@ -2343,28 +2278,6 @@ Note that these locations can be altered by various configure options
|
||||||
such as @option{--prefix} and @option{--datadir}.
|
such as @option{--prefix} and @option{--datadir}.
|
||||||
|
|
||||||
|
|
||||||
@c
|
|
||||||
@c Node
|
|
||||||
@c
|
|
||||||
@node Credits., , Documentation, Windows
|
|
||||||
@subsection Credits.
|
|
||||||
|
|
||||||
@noindent
|
|
||||||
Thanks to:
|
|
||||||
|
|
||||||
@itemize @bullet
|
|
||||||
@item
|
|
||||||
Dale Roberts for the giveio driver.
|
|
||||||
|
|
||||||
@item
|
|
||||||
Paula Tomlinson for the loaddrv sources.
|
|
||||||
|
|
||||||
@item
|
|
||||||
Chris Liechti <cliechti@@gmx.net> for modifying loaddrv to be command
|
|
||||||
line driven and for writing the batch files.
|
|
||||||
|
|
||||||
@end itemize
|
|
||||||
|
|
||||||
@c
|
@c
|
||||||
@c Node
|
@c Node
|
||||||
@c
|
@c
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
.deps
|
|
||||||
Makefile
|
|
||||||
Makefile.in
|
|
|
@ -1,57 +0,0 @@
|
||||||
#
|
|
||||||
# avrdude - A Downloader/Uploader for AVR device programmers
|
|
||||||
# Copyright (C) 2003 Theodore A. Roth <troth@openavr.org>
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation; either version 2 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
#
|
|
||||||
|
|
||||||
#
|
|
||||||
# $Id$
|
|
||||||
#
|
|
||||||
|
|
||||||
#
|
|
||||||
# This Makefile will only be used on windows based systems.
|
|
||||||
#
|
|
||||||
|
|
||||||
local_install_list = \
|
|
||||||
giveio.sys \
|
|
||||||
install_giveio.bat \
|
|
||||||
remove_giveio.bat \
|
|
||||||
status_giveio.bat
|
|
||||||
|
|
||||||
EXTRA_DIST = \
|
|
||||||
giveio.c \
|
|
||||||
$(local_install_list)
|
|
||||||
|
|
||||||
bin_PROGRAMS = loaddrv
|
|
||||||
|
|
||||||
loaddrv_SOURCES = \
|
|
||||||
loaddrv.c \
|
|
||||||
loaddrv.h
|
|
||||||
|
|
||||||
install-exec-local:
|
|
||||||
$(mkinstalldirs) $(DESTDIR)$(bindir)
|
|
||||||
@list='$(local_install_list)'; for file in $$list; do \
|
|
||||||
echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) \
|
|
||||||
$(srcdir)/$$file $(DESTDIR)$(bindir)/$$file"; \
|
|
||||||
$(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $(srcdir)/$$file \
|
|
||||||
$(DESTDIR)$(bindir)/$$file; \
|
|
||||||
done
|
|
||||||
|
|
||||||
uninstall-local:
|
|
||||||
@for file in $(local_install_list); do \
|
|
||||||
echo " rm -f $(DESTDIR)$(bindir)/$$file"; \
|
|
||||||
rm -f $(DESTDIR)$(bindir)/$$file; \
|
|
||||||
done
|
|
||||||
|
|
|
@ -1,168 +0,0 @@
|
||||||
/*********************************************************************
|
|
||||||
|
|
||||||
Author: Dale Roberts
|
|
||||||
Date: 8/30/95
|
|
||||||
Program: GIVEIO.SYS
|
|
||||||
Compile: Use DDK BUILD facility
|
|
||||||
|
|
||||||
Purpose: Give direct port I/O access to a user mode process.
|
|
||||||
|
|
||||||
*********************************************************************/
|
|
||||||
#include <ntddk.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The name of our device driver.
|
|
||||||
*/
|
|
||||||
#define DEVICE_NAME_STRING L"giveio"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This is the "structure" of the IOPM. It is just a simple
|
|
||||||
* character array of length 0x2000.
|
|
||||||
*
|
|
||||||
* This holds 8K * 8 bits -> 64K bits of the IOPM, which maps the
|
|
||||||
* entire 64K I/O space of the x86 processor. Any 0 bits will give
|
|
||||||
* access to the corresponding port for user mode processes. Any 1
|
|
||||||
* bits will disallow I/O access to the corresponding port.
|
|
||||||
*/
|
|
||||||
#define IOPM_SIZE 0x2000
|
|
||||||
typedef UCHAR IOPM[IOPM_SIZE];
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This will hold simply an array of 0's which will be copied
|
|
||||||
* into our actual IOPM in the TSS by Ke386SetIoAccessMap().
|
|
||||||
* The memory is allocated at driver load time.
|
|
||||||
*/
|
|
||||||
IOPM *IOPM_local = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* These are the two undocumented calls that we will use to give
|
|
||||||
* the calling process I/O access.
|
|
||||||
*
|
|
||||||
* Ke386IoSetAccessMap() copies the passed map to the TSS.
|
|
||||||
*
|
|
||||||
* Ke386IoSetAccessProcess() adjusts the IOPM offset pointer so that
|
|
||||||
* the newly copied map is actually used. Otherwise, the IOPM offset
|
|
||||||
* points beyond the end of the TSS segment limit, causing any I/O
|
|
||||||
* access by the user mode process to generate an exception.
|
|
||||||
*/
|
|
||||||
void Ke386SetIoAccessMap(int, IOPM *);
|
|
||||||
void Ke386QueryIoAccessMap(int, IOPM *);
|
|
||||||
void Ke386IoSetAccessProcess(PEPROCESS, int);
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
Release any allocated objects.
|
|
||||||
*********************************************************************/
|
|
||||||
VOID GiveioUnload(IN PDRIVER_OBJECT DriverObject)
|
|
||||||
{
|
|
||||||
WCHAR DOSNameBuffer[] = L"\\DosDevices\\" DEVICE_NAME_STRING;
|
|
||||||
UNICODE_STRING uniDOSString;
|
|
||||||
|
|
||||||
if(IOPM_local)
|
|
||||||
MmFreeNonCachedMemory(IOPM_local, sizeof(IOPM));
|
|
||||||
|
|
||||||
RtlInitUnicodeString(&uniDOSString, DOSNameBuffer);
|
|
||||||
IoDeleteSymbolicLink (&uniDOSString);
|
|
||||||
IoDeleteDevice(DriverObject->DeviceObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
Set the IOPM (I/O permission map) of the calling process so that it
|
|
||||||
is given full I/O access. Our IOPM_local[] array is all zeros, so
|
|
||||||
the IOPM will be all zeros. If OnFlag is 1, the process is given I/O
|
|
||||||
access. If it is 0, access is removed.
|
|
||||||
*********************************************************************/
|
|
||||||
VOID SetIOPermissionMap(int OnFlag)
|
|
||||||
{
|
|
||||||
Ke386IoSetAccessProcess(PsGetCurrentProcess(), OnFlag);
|
|
||||||
Ke386SetIoAccessMap(1, IOPM_local);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GiveIO(void)
|
|
||||||
{
|
|
||||||
SetIOPermissionMap(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
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. GiveIO() 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 GiveioCreateDispatch(
|
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
|
||||||
IN PIRP Irp
|
|
||||||
)
|
|
||||||
{
|
|
||||||
GiveIO(); // give the calling process I/O access
|
|
||||||
|
|
||||||
Irp->IoStatus.Information = 0;
|
|
||||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
Driver Entry routine.
|
|
||||||
|
|
||||||
This routine is called only once after the driver is initially
|
|
||||||
loaded into memory. It allocates everything necessary for the
|
|
||||||
driver's operation. In our case, it allocates memory for our IOPM
|
|
||||||
array, and creates a device which user mode applications can open.
|
|
||||||
It also creates a symbolic link to the device driver. This allows
|
|
||||||
a user mode application to access our driver using the \\.\giveio
|
|
||||||
notation.
|
|
||||||
*********************************************************************/
|
|
||||||
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;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Allocate a buffer for the local IOPM and zero it.
|
|
||||||
//
|
|
||||||
IOPM_local = MmAllocateNonCachedMemory(sizeof(IOPM));
|
|
||||||
if(IOPM_local == 0)
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
RtlZeroMemory(IOPM_local, sizeof(IOPM));
|
|
||||||
|
|
||||||
//
|
|
||||||
// Set up device driver name and device object.
|
|
||||||
//
|
|
||||||
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->MajorFunction[IRP_MJ_CREATE] = GiveioCreateDispatch;
|
|
||||||
DriverObject->DriverUnload = GiveioUnload;
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
Binary file not shown.
|
@ -1,34 +0,0 @@
|
||||||
@set DIRVERNAME=giveio
|
|
||||||
@set DIRVERFILE=%DIRVERNAME%.sys
|
|
||||||
|
|
||||||
@echo Copying the driver to the windows directory
|
|
||||||
@echo target file: %WINDIR%\%DIRVERFILE%
|
|
||||||
@copy %DIRVERFILE% %WINDIR%\%DIRVERFILE%
|
|
||||||
|
|
||||||
@echo Remove a running service if needed...
|
|
||||||
@loaddrv stop %DIRVERNAME% >NUL
|
|
||||||
@if errorlevel 2 goto install
|
|
||||||
|
|
||||||
@loaddrv remove %DIRVERNAME% >NUL
|
|
||||||
@if errorlevel 1 goto install
|
|
||||||
|
|
||||||
:install
|
|
||||||
@echo Installing Windows NT/2k/XP driver: %DIRVERNAME%
|
|
||||||
|
|
||||||
@loaddrv install %DIRVERNAME% %WINDIR%\%DIRVERFILE%
|
|
||||||
@if errorlevel 3 goto error
|
|
||||||
|
|
||||||
@loaddrv start %DIRVERNAME%
|
|
||||||
@if errorlevel 1 goto error
|
|
||||||
|
|
||||||
@loaddrv starttype %DIRVERNAME% auto
|
|
||||||
@if errorlevel 1 goto error
|
|
||||||
|
|
||||||
@echo Success
|
|
||||||
@goto exit
|
|
||||||
|
|
||||||
:error
|
|
||||||
@echo ERROR: Installation of %DIRVERNAME% failed
|
|
||||||
|
|
||||||
:exit
|
|
||||||
|
|
|
@ -1,461 +0,0 @@
|
||||||
// loaddrv.c - Dynamic driver install/start/stop/remove
|
|
||||||
// based on Paula Tomlinson's LOADDRV program.
|
|
||||||
// She describes it in her May 1995 article in Windows/DOS Developer's
|
|
||||||
// Journal (now Windows Developer's Journal).
|
|
||||||
// Modified by Chris Liechti <cliechti@gmx.net>
|
|
||||||
// I removed the old/ugly dialog, it now accepts command line options and
|
|
||||||
// prints error messages with textual description from the OS.
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include "loaddrv.h"
|
|
||||||
|
|
||||||
// globals
|
|
||||||
SC_HANDLE hSCMan = NULL;
|
|
||||||
|
|
||||||
//get ext messages for windows error codes:
|
|
||||||
void DisplayErrorText(DWORD dwLastError) {
|
|
||||||
LPSTR MessageBuffer;
|
|
||||||
DWORD dwBufferLength;
|
|
||||||
|
|
||||||
DWORD dwFormatFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
|
||||||
FORMAT_MESSAGE_IGNORE_INSERTS |
|
|
||||||
FORMAT_MESSAGE_FROM_SYSTEM;
|
|
||||||
|
|
||||||
dwBufferLength = FormatMessageA(
|
|
||||||
dwFormatFlags,
|
|
||||||
NULL, // module to get message from (NULL == system)
|
|
||||||
dwLastError,
|
|
||||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // default language
|
|
||||||
(LPSTR) &MessageBuffer,
|
|
||||||
0,
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
if (dwBufferLength) {
|
|
||||||
// Output message
|
|
||||||
puts(MessageBuffer);
|
|
||||||
// Free the buffer allocated by the system.
|
|
||||||
LocalFree(MessageBuffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int exists(char *filename) {
|
|
||||||
FILE * pFile;
|
|
||||||
pFile = fopen(filename, "r");
|
|
||||||
if (pFile) fclose(pFile);
|
|
||||||
return pFile != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void usage(void) {
|
|
||||||
printf("USGAE: loaddrv command drivername [args...]\n\n"
|
|
||||||
"NT/2k/XP Driver and Service modification tool.\n"
|
|
||||||
"(C)2002 Chris Liechti <cliechti@gmx.net>\n\n"
|
|
||||||
"Suported commands:\n\n"
|
|
||||||
" install [fullpathforinstall]\n"
|
|
||||||
" Install new service. Loaded from given path. If path is not present,\n"
|
|
||||||
" the local directory is searched for a .sys file. If the service\n"
|
|
||||||
" already exists, it must be removed first.\n"
|
|
||||||
" start\n"
|
|
||||||
" Start service. It must be installed in advance.\n"
|
|
||||||
" stop\n"
|
|
||||||
" Stop service.\n"
|
|
||||||
" remove\n"
|
|
||||||
" Remove service. It must be stopped in advance.\n"
|
|
||||||
" status\n"
|
|
||||||
" Show status information about service.\n"
|
|
||||||
" starttype auto|manual|system|disable\n"
|
|
||||||
" Change startup type to the given type.\n"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
|
||||||
DWORD status = 0;
|
|
||||||
int level = 0;
|
|
||||||
if (argc < 3) {
|
|
||||||
usage();
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
LoadDriverInit();
|
|
||||||
if (strcmp(argv[1], "start") == 0) {
|
|
||||||
printf("starting %s... ", argv[2]);
|
|
||||||
status = DriverStart(argv[2]);
|
|
||||||
if ( status != OKAY) {
|
|
||||||
printf("start failed (status %ld):\n", status);
|
|
||||||
level = 1;
|
|
||||||
} else {
|
|
||||||
printf("ok.\n");
|
|
||||||
}
|
|
||||||
} else if (strcmp(argv[1], "stop") == 0) {
|
|
||||||
printf("stoping %s... ", argv[2]);
|
|
||||||
status = DriverStop(argv[2]);
|
|
||||||
if ( status != OKAY) {
|
|
||||||
printf("stop failed (status %ld):\n", status);
|
|
||||||
level = 1;
|
|
||||||
} else {
|
|
||||||
printf("ok.\n");
|
|
||||||
}
|
|
||||||
} else if (strcmp(argv[1], "install") == 0) {
|
|
||||||
char path[MAX_PATH*2];
|
|
||||||
if (argc<4) {
|
|
||||||
char cwd[MAX_PATH];
|
|
||||||
getcwd(cwd, sizeof cwd);
|
|
||||||
sprintf(path, "%s\\%s.sys", cwd, argv[2]);
|
|
||||||
} else {
|
|
||||||
strncpy(path, argv[3], MAX_PATH);
|
|
||||||
}
|
|
||||||
if (exists(path)) {
|
|
||||||
printf("installing %s from %s... ", argv[2], path);
|
|
||||||
status = DriverInstall(path, argv[2]);
|
|
||||||
if ( status != OKAY) {
|
|
||||||
printf("install failed (status %ld):\n", status);
|
|
||||||
level = 2;
|
|
||||||
} else {
|
|
||||||
printf("ok.\n");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
printf("install failed, file not found: %s\n", path);
|
|
||||||
level = 1;
|
|
||||||
}
|
|
||||||
} else if (strcmp(argv[1], "remove") == 0) {
|
|
||||||
printf("removing %s... ", argv[2]);
|
|
||||||
status = DriverRemove(argv[2]);
|
|
||||||
if ( status != OKAY) {
|
|
||||||
printf("remove failed (status %ld):\n", status);
|
|
||||||
level = 1;
|
|
||||||
} else {
|
|
||||||
printf("ok.\n");
|
|
||||||
}
|
|
||||||
} else if (strcmp(argv[1], "status") == 0) {
|
|
||||||
printf("status of %s:\n", argv[2]);
|
|
||||||
status = DriverStatus(argv[2]);
|
|
||||||
if ( status != OKAY) {
|
|
||||||
printf("stat failed (status %ld):\n", status);
|
|
||||||
level = 1;
|
|
||||||
} else {
|
|
||||||
printf("ok.\n");
|
|
||||||
}
|
|
||||||
} else if (strcmp(argv[1], "starttype") == 0) {
|
|
||||||
if (argc < 4) {
|
|
||||||
printf("Error: need start type (string) as argument.\n");
|
|
||||||
level = 2;
|
|
||||||
} else {
|
|
||||||
DWORD type = 0;
|
|
||||||
printf("set start type of %s to %s... ", argv[2], argv[3]);
|
|
||||||
if (strcmp(argv[1], "boot") == 0) {
|
|
||||||
type = SERVICE_BOOT_START;
|
|
||||||
} else if (strcmp(argv[3], "system") == 0) {
|
|
||||||
type = SERVICE_SYSTEM_START;
|
|
||||||
} else if (strcmp(argv[3], "auto") == 0) {
|
|
||||||
type = SERVICE_AUTO_START;
|
|
||||||
} else if (strcmp(argv[3], "manual") == 0) {
|
|
||||||
type = SERVICE_DEMAND_START;
|
|
||||||
} else if (strcmp(argv[3], "disabled") == 0) {
|
|
||||||
type = SERVICE_DISABLED;
|
|
||||||
} else {
|
|
||||||
printf("unknown type\n");
|
|
||||||
level = 1;
|
|
||||||
}
|
|
||||||
if (level == 0) {
|
|
||||||
status = DriverStartType(argv[2], type);
|
|
||||||
if ( status != OKAY) {
|
|
||||||
printf("set start type failed (status %ld):\n", status);
|
|
||||||
level = 1;
|
|
||||||
} else {
|
|
||||||
printf("ok.\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
usage();
|
|
||||||
level = 1;
|
|
||||||
}
|
|
||||||
if (status) DisplayErrorText(status);
|
|
||||||
LoadDriverCleanup();
|
|
||||||
exit(level);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DWORD LoadDriverInit(void) {
|
|
||||||
// connect to local service control manager
|
|
||||||
if ((hSCMan = OpenSCManager(NULL, NULL,
|
|
||||||
SC_MANAGER_ALL_ACCESS)) == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return OKAY;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LoadDriverCleanup(void) {
|
|
||||||
if (hSCMan != NULL) CloseServiceHandle(hSCMan);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**-----------------------------------------------------**/
|
|
||||||
DWORD DriverInstall(LPSTR lpPath, LPSTR lpDriver) {
|
|
||||||
BOOL dwStatus = OKAY;
|
|
||||||
SC_HANDLE hService = NULL;
|
|
||||||
|
|
||||||
// add to service control manager's database
|
|
||||||
if ((hService = CreateService(hSCMan, lpDriver,
|
|
||||||
lpDriver, SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER,
|
|
||||||
SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, lpPath,
|
|
||||||
NULL, NULL, NULL, NULL, NULL)) == NULL)
|
|
||||||
dwStatus = GetLastError();
|
|
||||||
else CloseServiceHandle(hService);
|
|
||||||
|
|
||||||
return dwStatus;
|
|
||||||
} // DriverInstall
|
|
||||||
|
|
||||||
/**-----------------------------------------------------**/
|
|
||||||
DWORD DriverStart(LPSTR lpDriver) {
|
|
||||||
BOOL dwStatus = OKAY;
|
|
||||||
SC_HANDLE hService = NULL;
|
|
||||||
|
|
||||||
// get a handle to the service
|
|
||||||
if ((hService = OpenService(hSCMan, lpDriver,
|
|
||||||
SERVICE_ALL_ACCESS)) != NULL)
|
|
||||||
{
|
|
||||||
// start the driver
|
|
||||||
if (!StartService(hService, 0, NULL))
|
|
||||||
dwStatus = GetLastError();
|
|
||||||
} else dwStatus = GetLastError();
|
|
||||||
|
|
||||||
if (hService != NULL) CloseServiceHandle(hService);
|
|
||||||
return dwStatus;
|
|
||||||
} // DriverStart
|
|
||||||
|
|
||||||
/**-----------------------------------------------------**/
|
|
||||||
DWORD DriverStop(LPSTR lpDriver)
|
|
||||||
{
|
|
||||||
BOOL dwStatus = OKAY;
|
|
||||||
SC_HANDLE hService = NULL;
|
|
||||||
SERVICE_STATUS serviceStatus;
|
|
||||||
|
|
||||||
// get a handle to the service
|
|
||||||
if ((hService = OpenService(hSCMan, lpDriver,
|
|
||||||
SERVICE_ALL_ACCESS)) != NULL)
|
|
||||||
{
|
|
||||||
// stop the driver
|
|
||||||
if (!ControlService(hService, SERVICE_CONTROL_STOP,
|
|
||||||
&serviceStatus))
|
|
||||||
dwStatus = GetLastError();
|
|
||||||
} else dwStatus = GetLastError();
|
|
||||||
|
|
||||||
if (hService != NULL) CloseServiceHandle(hService);
|
|
||||||
return dwStatus;
|
|
||||||
} // DriverStop
|
|
||||||
|
|
||||||
/**-----------------------------------------------------**/
|
|
||||||
DWORD DriverRemove(LPSTR lpDriver)
|
|
||||||
{
|
|
||||||
BOOL dwStatus = OKAY;
|
|
||||||
SC_HANDLE hService = NULL;
|
|
||||||
|
|
||||||
// get a handle to the service
|
|
||||||
if ((hService = OpenService(hSCMan, lpDriver,
|
|
||||||
SERVICE_ALL_ACCESS)) != NULL)
|
|
||||||
{ // remove the driver
|
|
||||||
if (!DeleteService(hService))
|
|
||||||
dwStatus = GetLastError();
|
|
||||||
} else dwStatus = GetLastError();
|
|
||||||
|
|
||||||
if (hService != NULL) CloseServiceHandle(hService);
|
|
||||||
return dwStatus;
|
|
||||||
} // DriverRemove
|
|
||||||
|
|
||||||
/**-----------------------------------------------------**/
|
|
||||||
////extensions by Lch
|
|
||||||
/**-----------------------------------------------------**/
|
|
||||||
DWORD DriverStatus(LPSTR lpDriver) {
|
|
||||||
BOOL dwStatus = OKAY;
|
|
||||||
SC_HANDLE hService = NULL;
|
|
||||||
DWORD dwBytesNeeded;
|
|
||||||
|
|
||||||
// get a handle to the service
|
|
||||||
if ((hService = OpenService(hSCMan, lpDriver,
|
|
||||||
SERVICE_ALL_ACCESS)) != NULL)
|
|
||||||
{
|
|
||||||
LPQUERY_SERVICE_CONFIG lpqscBuf;
|
|
||||||
//~ LPSERVICE_DESCRIPTION lpqscBuf2;
|
|
||||||
// Allocate a buffer for the configuration information.
|
|
||||||
if ((lpqscBuf = (LPQUERY_SERVICE_CONFIG) LocalAlloc(
|
|
||||||
LPTR, 4096)) != NULL)
|
|
||||||
{
|
|
||||||
//~ if ((lpqscBuf2 = (LPSERVICE_DESCRIPTION) LocalAlloc(
|
|
||||||
//~ LPTR, 4096)) != NULL)
|
|
||||||
{
|
|
||||||
// Get the configuration information.
|
|
||||||
if (QueryServiceConfig(
|
|
||||||
hService,
|
|
||||||
lpqscBuf,
|
|
||||||
4096,
|
|
||||||
&dwBytesNeeded) //&&
|
|
||||||
//~ QueryServiceConfig2(
|
|
||||||
//~ hService,
|
|
||||||
//~ SERVICE_CONFIG_DESCRIPTION,
|
|
||||||
//~ lpqscBuf2,
|
|
||||||
//~ 4096,
|
|
||||||
//~ &dwBytesNeeded
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// Print the configuration information.
|
|
||||||
printf("Type: [0x%02lx] ", lpqscBuf->dwServiceType);
|
|
||||||
switch (lpqscBuf->dwServiceType) {
|
|
||||||
case SERVICE_WIN32_OWN_PROCESS:
|
|
||||||
printf("The service runs in its own process.");
|
|
||||||
break;
|
|
||||||
case SERVICE_WIN32_SHARE_PROCESS:
|
|
||||||
printf("The service shares a process with other services.");
|
|
||||||
break;
|
|
||||||
case SERVICE_KERNEL_DRIVER:
|
|
||||||
printf("Kernel driver.");
|
|
||||||
break;
|
|
||||||
case SERVICE_FILE_SYSTEM_DRIVER:
|
|
||||||
printf("File system driver.");
|
|
||||||
break;
|
|
||||||
case SERVICE_INTERACTIVE_PROCESS:
|
|
||||||
printf("The service can interact with the desktop.");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
printf("Unknown type.");
|
|
||||||
}
|
|
||||||
printf("\nStart Type: [0x%02lx] ", lpqscBuf->dwStartType);
|
|
||||||
switch (lpqscBuf->dwStartType) {
|
|
||||||
case SERVICE_BOOT_START:
|
|
||||||
printf("Boot");
|
|
||||||
break;
|
|
||||||
case SERVICE_SYSTEM_START:
|
|
||||||
printf("System");
|
|
||||||
break;
|
|
||||||
case SERVICE_AUTO_START:
|
|
||||||
printf("Automatic");
|
|
||||||
break;
|
|
||||||
case SERVICE_DEMAND_START:
|
|
||||||
printf("Manual");
|
|
||||||
break;
|
|
||||||
case SERVICE_DISABLED:
|
|
||||||
printf("Disabled");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
printf("Unknown.");
|
|
||||||
}
|
|
||||||
printf("\nError Control: [0x%02lx] ", lpqscBuf->dwErrorControl);
|
|
||||||
switch (lpqscBuf->dwErrorControl) {
|
|
||||||
case SERVICE_ERROR_IGNORE:
|
|
||||||
printf("IGNORE: Ignore.");
|
|
||||||
break;
|
|
||||||
case SERVICE_ERROR_NORMAL:
|
|
||||||
printf("NORMAL: Display a message box.");
|
|
||||||
break;
|
|
||||||
case SERVICE_ERROR_SEVERE:
|
|
||||||
printf("SEVERE: Restart with last-known-good config.");
|
|
||||||
break;
|
|
||||||
case SERVICE_ERROR_CRITICAL:
|
|
||||||
printf("CRITICAL: Restart w/ last-known-good config.");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
printf("Unknown.");
|
|
||||||
}
|
|
||||||
printf("\nBinary path: %s\n", lpqscBuf->lpBinaryPathName);
|
|
||||||
|
|
||||||
if (lpqscBuf->lpLoadOrderGroup != NULL)
|
|
||||||
printf("Load order grp: %s\n", lpqscBuf->lpLoadOrderGroup);
|
|
||||||
if (lpqscBuf->dwTagId != 0)
|
|
||||||
printf("Tag ID: %ld\n", lpqscBuf->dwTagId);
|
|
||||||
if (lpqscBuf->lpDependencies != NULL)
|
|
||||||
printf("Dependencies: %s\n", lpqscBuf->lpDependencies);
|
|
||||||
if (lpqscBuf->lpServiceStartName != NULL)
|
|
||||||
printf("Start Name: %s\n", lpqscBuf->lpServiceStartName);
|
|
||||||
//~ if (lpqscBuf2->lpDescription != NULL)
|
|
||||||
//~ printf("Description: %s\n", lpqscBuf2->lpDescription);
|
|
||||||
}
|
|
||||||
//~ LocalFree(lpqscBuf2);
|
|
||||||
}
|
|
||||||
LocalFree(lpqscBuf);
|
|
||||||
} else {
|
|
||||||
dwStatus = GetLastError();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dwStatus = GetLastError();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hService != NULL) CloseServiceHandle(hService);
|
|
||||||
return dwStatus;
|
|
||||||
} // DriverStatus
|
|
||||||
|
|
||||||
/**-----------------------------------------------------**/
|
|
||||||
DWORD DriverStartType(LPSTR lpDriver, DWORD dwStartType) {
|
|
||||||
BOOL dwStatus = OKAY;
|
|
||||||
SC_HANDLE hService = NULL;
|
|
||||||
|
|
||||||
SC_LOCK sclLock;
|
|
||||||
LPQUERY_SERVICE_LOCK_STATUS lpqslsBuf;
|
|
||||||
DWORD dwBytesNeeded;
|
|
||||||
|
|
||||||
// Need to acquire database lock before reconfiguring.
|
|
||||||
sclLock = LockServiceDatabase(hSCMan);
|
|
||||||
|
|
||||||
// If the database cannot be locked, report the details.
|
|
||||||
if (sclLock == NULL) {
|
|
||||||
// Exit if the database is not locked by another process.
|
|
||||||
if (GetLastError() == ERROR_SERVICE_DATABASE_LOCKED) {
|
|
||||||
|
|
||||||
// Allocate a buffer to get details about the lock.
|
|
||||||
lpqslsBuf = (LPQUERY_SERVICE_LOCK_STATUS) LocalAlloc(
|
|
||||||
LPTR, sizeof(QUERY_SERVICE_LOCK_STATUS)+256);
|
|
||||||
if (lpqslsBuf != NULL) {
|
|
||||||
// Get and print the lock status information.
|
|
||||||
if (QueryServiceLockStatus(
|
|
||||||
hSCMan,
|
|
||||||
lpqslsBuf,
|
|
||||||
sizeof(QUERY_SERVICE_LOCK_STATUS)+256,
|
|
||||||
&dwBytesNeeded) )
|
|
||||||
{
|
|
||||||
if (lpqslsBuf->fIsLocked) {
|
|
||||||
printf("Locked by: %s, duration: %ld seconds\n",
|
|
||||||
lpqslsBuf->lpLockOwner,
|
|
||||||
lpqslsBuf->dwLockDuration
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
printf("No longer locked\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LocalFree(lpqslsBuf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dwStatus = GetLastError();
|
|
||||||
} else {
|
|
||||||
// The database is locked, so it is safe to make changes.
|
|
||||||
// Open a handle to the service.
|
|
||||||
hService = OpenService(
|
|
||||||
hSCMan, // SCManager database
|
|
||||||
lpDriver, // name of service
|
|
||||||
SERVICE_CHANGE_CONFIG
|
|
||||||
); // need CHANGE access
|
|
||||||
if (hService != NULL) {
|
|
||||||
// Make the changes.
|
|
||||||
if (!ChangeServiceConfig(
|
|
||||||
hService, // handle of service
|
|
||||||
SERVICE_NO_CHANGE, // service type: no change
|
|
||||||
dwStartType, // change service start type
|
|
||||||
SERVICE_NO_CHANGE, // error control: no change
|
|
||||||
NULL, // binary path: no change
|
|
||||||
NULL, // load order group: no change
|
|
||||||
NULL, // tag ID: no change
|
|
||||||
NULL, // dependencies: no change
|
|
||||||
NULL, // account name: no change
|
|
||||||
NULL, // password: no change
|
|
||||||
NULL) ) // display name: no change
|
|
||||||
{
|
|
||||||
dwStatus = GetLastError();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Release the database lock.
|
|
||||||
UnlockServiceDatabase(sclLock);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hService != NULL) CloseServiceHandle(hService);
|
|
||||||
return dwStatus;
|
|
||||||
} // DriverStartType
|
|
|
@ -1,20 +0,0 @@
|
||||||
#ifndef LOADDRV_H
|
|
||||||
#define LOADDRV_H
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#define OKAY 0
|
|
||||||
#define UNEXPECTED_ERROR 9999
|
|
||||||
|
|
||||||
//prototypes
|
|
||||||
DWORD LoadDriverInit(void);
|
|
||||||
void LoadDriverCleanup(void);
|
|
||||||
DWORD DriverInstall(LPSTR, LPSTR);
|
|
||||||
DWORD DriverStart(LPSTR);
|
|
||||||
DWORD DriverStop(LPSTR);
|
|
||||||
DWORD DriverRemove(LPSTR);
|
|
||||||
DWORD DriverStatus(LPSTR);
|
|
||||||
DWORD DriverStartType(LPSTR, DWORD);
|
|
||||||
#endif //LOADDRV_H
|
|
||||||
|
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
@set DIRVERNAME=giveio
|
|
||||||
|
|
||||||
@loaddrv stop %DIRVERNAME%
|
|
||||||
@if errorlevel 2 goto error
|
|
||||||
|
|
||||||
@loaddrv remove %DIRVERNAME%
|
|
||||||
@if errorlevel 1 goto error
|
|
||||||
|
|
||||||
@goto exit
|
|
||||||
|
|
||||||
:error
|
|
||||||
@echo ERROR: Deinstallation of %DIRVERNAME% failed
|
|
||||||
|
|
||||||
:exit
|
|
|
@ -1,12 +0,0 @@
|
||||||
@set DIRVERNAME=giveio
|
|
||||||
|
|
||||||
@loaddrv status %DIRVERNAME%
|
|
||||||
@if errorlevel 1 goto error
|
|
||||||
|
|
||||||
@goto exit
|
|
||||||
|
|
||||||
:error
|
|
||||||
@echo ERROR: Status querry for %DIRVERNAME% failed
|
|
||||||
|
|
||||||
:exit
|
|
||||||
|
|
Loading…
Reference in New Issue