	             _         __ _               _                        _ 
	            | |       / _(_)             | |                      | |
	  __ _ _   _| |_ ___ | |_ _ _ __ ___     | | _____ _ __ _ __   ___| |
	 / _` | | | | __/ _ \|  _| | '__/ _ \    | |/ / _ \ '__| '_ \ / _ \ |
	| (_| | |_| | || (_) | | | | | |  __/    |   <  __/ |  | | | |  __/ |
	 \__,_|\__,_|\__\___/|_| |_|_|  \___|    |_|\_\___|_|  |_| |_|\___|_|
                                                                  


    -- [ programmation kernel pour un autofire !
 


	a/ readme
	b/ codes sources 
	c/ annexes pour la suite des codes


Place a l'article!

	a/ readme

I - c'est quoi cette bete l ?
------------------------------

Cette bestiole, c'est une petite dmo de programmation noyau
pour windows. Le driver s'accroche  la gestion de la souris,
et simule un autofire comme sur nos bons vieux joysticks. Quand
vous cliquez gauche et laissez appuy, le driver envoie des
signaux (pas clic) / (clic) en rafale.

Utilit ? Rendre impossible les parties de solitaire, dja.
Forcment, le cliquer-glisser ne marche plus car le clic long
se transforme en rafale de clic courts. Rendre galre la
navigation sous windows, vous lancez des applis au lieu de
slectionner l'icone et des choses du genre.

Plus srieusement, un ami m'avait demand un truc de ce genre
il y a un moment, pour... tricher aux FPS ! pour les armes qui
grent mal le rate of fire maximal, c'est pas mal du tout.
Essayez dans un hlico  Battlefield 2, c'est marrant.



II - limitations et bugs
------------------------

Je ne suis pas une brute de programmation noyau.

Voila, c'est dit :)

Donc c'est plus histoire de faire profiter de mes petits dlires
persos. Le programme est tributaire des messages souris existants.
Ca veut dire que quand la souris ne bouge pas, pas de message, donc
l'autofire n'agit pas. C'est comme orangina, il faut secouer pour
que ca pete. En jeu, ca ne gene pas car la souris reste rarement
immobile, pour viser ou piloter ca bouge tout le temps.

Autre limitation : je n'ai pas encore trouv comment ne pas faire
planter le driver lorsqu'on veut le dcharger. Donc quand vous voudrez
cliquer sur "arreter" pour reprendre une utilisation normale de votre pc...
attendez vous  un plantage. Et quand un driver plante, c'est pas une
belle boite de dialogue sympa, c'est un ecran bleu. Dsol :p


III - utilisation
-----------------

Appli est mon centre de test de drivers. C'est pas fait pour etre
super convivial, dsol. Pour vous viter des tracas, vla la marche
 suivre pour aller au plus simple :

1) copiez les 2 fichiers du rpertoire Toys vers c:\
2) lancez appli.exe
3) cliquez sur enregistrement
4) cliquez sur lancement

5) et quand vous en aurez marre, cliquez sur arrt
6) ensuite, ou apres un reboot, revenez cliquer sur suppression

voila. Si,  lecteur, tu as des infos sur comment grer ces !#@!!%$ IRP
de maniere  ce que ca ne plante plus  la fin, sache que je suivrais
tes conseils avec gratitude !





	b/ codes sources 



				- driver_management.cpp - 

#include "stdafx.h"
#include "appli.h"
#include "appliDlg.h"

#include "Winsvc.h"
#include "driver_management.h"
#include "Windows.h"

//Vrifie le status du driver ==========================================================
int verifie_status (char* nom_court)
{
	//Ouvre le service manager
	HANDLE hSCManager = OpenSCManager(
		NULL,										//lpMachineName
		NULL,										//lpDatabaseName
		SC_MANAGER_ENUMERATE_SERVICE				//dwDesiredAccess
		);

	//Ouvre le service
	HANDLE hFile = OpenService(
		 hSCManager,
		 nom_court,
		 SC_MANAGER_ENUMERATE_SERVICE
		 );
         
	//Si on y a pas accd, alors cassos !
	if(hFile == NULL)
	{
		CloseServiceHandle(hSCManager);
		return DRIVER_MANAGER_STATUS_ABSENT;
	}

	//Chope les informations sur le driver
	SERVICE_STATUS les_infos;
	QueryServiceStatus(
		hFile,								//hService
		&les_infos							//lpServiceStatus
		);

	//Nettoyage
	CloseServiceHandle(hSCManager);
	CloseServiceHandle(hFile);

	//Et selon les infos, cassos
	switch (les_infos.dwCurrentState)
	{
		case SERVICE_STOPPED:
			return DRIVER_MANAGER_STATUS_INACTIF;
		default:
			return DRIVER_MANAGER_STATUS_ACTIF;
	}
}


// Teste l'existance d'un fichier ======================================================
BOOL IsFileExist(LPSTR lpszFilename)
{
	DWORD dwAttr = GetFileAttributes(lpszFilename);
	if (dwAttr == 0xffffffff)
		return FALSE;
	else 
		return TRUE;
}


// Appel  IO Ctrl =====================================================================
bool ioctrl_driver (char* nom_dos, char*message, DWORD io_type, char*buffer, unsigned long *taille )
{
	char buffer1[1024];
	DWORD taille1;
	
	//Calcule la taille  envoyer
	taille1 = strlen(message);
	if (taille1 > 1023)
		taille1 = 1023;
		
	//Et recopie le message venant de ioctrl dans le buffer
	memset(buffer1,0, 1024);
	memcpy(buffer1,message,taille1);


	//Accde au driver
	HANDLE hFile = CreateFile(
		 nom_dos, 
         GENERIC_READ | GENERIC_WRITE,
		 0, 
		 NULL, 
         OPEN_EXISTING, 
		 0, 
		 NULL
		 );

	//Si on y a pas accd, alors cassos !
	if(hFile == INVALID_HANDLE_VALUE)
		return false;

	//Sinon initialise le buffer et Action !
	memset(buffer,0, *taille);
	DeviceIoControl(hFile,
                       io_type, 
                       buffer1, 
                       1024, 
                       buffer, 
                       1024, 
                       taille, 
                       NULL);

	//Ferme l'accs au driver
	CloseHandle(hFile);
	return true;
}


// Appel  Write =======================================================================
bool ecris_driver (char* nom_dos, char*message )
{
	//Prpare le buffer d'envoi
	char buffer[1024];
	int taille;
	memset(buffer,0,1024);
	
	//Calcule la taille du message
	taille = strlen(message);
	if (taille > 1023)
		taille = 1023;
		
	//Et recopie le message dans le buffer
	memcpy(buffer,message,taille);

	//Accde au driver
	HANDLE hFile = CreateFile(
		 nom_dos, 
         GENERIC_READ | GENERIC_WRITE,
		 0, 
		 NULL, 
         OPEN_EXISTING, 
		 0, 
		 NULL
		 );

	if (hFile == INVALID_HANDLE_VALUE)
		return false;
 
	//Si on a l'accs, envoie le buffer
	DWORD taille_ecrite;
    WriteFile(hFile, buffer, taille+1, &taille_ecrite, NULL);
	
	//Ferme l'accs au driver
 	CloseHandle(hFile);
	return true;
}

// Appel  Read ========================================================================
bool lis_driver (char* nom_dos, char*buffer, unsigned long *taille )
{
	//Prpare le buffer de lecture
	memset(buffer,0,*taille);
	
	//Accde au driver
	HANDLE hFile = CreateFile(
		 nom_dos, 
         GENERIC_READ | GENERIC_WRITE,
		 0, 
		 NULL, 
         OPEN_EXISTING, 
		 0, 
		 NULL
		 );
 
	if(hFile == INVALID_HANDLE_VALUE)
		return false;
	//Si on y a accd, alors lecture ! taille contiendra alors la taille lue
	ReadFile(hFile, buffer, *taille, taille, NULL);
	
	//Ferme l'accs au driver
	CloseHandle(hFile);
	return true;
}

// Mise en place du pilote dans la base de registre ====================================
int enregistre_driver (char* emplacement, char* nom_court, char* nom_complet, int type)
{

    //Vrifie si le fichier existe
	if (!IsFileExist(emplacement))
		return DRIVER_MANAGER_NO_FILE;
	
	//Ouvre le Service Manager
	HANDLE hSCManager = OpenSCManager(
		NULL,										//lpMachineName
		NULL,										//lpDatabaseName
		SC_MANAGER_CREATE_SERVICE					//dwDesiredAccess
		);
    
	if(!hSCManager)
		return DRIVER_MANAGER_ERROR_SCM;

	int type_value;
	switch (type)
	{
	case 0://A la demande
		type_value = SERVICE_DEMAND_START;
		break;
	case 1://Automatique
		type_value = SERVICE_AUTO_START;
		break;
	case 2://Boot
		type_value = SERVICE_BOOT_START;
		break;
	case 3://Dsactiv
		type_value = SERVICE_DISABLED;
		break;
	case 4://Systme
		type_value = SERVICE_SYSTEM_START;
		break;
	default:
		return DRIVER_MANAGER_ERROR_CREATE;
	}


	
	//Si tout va bien, cr le driver
    HANDLE hService = CreateService(
		hSCManager,									//hSCManager
		nom_court,									//lpServiceName
		nom_complet,								//lpDisplayName
		SERVICE_START | DELETE | SERVICE_STOP,		//dwDesiredAccess
		SERVICE_KERNEL_DRIVER,						//dwServiceType
		SERVICE_DEMAND_START,						//dwStartType
		SERVICE_ERROR_IGNORE,						//dwErrorControl
		emplacement,								//lpBinaryPathName
		NULL,										//lpLoadOrderGroup
		NULL,										//lpdwTagId
		NULL,										//lpDependencies
		NULL,										//lpServiceStartName
		NULL										//lpPassword
		);

	if (!hService)
	{
		CloseServiceHandle(hSCManager);

		if (GetLastError() == ERROR_SERVICE_EXISTS)
			return DRIVER_MANAGER_ERROR_ALREADY;
		else
			return DRIVER_MANAGER_ERROR_CREATE;
	}

	//Nettoie tout ca
    CloseServiceHandle(hService); 
	CloseServiceHandle(hSCManager);
        
    return DRIVER_MANAGER_OK;
}

// Efface le driver du registre ========================================================
int supprime_driver (char* nom_driver)
{

	//Ouvre le Service Manager
	HANDLE hSCManager = OpenSCManager(
		NULL,										//lpMachineName
		NULL,										//lpDatabaseName
		SC_MANAGER_CREATE_SERVICE					//dwDesiredAccess
		);
    
	if(!hSCManager)
		return DRIVER_MANAGER_ERROR_SCM;

	//Si tout va bien, ouvre le driver
	HANDLE hService = OpenService(
		hSCManager,									//hSCManager
		nom_driver,									//lpServiceName
		SERVICE_START | DELETE | SERVICE_STOP		//dwDesiredAccess
		);

	if (!hService)
	{
		CloseServiceHandle(hSCManager);
		return DRIVER_MANAGER_ERROR_ACCESS;
	}


    //L'efface
	if (!DeleteService(hService))
	{
		CloseServiceHandle(hService); 
		CloseServiceHandle(hSCManager);
		return DRIVER_MANAGER_ERROR_DELETE;

	}


	//Nettoie tout ca
    CloseServiceHandle(hService); 
	CloseServiceHandle(hSCManager);
        
    return DRIVER_MANAGER_OK;
}

// Lance le driver =====================================================================
int load_driver (char* nom_driver)
{

	//Ouvre le Service Manager
	HANDLE hSCManager = OpenSCManager(
		NULL,										//lpMachineName
		NULL,										//lpDatabaseName
		SC_MANAGER_CREATE_SERVICE					//dwDesiredAccess
		);
    
	if(!hSCManager)
		return DRIVER_MANAGER_ERROR_SCM;

	//Si tout va bien, ouvre le driver
	HANDLE hService = OpenService(
		hSCManager,									//hSCManager
		nom_driver,									//lpServiceName
		SERVICE_START | DELETE | SERVICE_STOP		//dwDesiredAccess
		);

	if (!hService)
	{
		CloseServiceHandle(hSCManager);
		return DRIVER_MANAGER_ERROR_ACCESS;
	}


    //Le dmarre
	if (!StartService(
			hService,								//hService
			0,										//dwNumServiceArgs
			NULL									//lpServiceArgVectors
			)
		)
	{
		CloseServiceHandle(hService); 
		CloseServiceHandle(hSCManager);
		return DRIVER_MANAGER_ERROR_RUN;

	}


	//Nettoie tout ca
    CloseServiceHandle(hService); 
	CloseServiceHandle(hSCManager);
        
    return DRIVER_MANAGER_OK;
}

//Arrete le driver =====================================================================
int unload_driver (char* nom_driver)
{
	//Ouvre le Service Manager
	HANDLE hSCManager = OpenSCManager(
		NULL,										//lpMachineName
		NULL,										//lpDatabaseName
		SC_MANAGER_CREATE_SERVICE					//dwDesiredAccess
		);
    
	if(!hSCManager)
		return DRIVER_MANAGER_ERROR_SCM;

	//Si tout va bien, ouvre le driver
	HANDLE hService = OpenService(
		hSCManager,									//hSCManager
		nom_driver,									//lpServiceName
		SERVICE_START | DELETE | SERVICE_STOP		//dwDesiredAccess
		);

	if (!hService)
	{
		CloseServiceHandle(hSCManager);
		return DRIVER_MANAGER_ERROR_ACCESS;
	}


    //L'teint
	SERVICE_STATUS ss;
	if (!ControlService(
			hService,								//hService
			SERVICE_CONTROL_STOP,					//dwControl
			&ss										//lpServiceStatus
			)
		)
	{
		CloseServiceHandle(hService); 
		CloseServiceHandle(hSCManager);
		return DRIVER_MANAGER_ERROR_SHUTDOWN;

	}


	//Nettoie tout ca
    CloseServiceHandle(hService); 
	CloseServiceHandle(hSCManager);
        
    return DRIVER_MANAGER_OK;
}















				- appliDlg.cpp -


// appliDlg.cpp : implementation file
//

#include "stdafx.h"
#include "appli.h"
#include "appliDlg.h"

#include "driver_management.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CAppliDlg dialog

CAppliDlg::CAppliDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CAppliDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CAppliDlg)
	m_emplacement = _T("");
	m_fullname = _T("");
	m_shortname = _T("");
	m_write = _T("");
	m_read = _T("");
	m_dos = _T("");
	m_ioctrl = _T("");
	m_iotype = -1;
	m_startupmode = -1;
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

	m_shortname =	(LPCSTR)"Exemple";
	m_fullname =	(LPCSTR)"Driver d'exemple";
	m_dos =			(LPCSTR)"\\\\.\\test_driver";
	m_emplacement =	(LPCSTR)"c:\\test_driver.sys";
	m_iotype = 0;
	m_startupmode = 0;
}

void CAppliDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAppliDlg)
	DDX_Text(pDX, IDC_EMPLACEMENT, m_emplacement);
	DDX_Text(pDX, IDC_FULLNAME, m_fullname);
	DDX_Text(pDX, IDC_SHORTNAME, m_shortname);
	DDX_Text(pDX, IDC_WRITE, m_write);
	DDX_Text(pDX, IDC_READ, m_read);
	DDX_Text(pDX, IDC_DOS, m_dos);
	DDX_Text(pDX, IDC_IOCTRL, m_ioctrl);
	DDX_CBIndex(pDX, IDC_COMBO1, m_iotype);
	DDX_CBIndex(pDX, IDC_COMBO2, m_startupmode);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAppliDlg, CDialog)
	//{{AFX_MSG_MAP(CAppliDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_DESTROY()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BUTTON1, OnEnregistrement)
	ON_WM_CREATE()
	ON_WM_CANCELMODE()
	ON_BN_CLICKED(IDC_BUTTON2, OnSuppression)
	ON_BN_CLICKED(IDC_BUTTON3, OnLancement)
	ON_BN_CLICKED(IDC_BUTTON4, OnArret)
	ON_BN_CLICKED(IDC_BUTTON5, OnWrite)
	ON_BN_CLICKED(IDC_BUTTON6, OnRead)
	ON_BN_CLICKED(IDC_BUTTON7, OnEnvoi)
	ON_BN_CLICKED(IDC_BUTTON8, OnStatus)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CAppliDlg message handlers

BOOL CAppliDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	//Initialise les champs

	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CAppliDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

void CAppliDlg::OnDestroy()
{
	WinHelp(0L, HELP_QUIT);
	CDialog::OnDestroy();
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CAppliDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CAppliDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

int CAppliDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CDialog::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	// TODO: Add your specialized creation code here
	return 0;
}

void CAppliDlg::OnCancelMode() 
{
	CDialog::OnCancelMode();
	
	// TODO: Add your message handler code here
	
}





void CAppliDlg::OnEnregistrement() 
{
	//Rcupre les variables et les rend plus faciles  manipuler
	UpdateData(); 
	char* emplacement =(char*)LPCTSTR(m_emplacement); 
	char* nom_court =(char*)LPCTSTR(m_shortname); 
	char* nom_complet =(char*)LPCTSTR(m_fullname); 

	//Si il manque des infos, message et cassos
	if (!(strlen(emplacement) && strlen (nom_court) && strlen (nom_complet)))
	{
		MessageBox("Veuillez renseigner les champs ci dessus");
		return;
	}

	//Appel  la fonction et messages  afficher  l'utilisateur	
	switch (enregistre_driver(emplacement, nom_court, nom_complet, m_startupmode))
	{
		case DRIVER_MANAGER_OK:
			MessageBox("Driver enregistr avec succes");
			break;
		case DRIVER_MANAGER_ERROR_CREATE:
			MessageBox("Impossible d'enregistrer le driver, peut-tre est il lanc");
			break;
		case DRIVER_MANAGER_ERROR_SCM:
			MessageBox("Accs au Service Control Manager interdit");
			break;
		case DRIVER_MANAGER_NO_FILE:
			MessageBox("Le fichier n'existe pas");
			break;
		case DRIVER_MANAGER_ERROR_ALREADY:
			MessageBox("Le driver existe dja");
			break;
	}
}


void CAppliDlg::OnSuppression() 
{
	//Rcupre les variables et les rend plus faciles  manipuler
	UpdateData(); 
	char* emplacement =(char*)LPCTSTR(m_emplacement); 
	char* nom_court =(char*)LPCTSTR(m_shortname); 
	char* nom_complet =(char*)LPCTSTR(m_fullname); 

	//Si il manque des infos, message d'erreur et cassos
	if (!(strlen(emplacement) && strlen (nom_court) && strlen (nom_complet)))
	{
		MessageBox("Veuillez renseigner les champs ci dessus");
		return;
	}

	//Appel  la fonction et messages pour l'utilisateur
	switch (supprime_driver(nom_court))
	{
		case DRIVER_MANAGER_OK:
			MessageBox("Driver supprim avec succes");
			break;
		case DRIVER_MANAGER_ERROR_ACCESS:
			MessageBox("Impossible d'accder au driver, il n'est peut-tre pas enregistr");
			break;
		case DRIVER_MANAGER_ERROR_SCM:
			MessageBox("Accs au Service Control Manager interdit");
			break;
		case DRIVER_MANAGER_ERROR_DELETE:
			MessageBox("Impossible de supprimer le driver");
			break;
	}
}


void CAppliDlg::OnLancement() 
{
	//Rcupre les variables et les rend plus faciles  utiliser
	UpdateData(); 
	char* emplacement =(char*)LPCTSTR(m_emplacement); 
	char* nom_court =(char*)LPCTSTR(m_shortname); 
	char* nom_complet =(char*)LPCTSTR(m_fullname); 

	//Si il manque des infos, message et cassos
	if (!(strlen(emplacement) && strlen (nom_court) && strlen (nom_complet)))
	{
		MessageBox("Veuillez renseigner les champs ci dessus");
		return;
	}

	//Appel  la fonction et messages utilisateur
	switch (load_driver(nom_court))
	{
		case DRIVER_MANAGER_OK:
			MessageBox("Driver dmarr avec succes");
			break;

		case DRIVER_MANAGER_ERROR_ACCESS:
			MessageBox("Impossible d'accder au driver, il n'est peut-tre pas enregistr");
			break;

		case DRIVER_MANAGER_ERROR_SCM:
			MessageBox("Accs au Service Control Manager interdit");
			break;

		case DRIVER_MANAGER_ERROR_RUN:
			MessageBox("Impossible de dmarrer le driver, il est peut-tre dja lanc");
			break;
	}	
}


void CAppliDlg::OnArret() 
{
	//Rcupration des variables et les rend plus faciles  manipuler
	UpdateData(); 
	char* emplacement =(char*)LPCTSTR(m_emplacement); 
	char* nom_court =(char*)LPCTSTR(m_shortname); 
	char* nom_complet =(char*)LPCTSTR(m_fullname); 

	//Si il manque des informations, message et cassos
	if (!(strlen(emplacement) && strlen (nom_court) && strlen (nom_complet)))
	{
		MessageBox("Veuillez renseigner les champs ci dessus");
		return;
	}

	//Appel  la fonction et message utilisateur	
	switch (unload_driver(nom_court))
	{
		case DRIVER_MANAGER_OK:
			MessageBox("Driver arrt avec succes");
			break;
		case DRIVER_MANAGER_ERROR_ACCESS:
			MessageBox("Impossible d'accder au driver, il n'est peut-tre pas enregistr");
			break;
		case DRIVER_MANAGER_ERROR_SCM:
			MessageBox("Accs au Service Control Manager interdit");
			break;
		case DRIVER_MANAGER_ERROR_SHUTDOWN:
			MessageBox("Impossible d'teindre le driver, il n'est peut-tre pas lanc");
			break;
	}	
}


void CAppliDlg::OnWrite() 
{
	// Rcupre les champs
	UpdateData(); 
	if (!ecris_driver ((char*)LPCTSTR(m_dos), (char*)LPCTSTR(m_write) ))
		MessageBox("Ecriture impossible, le driver ne semble pas charg");
}


void CAppliDlg::OnRead() 
{
	//Le buffer local pour stoquer les infos lues
	char buffer_lecture[1024];
	unsigned long taille_buffer_lecture = 1024;
	
	//Rcupre les variables
	UpdateData(); 
	
	//Appelle la fonction de lecture
	if (!lis_driver ((char*)LPCTSTR(m_dos), buffer_lecture, &taille_buffer_lecture))
		MessageBox("Lecture impossible, le driver ne semble pas charg");
	else
	{
		//Et renvoie la valeur dans le champ
		m_read = (LPCTSTR)buffer_lecture;
 		UpdateData(FALSE);
	}
}


void CAppliDlg::OnEnvoi() 
{
	//Buffer local pour la partie MDL de la communication avec le driver	
	char buffer_ioctrl[1024];
	unsigned long taille_buffer_ioctrl = 1024;

	//Les deux types de communication possibles
	DWORD IOCTL_EXAMPLE_SAMPLE_DIRECT_IN_IO = 2285569;
	DWORD IOCTL_EXAMPLE_SAMPLE_DIRECT_OUT_IO = 2285574;

	//Rcupration des variables
	UpdateData(); 

	//Un mode de communication doit etre slectionn, sinon cassos
	CString string_controle;
	int nIndex = GetDlgItemText(IDC_COMBO1, string_controle); 

	//Action
	bool verdict;
	if (m_iotype == 0)
		verdict = ioctrl_driver ((char*)LPCTSTR(m_dos), (char*)LPCTSTR(m_ioctrl), IOCTL_EXAMPLE_SAMPLE_DIRECT_IN_IO, buffer_ioctrl, &taille_buffer_ioctrl );
	else
		verdict = ioctrl_driver ((char*)LPCTSTR(m_dos), (char*)LPCTSTR(m_ioctrl), IOCTL_EXAMPLE_SAMPLE_DIRECT_OUT_IO, buffer_ioctrl, &taille_buffer_ioctrl);

	if (verdict)
	{
		m_ioctrl = (LPCTSTR)buffer_ioctrl;
		UpdateData(FALSE); 
	}
	else
		MessageBox("IO-Control impossible, le driver ne semble pas charg");
}


void CAppliDlg::OnStatus() 
{
	// Rcupre les variables
	UpdateData(); 

	switch (verifie_status((char*)LPCTSTR(m_shortname)))
	{
	case DRIVER_MANAGER_STATUS_ABSENT:
		MessageBox("Le driver n'est pas enregistr");
		break;
	case DRIVER_MANAGER_STATUS_ACTIF:
		MessageBox("Le driver est enregistr et actif");
		break;
	case DRIVER_MANAGER_STATUS_INACTIF:
		MessageBox("Le driver est enregistr mais inactif");
		break;
	}
	
}














				- appli.cpp -




// appli.cpp : Defines the class behaviors for the application.
//

#include "stdafx.h"
#include "appli.h"
#include "appliDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CAppliApp

BEGIN_MESSAGE_MAP(CAppliApp, CWinApp)
	//{{AFX_MSG_MAP(CAppliApp)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG
	ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CAppliApp construction

CAppliApp::CAppliApp()
{
	// TODO: add construction code here,
	// Place all significant initialization in InitInstance
}

/////////////////////////////////////////////////////////////////////////////
// The one and only CAppliApp object

CAppliApp theApp;

/////////////////////////////////////////////////////////////////////////////
// CAppliApp initialization

BOOL CAppliApp::InitInstance()
{
	// Standard initialization
	// If you are not using these features and wish to reduce the size
	//  of your final executable, you should remove from the following
	//  the specific initialization routines you do not need.

#ifdef _AFXDLL
	Enable3dControls();			// Call this when using MFC in a shared DLL
#else
	Enable3dControlsStatic();	// Call this when linking to MFC statically
#endif

	CAppliDlg dlg;
	m_pMainWnd = &dlg;
	int nResponse = dlg.DoModal();
	if (nResponse == IDOK)
	{
		// TODO: Place code here to handle when the dialog is
		//  dismissed with OK
	}
	else if (nResponse == IDCANCEL)
	{
		// TODO: Place code here to handle when the dialog is
		//  dismissed with Cancel
	}

	// Since the dialog has been closed, return FALSE so that we exit the
	//  application, rather than start the application's message pump.
	return FALSE;
}









			- test_driver.c -


//tolwin_kernel.h
#define	DWORD	unsigned long
#define	BOOL	unsigned long
#define	WORD	unsigned int
#define	UINT	unsigned int
#define	BYTE	unsigned char


#include "ntddk.h"
#include "ntstrsafe.h"



// TYPES UTILISES ===============================================================================
	// Le device extension
	typedef struct {
		PDEVICE_OBJECT pMouseOldTopOfStack;
		BOOL autofire;
		int pending;
		PCHAR buffer;
		PIRP MouseIrp;
		BOOL latch;
		BOOL terminate_thread;
		HANDLE thread_handle;
		
	}DEVICE_EXTENSION, *PDEVICE_EXTENSION;

	// Les donnes d'un IRP souris
	typedef struct {
		USHORT UnitId;
		USHORT flags;
		union {
			ULONG Buttons;
			struct {
				USHORT ButtonFlags;
				USHORT ButtonData;
			};
		};
		ULONG RawButtons;
		long LastX;
		long LastY;
		ULONG ExtraInformation;
	} MOUSE_INPUT_DATA, *PMOUSE_INPUT_DATA;



// PROTOTYPES DES FONCTIONS ====================================================================
	// Utilitaires
	UINT IsStringTerminatedAndSize	(PCHAR pString, UINT uiLength);
	
	//Driver
	VOID	 Unload					(IN PDRIVER_OBJECT  pDriverObject);
	
	//Device
	NTSTATUS PasTouche 				( IN PDEVICE_OBJECT pDeviceObject, IN PIRP Irp );
	NTSTATUS FiltreLecture 				( IN PDEVICE_OBJECT pDeviceObject, IN PIRP Irp );
	NTSTATUS ConfigurationDriver 		( IN PDEVICE_OBJECT pDeviceObject, IN PIRP Irp );
	NTSTATUS CompletionRoutine		( IN PDEVICE_OBJECT pDeviceObject, IN PIRP Irp, IN PVOID Context);


	void the_thread (IN PVOID pcontext);




//KeGetCurrentIrql()
/*#define PASSIVE_LEVEL            0      // Passive release level
#define LOW_LEVEL                0      // Lowest interrupt level
#define APC_LEVEL                1      // APC interrupt level
#define DISPATCH_LEVEL           2      // Dispatcher level
#define CMC_LEVEL                3      // Correctable machine check level
#define DEVICE_LEVEL_BASE        4      // 4 - 11 - Device IRQLs
#define PC_LEVEL                12      // Performance Counter IRQL
#define IPI_LEVEL               14      // IPI IRQL
#define CLOCK_LEVEL             13      // Clock Timer IRQL
#define POWER_LEVEL             15      // Power failure level
#define PROFILE_LEVEL           15      // Profiling level
#define HIGH_LEVEL              15      // Highest interrupt level
*/

// DRIVER ENTRY POINT ===========================================================================
NTSTATUS DriverEntry(IN PDRIVER_OBJECT  pDriverObject, IN PUNICODE_STRING  pRegistryPath)
{
	//Variables regroupes sinon bug de compilation  cause des DbgPrint
		//Divers
		NTSTATUS status = STATUS_UNSUCCESSFUL;
		int mj_function;
		//Cration du device
		PDEVICE_OBJECT pMouseDeviceObject;
		PDEVICE_EXTENSION pDeviceExtension; 
		//Attache du device au stack souris
		CCHAR NomDriverStack[] = "\\Device\\PointerClass0";
		STRING NomDriverStackString;
		UNICODE_STRING uNomDriverStack;

		LARGE_INTEGER offset;



	//Le code de DriverEntry
		//Petit texte de debut d'excution
		DbgPrint("\r\n\r\ntest_driver> Execution de DriverEntry\r\n");
		DbgPrint("test_driver> Irql : %i\r\n",KeGetCurrentIrql());


		//Initialise les irp majeures sur la fonction de dispatch de base
		DbgPrint("test_driver> Initialisation des fonctions majeures du driver filtrant\r\n");
		for (mj_function = 0; mj_function < IRP_MJ_MAXIMUM_FUNCTION; mj_function++)
			pDriverObject->MajorFunction[mj_function] = PasTouche;

		//Rgle les irps qui auront un traitement spcifiques, les veinardes
		pDriverObject->MajorFunction[IRP_MJ_READ] = FiltreLecture;
		pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ConfigurationDriver;
		pDriverObject->DriverUnload = Unload;

		//Cration du device
		DbgPrint("test_driver> Creation du device de filtrage\r\n");
		status = IoCreateDevice (pDriverObject,sizeof(DEVICE_EXTENSION),NULL,FILE_DEVICE_MOUSE,0,TRUE,&pMouseDeviceObject);
		if (status != STATUS_SUCCESS)
		{
			//Si erreur alors cassos
			DbgPrint("test_driver> Erreur lors de la creation du device\r\n");
			return status;
		}
		else
			DbgPrint("test_driver> Device cree avec succes\r\n");

		//Initialisation du device extension : mise  zro et utilisation d'un pointeur plus pratique  manipuler
		DbgPrint("test_driver> Initialisation du device de filtrage : mise a zero de la ram device extension\r\n");
		RtlZeroMemory(pMouseDeviceObject->DeviceExtension, sizeof(DEVICE_EXTENSION));
		pDeviceExtension = (DEVICE_EXTENSION*)pMouseDeviceObject->DeviceExtension;

		//Attache le device a la premiere device stack de classe souris
		DbgPrint("test_driver> Attache le device de filtrage sur %s\r\n",NomDriverStack);
		RtlInitAnsiString(&NomDriverStackString,NomDriverStack);
		RtlAnsiStringToUnicodeString(&uNomDriverStack,&NomDriverStackString,TRUE);
		status = IoAttachDevice(pMouseDeviceObject, &uNomDriverStack,&pDeviceExtension->pMouseOldTopOfStack);
		RtlFreeUnicodeString(&uNomDriverStack);
		if (status != STATUS_SUCCESS)
		{
			//Si erreur alors efface le device et cassos
			DbgPrint("test_driver> Erreur lors de l'insertion du device sur %s\r\n",NomDriverStack);
			IoDeleteDevice (pMouseDeviceObject);
			return status;
		}
		else
			DbgPrint("test_driver> Device insere avec succes sur %s\r\n",NomDriverStack);

		//Paramtrage de notre device filtrant notamment au moyen de valeurs provenant du driver souris original
		DbgPrint("test_driver> Parametrage du device\r\n");
		pMouseDeviceObject->Flags |= DO_BUFFERED_IO; //(pDeviceExtension->pMouseOldTopOfStack->Flags & DO_BUFFERED_IO)
		pMouseDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
		pMouseDeviceObject->DeviceType = pDeviceExtension->pMouseOldTopOfStack->DeviceType;
		pMouseDeviceObject->Characteristics = pDeviceExtension->pMouseOldTopOfStack->Characteristics;


/*
		//Lance le thread systeme
		pDeviceExtension->terminate_thread = FALSE;
		status = PsCreateSystemThread (
			&pDeviceExtension->thread_handle,
			(ACCESS_MASK)0,
			NULL,
			(HANDLE)0,
			NULL,
			the_thread,			//Adresse du thread
			pDeviceExtension		//Pagametre
			);
		if (status != STATUS_SUCCESS)
		{
			//Si erreur alors efface le device et cassos
			DbgPrint("Erreur lors de ca creation du thread\r\n");
			IoDetachDevice(pDeviceExtension->pMouseOldTopOfStack);
			IoDeleteDevice (pMouseDeviceObject);
			return status;
		}
		else
			DbgPrint("Thread cree avec succes\r\n");


		//Alloue le buffer pour l'IRP
		pDeviceExtension->buffer = ExAllocatePoolWithTag (NonPagedPool, sizeof(MOUSE_INPUT_DATA), 'Mous');
		if (pDeviceExtension->buffer == NULL)
		{
			//Si erreur alors detache et efface le device et cassos
			DbgPrint("Erreur lors de l'allocation du buffer\r\n");
			IoDetachDevice(pDeviceExtension->pMouseOldTopOfStack);
			IoDeleteDevice (pMouseDeviceObject);
			return status;
		}
		else
			DbgPrint("Buffer alloue avec succes\r\n");

		//Cr l'irp
		offset.QuadPart = 0;
		pDeviceExtension->MouseIrp = IoBuildAsynchronousFsdRequest( IRP_MJ_READ, pDeviceExtension->pMouseOldTopOfStack, pDeviceExtension->buffer, sizeof(MOUSE_INPUT_DATA), &offset, NULL);
		if (pDeviceExtension->MouseIrp == NULL)
		{
			//Si erreur alors detache et efface le device et cassos
			DbgPrint("Erreur lors de la creation de l'irp souris\r\n");
			IoDetachDevice(pDeviceExtension->pMouseOldTopOfStack);
			IoDeleteDevice (pMouseDeviceObject);
			return status;
		}
		else
			DbgPrint("Irp souris creee avec succes\r\n");
*/

		//Fin du driver entry
		return status;
}





// FONCTION DE DECHARGEMENT =====================================================================
VOID Unload(IN PDRIVER_OBJECT  pDriverObject)
{    
	PDEVICE_EXTENSION pDeviceExtension; 

	DbgPrint("test_driver> Execution de FilterUnload\r\n");
	DbgPrint("test_driver> Irql : %i\r\n",KeGetCurrentIrql());
//	__asm int 3
	
	pDeviceExtension = pDriverObject->DeviceObject->DeviceExtension;
	DbgPrint("test_driver> pending : %i\r\n",pDeviceExtension->pending );

	do 	DbgPrint("test_driver> Wait pending\r\n");
		while (pDeviceExtension->pending > 0);

	//Sparation
//	__asm int 3
//	IoDetachDevice(pDeviceExtension->pMouseOldTopOfStack);

	//Efface le device
//	__asm int 3
//	IoDeleteDevice(pDriverObject->DeviceObject);

}


// QUELQUES FONCTIONS QUI APPELLENT L'ANCIEN DRIVER ====================================================
NTSTATUS ConfigurationDriver ( IN PDEVICE_OBJECT pDeviceObject, IN PIRP Irp )
{
	PDEVICE_EXTENSION pDeviceExtension; 

	DbgPrint("test_driver> Execution de ConfigurationDriver\r\n");
	DbgPrint("test_driver> Irql : %i\r\n",KeGetCurrentIrql());

	pDeviceExtension = pDeviceObject->DeviceExtension;

    	IoSkipCurrentIrpStackLocation(Irp);
	return IoCallDriver(pDeviceExtension->pMouseOldTopOfStack, Irp);
}


NTSTATUS PasTouche ( IN PDEVICE_OBJECT pDeviceObject, IN PIRP Irp )
{
	PDEVICE_EXTENSION pDeviceExtension; 

	DbgPrint("test_driver> Execution de PasTouche\r\n");
	DbgPrint("test_driver> Irql : %i\r\n",KeGetCurrentIrql());

	
	pDeviceExtension = pDeviceObject->DeviceExtension;

    	IoSkipCurrentIrpStackLocation(Irp);
	return IoCallDriver(pDeviceExtension->pMouseOldTopOfStack, Irp);
}




// LA FONCTION DE LECTURE ET SON CALLBACK ============================================================

NTSTATUS FiltreLecture ( IN PDEVICE_OBJECT pDeviceObject, IN PIRP Irp )
{
	PDEVICE_EXTENSION pDeviceExtension; 
	PIO_STACK_LOCATION pIoStackIrp = NULL;
	NTSTATUS status = STATUS_UNSUCCESSFUL;


	DbgPrint("test_driver> Execution de FiltreLecture\r\n");
	DbgPrint("test_driver> Irql : %i\r\n",KeGetCurrentIrql());


	pDeviceExtension = pDeviceObject->DeviceExtension;

	//Chope les positions dans l'irp stack
   	pIoStackIrp = IoGetCurrentIrpStackLocation(Irp);
   	IoCopyCurrentIrpStackLocationToNext(Irp);

	//Mise en place de la completion routine
	DbgPrint("test_driver> Regle CompletionRoutine et down the stack\r\n");
	IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE) CompletionRoutine, NULL, TRUE, TRUE, TRUE);

	//Appel au driver d'origine
	pDeviceExtension->pending++;
	status = IoCallDriver(pDeviceExtension->pMouseOldTopOfStack, Irp);
	pDeviceExtension->pending--;

	return status;
}





NTSTATUS CompletionRoutine(PDEVICE_OBJECT pDeviceObject, PIRP Irp, PVOID Context)
{
    	PMOUSE_INPUT_DATA pMouseData;
	PDEVICE_EXTENSION pDeviceExtension; 

	DbgPrint("test_driver> Execution de CompletionRoutine\r\n");
	DbgPrint("test_driver> Irql : %i\r\n",KeGetCurrentIrql());

	pMouseData = (PMOUSE_INPUT_DATA)Irp->AssociatedIrp.SystemBuffer;
	pDeviceExtension = pDeviceObject->DeviceExtension;


	//Teste pour l'autofire : si appel d'origine et que le bouton 1 est en jeu alors... ...
	if (pMouseData->UnitId == 0)
	{
		if (pMouseData->Buttons & 1)
			{
				pDeviceExtension->autofire = TRUE;
				pDeviceExtension->latch=TRUE;
			 	DbgPrint("test_driver> Autofire on\r\n");
			}
			else if (pMouseData->Buttons & 2)
			{
				pDeviceExtension->autofire = FALSE;
			    	DbgPrint("test_driver> Autofire off\r\n");
			}
	}

	if (pDeviceExtension->autofire == TRUE)
	{
		if (pDeviceExtension->latch == TRUE)
		{
			//Ici je passe le bouton  1
			pMouseData->Buttons &= 0xFFFD;
			pMouseData->Buttons |= 0x0001;
			pDeviceExtension->latch = FALSE;
		}
		else
		{
			//Ici je passe le bouton  2
			pMouseData->Buttons &= 0xFFFE;
			pMouseData->Buttons |= 0x0002;
			pDeviceExtension->latch = TRUE;
		}
	}

	if (Irp->PendingReturned)
		IoMarkIrpPending(Irp);
	
	return Irp->IoStatus.Status;
}



void the_thread (IN PVOID pcontext)
{
	PDEVICE_EXTENSION pDeviceExtension = (PDEVICE_EXTENSION) pcontext;
	PMOUSE_INPUT_DATA pMouseData;
	PIO_STACK_LOCATION nextstack;

	DbgPrint("test_driver> Execution de void the_thread\r\n");
	DbgPrint("test_driver> Irql : %i\r\n",KeGetCurrentIrql());

	pMouseData = pDeviceExtension->MouseIrp->AssociatedIrp.SystemBuffer;
	nextstack = IoGetNextIrpStackLocation(pDeviceExtension->MouseIrp);
	nextstack->MajorFunction = IRP_MJ_READ;
	nextstack->Parameters.Read.Length = sizeof(MOUSE_INPUT_DATA);


while (1)
{
	if (pDeviceExtension->autofire == TRUE)
	{
		if (pDeviceExtension->latch == TRUE)
		{
			RtlZeroMemory(pMouseData, sizeof(MOUSE_INPUT_DATA));
			pMouseData->UnitId = 1;
			pMouseData->flags = 1;
			pMouseData->Buttons = 1;
			pMouseData->RawButtons = 0;
			pMouseData->LastX = 0;
			pMouseData->LastY = 0;
			pMouseData->ExtraInformation = 0;
		//	pDeviceExtension->MouseIrp->IoStatus.Status = STATUS_SUCCESS;
			//pDeviceExtension->MouseIrp->IoStatus.Information = sizeof(MOUSE_INPUT_DATA);
			if (pDeviceExtension->pending == 0) IoCallDriver(pDeviceExtension->pMouseOldTopOfStack, pDeviceExtension->MouseIrp);
		
			pDeviceExtension->latch = FALSE;
		 	DbgPrint("test_driver> Fire !!!\r\n");
		}
		else
		{
			RtlZeroMemory(pMouseData, sizeof(MOUSE_INPUT_DATA));
			pMouseData->UnitId = 1;
			pMouseData->flags = 1;
			pMouseData->Buttons = 2;
			pMouseData->RawButtons = 0;
			pMouseData->LastX = 0;
			pMouseData->LastY = 0;
			pMouseData->ExtraInformation = 0;
			//pDeviceExtension->MouseIrp->IoStatus.Status = STATUS_SUCCESS;
			//pDeviceExtension->MouseIrp->IoStatus.Information = sizeof(MOUSE_INPUT_DATA);
			if (pDeviceExtension->pending == 0) IoCallDriver(pDeviceExtension->pMouseOldTopOfStack, pDeviceExtension->MouseIrp);
		
			pDeviceExtension->latch = TRUE;
		}
	}
}

}


// QUELQUES FONCTIONS UTILES ====================================================================
UINT IsStringTerminatedAndSize(PCHAR pString, UINT uiLength)
{
    UINT uiIndex = 0;

    while(uiIndex < uiLength)
    {
        if(pString[uiIndex] == '\0')
        {
            return uiIndex+1;
        }
        else
        {
           uiIndex++;
        }
    }

    return 0;
}






		c/ annexes

direction l'index ou l'annexe pour la suite du programme, executable et autres
fichiers compris.


    -- [ Tolwin