Printing out Recieved string from DeviceIOControl

Hi,
apologies for maybe a noob question, but am just starting with Windows Driver programming.

I am trying to create an IOCTL and communicate with the driver from a user mode application. I am sending a string (char) to KM and printing it out in Windbg. In turn, KM will send another string back (char again) and I want to print it on a Mesage box or window text or anything.

The string I am sending from my user mode application is arriving fine and I can print it out in WinDbg.
However, from the UM application, I cannot see the recieved string in the DeviceIOControl function.

Here is my User Mode function PART:

HANDLE hDevice;
DWORD nb;
CString Windowmessage = L" ";
char texttosend[4] = “arg”; //I am sending this
CHAR pRecievedString[250]; //I am supposed to recieve in this

bool bResult = 0;

Windowmessage.Append(L"Sending meessage to Kernel Mode\r\n");
GetDlgItem(OutputTextboxec)->SetWindowTextW(Windowmessage);

Windowmessage.Append(L"Creating FileIO\r\n");
GetDlgItem(OutputTextboxec)->SetWindowTextW(Windowmessage);

hDevice = CreateFile(
	TEXT("\\\\.\\DOSXXXDeviceName"),			//File Name of File or IO device
	GENERIC_READ | GENERIC_WRITE,		//Desired Access 
	0,							     //share mode (0-prevent other processes from opening a file f they request delete/read/write access)
										//FILE_SHARE_DELETE(0x00000004),FILE_SHARE_READ(0x00000001),FILE_SHARE_WRITE(0x00000002),
	NULL,								//SecurityAttributes
	OPEN_EXISTING,						//CreationDisposition:An action to take on a file or device that exists or does not exist.
	FILE_ATTRIBUTE_NORMAL,				// FlagsAndAttributes
	NULL);								// TemplateFile


Windowmessage.Append(L"Sending Control Command \r\n");
GetDlgItem(OutputTextboxec)->SetWindowTextW(Windowmessage);

ZeroMemory(pRecievedString, sizeof(pRecievedString));

bResult = DeviceIoControl(
			hDevice, IOCTL_ADDEXT,
			&texttosend, sizeof(texttosend),
			pRecievedString, sizeof(pRecievedString) ,
			&nb, NULL);

Windowmessage.Append(L"Add Ext Cmnd sent\r\n");
GetDlgItem(OutputTextboxec)->SetWindowTextW(Windowmessage);
	
_**// I tried a lot of formatting to output PRecievedString here but to no avail. %c outputs rubbish. %s creates a memory error//**_
/*wchar_t op[200] = {L'0'};
swprintf(op, sizeof(op), L"in: % %c %s   \r\n ", pRecievedString, pRecievedString);

Windowmessage.Append(op);
GetDlgItem(OutputTextboxec)->SetWindowTextW(Windowmessage);*/

CloseHandle(hDevice);

}

And here is my Kernel Mode function

RegisterExtension_BufferedIO(PIRP Irp, PIO_STACK_LOCATION pIoStackIrp, ULONG_PTR dwDataWritten)
{
PAGED_CODE();

NTSTATUS status = STATUS_UNSUCCESSFUL;
PCHAR pOutputBuffer, pInputBuffer;
ULONG dwDataRead = 0;
PCHAR pReturnData = "Hello from Kernel Buffered IO";
UINT16 dwDataSize = sizeof("Hello from Kernel Buffered IO");

KdPrint(("->->->In Register Extension Buffered IO\r\n"));

pInputBuffer = Irp->AssociatedIrp.SystemBuffer;
pOutputBuffer = Irp->AssociatedIrp.SystemBuffer;

if (pInputBuffer && pOutputBuffer)
{
	if (IsStringTerminated(pInputBuffer, pIoStackIrp->Parameters.DeviceIoControl.InputBufferLength, dwDataRead))
	{
		KdPrint((" Message from User Mode: %s \r\n", pInputBuffer));
		KdPrint((" Output buffer length: %i >= %i:DataSize to Send to UM? \r\n ", pIoStackIrp->Parameters.DeviceIoControl.OutputBufferLength, dwDataSize));

		if (pIoStackIrp->Parameters.DeviceIoControl.OutputBufferLength >= dwDataSize)
		{

			RtlCopyMemory(pOutputBuffer, pReturnData, dwDataSize);
			KdPrint(("Output Buffer = %s \r\n", pOutputBuffer));   _**//This prints fine but I do not see it in User Mode **_
			dwDataWritten = dwDataSize;
			status = STATUS_SUCCESS;
		}
		else
		{
			dwDataWritten = dwDataSize;
			status = STATUS_BUFFER_TOO_SMALL;
		}
	}
}
return status;

}

I know that something is arriving back cause when I initiate pRecievedString, it prints out rubbish. However if I initiate it and do not call DeviceIOControl I see the initiated string in the TextWindow.

I hope it is just some stupid formatting issue.

thanks in advance for your help.
regards
Mario

Not sure if there are other problems, but:

dwDataWritten = dwDataSize;

Doesn’t return anything to the caller. You need PULONG_PTR and a *dwDataWritten. Setting a breakpoint and stepping through your code probably would have been faster…

Also, WHY are you passing strings around like this?

@“Scott_Noone_(OSR)” said:
Not sure if there are other problems, but:

dwDataWritten = dwDataSize;

Doesn’t return anything to the caller. You need PULONG_PTR and a *dwDataWritten. Setting a breakpoint and stepping through your code probably would have been faster…

Also, WHY are you passing strings around like this?

Thanks for the reply. As I said I’m new to this and even after a lot of reading I am still thinking with the ‘high level language’ mind. Hence why I am ‘passing strings around’ like this. I do not know how to make sure that something has been sent from Kernel to User mode (and thus can be used by it) ,and vice versa.

The first things for you to consider are:

  1. Why are you posting this to the file system development forum? Would not NTDEV be more appropriate? Or are you trying to write a file system or filter?
  2. If you’re not trying to write a file system or filter, you should be using WDF… it’ll make your file much easier.

Peter

@“Peter_Viscarola_(OSR)” said:
The first things for you to consider are:

  1. Why are you posting this to the file system development forum? Would not NTDEV be more appropriate? Or are you trying to write a file system or filter?
  2. If you’re not trying to write a file system or filter, you should be using WDF… it’ll make your file much easier.

Peter

HI Peter,
I’m writing a MiniFilter to filter certain operations, but using IOCTL to control it from USER mode. Hence why I posted in NTFS, but on second thoughts, since my question regarded specifically IOCTLs, maybe I should repost it in the NTDEV forum.
My Apologies.

You should look at using a Communication Port instead, much easier to deal with than IRPs for a minfilter.

@“Scott_Noone_(OSR)” said:
Not sure if there are other problems, but:

dwDataWritten = dwDataSize;

Doesn’t return anything to the caller. You need PULONG_PTR and a *dwDataWritten. Setting a breakpoint and stepping through your code probably would have been faster…

Also, WHY are you passing strings around like this?

Hi Scott, thanks a lot, that was my mistake. using dwDataWritten solved the issue. Need kick up my a** on my pointer knowledge