From:	SMTP%"roman@softwinter.com" 27-JAN-1998 17:25:20.58
To:	"'Paul Sanders'" <paulsan@MICROSOFT.com>,        "ntfsd@atria.com" <ntfsd@atria.com>,        "'Jonathan M Daley'" <jondaley+@andrew.cmu.edu>
CC:	
Subj:	RE: [ntfsd] Keyboard hook

-----BEGIN PGP SIGNED MESSAGE-----

Hello All,

Keyboard filter possible to unload, there way -it not clear - due some
limitation in class driver:
should run on signle CPU machine and with standard mouse class driver.


You can use it on your own risk :) 

In DriverEntry:

	HookDeviceObject = kbdDevice = NULL;
	AttachFilter( DriverObject, L"\\Device\\KeyboardClass0",  
			&kbdDevice, &HookDeviceObject, FILE_DEVICE_KEYBOARD);
	if (kbdDevice) CancelPendings(kbdDevice);

In UnloadDriver:

		if (kbdDevice) IoDetachDevice(kbdDevice);
		//possible racing condition
			if (kbdDevice) CancelPendings(kbdDevice);
			kbdDevice = NULL;
			if (HookDeviceObject) IoDeleteDevice(HookDeviceObject);
		HookDeviceObject = NULL;

- -------------------------------------
struct KeyboardExtention {
    BOOLEAN RequestIsPending;
    BOOLEAN CleanupWasInitiated;
    BOOLEAN TrustedSubsystemConnected;
    ULONG InputCount;
};

static NTSTATUS IoCompletionClear(PDEVICE_OBJECT DeviceObject,
                                PIRP Irp,
                                PVOID Context)
{
    // Copy the status information back into the "user" IOSB.
    *Irp->UserIosb = Irp->IoStatus;
    
    // Set the user event - wakes up the mainline code doing this.
    KeSetEvent(Irp->UserEvent, 0, FALSE);

    // Free the IRP now that we are done with it.

    IoFreeIrp(Irp);
    
    // We return STATUS_MORE_PROCESSING_REQUIRED because this "magic"
return value
    // tells the I/O Manager that additional processing will be done
by this driver
    // to the IRP - in fact, it might (as it is in this case) already
BE done - and
    // the IRP cannot be completed.
    return STATUS_MORE_PROCESSING_REQUIRED;
}


NTSTATUS CancelPendings(PDEVICE_OBJECT deviceObject)
{
    PIRP irp;
    KEVENT event;
	IO_STATUS_BLOCK IoStatusBlock;
    PIO_STACK_LOCATION ioStackLocation;
	FILE_OBJECT FileObject;
	FileObject.FsContext = (PVOID) 1; //small fake 


	if (KeGetCurrentIrql()!=PASSIVE_LEVEL)
	{
		DbgPrint(("XXDrv: PASSIVE_LEVEL Requested!\n"));
	}

    // Set up the event we'll use.
    KeInitializeEvent(&event, SynchronizationEvent, FALSE);
    
    // Allocate and build the IRP we'll be sending to the FSD.
    irp = IoAllocateIrp(deviceObject->StackSize, FALSE);
    if (!irp) 
	{
        // Allocation failed, presumably due to memory allocation
failure.
        return STATUS_INSUFFICIENT_RESOURCES;
    }
    
    irp->MdlAddress = NULL;
    irp->UserEvent = &event;
    irp->UserIosb = &IoStatusBlock;
    irp->Tail.Overlay.Thread = PsGetCurrentThread();
    irp->Tail.Overlay.OriginalFileObject= NULL;
    irp->RequestorMode = KernelMode;
    // Set up the next I/O stack location.  These are the parameters
    // that will be passed to the underlying driver.
    ioStackLocation = IoGetNextIrpStackLocation(irp);
    ioStackLocation->MajorFunction = IRP_MJ_CLEANUP;
    ioStackLocation->MinorFunction = 0;
    ioStackLocation->DeviceObject = deviceObject;
    ioStackLocation->FileObject = &FileObject;
    // use a completion routine to keep the I/O Manager from doing
    // "cleanup" on our IRP - like freeing our MDL.
    IoSetCompletionRoutine(irp, IoCompletionClear, 0, TRUE, TRUE,
TRUE);

    // Send it on.  Ignore the return code.

// I should run alone!!!!!!

	KIRQL oldirql=KeRaiseIrqlToDpcLevel(); 

	(void) IoCallDriver(deviceObject, irp);

	KeyboardExtention *ext;
	ext=(KeyboardExtention *)deviceObject->DeviceExtension;
	ext->CleanupWasInitiated = FALSE;
    
	KeLowerIrql(oldirql);
    // Wait for the I/O to complete.

    KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, 0);
    // Done.  Return results are in the io status block.
    return IoStatusBlock.Status;
}


