Please help ! Link data pipe user-mode<-->kernel-mode

Hello
I wish I had one source sample C that communicates by pipe of user-mode<–>kernel-mode.

A Sample which work please !
I understand nothing at all!

Thank you.

Party function Vdum_Compipe :
status = IoCallDriver(io_stack->FileObject->DeviceObject, irp);

if (status == STATUS_PENDING)
KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); // There is blocking same why ReadFile of this pipe is called of user-mode
else if (!NT_SUCCESS(status))
break;

But the pipe is creating!

Incomplete Sample :

typedef struct {
WCHAR pipe[64];
WCHAR eventrecv[64];
WCHAR eventsend[64];
DWORD sizeko;
CHAR letter;
DISK_GEOMETRY disk_geometry;
UCHAR time_out;

}TCONFIGVD,*PCONFIGVD;

Kernel-Mode

NTSTATUS vdums_deviceiocontrol(IN PDEVICE_OBJECT DeviceObject, IN PIRP irp, PIO_STACK_LOCATION irps)
{
NTSTATUS status=STATUS_NOT_IMPLEMENTED;

switch (iocode)
{


case IOCTL_CMD_PARAMETERVIRTUALDISK:
{
WCHAR eventsend[256];
WCHAR eventrecv[256];
KdPrint((“[VDUM] CMD ParametreVirtualDisk\n”));
if ((irps->Parameters.DeviceIoControl.InputBufferLength < sizeof(TCONFIGVD)))
{
KdPrint((“[VDUM] CMD ParametreVirtualDisk Size mismatch\n”));
status = STATUS_INVALID_PARAMETER;
irp->IoStatus.Information = 0;
break;
}
configvd=(PCONFIGVD)irp->AssociatedIrp.SystemBuffer;
lod=VDUM_GetDevice(configvd->letter);
status=STATUS_INVALID_HANDLE;
if (lod!=0)
{
UNICODE_STRING uszNotifyEventString,pipe_name,uszsend,uszrecv;
KdPrint((“[VDUM] CMD ParametreVirtualDisk lod ok\n”));
paramvd=(PPARAMVD) lod->DeviceExtension;
/*RtlInitUnicodeString(&uszNotifyEventString,
configvd->eventrecv);
paramvd->eventrecv = IoCreateNotificationEvent(&uszNotifyEventString, &paramvd->NotifyHandleRecv);*/
//if (paramvd->eventrecv!=NULL)
{
KdPrint((“[VDUM] CMD ParametreVirtualDisk eventrecv ok\n”));

wcscpy(eventsend,L"\BaseNamedObjects\“);
wcscpy(eventrecv,L”\BaseNamedObjects\“);
wcscat(eventsend,configvd->eventsend);
wcscat(eventrecv,configvd->eventrecv);
KdPrint((”[VDUM] CMD ParametreVirtualDisk EventSend Name %ws\n",eventsend));
KdPrint((“[VDUM] CMD ParametreVirtualDisk EventRecv Name %ws\n”,eventrecv));
RtlInitUnicodeString(&uszsend,
eventsend);
RtlInitUnicodeString(&uszrecv,
eventrecv);
paramvd->eventsend = IoCreateNotificationEvent(&uszsend, &paramvd->NotifyHandleSend);
paramvd->eventrecv = IoCreateNotificationEvent(&uszrecv, &paramvd->NotifyHandleRecv);
KeClearEvent(paramvd->eventsend);
KeClearEvent(paramvd->eventrecv);

if (paramvd->eventsend!=NULL)
{
KdPrint((“[VDUM] CMD ParametreVirtualDisk eventsend ok\n”));

wcscpy(wpipe,L"\??\pipe\");
wcscat(wpipe,configvd->pipe);
paramvd->sizeko=configvd->sizeko;
paramvd->disk_geometry=configvd->disk_geometry;
paramvd->time_out=configvd->time_out;

KdPrint((“[VDUM] CMD ParametreVirtualDisk pipe name %ws\n”,wpipe));

RtlInitUnicodeString(
&pipe_name,
wpipe
);

InitializeObjectAttributes(
&attr,
&pipe_name,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL,
NULL);

status = ZwCreateFile(
&paramvd->file_handle,
GENERIC_READ | GENERIC_WRITE , // or FILE_READ_DATA
&attr,
&io_status,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ |
FILE_SHARE_DELETE |
FILE_SHARE_WRITE,
FILE_OPEN,
//IMDISK_TYPE(CreateData->Flags) == IMDISK_TYPE_PROXY ?
FILE_NON_DIRECTORY_FILE |
FILE_SEQUENTIAL_ONLY |
FILE_NO_INTERMEDIATE_BUFFERING |
FILE_SYNCHRONOUS_IO_NONALERT |
FILE_NON_DIRECTORY_FILE |
FILE_RANDOM_ACCESS |
FILE_NO_INTERMEDIATE_BUFFERING |
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0);
if (status==STATUS_SUCCESS)
{
status =
ObReferenceObjectByHandle(paramvd->file_handle,
FILE_READ_ATTRIBUTES |
FILE_READ_DATA |
FILE_WRITE_DATA,
*IoFileObjectType,
KernelMode,
&paramvd->pipe,
NULL);

if (status==STATUS_SUCCESS)
{
KdPrint((“[VDUM] CMD ParametreVirtualDisk pipe ok\n”));
irp->IoStatus.Information=0;
paramvd->parametrer=TRUE;
status=STATUS_SUCCESS;
}
else
{
KdPrint((“[VDUM] CMD ParametreVirtualDisk pipeerror %x \n”,status));
}
}
else
KdPrint((“[VDUM] ZwCreateFile status returned %x \n”,status));
}
else
{
KdPrint((“[VDUM] CMD ParametreVirtualDisk eventsend fail\n”));
ZwClose(&paramvd->eventrecv);
status=STATUS_INSUFFICIENT_RESOURCES;
}
}
/*else
{
KdPrint((“[VDUM] CMD ParametreVirtualDisk eventrecv fail\n”));
status=STATUS_INSUFFICIENT_RESOURCES;
}*/
}

}
break;
}


NTSTATUS COM_PIPE(PCP cp)
{
NTSTATUS status=STATUS_SUCCESS;
LARGE_INTEGER dt;
UCHAR len;
PIO_STATUS_BLOCK ios=cp->iostatusblock;

ULONG length=cp->_length;
//LONGLONG offset=(cp->offsethigh<<32)+cp->offsetlow;
ULONG offsethigh=cp->offsethigh;
ULONG offsetlow=cp->offsetlow;
PPARAMVD pvd=cp->pvd;
BOOLEAN writedirect=cp->writedirect;
UCHAR* buffer=cp->buffer;
UCHAR *commande=cp->commande;

//KdPrint((“COM PIPE 1 Commande %s Offset:%x Length:%p\n”,commande,offset,length));
KdPrint((“COM PIPE Offset:%p%p Length:%p\n”,offsethigh,offsetlow,length));

RtlZeroMemory(&dt, sizeof(LARGE_INTEGER));

KeSetEvent(pvd->eventrecv,(KPRIORITY) 0, FALSE);
KeClearEvent(pvd->eventrecv);
len=strlen(commande);
//KdPrint((“COM PIPE 2 Offset:%p%p Length:%p\n”,offsethigh,offsetlow,length));
VDUM_ReadPipe(pvd->pipe,ios,&writedirect,1,&dt,&status);
VDUM_ReadPipe(pvd->pipe,ios,&len,1,&dt,&status);
VDUM_ReadPipe(pvd->pipe,ios,commande,len,&dt,&status);
VDUM_ReadPipe(pvd->pipe,ios,&offsetlow,sizeof (ULONG),&dt,&status);
VDUM_ReadPipe(pvd->pipe,ios,&offsethigh,sizeof (ULONG),&dt,&status);
VDUM_ReadPipe(pvd->pipe,ios,&length,sizeof (ULONG),&dt,&status);
if (status!=STATUS_SUCCESS)
{
KdPrint((“Status VDUM_ReadPipe IN return %x\n”,status));
return status;
}
if (writedirect)
{
VDUM_WritePipe(pvd->pipe,ios,buffer,length,&dt,&status);
}
if (status!=STATUS_SUCCESS)
{
KdPrint((“Status VDUM_WritePipe IN return %x\n”,status));
return status;
}
else
{
status=KeWaitForSingleObject(&pvd->eventsend,
Executive,
KernelMode,
FALSE,
pvd->time_out*1000);
if (status!=STATUS_SUCCESS)
{
KdPrint((“Status KeWaitForSingleObject return %x\n”,status));
}
else
{
CHAR flag=0;
status=VDUM_ReadPipe(pvd->pipe,ios,&flag,1,&dt,&status);
if (status==STATUS_SUCCESS)
{
switch (flag)
{
case 0:
if (!writedirect)
status=VDUM_ReadPipe(pvd->pipe,ios,buffer,length,&dt,&status);
if (status!=STATUS_SUCCESS)
{
KdPrint((“Status VDUM_ReadPipe OUT return %x\n”,status));
return status;
}
break;
case 1:status=STATUS_ACCESS_DENIED;break;
case 2:status=STATUS_NOT_IMPLEMENTED;break;
case 3:status=STATUS_MEDIA_WRITE_PROTECTED;break;
}
KdPrint((“Status COM_PIPE personalize OUT return %x\n”,status));
}
else
{
if (status!=STATUS_SUCCESS)
{
KdPrint((“Status ZwReadFile OUT return %x\n”,status));
}
}
}
}
return status;

}

NTSTATUS
VDUM_ComPipe(IN PFILE_OBJECT FileObject,
IN UCHAR MajorFunction,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID Buffer,
IN ULONG Length)
{
NTSTATUS status;
//IO_STATUS_BLOCK IoStatusBlock;
ULONG length_done = 0;
KEVENT event;
PIO_STACK_LOCATION io_stack;
LARGE_INTEGER offset = { 0 };

PAGED_CODE();

KdPrint((“[VDUM]: FileObject=%#x, MajorFunction=%#x, IoStatusBlock=%#x, Buffer=%#x, Length=%#x.\n”, FileObject, MajorFunction, IoStatusBlock, Buffer, Length));

ASSERT(FileObject != NULL);
ASSERT(IoStatusBlock != NULL);
ASSERT(Buffer != NULL);

KeInitializeEvent(&event,
NotificationEvent,
FALSE);

while (length_done < Length)
{
ULONG RequestLength = Length - length_done;

do
{
PIRP irp;

KdPrint((“[VDUM]: Building IRP…\n”));

irp = IoBuildSynchronousFsdRequest(MajorFunction,
FileObject->DeviceObject,
(PUCHAR) Buffer + length_done,
RequestLength,
&offset,
&event,
IoStatusBlock);

if (irp == NULL)
{
KdPrint((“[VDUM]: Error building IRP.\n”));

IoStatusBlock->Status = STATUS_INSUFFICIENT_RESOURCES;
IoStatusBlock->Information = length_done;
return IoStatusBlock->Status;
}

KdPrint((“[VDUM] : Built IRP=%#x.\n”, irp));

io_stack = IoGetNextIrpStackLocation(irp);
io_stack->FileObject = FileObject;
io_stack->DeviceObject = FileObject->DeviceObject;

KdPrint((“[VDUM]: MajorFunction= %#x, Length=%#x\n”,
io_stack->MajorFunction,
io_stack->Parameters.Write.Length));

KeResetEvent(&event);

status = IoCallDriver(io_stack->FileObject->DeviceObject, irp);

if (status == STATUS_PENDING)
KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
else if (!NT_SUCCESS(status))
break;

status = IoStatusBlock->Status;

KdPrint((“[VDUM]: IRP %#x completed. Status=%#x.\n”,
irp, IoStatusBlock->Status));

RequestLength >>= 1;
}
while ((status == STATUS_INVALID_BUFFER_SIZE) |
(status == STATUS_INVALID_PARAMETER));

if (!NT_SUCCESS(status))
{
KdPrint((“[VDUM]: I/O failed. Status=%#x.\n”, status));

IoStatusBlock->Status = status;
IoStatusBlock->Information = 0;
return IoStatusBlock->Status;
}

KdPrint((“[VDUM]: I/O done. Status=%#x. Length=%#x\n”,
status, IoStatusBlock->Information));

if (IoStatusBlock->Information == 0)
{
IoStatusBlock->Status = STATUS_CONNECTION_RESET;
IoStatusBlock->Information = 0;
return IoStatusBlock->Status;
}

length_done += (ULONG) IoStatusBlock->Information;
}

KdPrint((“[VDUM]: I/O complete.\n”));

IoStatusBlock->Status = STATUS_SUCCESS;
IoStatusBlock->Information = length_done;
return IoStatusBlock->Status;
}

NTSTATUS
VDUM_ReadPipe(IN PFILE_OBJECT ProxyDevice,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset,
NTSTATUS *status)
{

PAGED_CODE();

/*ASSERT(ProxyDevice != NULL);
ASSERT(IoStatusBlock != NULL);
ASSERT(Buffer != NULL);
ASSERT(ByteOffset != NULL);*/

if (*status==STATUS_SUCCESS)
{

*status = VDUM_ComPipe(ProxyDevice,
IRP_MJ_READ,
IoStatusBlock,
Buffer,
(ULONG) Length);

if (!NT_SUCCESS(*status))
KdPrint(("[VDUM] Proxy Client: Data stream of %u bytes received with I/O "
“status %#x. Status returned by stream reader is %#x.\n”,
IoStatusBlock->Information, IoStatusBlock->Status, status));

KdPrint
((“[VDUM]: Received %u byte data stream.\n”,
IoStatusBlock->Information));
}
return *status;
}

typedef struct {
PPARAMVD pvd;
UCHAR *commande;
//LONGLONG offset;
ULONG offsethigh;
ULONG offsetlow;
ULONG _length;
UCHAR *buffer;
BOOLEAN writedirect;
PIO_STATUS_BLOCK iostatusblock;
}TCP,*PCP;


case IRP_MJ_READ:
TCP cp;
ULONG len=0;
ULONG lxx=0;
LONGLONG xl=0;
PUCHAR buffer;
PUCHAR system_buffer =
(PUCHAR) MmGetSystemAddressForMdlSafe(irp->MdlAddress,
NormalPagePriority);
LARGE_INTEGER offset;

if (system_buffer == NULL)
{
status=irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
irp->IoStatus.Information = 0;
break;
}
buffer = (PUCHAR)ExAllocatePool(NonPagedPool, io_stack->Parameters.Read.Length);
if (buffer == NULL)
{
status=irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
irp->IoStatus.Information = 0;
break;
}

if (io_stack->MajorFunction==IRP_MJ_WRITE)
{
KdPrint((“[VDUM] Device %i got write request Offset=%p%p Len=%p.\n”,
pvd->index,
io_stack->Parameters.Read.ByteOffset.HighPart,
io_stack->Parameters.Read.ByteOffset.LowPart,
io_stack->Parameters.Read.Length));

RtlCopyMemory(buffer,system_buffer, irp->IoStatus.Information);
xl=io_stack->Parameters.Read.ByteOffset.LowPart+(io_stack->Parameters.Read.ByteOffset.HighPart<<32);
cp.pvd=pvd;
cp.commande=cWRITE;
//cp.offset=xl;
cp.offsethigh=io_stack->Parameters.Read.ByteOffset.HighPart;
cp.offsetlow=io_stack->Parameters.Read.ByteOffset.LowPart;
cp._length=io_stack->Parameters.Read.Length;
cp.writedirect=TRUE;
cp.iostatusblock=&irp->IoStatus;
status=COM_PIPE(&cp);

irp->IoStatus.Information=0;

}
else
if (io_stack->MajorFunction==IRP_MJ_READ)
{

len=io_stack->Parameters.Read.Length;

xl=io_stack->Parameters.Read.ByteOffset.LowPart+(io_stack->Parameters.Read.ByteOffset.HighPart<<32);

irp->IoStatus.Information = io_stack->Parameters.Read.Length;

cp._length=len;
cp.pvd=pvd;
cp.commande=cREAD;

cp.offsethigh=io_stack->Parameters.Read.ByteOffset.HighPart;
cp.offsetlow=io_stack->Parameters.Read.ByteOffset.LowPart;

cp.writedirect=FALSE;
cp.iostatusblock=&irp->IoStatus;

status=COM_PIPE(&cp);
if (status==STATUS_SUCCESS)
RtlCopyMemory(system_buffer, buffer,irp->IoStatus.Information);
if (status!=STATUS_SUCCESS)
irp->IoStatus.Information=0;

}

ExFreePool(buffer);
}
break;

User - mode :

DWORD WINAPI threadC(PVOID context)
{
PCT ct=(PCT)context;
Sleep(3000);
DWORD dt=0;
DeviceIoControl(ct->hf,IOCTL_CMD_PARAMETERVIRTUALDISK,ct->configvd,sizeof (TCONFIGVD),NULL,0,&dt,NULL);
ct->heventrecv=OpenEvent(SYNCHRONIZE,false,“VDUMeventrecv”);
ct->heventsend=OpenEvent(SYNCHRONIZE,false,“VDUMeventsend”);
return 0;
}

wcscpy(configvd->pipe,L"VDUMtest");
wcscpy(configvd->eventrecv,L"VDUMeventrecv");
wcscpy(configvd->eventsend,L"VDUMeventsend");

HANDLE hConnectEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

TCHAR s2[128];
HANDLE hPipe = CreateNamedPipe(
“\\.\Pipe\VDUMtest”, // pipe name
PIPE_ACCESS_DUPLEX| // read/write access
FILE_FLAG_WRITE_THROUGH, // message type pipe
PIPE_WAIT, // blocking mode
PIPE_UNLIMITED_INSTANCES, // max. instances
BUFSIZE, // output buffer size
BUFSIZE, // input buffer size
100, // client time-out
NULL);

// default security attribute
DWORD dt=0;
SetLastError(0);
WORD thid=0;
hthread=CreateThread(NULL,0,threadC,ct,0,&thid);
if (fConnected)
{
while (!sort)
{
char commande[64];
char len=0;
int x=WaitForSingleObject(ct->heventrecv,5000);

if ((x==WAIT_OBJECT_0)&&(!sort))
{
DWORD dt=0;
bool writedirect=false;
LARGE_INTEGER offset;
ZeroMemory(&offset,sizeof (LARGE_INTEGER));
ULONG length=0;
ReadFile(hPipe,&writedirect,1,&dt,NULL);

Can you help please ???
A Access at IRP_MJ_READ , the event ct->heventrecv is setted by kernel but ReadFile Block
Yet although the driver called function COM_PIPE to send data to the pipe.
I understand nothing at all!

Thank you

Why do you want to use a pipe for user-kernel communication in the first
place, instead of the blessed IOCTL model?

Have a nice day
GV

----- Original Message -----
From:
To: “Windows System Software Devs Interest List”
Sent: Tuesday, October 20, 2009 12:04 PM
Subject: [ntdev] Please help ! Link data pipe user-mode<–>kernel-mode

> Hello
> I wish I had one source sample C that communicates by pipe of
> user-mode<–>kernel-mode.
>
> A Sample which work please !
> I understand nothing at all!
>
>
> Thank you.
>
> Party function Vdum_Compipe :
> status = IoCallDriver(io_stack->FileObject->DeviceObject, irp);
>
> if (status == STATUS_PENDING)
> KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); //
> There is blocking same why ReadFile of this pipe is called of user-mode
> else if (!NT_SUCCESS(status))
> break;
>
>
> But the pipe is creating!
>
>
> Incomplete Sample :
>
>
> typedef struct {
> WCHAR pipe[64];
> WCHAR eventrecv[64];
> WCHAR eventsend[64];
> DWORD sizeko;
> CHAR letter;
> DISK_GEOMETRY disk_geometry;
> UCHAR time_out;
>
> }TCONFIGVD,*PCONFIGVD;
>
>
> Kernel-Mode
>
>
> NTSTATUS vdums_deviceiocontrol(IN PDEVICE_OBJECT DeviceObject, IN PIRP
> irp, PIO_STACK_LOCATION irps)
> {
> NTSTATUS status=STATUS_NOT_IMPLEMENTED;
> …
> switch (iocode)
> {
> …
> …
> case IOCTL_CMD_PARAMETERVIRTUALDISK:
> {
> WCHAR eventsend[256];
> WCHAR eventrecv[256];
> KdPrint((“[VDUM] CMD ParametreVirtualDisk\n”));
> if ((irps->Parameters.DeviceIoControl.InputBufferLength <
> sizeof(TCONFIGVD)))
> {
> KdPrint((“[VDUM] CMD ParametreVirtualDisk Size mismatch\n”));
> status = STATUS_INVALID_PARAMETER;
> irp->IoStatus.Information = 0;
> break;
> }
> configvd=(PCONFIGVD)irp->AssociatedIrp.SystemBuffer;
> lod=VDUM_GetDevice(configvd->letter);
> status=STATUS_INVALID_HANDLE;
> if (lod!=0)
> {
> UNICODE_STRING uszNotifyEventString,pipe_name,uszsend,uszrecv;
> KdPrint((“[VDUM] CMD ParametreVirtualDisk lod ok\n”));
> paramvd=(PPARAMVD) lod->DeviceExtension;
> /RtlInitUnicodeString(&uszNotifyEventString,
> configvd->eventrecv);
> paramvd->eventrecv = IoCreateNotificationEvent(&uszNotifyEventString,
> &paramvd->NotifyHandleRecv);
/
> //if (paramvd->eventrecv!=NULL)
> {
> KdPrint((“[VDUM] CMD ParametreVirtualDisk eventrecv ok\n”));
>
> wcscpy(eventsend,L"\BaseNamedObjects\“);
> wcscpy(eventrecv,L”\BaseNamedObjects\“);
> wcscat(eventsend,configvd->eventsend);
> wcscat(eventrecv,configvd->eventrecv);
> KdPrint((”[VDUM] CMD ParametreVirtualDisk EventSend Name
> %ws\n",eventsend));
> KdPrint((“[VDUM] CMD ParametreVirtualDisk EventRecv Name
> %ws\n”,eventrecv));
> RtlInitUnicodeString(&uszsend,
> eventsend);
> RtlInitUnicodeString(&uszrecv,
> eventrecv);
> paramvd->eventsend = IoCreateNotificationEvent(&uszsend,
> &paramvd->NotifyHandleSend);
> paramvd->eventrecv = IoCreateNotificationEvent(&uszrecv,
> &paramvd->NotifyHandleRecv);
> KeClearEvent(paramvd->eventsend);
> KeClearEvent(paramvd->eventrecv);
>
> if (paramvd->eventsend!=NULL)
> {
> KdPrint((“[VDUM] CMD ParametreVirtualDisk eventsend ok\n”));
>
> wcscpy(wpipe,L"\??\pipe\“);
> wcscat(wpipe,configvd->pipe);
> paramvd->sizeko=configvd->sizeko;
> paramvd->disk_geometry=configvd->disk_geometry;
> paramvd->time_out=configvd->time_out;
>
> KdPrint((”[VDUM] CMD ParametreVirtualDisk pipe name %ws\n",wpipe));
>
> RtlInitUnicodeString(
> &pipe_name,
> wpipe
> );
>
> InitializeObjectAttributes(
> &attr,
> &pipe_name,
> OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
> NULL,
> NULL);
>
> status = ZwCreateFile(
> &paramvd->file_handle,
> GENERIC_READ | GENERIC_WRITE , // or FILE_READ_DATA
> &attr,
> &io_status,
> NULL,
> FILE_ATTRIBUTE_NORMAL,
> FILE_SHARE_READ |
> FILE_SHARE_DELETE |
> FILE_SHARE_WRITE,
> FILE_OPEN,
> //IMDISK_TYPE(CreateData->Flags) == IMDISK_TYPE_PROXY ?
> FILE_NON_DIRECTORY_FILE |
> FILE_SEQUENTIAL_ONLY |
> FILE_NO_INTERMEDIATE_BUFFERING |
> FILE_SYNCHRONOUS_IO_NONALERT |
> FILE_NON_DIRECTORY_FILE |
> FILE_RANDOM_ACCESS |
> FILE_NO_INTERMEDIATE_BUFFERING |
> FILE_SYNCHRONOUS_IO_NONALERT,
> NULL,
> 0);
> if (status==STATUS_SUCCESS)
> {
> status =
> ObReferenceObjectByHandle(paramvd->file_handle,
> FILE_READ_ATTRIBUTES |
> FILE_READ_DATA |
> FILE_WRITE_DATA,
> IoFileObjectType,
> KernelMode,
> &paramvd->pipe,
> NULL);
>
>
> if (status==STATUS_SUCCESS)
> {
> KdPrint((“[VDUM] CMD ParametreVirtualDisk pipe ok\n”));
> irp->IoStatus.Information=0;
> paramvd->parametrer=TRUE;
> status=STATUS_SUCCESS;
> }
> else
> {
> KdPrint((“[VDUM] CMD ParametreVirtualDisk pipeerror %x \n”,status));
> }
> }
> else
> KdPrint((“[VDUM] ZwCreateFile status returned %x \n”,status));
> }
> else
> {
> KdPrint((“[VDUM] CMD ParametreVirtualDisk eventsend fail\n”));
> ZwClose(&paramvd->eventrecv);
> status=STATUS_INSUFFICIENT_RESOURCES;
> }
> }
> /else
> {
> KdPrint((“[VDUM] CMD ParametreVirtualDisk eventrecv fail\n”));
> status=STATUS_INSUFFICIENT_RESOURCES;
> }
/
> }
>
> }
> break;
> }
>
> …
> …
>
> NTSTATUS COM_PIPE(PCP cp)
> {
> NTSTATUS status=STATUS_SUCCESS;
> LARGE_INTEGER dt;
> UCHAR len;
> PIO_STATUS_BLOCK ios=cp->iostatusblock;
>
> ULONG length=cp->_length;
> //LONGLONG offset=(cp->offsethigh<<32)+cp->offsetlow;
> ULONG offsethigh=cp->offsethigh;
> ULONG offsetlow=cp->offsetlow;
> PPARAMVD pvd=cp->pvd;
> BOOLEAN writedirect=cp->writedirect;
> UCHAR
buffer=cp->buffer;
> UCHAR commande=cp->commande;
>
> //KdPrint((“COM PIPE 1 Commande %s Offset:%x
> Length:%p\n”,commande,offset,length));
> KdPrint((“COM PIPE Offset:%p%p Length:%p\n”,offsethigh,offsetlow,length));
>
> RtlZeroMemory(&dt, sizeof(LARGE_INTEGER));
>
> KeSetEvent(pvd->eventrecv,(KPRIORITY) 0, FALSE);
> KeClearEvent(pvd->eventrecv);
> len=strlen(commande);
> //KdPrint((“COM PIPE 2 Offset:%p%p
> Length:%p\n”,offsethigh,offsetlow,length));
> VDUM_ReadPipe(pvd->pipe,ios,&writedirect,1,&dt,&status);
> VDUM_ReadPipe(pvd->pipe,ios,&len,1,&dt,&status);
> VDUM_ReadPipe(pvd->pipe,ios,commande,len,&dt,&status);
> VDUM_ReadPipe(pvd->pipe,ios,&offsetlow,sizeof (ULONG),&dt,&status);
> VDUM_ReadPipe(pvd->pipe,ios,&offsethigh,sizeof (ULONG),&dt,&status);
> VDUM_ReadPipe(pvd->pipe,ios,&length,sizeof (ULONG),&dt,&status);
> if (status!=STATUS_SUCCESS)
> {
> KdPrint((“Status VDUM_ReadPipe IN return %x\n”,status));
> return status;
> }
> if (writedirect)
> {
> VDUM_WritePipe(pvd->pipe,ios,buffer,length,&dt,&status);
> }
> if (status!=STATUS_SUCCESS)
> {
> KdPrint((“Status VDUM_WritePipe IN return %x\n”,status));
> return status;
> }
> else
> {
> status=KeWaitForSingleObject(&pvd->eventsend,
> Executive,
> KernelMode,
> FALSE,
> pvd->time_out
1000);
> if (status!=STATUS_SUCCESS)
> {
> KdPrint((“Status KeWaitForSingleObject return %x\n”,status));
> }
> else
> {
> CHAR flag=0;
> status=VDUM_ReadPipe(pvd->pipe,ios,&flag,1,&dt,&status);
> if (status==STATUS_SUCCESS)
> {
> switch (flag)
> {
> case 0:
> if (!writedirect)
> status=VDUM_ReadPipe(pvd->pipe,ios,buffer,length,&dt,&status);
> if (status!=STATUS_SUCCESS)
> {
> KdPrint((“Status VDUM_ReadPipe OUT return %x\n”,status));
> return status;
> }
> break;
> case 1:status=STATUS_ACCESS_DENIED;break;
> case 2:status=STATUS_NOT_IMPLEMENTED;break;
> case 3:status=STATUS_MEDIA_WRITE_PROTECTED;break;
> }
> KdPrint((“Status COM_PIPE personalize OUT return %x\n”,status));
> }
> else
> {
> if (status!=STATUS_SUCCESS)
> {
> KdPrint((“Status ZwReadFile OUT return %x\n”,status));
> }
> }
> }
> }
> return status;
>
>
> }
>
> NTSTATUS
> VDUM_ComPipe(IN PFILE_OBJECT FileObject,
> IN UCHAR MajorFunction,
> OUT PIO_STATUS_BLOCK IoStatusBlock,
> OUT PVOID Buffer,
> IN ULONG Length)
> {
> NTSTATUS status;
> //IO_STATUS_BLOCK IoStatusBlock;
> ULONG length_done = 0;
> KEVENT event;
> PIO_STACK_LOCATION io_stack;
> LARGE_INTEGER offset = { 0 };
>
> PAGED_CODE();
>
> KdPrint((“[VDUM]: FileObject=%#x, MajorFunction=%#x, IoStatusBlock=%#x,
> Buffer=%#x, Length=%#x.\n”, FileObject, MajorFunction, IoStatusBlock,
> Buffer, Length));
>
> ASSERT(FileObject != NULL);
> ASSERT(IoStatusBlock != NULL);
> ASSERT(Buffer != NULL);
>
> KeInitializeEvent(&event,
> NotificationEvent,
> FALSE);
>
> while (length_done < Length)
> {
> ULONG RequestLength = Length - length_done;
>
> do
> {
> PIRP irp;
>
> KdPrint((“[VDUM]: Building IRP…\n”));
>
> irp = IoBuildSynchronousFsdRequest(MajorFunction,
> FileObject->DeviceObject,
> (PUCHAR) Buffer + length_done,
> RequestLength,
> &offset,
> &event,
> IoStatusBlock);
>
> if (irp == NULL)
> {
> KdPrint((“[VDUM]: Error building IRP.\n”));
>
> IoStatusBlock->Status = STATUS_INSUFFICIENT_RESOURCES;
> IoStatusBlock->Information = length_done;
> return IoStatusBlock->Status;
> }
>
> KdPrint((“[VDUM] : Built IRP=%#x.\n”, irp));
>
> io_stack = IoGetNextIrpStackLocation(irp);
> io_stack->FileObject = FileObject;
> io_stack->DeviceObject = FileObject->DeviceObject;
>
> KdPrint((“[VDUM]: MajorFunction= %#x, Length=%#x\n”,
> io_stack->MajorFunction,
> io_stack->Parameters.Write.Length));
>
> KeResetEvent(&event);
>
> status = IoCallDriver(io_stack->FileObject->DeviceObject, irp);
>
> if (status == STATUS_PENDING)
> KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
> else if (!NT_SUCCESS(status))
> break;
>
> status = IoStatusBlock->Status;
>
> KdPrint((“[VDUM]: IRP %#x completed. Status=%#x.\n”,
> irp, IoStatusBlock->Status));
>
> RequestLength >>= 1;
> }
> while ((status == STATUS_INVALID_BUFFER_SIZE) |
> (status == STATUS_INVALID_PARAMETER));
>
> if (!NT_SUCCESS(status))
> {
> KdPrint((“[VDUM]: I/O failed. Status=%#x.\n”, status));
>
> IoStatusBlock->Status = status;
> IoStatusBlock->Information = 0;
> return IoStatusBlock->Status;
> }
>
> KdPrint((“[VDUM]: I/O done. Status=%#x. Length=%#x\n”,
> status, IoStatusBlock->Information));
>
> if (IoStatusBlock->Information == 0)
> {
> IoStatusBlock->Status = STATUS_CONNECTION_RESET;
> IoStatusBlock->Information = 0;
> return IoStatusBlock->Status;
> }
>
> length_done += (ULONG) IoStatusBlock->Information;
> }
>
> KdPrint((“[VDUM]: I/O complete.\n”));
>
> IoStatusBlock->Status = STATUS_SUCCESS;
> IoStatusBlock->Information = length_done;
> return IoStatusBlock->Status;
> }
>
> NTSTATUS
> VDUM_ReadPipe(IN PFILE_OBJECT ProxyDevice,
> OUT PIO_STATUS_BLOCK IoStatusBlock,
> OUT PVOID Buffer,
> IN ULONG Length,
> IN PLARGE_INTEGER ByteOffset,
> NTSTATUS *status)
> {
>
>
>
> PAGED_CODE();
>
> /ASSERT(ProxyDevice != NULL);
> ASSERT(IoStatusBlock != NULL);
> ASSERT(Buffer != NULL);
> ASSERT(ByteOffset != NULL);
/
>
> if (*status==STATUS_SUCCESS)
> {
>
> *status = VDUM_ComPipe(ProxyDevice,
> IRP_MJ_READ,
> IoStatusBlock,
> Buffer,
> (ULONG) Length);
>
> if (!NT_SUCCESS(*status))
> KdPrint((“[VDUM] Proxy Client: Data stream of %u bytes received with I/O
> “
> “status %#x. Status returned by stream reader is %#x.\n”,
> IoStatusBlock->Information, IoStatusBlock->Status, status));
>
> KdPrint
> ((”[VDUM]: Received %u byte data stream.\n”,
> IoStatusBlock->Information));
> }
> return *status;
> }
>
>
>
> typedef struct {
> PPARAMVD pvd;
> UCHAR *commande;
> //LONGLONG offset;
> ULONG offsethigh;
> ULONG offsetlow;
> ULONG _length;
> UCHAR *buffer;
> BOOLEAN writedirect;
> PIO_STATUS_BLOCK iostatusblock;
> }TCP,*PCP;
> …
> …
> case IRP_MJ_READ:
> TCP cp;
> ULONG len=0;
> ULONG lxx=0;
> LONGLONG xl=0;
> PUCHAR buffer;
> PUCHAR system_buffer =
> (PUCHAR) MmGetSystemAddressForMdlSafe(irp->MdlAddress,
> NormalPagePriority);
> LARGE_INTEGER offset;
>
> if (system_buffer == NULL)
> {
> status=irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
> irp->IoStatus.Information = 0;
> break;
> }
> buffer = (PUCHAR)ExAllocatePool(NonPagedPool,
> io_stack->Parameters.Read.Length);
> if (buffer == NULL)
> {
> status=irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
> irp->IoStatus.Information = 0;
> break;
> }
>
> if (io_stack->MajorFunction==IRP_MJ_WRITE)
> {
> KdPrint((“[VDUM] Device %i got write request Offset=%p%p Len=%p.\n”,
> pvd->index,
> io_stack->Parameters.Read.ByteOffset.HighPart,
> io_stack->Parameters.Read.ByteOffset.LowPart,
> io_stack->Parameters.Read.Length));
>
>
>
> RtlCopyMemory(buffer,system_buffer, irp->IoStatus.Information);
> xl=io_stack->Parameters.Read.ByteOffset.LowPart+(io_stack->Parameters.Read.ByteOffset.HighPart<<32);
> cp.pvd=pvd;
> cp.commande=cWRITE;
> //cp.offset=xl;
> cp.offsethigh=io_stack->Parameters.Read.ByteOffset.HighPart;
> cp.offsetlow=io_stack->Parameters.Read.ByteOffset.LowPart;
> cp._length=io_stack->Parameters.Read.Length;
> cp.writedirect=TRUE;
> cp.iostatusblock=&irp->IoStatus;
> status=COM_PIPE(&cp);
>
> irp->IoStatus.Information=0;
>
> }
> else
> if (io_stack->MajorFunction==IRP_MJ_READ)
> {
>
>
> len=io_stack->Parameters.Read.Length;
>
> xl=io_stack->Parameters.Read.ByteOffset.LowPart+(io_stack->Parameters.Read.ByteOffset.HighPart<<32);
>
> irp->IoStatus.Information = io_stack->Parameters.Read.Length;
>
>
>
>
>
> cp._length=len;
> cp.pvd=pvd;
> cp.commande=cREAD;
>
>
>
> cp.offsethigh=io_stack->Parameters.Read.ByteOffset.HighPart;
> cp.offsetlow=io_stack->Parameters.Read.ByteOffset.LowPart;
>
> cp.writedirect=FALSE;
> cp.iostatusblock=&irp->IoStatus;
>
>
> status=COM_PIPE(&cp);
> if (status==STATUS_SUCCESS)
> RtlCopyMemory(system_buffer, buffer,irp->IoStatus.Information);
> if (status!=STATUS_SUCCESS)
> irp->IoStatus.Information=0;
>
> }
>
>
> ExFreePool(buffer);
> }
> break;
>
>
>
>
> User - mode :
>
> DWORD WINAPI threadC(PVOID context)
> {
> PCT ct=(PCT)context;
> Sleep(3000);
> DWORD dt=0;
> DeviceIoControl(ct->hf,IOCTL_CMD_PARAMETERVIRTUALDISK,ct->configvd,sizeof
> (TCONFIGVD),NULL,0,&dt,NULL);
> ct->heventrecv=OpenEvent(SYNCHRONIZE,false,“VDUMeventrecv”);
> ct->heventsend=OpenEvent(SYNCHRONIZE,false,“VDUMeventsend”);
> return 0;
> }
>
>
> wcscpy(configvd->pipe,L"VDUMtest");
> wcscpy(configvd->eventrecv,L"VDUMeventrecv");
> wcscpy(configvd->eventsend,L"VDUMeventsend");
>
> HANDLE hConnectEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
>
>
> TCHAR s2[128];
> HANDLE hPipe = CreateNamedPipe(
> “\\.\Pipe\VDUMtest”, // pipe name
> PIPE_ACCESS_DUPLEX| // read/write access
> FILE_FLAG_WRITE_THROUGH, // message type pipe
> PIPE_WAIT, // blocking mode
> PIPE_UNLIMITED_INSTANCES, // max. instances
> BUFSIZE, // output buffer size
> BUFSIZE, // input buffer size
> 100, // client time-out
> NULL);
>
> // default security attribute
> DWORD dt=0;
> SetLastError(0);
> WORD thid=0;
> hthread=CreateThread(NULL,0,threadC,ct,0,&thid);
> if (fConnected)
> {
> while (!sort)
> {
> char commande[64];
> char len=0;
> int x=WaitForSingleObject(ct->heventrecv,5000);
>
> if ((x==WAIT_OBJECT_0)&&(!sort))
> {
> DWORD dt=0;
> bool writedirect=false;
> LARGE_INTEGER offset;
> ZeroMemory(&offset,sizeof (LARGE_INTEGER));
> ULONG length=0;
> ReadFile(hPipe,&writedirect,1,&dt,NULL);
>
>
> Can you help please ???
> A Access at IRP_MJ_READ , the event ct->heventrecv is setted by kernel but
> ReadFile Block
> Yet although the driver called function COM_PIPE to send data to the pipe.
> I understand nothing at all!
>
> Thank you
>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer

First, perhaps, you might ask yourself why you want to use a PIPE as the
form of communication between UM and KM.

What, for instance, is wrong with Read/Write or IOCTL?

Do you really need the facilities of Named Pipes or are you just stuck on
thinking that is a good way to shuffle bits around?

It’s your KM driver right? It’s your UM service right? Why not have them
communicate ‘directly’ instead of having an intermediate facility (Named
Pipes) be involved.

Good Luck,
Dave Cattley

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@sivaller.no-ip.org
Sent: Tuesday, October 20, 2009 3:04 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Please help ! Link data pipe user-mode<–>kernel-mode

Hello
I wish I had one source sample C that communicates by pipe of
user-mode<–>kernel-mode.

A Sample which work please !
I understand nothing at all!

Thank you.

Party function Vdum_Compipe :
status = IoCallDriver(io_stack->FileObject->DeviceObject, irp);

if (status == STATUS_PENDING)
KeWaitForSingleObject(&event, Executive, KernelMode, FALSE,
NULL); // There is blocking same why ReadFile of this pipe is called of
user-mode
else if (!NT_SUCCESS(status))
break;

But the pipe is creating!

Incomplete Sample :

typedef struct {
WCHAR pipe[64];
WCHAR eventrecv[64];
WCHAR eventsend[64];
DWORD sizeko;
CHAR letter;
DISK_GEOMETRY disk_geometry;
UCHAR time_out;

}TCONFIGVD,*PCONFIGVD;

Kernel-Mode

NTSTATUS vdums_deviceiocontrol(IN PDEVICE_OBJECT DeviceObject, IN PIRP irp,
PIO_STACK_LOCATION irps)
{
NTSTATUS status=STATUS_NOT_IMPLEMENTED;

switch (iocode)
{


case IOCTL_CMD_PARAMETERVIRTUALDISK:
{
WCHAR eventsend[256];
WCHAR eventrecv[256];
KdPrint((“[VDUM] CMD
ParametreVirtualDisk\n”));
if
((irps->Parameters.DeviceIoControl.InputBufferLength < sizeof(TCONFIGVD)))
{
KdPrint((“[VDUM] CMD
ParametreVirtualDisk Size mismatch\n”));
status = STATUS_INVALID_PARAMETER;
irp->IoStatus.Information = 0;
break;
}

configvd=(PCONFIGVD)irp->AssociatedIrp.SystemBuffer;

lod=VDUM_GetDevice(configvd->letter);
status=STATUS_INVALID_HANDLE;
if (lod!=0)
{
UNICODE_STRING
uszNotifyEventString,pipe_name,uszsend,uszrecv;
KdPrint((“[VDUM] CMD
ParametreVirtualDisk lod ok\n”));
paramvd=(PPARAMVD)
lod->DeviceExtension;

/*RtlInitUnicodeString(&uszNotifyEventString,

configvd->eventrecv);
paramvd->eventrecv =
IoCreateNotificationEvent(&uszNotifyEventString,
&paramvd->NotifyHandleRecv);*/
//if
(paramvd->eventrecv!=NULL)
{

KdPrint((“[VDUM] CMD ParametreVirtualDisk eventrecv ok\n”));

wcscpy(eventsend,L"\BaseNamedObjects\");

wcscpy(eventrecv,L"\BaseNamedObjects\");

wcscat(eventsend,configvd->eventsend);

wcscat(eventrecv,configvd->eventrecv);

KdPrint((“[VDUM] CMD ParametreVirtualDisk EventSend Name %ws\n”,eventsend));

KdPrint((“[VDUM] CMD ParametreVirtualDisk EventRecv Name %ws\n”,eventrecv));

RtlInitUnicodeString(&uszsend,

eventsend);

RtlInitUnicodeString(&uszrecv,

eventrecv);

paramvd->eventsend = IoCreateNotificationEvent(&uszsend,
&paramvd->NotifyHandleSend);

paramvd->eventrecv = IoCreateNotificationEvent(&uszrecv,
&paramvd->NotifyHandleRecv);

KeClearEvent(paramvd->eventsend);

KeClearEvent(paramvd->eventrecv);

if
(paramvd->eventsend!=NULL)
{

KdPrint((“[VDUM] CMD ParametreVirtualDisk eventsend ok\n”));

wcscpy(wpipe,L"\??\pipe\");

wcscat(wpipe,configvd->pipe);

paramvd->sizeko=configvd->sizeko;

paramvd->disk_geometry=configvd->disk_geometry;

paramvd->time_out=configvd->time_out;

KdPrint((“[VDUM] CMD ParametreVirtualDisk pipe name %ws\n”,wpipe));

RtlInitUnicodeString(

&pipe_name,

wpipe

);

InitializeObjectAttributes(

&attr,

&pipe_name,

OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,

NULL,

NULL);

status = ZwCreateFile(

&paramvd->file_handle,

GENERIC_READ | GENERIC_WRITE , // or FILE_READ_DATA

&attr,

&io_status,

NULL,

FILE_ATTRIBUTE_NORMAL,

FILE_SHARE_READ |

FILE_SHARE_DELETE |

FILE_SHARE_WRITE,

FILE_OPEN,

//IMDISK_TYPE(CreateData->Flags) == IMDISK_TYPE_PROXY ?

FILE_NON_DIRECTORY_FILE |

FILE_SEQUENTIAL_ONLY |

FILE_NO_INTERMEDIATE_BUFFERING |

FILE_SYNCHRONOUS_IO_NONALERT |

FILE_NON_DIRECTORY_FILE |

FILE_RANDOM_ACCESS |

FILE_NO_INTERMEDIATE_BUFFERING |

FILE_SYNCHRONOUS_IO_NONALERT,

NULL,

0);

if (status==STATUS_SUCCESS)

{

status =

ObReferenceObjectByHandle(paramvd->file_handle,

FILE_READ_ATTRIBUTES |

FILE_READ_DATA |

FILE_WRITE_DATA,

*IoFileObjectType,

KernelMode,

&paramvd->pipe,

NULL);

if (status==STATUS_SUCCESS)

{

KdPrint((“[VDUM] CMD ParametreVirtualDisk pipe ok\n”));

irp->IoStatus.Information=0;

paramvd->parametrer=TRUE;

status=STATUS_SUCCESS;

}

else

{

KdPrint((“[VDUM] CMD ParametreVirtualDisk pipeerror %x \n”,status));

}

}

else

KdPrint((“[VDUM] ZwCreateFile status returned %x \n”,status));
}
else
{

KdPrint((“[VDUM] CMD ParametreVirtualDisk eventsend fail\n”));

ZwClose(&paramvd->eventrecv);

status=STATUS_INSUFFICIENT_RESOURCES;
}
}
/*else
{
KdPrint((“[VDUM] CMD
ParametreVirtualDisk eventrecv fail\n”));

status=STATUS_INSUFFICIENT_RESOURCES;
}*/
}

}
break;
}


NTSTATUS COM_PIPE(PCP cp)
{
NTSTATUS status=STATUS_SUCCESS;
LARGE_INTEGER dt;
UCHAR len;
PIO_STATUS_BLOCK ios=cp->iostatusblock;

ULONG length=cp->_length;
//LONGLONG offset=(cp->offsethigh<<32)+cp->offsetlow;
ULONG offsethigh=cp->offsethigh;
ULONG offsetlow=cp->offsetlow;
PPARAMVD pvd=cp->pvd;
BOOLEAN writedirect=cp->writedirect;
UCHAR* buffer=cp->buffer;
UCHAR *commande=cp->commande;

//KdPrint((“COM PIPE 1 Commande %s Offset:%x
Length:%p\n”,commande,offset,length));
KdPrint((“COM PIPE Offset:%p%p
Length:%p\n”,offsethigh,offsetlow,length));

RtlZeroMemory(&dt, sizeof(LARGE_INTEGER));

KeSetEvent(pvd->eventrecv,(KPRIORITY) 0, FALSE);
KeClearEvent(pvd->eventrecv);
len=strlen(commande);
//KdPrint((“COM PIPE 2 Offset:%p%p
Length:%p\n”,offsethigh,offsetlow,length));
VDUM_ReadPipe(pvd->pipe,ios,&writedirect,1,&dt,&status);
VDUM_ReadPipe(pvd->pipe,ios,&len,1,&dt,&status);
VDUM_ReadPipe(pvd->pipe,ios,commande,len,&dt,&status);
VDUM_ReadPipe(pvd->pipe,ios,&offsetlow,sizeof (ULONG),&dt,&status);
VDUM_ReadPipe(pvd->pipe,ios,&offsethigh,sizeof (ULONG),&dt,&status);
VDUM_ReadPipe(pvd->pipe,ios,&length,sizeof (ULONG),&dt,&status);
if (status!=STATUS_SUCCESS)
{
KdPrint((“Status VDUM_ReadPipe IN return %x\n”,status));
return status;
}
if (writedirect)
{
VDUM_WritePipe(pvd->pipe,ios,buffer,length,&dt,&status);
}
if (status!=STATUS_SUCCESS)
{
KdPrint((“Status VDUM_WritePipe IN return %x\n”,status));
return status;
}
else
{
status=KeWaitForSingleObject(&pvd->eventsend,

Executive,

KernelMode,

FALSE,

pvd->time_out*1000);
if (status!=STATUS_SUCCESS)
{
KdPrint((“Status
KeWaitForSingleObject return %x\n”,status));
}
else
{
CHAR flag=0;

status=VDUM_ReadPipe(pvd->pipe,ios,&flag,1,&dt,&status);
if (status==STATUS_SUCCESS)
{
switch (flag)
{
case 0:
if (!writedirect)

status=VDUM_ReadPipe(pvd->pipe,ios,buffer,length,&dt,&status);
if
(status!=STATUS_SUCCESS)
{

KdPrint((“Status VDUM_ReadPipe OUT return %x\n”,status));
return
status;
}
break;
case
1:status=STATUS_ACCESS_DENIED;break;
case
2:status=STATUS_NOT_IMPLEMENTED;break;
case
3:status=STATUS_MEDIA_WRITE_PROTECTED;break;
}
KdPrint((“Status COM_PIPE
personalize OUT return %x\n”,status));
}
else
{
if (status!=STATUS_SUCCESS)
{
KdPrint((“Status ZwReadFile
OUT return %x\n”,status));
}
}
}
}
return status;

}

NTSTATUS
VDUM_ComPipe(IN PFILE_OBJECT FileObject,
IN UCHAR MajorFunction,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID Buffer,
IN ULONG Length)
{
NTSTATUS status;
//IO_STATUS_BLOCK IoStatusBlock;
ULONG length_done = 0;
KEVENT event;
PIO_STACK_LOCATION io_stack;
LARGE_INTEGER offset = { 0 };

PAGED_CODE();

KdPrint((“[VDUM]: FileObject=%#x, MajorFunction=%#x, IoStatusBlock=%#x,
Buffer=%#x, Length=%#x.\n”, FileObject, MajorFunction, IoStatusBlock,
Buffer, Length));

ASSERT(FileObject != NULL);
ASSERT(IoStatusBlock != NULL);
ASSERT(Buffer != NULL);

KeInitializeEvent(&event,
NotificationEvent,
FALSE);

while (length_done < Length)
{
ULONG RequestLength = Length - length_done;

do
{
PIRP irp;

KdPrint((“[VDUM]: Building IRP…\n”));

irp = IoBuildSynchronousFsdRequest(MajorFunction,
FileObject->DeviceObject,
(PUCHAR) Buffer + length_done,
RequestLength,
&offset,
&event,
IoStatusBlock);

if (irp == NULL)
{
KdPrint((“[VDUM]: Error building IRP.\n”));

IoStatusBlock->Status = STATUS_INSUFFICIENT_RESOURCES;
IoStatusBlock->Information = length_done;
return IoStatusBlock->Status;
}

KdPrint((“[VDUM] : Built IRP=%#x.\n”, irp));

io_stack = IoGetNextIrpStackLocation(irp);
io_stack->FileObject = FileObject;
io_stack->DeviceObject = FileObject->DeviceObject;

KdPrint((“[VDUM]: MajorFunction= %#x, Length=%#x\n”,
io_stack->MajorFunction,
io_stack->Parameters.Write.Length));

KeResetEvent(&event);

status = IoCallDriver(io_stack->FileObject->DeviceObject, irp);

if (status == STATUS_PENDING)
KeWaitForSingleObject(&event, Executive, KernelMode, FALSE,
NULL);
else if (!NT_SUCCESS(status))
break;

status = IoStatusBlock->Status;

KdPrint((“[VDUM]: IRP %#x completed. Status=%#x.\n”,
irp, IoStatusBlock->Status));

RequestLength >>= 1;
}
while ((status == STATUS_INVALID_BUFFER_SIZE) |
(status == STATUS_INVALID_PARAMETER));

if (!NT_SUCCESS(status))
{
KdPrint((“[VDUM]: I/O failed. Status=%#x.\n”, status));

IoStatusBlock->Status = status;
IoStatusBlock->Information = 0;
return IoStatusBlock->Status;
}

KdPrint((“[VDUM]: I/O done. Status=%#x. Length=%#x\n”,
status, IoStatusBlock->Information));

if (IoStatusBlock->Information == 0)
{
IoStatusBlock->Status = STATUS_CONNECTION_RESET;
IoStatusBlock->Information = 0;
return IoStatusBlock->Status;
}

length_done += (ULONG) IoStatusBlock->Information;
}

KdPrint((“[VDUM]: I/O complete.\n”));

IoStatusBlock->Status = STATUS_SUCCESS;
IoStatusBlock->Information = length_done;
return IoStatusBlock->Status;
}

NTSTATUS
VDUM_ReadPipe(IN PFILE_OBJECT ProxyDevice,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset,
NTSTATUS *status)
{

PAGED_CODE();

/*ASSERT(ProxyDevice != NULL);
ASSERT(IoStatusBlock != NULL);
ASSERT(Buffer != NULL);
ASSERT(ByteOffset != NULL);*/

if (*status==STATUS_SUCCESS)
{

*status = VDUM_ComPipe(ProxyDevice,
IRP_MJ_READ,
IoStatusBlock,
Buffer,
(ULONG) Length);

if (!NT_SUCCESS(*status))
KdPrint(("[VDUM] Proxy Client: Data stream of %u bytes received
with I/O "
“status %#x. Status returned by stream reader is %#x.\n”,
IoStatusBlock->Information, IoStatusBlock->Status, status));

KdPrint
((“[VDUM]: Received %u byte data stream.\n”,
IoStatusBlock->Information));
}
return *status;
}

typedef struct {
PPARAMVD pvd;
UCHAR *commande;
//LONGLONG offset;
ULONG offsethigh;
ULONG offsetlow;
ULONG _length;
UCHAR *buffer;
BOOLEAN writedirect;
PIO_STATUS_BLOCK iostatusblock;
}TCP,*PCP;


case IRP_MJ_READ:
TCP cp;
ULONG len=0;
ULONG lxx=0;
LONGLONG xl=0;
PUCHAR buffer;
PUCHAR system_buffer =
(PUCHAR)
MmGetSystemAddressForMdlSafe(irp->MdlAddress,

NormalPagePriority);
LARGE_INTEGER offset;

if (system_buffer == NULL)
{
status=irp->IoStatus.Status
= STATUS_INSUFFICIENT_RESOURCES;
irp->IoStatus.Information =
0;
break;
}
buffer =
(PUCHAR)ExAllocatePool(NonPagedPool, io_stack->Parameters.Read.Length);
if (buffer == NULL)
{
status=irp->IoStatus.Status
= STATUS_INSUFFICIENT_RESOURCES;
irp->IoStatus.Information =
0;
break;
}

if (io_stack->MajorFunction==IRP_MJ_WRITE)
{
KdPrint((“[VDUM] Device %i got write
request Offset=%p%p Len=%p.\n”,
pvd->index,
io_stack->Parameters.Read.ByteOffset.HighPart,
io_stack->Parameters.Read.ByteOffset.LowPart,
io_stack->Parameters.Read.Length));

RtlCopyMemory(buffer,system_buffer,
irp->IoStatus.Information);

xl=io_stack->Parameters.Read.ByteOffset.LowPart+(io_stack->Parameters.Read.B
yteOffset.HighPart<<32);
cp.pvd=pvd;
cp.commande=cWRITE;
//cp.offset=xl;

cp.offsethigh=io_stack->Parameters.Read.ByteOffset.HighPart;

cp.offsetlow=io_stack->Parameters.Read.ByteOffset.LowPart;
cp._length=io_stack->Parameters.Read.Length;
cp.writedirect=TRUE;
cp.iostatusblock=&irp->IoStatus;
status=COM_PIPE(&cp);

irp->IoStatus.Information=0;

}
else
if (io_stack->MajorFunction==IRP_MJ_READ)
{

len=io_stack->Parameters.Read.Length;

xl=io_stack->Parameters.Read.ByteOffset.LowPart+(io_stack->Parameters.Read.B
yteOffset.HighPart<<32);

irp->IoStatus.Information =
io_stack->Parameters.Read.Length;

cp._length=len;
cp.pvd=pvd;
cp.commande=cREAD;

cp.offsethigh=io_stack->Parameters.Read.ByteOffset.HighPart;

cp.offsetlow=io_stack->Parameters.Read.ByteOffset.LowPart;

cp.writedirect=FALSE;
cp.iostatusblock=&irp->IoStatus;

status=COM_PIPE(&cp);
if (status==STATUS_SUCCESS)
RtlCopyMemory(system_buffer,
buffer,irp->IoStatus.Information);
if (status!=STATUS_SUCCESS)
irp->IoStatus.Information=0;

}

ExFreePool(buffer);
}
break;

User - mode :

DWORD WINAPI threadC(PVOID context)
{
PCT ct=(PCT)context;
Sleep(3000);
DWORD dt=0;

DeviceIoControl(ct->hf,IOCTL_CMD_PARAMETERVIRTUALDISK,ct->configvd,sizeof
(TCONFIGVD),NULL,0,&dt,NULL);
ct->heventrecv=OpenEvent(SYNCHRONIZE,false,“VDUMeventrecv”);
ct->heventsend=OpenEvent(SYNCHRONIZE,false,“VDUMeventsend”);
return 0;
}

wcscpy(configvd->pipe,L"VDUMtest");
wcscpy(configvd->eventrecv,L"VDUMeventrecv");
wcscpy(configvd->eventsend,L"VDUMeventsend");

HANDLE hConnectEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

TCHAR s2[128];
HANDLE hPipe = CreateNamedPipe(
“\\.\Pipe\VDUMtest”, // pipe name
PIPE_ACCESS_DUPLEX| // read/write access
FILE_FLAG_WRITE_THROUGH, // message type pipe
PIPE_WAIT, // blocking mode
PIPE_UNLIMITED_INSTANCES, // max. instances
BUFSIZE, // output buffer size
BUFSIZE, // input buffer size
100, // client time-out
NULL);

// default security attribute
DWORD dt=0;
SetLastError(0);
WORD thid=0;
hthread=CreateThread(NULL,0,threadC,ct,0,&thid);
if (fConnected)
{
while (!sort)
{
char commande[64];
char len=0;
int
x=WaitForSingleObject(ct->heventrecv,5000);

if ((x==WAIT_OBJECT_0)&&(!sort))
{
DWORD dt=0;
bool writedirect=false;
LARGE_INTEGER offset;
ZeroMemory(&offset,sizeof
(LARGE_INTEGER));
ULONG length=0;

ReadFile(hPipe,&writedirect,1,&dt,NULL);

Can you help please ???
A Access at IRP_MJ_READ , the event ct->heventrecv is setted by kernel but
ReadFile Block
Yet although the driver called function COM_PIPE to send data to the pipe.
I understand nothing at all!

Thank you


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

a) Please read and follow the guidelines at: http://catb.org/~esr/faqs/smart-questions.html – Note these are cited in the FAQ for this list.

b) Please resist the temptation to post a thousand lines of random code. If you have a question please ask it specifically and clearly, with specific supporting code fragments. “I understand nothing at all” is not a question, and neither is “help please”…

I’m not trying to be harsh, I’m trying to help you get answers,

Peter
OSR

I’m not an expert, but I’ve in the situation where I want to send data
to the user <-> kernel and I even have pipe mode communication code
already written ( sorry I can’t away company code) but I am still
writing the driver to support IOCTL Read/Write commands. I think this
is the standard way of communicating with driver. So I suggest for you
to look at C:\WinDDK<version> \src\general\ioctl for a wonderful
example of communicating in 3 different modes.

Cheers
Obble.

“David R. Cattley” wrote in message news:xxxxx@ntdev…
> First, perhaps, you might ask yourself why you want to use a PIPE as the
> form of communication between UM and KM.
>
> What, for instance, is wrong with Read/Write or IOCTL?
>
> Do you really need the facilities of Named Pipes or are you just stuck on
> thinking that is a good way to shuffle bits around?

What if OP wants an uniform way to do IPC, not having to know
who is the other party - be it a kernel driver,
UMDF driver or a normal usermode service?

In such situations every Linux-minded person I know would use a tcp/ip
socket
on localhost, without even thinking a second. But this seems a bit wasteful.

Well, finally we’ve got kernel sockets on NT6, and winsock direct…

–pa

Yes, I have seen that done as well since it made expressing certain types of
drivers ‘uniform’ across 9x, NT, CE, and even the odd ‘other’ platform.
Although in each case the endpoints were sure to bind only to ‘local’
(127.xxx.xxx.xxx) address and allow connection from the same.

This obliterates security of course since you really cannot control who on
the local machine can connect. It is an incredibly unsafe way of performing
KM/UM communications since each and every one of the aforementioned
platforms (*nixs too I would guess) have IOCTL.

Since the OP had settled on Named Pipes, I am guess that they were not
looking for a ‘uniform’ way to do IPC :slight_smile:

I will leave it to the OP to express the constraints and goals.

Dave Cattley

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Pavel A.
Sent: Tuesday, October 20, 2009 9:29 PM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] Please help ! Link data pipe user-mode<–>kernel-mode

“David R. Cattley” wrote in message news:xxxxx@ntdev…
> First, perhaps, you might ask yourself why you want to use a PIPE as the
> form of communication between UM and KM.
>
> What, for instance, is wrong with Read/Write or IOCTL?
>
> Do you really need the facilities of Named Pipes or are you just stuck on
> thinking that is a good way to shuffle bits around?

What if OP wants an uniform way to do IPC, not having to know
who is the other party - be it a kernel driver,
UMDF driver or a normal usermode service?

In such situations every Linux-minded person I know would use a tcp/ip
socket
on localhost, without even thinking a second. But this seems a bit wasteful.

Well, finally we’ve got kernel sockets on NT6, and winsock direct…

–pa


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

> In such situations every Linux-minded person I know would use a tcp/ip

socket
on localhost

In Windows, this will result in lots of interop issues with all existing firewall software.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com