Driver Problems? Questions? Issues?
Put OSR's experience to work for you! Contact us for assistance with:
  • Creating the right design for your requirements
  • Reviewing your existing driver code
  • Analyzing driver reliability/performance issues
  • Custom training mixed with consulting and focused directly on your specific areas of interest/concern.
Check us out. OSR, the Windows driver experts.

Upcoming OSR Seminars:
Writing WDF Drivers: Core Concepts Lab, Boston/Waltham, MA 22-26 September, 2014
Windows Internals & Software Drivers Lab, Dulles/Sterling, VA, 20-24 October, 2014
Developing File Systems for Windows, Seattle, WA 4-7 November, 2014
Kernel Debugging & Crash Analysis Lab, Boston/Waltham, MA 10-14 November, 2014


Go Back   OSR Online Lists > ntdev
Welcome, Guest
You must login to post to this list
  Message 1 of 6  
26 Feb 09 04:24
NTDEV
xxxxxx@gmail.com
Join Date: 27 Nov 2008
Posts To This List: 249
GetLastError after calling DeviceIoControl

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 --
  Message 2 of 6  
26 Feb 09 04:59
Pavel A
xxxxxx@fastmail.fm
Join Date: 21 Jul 2008
Posts To This List: 2084
GetLastError after calling DeviceIoControl

When DeviceIoControl returns TRUE (non-zero), value of GetLastError() is undefined. It is not expected to be 0 on success. Maybe it's left unchanged from a previous call. --pa Deepak Gupta wrote: > 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 <...excess quoted lines suppressed...>
  Message 3 of 6  
26 Feb 09 04:59
Mark S. Edwards
xxxxxx@muttsnuts.com
Join Date:
Posts To This List: 393
GetLastError after calling DeviceIoControl

You should only call GetLastError() when there has been an error. When DeviceIoControl() succeeds it does not update the internal last error variable, because this is not an error. So what gets returned by the 2nd call to GetLastError() is the last error value placed in the internal variable i.e. the value placed there by your first failing call to DeviceIoControl(). At 09:24 26/02/2009, Deepak Gupta wrote: >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 <...excess quoted lines suppressed...> --
  Message 4 of 6  
26 Feb 09 05:05
NTDEV
xxxxxx@gmail.com
Join Date: 27 Nov 2008
Posts To This List: 249
GetLastError after calling DeviceIoControl

Mark, Pavel. Thanks a lot for your inputs. I was also expecting same thing. So Last Error only gets updated only if some error happens in any call and other wise not. Regards Deepak On Thu, Feb 26, 2009 at 3:28 PM, Mark S. Edwards <xxxxx@muttsnuts.com>wrote: > You should only call GetLastError() when there has been an error. > > When DeviceIoControl() succeeds it does not update the internal last error > variable, because this is not an error. > > So what gets returned by the 2nd call to GetLastError() is the last error > value placed in the internal variable i.e. the value placed there by your > first failing call to DeviceIoControl(). > > <...excess quoted lines suppressed...> --
  Message 5 of 6  
26 Feb 09 09:49
Doron Holan
xxxxxx@microsoft.com
Join Date: 08 Sep 2005
Posts To This List: 9115
GetLastError after calling DeviceIoControl

To be 100% clear, ther is no definitive rule in windows about when lasterror is set outside of an error condition. Some APIs always clear it on entry, some set it on success. The overall rule you must heed is that you only check it on error, it is undefined for success d Sent from my phone with no t9, all spilling mistakes are not intentional. ________________________________ From: Deepak Gupta <xxxxx@gmail.com> Sent: Thursday, February 26, 2009 2:07 AM To: Windows System Software Devs Interest List <xxxxx@lists.osr.com> Subject: Re: [ntdev] GetLastError after calling DeviceIoControl Mark, Pavel. Thanks a lot for your inputs. I was also expecting same thing. So Last Error only gets updated only if some error happens in any call and other wise not. Regards Deepak On Thu, Feb 26, 2009 at 3:28 PM, Mark S. Edwards <xxxxx@muttsnuts.com<mailto:xxxxx@muttsnuts.com>> wrote: You should only call GetLastError() when there has been an error. When DeviceIoControl() succeeds it does not update the internal last error variable, because this is not an error. So what gets returned by the 2nd call to GetLastError() is the last error value placed in the internal variable i.e. the value placed there by your first failing call to DeviceIoControl(). At 09:24 26/02/2009, Deepak Gupta wrote: 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 --- 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=3DListServer --- 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 --- 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=3DListServer --
  Message 6 of 6  
26 Feb 09 10:45
ntdev member 28798
xxxxxx@comcast.net
Join Date:
Posts To This List: 218
GetLastError after calling DeviceIoControl

> 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). Doron already said that GLE is meaningful only after an error. But just out of interest you may want toclear GLE right before DeviceIoControl: printf("Before from DeviceIoControl\n"); SetLastError(S_OK); // reset it bRet = DeviceIoControl(hDevice, ioctlcode, NULL, 0, pBuf, dwMemSize, &dwBytesRet, NULL); dwRet = GetLastError(); // I am always getting ERROR_INSUFFICIENT_BUFFER here ----- Original Message ----- From: Deepak Gupta To: Windows System Software Devs Interest List Sent: Thursday, February 26, 2009 4:24 AM Subject: [ntdev] GetLastError after calling DeviceIoControl 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 --- 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 --
Posting Rules  
You may not post new threads
You may not post replies
You may not post attachments
You must login to OSR Online AND be a member of the ntdev list to be able to post.

All times are GMT -5. The time now is 10:00.


Copyright ©2014, OSR Open Systems Resources, Inc.
Based on vBulletin Copyright ©2000 - 2005, Jelsoft Enterprises Ltd.
Modified under license