NTSTATUS AttachFilter( IN PDRIVER_OBJECT DriverObject, WCHAR
*DeviceName, PDEVICE_OBJECT *device, PDEVICE_OBJECT *HookDeviceObject,
DEVICE_TYPE dtype)
{
    UNICODE_STRING       ntUnicodeString;
    NTSTATUS             status;
    // Only hook onto the first keyboard's chain.
    RtlInitUnicodeString( &ntUnicodeString, DeviceName );
    // Create device object for the filter
    status = IoCreateDevice( DriverObject,
			     sizeof(ENCHOTKEY_EXTENSION),
			     NULL,
			     dtype,
			     0,
			     TRUE,
			     HookDeviceObject );
	
    if( !NT_SUCCESS(status) ) 
	{
	 DbgPrint((": Keyboard hook failed to create device!\n"));
	 return STATUS_SUCCESS;
    }

	ENCHOTKEY_EXTENSION *	HotKeyExt=(ENCHOTKEY_EXTENSION
*)(*HookDeviceObject)->DeviceExtension;

	HotKeyExt->TheDevice=HotKey;
	HotKeyExt->deviceObject = *HookDeviceObject;
    //
    // Keyboard uses buffered I/O so we must as well.
    //
    (*HookDeviceObject)->Flags |= DO_BUFFERED_IO;
    //
    // Attach to the keyboard chain.
    //
    status = IoAttachDevice( *HookDeviceObject, &ntUnicodeString,
device );
    if( !NT_SUCCESS(status) ) 
	{
	 DiskDump(DDIAG1, (": Connect with driver failed!\n"));
	 IoDeleteDevice( *HookDeviceObject );
	 *HookDeviceObject = NULL;
	 return status;
    }

    //
    // Done! Just free our string and be on our way...
    //

    DiskDump(DDIAG1, (": Successfully connected to keyboard
device\n"));
    return STATUS_SUCCESS;
}




NTSTATUS HotKeyDispatchGeneral(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP           Irp )
{
	PIO_STACK_LOCATION currentIrpStack =
IoGetCurrentIrpStackLocation(Irp);
    PIO_STACK_LOCATION nextIrpStack    =
IoGetNextIrpStackLocation(Irp);
    // Push params down for keyboard class driver.
    *nextIrpStack = *currentIrpStack;
    // Set the completion callback, so we can "frob" the keyboard
data.
    if (nextIrpStack->MajorFunction == IRP_MJ_READ)
		IoSetCompletionRoutine( Irp, HotKeyReadComplete, DeviceObject, TRUE,
FALSE, FALSE );
    // Return the results of the call to the keyboard class driver.
    return IoCallDriver( kbdDevice, Irp );
}

// Gets control after a read operation has completed.
NTSTATUS HotKeyReadComplete( IN PDEVICE_OBJECT DeviceObject, IN PIRP
Irp,
				IN PVOID Context )
{
    PIO_STACK_LOCATION        IrpSp;
    PKEYBOARD_INPUT_DATA      KeyData;
    // Request completed - look at the result.
    IrpSp = IoGetCurrentIrpStackLocation( Irp );
    if( NT_SUCCESS( Irp->IoStatus.Status ) ) 
	{
  		KeyData = (PKEYBOARD_INPUT_DATA)Irp->AssociatedIrp.SystemBuffer;
		DbgPrint("Checking keys bla bla bla!!!!!");
    }
    if( Irp->PendingReturned )    IoMarkIrpPending( Irp );
    return Irp->IoStatus.Status;

}

Have a nice day,

Roman Rutman
roman@softwinter.com

seNTry 2020 - transparent disk encryption software -
http://www.softwinter.com


On Tuesday, January 27, 1998 6:45 PM, Paul Sanders
[SMTP:paulsan@MICROSOFT.com] wrote:
> Jonathan, I'm assuming that your driver is based on the one from
> www.ntinternals.com or the one on our website.  I don't believe you
can stop
> this filter driver once it is inserted.  I know you can't stop the
one from
> us and I think the same holds true for Mark's sample.
> 
> A driver is not mandatory for this.  There are user-mode solutions,
but I
> know a lot of people prefer a kernel-mode solution.  A good rule of
thumb is
> don't use a driver if a user-mode soltuion is available.  This is
not set in
> stone and I know that keyboard filtering is one area that people
like the
> driver approach.  I 'think' the SDK world is easier now in this
realm.  I
> 'think' that some previously undocumented features have now been
documented
> that make this easier, but I honestly can't remember what they are. 
You
> might ask some SDK types about keyboard filtering.  I might be wrong
on
> this, but something is in the back of my head that makes me think
they have
> improved it, but my memory is failing me right now.
> 
> -Paul
> 
> > ----------
> > From: 	Jonathan M Daley[SMTP:jondaley+@andrew.cmu.edu]
> > Sent: 	Tuesday, January 27, 1998 8:32 AM
> > To: 	ntfsd@atria.com
> > Subject: 	[ntfsd] Keyboard hook
> > 
> >    I am writing a driver to trap keyboard strokes and change their
> > values.  We are trying to diable ctl-alt-del and other such system
> > calls, and it seems that a driver is the only way to go.  However,
this
> > is my first driver under NT, and am having a problem shutting down
my
> > driver.  I have it set up to start and stop via the net start
command,
> > and when I type net stop, it closes the driver, and says that the
> > command has completed successfully, but unfortunately, the driver
has
> > not let go of its keyboard hook, and therefore crashed on the next
> > keyboard stroke.
> >    In my driver entry function I declare:
> >      DriverObject->DriverUnload = KeyDriverUnload;
> > 
> > And in my KeyDriverUnload(IN PDRIVER_OBJECT DriverObject)
function, I
> > run IoDetachDevice and IoDeleteDevice.
> > 
> > Any ideas what I could be forgetting?   Thanks.
> > 
> > 
> > -Jonathan M. Daley
> > http://www.andrew.cmu.edu/~jondaley
> > 
> > 
> >  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
> > [ To unsubscribe, send email to ntfsd-request@atria.com with body
> > UNSUBSCRIBE (the subject is ignored). ]
> > 
>  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
> [ To unsubscribe, send email to ntfsd-request@atria.com with body
> UNSUBSCRIBE (the subject is ignored). ]
> 

-----BEGIN PGP SIGNATURE-----
Version: PGP for Business Security 5.5

iQCVAwUBNM4b+BFtKtoCwwQZAQEEJwQAuMMnAuhTjsmAmdru1ZfHa7zoH87mulXE
ksyCV7cjKcbPu8KoKq0A2YmPWDVe+cjMUNxgtsSy35UkeznZM54nfyTfKGLFIjlr
WycbN45YM9rXA/ZzDZOgH446T4MhZijM4+VtfVO0Ht6qaeNWKc4Wy0yDWCe4HTPd
QsxG8QAtC4Q=
=Pe9U
-----END PGP SIGNATURE-----

 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[ To unsubscribe, send email to ntfsd-request@atria.com with body
UNSUBSCRIBE (the subject is ignored). ]
================== RFC 822 Headers ==================
Return-Path: owner-ntfsd@atria.com
Received: by norlmn.gce.com (UCX X4.2-14, OpenVMS E7.1-1H1 Alpha);
	Tue, 27 Jan 1998 17:25:06 -0500
Received: by gw.atria.com id <OAA26916@gw.atria.com> Tue, 27 Jan 1998 14:40:30 -0500    
Received: from noodle.mentasoftware.com by gw.atria.com id <OAA26882@gw.atria.com> Tue, 27 Jan 1998 14:40:22 -0500    
Received: from test_pc ([207.232.21.21]) by noodle.mentasoftware.com
          (Netscape Messaging Server 3.01)  with SMTP id 96;
          Tue, 27 Jan 1998 21:37:51 +0200
Received: by localhost with Microsoft MAPI; Tue, 27 Jan 1998 21:40:09 +0200
Message-ID: <01BD2B6C.23BBBB50.roman@softwinter.com>
From: "Roman Rutman (sw)" <roman@softwinter.com>
Reply-To: "roman@softwinter.com" <roman@softwinter.com>
To: "'Paul Sanders'" <paulsan@MICROSOFT.com>,
        "ntfsd@atria.com" <ntfsd@atria.com>,
        "'Jonathan M Daley'" <jondaley+@andrew.cmu.edu>
Subject: RE: [ntfsd] Keyboard hook
Date: Tue, 27 Jan 1998 21:40:07 +0200
Importance: high
X-Priority: 1 (Highest)
Organization: Soft Winter
X-Mailer: Microsoft Internet E-mail/MAPI - 8.0.0.4211
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Sender: owner-ntfsd@atria.com
Precedence: bulk
X-Majordomo-Taboo: ntfsd
