Folks,
I have implemented a IOCTL interface in my driver.
All my IOCTLs are METHOD_BUFFERED.
My user application need some info from my driver.
Inside my driver if the buffer length is insufficient, then i return with
error status STATUS_BUFFER_TOO_SMALL which eventually translates to Win32
error code
ERROR_INSUFFICIENT_BUFFER for my user mode app (I do a GetLastError() just
after DeviceIoControl).
After this my user app frees that buffer and increase the buffer size and
again do a DeviceIoControl.
My driver sees that buffer length is enough for I/O to perform.
This time I get SUCCESS return status (.i.e a non zero value which is
success as per docs) from DeviceIoControl but GetLastError() still returns
ERROR_INSUFFICIENT_BUFFER (although I have returned STATUS_SUCCESS from
driver).
Can any body point what I am doing wrong?
Those who are interested in code snippet can see below:-
I am getting the problem for UAL_IOC_LIST ioctl.
*Driver code:–*
NTSTATUS
My_Drv_Ioctl(
IN DEVICE_OBJECT *p_dev_obj,
IN IRP *p_irp )
{
NTSTATUS status = STATUS_SUCCESS;
PIO_STACK_LOCATION p_io_stack;
ULONG controlcode, n_iocs, n_bytes;
ca_ioc_info_t *p_ca_ioc_info;
child_device_info_t *p_child_dev;
/* Get the stack location. */
p_io_stack = IoGetCurrentIrpStackLocation( p_irp );
controlcode = p_io_stack->Parameters.DeviceIoControl.IoControlCode;
p_irp->IoStatus.Information = 0;
switch (controlcode) {
case UAL_IOC_DEVICE_CREATE:
p_child_dev = p_irp->AssociatedIrp.SystemBuffer;
if (sizeof(child_device_info_t) >=
(p_io_stack->Parameters.DeviceIoControl.InputBufferLength)) {
status = STATUS_BUFFER_TOO_SMALL;
} else {
status = create_child_ioc_device(p_child_dev);
}
break;
case UAL_IOC_LIST:
p_ca_ioc_info = p_irp->AssociatedIrp.SystemBuffer;
cl_mutex_acquire(&iou_globals.list_mutex);
n_iocs = cl_qlist_count(&iou_globals.ca_ioc_map_list);
if (n_iocs*sizeof(ca_ioc_info_t) <=
p_io_stack->Parameters.DeviceIoControl.OutputBufferLength) {
n_bytes = build_ca_ioc_list(p_ca_ioc_info);
p_irp->IoStatus.Information = n_bytes;
status = STATUS_SUCCESS;
} else {
status = STATUS_BUFFER_TOO_SMALL;
}
cl_mutex_release(&iou_globals.list_mutex);
break;
default:
status = STATUS_INVALID_DEVICE_REQUEST;
break;
}
p_irp->IoStatus.Status = status;
IoCompleteRequest(p_irp, IO_NO_INCREMENT);
return status;
}
*Application Snippet:–*
Some_function (arguments) {
…some code
pBuf = NULL;
ioctlcode = UAL_IOC_LIST;
do {
if (pBuf) {
printf(“Before calling free in send_device_ioctl, value
of pBuf %I64X\n”, pBuf);
free(pBuf);
dwMemSize *= 2;
pBuf = NULL;
}
pBuf = malloc(dwMemSize);
if (!pBuf) {
printf(“Insufficient memory\n”);
dwRet = ERROR_NOT_ENOUGH_MEMORY;
break;
}
printf(“Before from DeviceIoControl\n”);
bRet = DeviceIoControl(hDevice, ioctlcode, NULL, 0, pBuf,
dwMemSize, &dwBytesRet, NULL);
dwRet = GetLastError(); *// I am always getting
ERROR_INSUFFICIENT_BUFFER here*
if (bRet) {
printf(“Returned from DeviceIoControl and error code is
%d and bool value is %d\n”, dwRet, bRet);
dwRet = 0;
break;
}
printf(“Returned from DeviceIoControl and error code is %d
and bool value is %d\n”, dwRet, bRet);
}while(dwRet == ERROR_INSUFFICIENT_BUFFER)
…some code
}
Any help/pointers will be appreciated.
Regards
Deepak