2008-12-20, 06:29 AM
Quote:Bad Request
Your browser sent a request that this server could not understand.
NTSTATUS Control(PDEVICE_OBJECT DeviceObject,PIRP Irp)
{
NTSTATUS s=STATUS_SUCCESS;
PIO_STACK_LOCATION Stack;
unsigned int escritos;
char *iBuffer;
char *oBuffer;
char *Mensaje = "Hola desde el kernel!";
unsigned int Tam = sizeof("Hola desde el kernel!");
Stack=IoGetCurrentIrpStackLocation(Irp);
switch(Stack->Parameters.DeviceIoControl.IoControlCode)
{
case Escribe:
DbgPrint("Funcion escribir llamada");
DbgPrint("Asociando buffers...");
iBuffer = oBuffer = Irp->AssociatedIrp.SystemBuffer;
if(oBuffer && oBuffer)
{
DbgPrint("OK");
if(Stack->Parameters.DeviceIoControl.InputBufferLength !=0)
{
DbgPrint("Datos desde modo usuario: %s",iBuffer);
if(Stack->Parameters.DeviceIoControl.OutputBufferLength>= Tam)
{
DbgPrint("Enviando datos...");
RtlCopyMemory(oBuffer, Mensaje, Tam);
Irp->IoStatus.Information = Tam;
s = STATUS_SUCCESS;
}else{
DbgPrint("NO ENVIAMOS LOS DATOS");
Irp->IoStatus.Information = 0;
s = STATUS_BUFFER_TOO_SMALL;
}
}
}
else DbgPrint("ERROR");
break;
}
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return s;
}
Al inicio declaramos los buffers de entrara y salida y los mensajes que vamos a enviar a MU.
Stack=IoGetCurrentIrpStackLocation(Irp);
Esta linea sirve para poder localizar los datos que vamos a usar posteriormente, Stack esta declarada como un puntero a IO_STACK_LOCATION.
iBuffer = oBuffer = Irp->AssociatedIrp.SystemBuffer;
Assignamos los buffers de E/S, si no hay error proseguimos.
RtlCopyMemory(oBuffer, Mensaje, Tam);
Irp->IoStatus.Information = Tam;
En la primera linea copiamos los datos al buffer de salida, en la segunda, ajustamos el tamaño del buffer de salida, esto es importante, ya que si no se configura no se transmitiran datos.
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return s;
Completamos y salimos.
Ahora vamos a ver la aplicación de consola en MU:
#include <stdio.h>
#include <windows.h>
#include <winioctl.h>
#define Escribe CTL_CODE(FILE_DEVICE_UNKNOWN, 0x00000001, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
int main()
{
DWORD a;
HANDLE hDevice = CreateFile("\\\\.\\midriver5",GENERIC_READ | GENERIC_WRITE ,FILE_SHARE_READ | FILE_SHARE_WRITE,0,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,0);
char iBuffer[30];
char oBuffer[1024];
if (hDevice!=INVALID_HANDLE_VALUE)
{
printf("Conectado");
strcpy(iBuffer,"Hola desde Modo Usuario!!!");
if(DeviceIoControl(hDevice,(DWORD)Escribe,iBuffer,(DWORD)sizeof(iBuffer),(LPVOID)oBuffer,(DWORD)sizeof(oBuffer),&a,NULL)==true)
{
printf("\n%d Bytes\n%s\n%s",a,iBuffer,oBuffer);
}else
printf("0x%08x",GetLastError());
}
system("pause");
return 0;
}
La verdad es que no hay mucho que explicar de este código.
En este ejemplo se transfieren cadenas, pero se puede transferir todo lo que nosotros queramos.
Dicho esto doy por zanjado este segundo capítulo, si alguien tiene alguna duda comentenlo.
PD: Tengo que decir que parte de estos codigo son de lympex, de un codigo que publicó, lo e modificado un poco ya que usaba mas funciona, pero los nombres de las variables y eso no lo e cambiado.