win-pvdrivers

changeset 446:df024d2ff15f

Fix for memory leak from Steve Meisner
author James Harper <james.harper@bendigoit.com.au>
date Fri Nov 07 11:14:16 2008 +1100 (2008-11-07)
parents f99bd17ed79f
children 5a8502167007
files xenpci/xenpci_fdo.c
line diff
     1.1 --- a/xenpci/xenpci_fdo.c	Fri Nov 07 11:13:27 2008 +1100
     1.2 +++ b/xenpci/xenpci_fdo.c	Fri Nov 07 11:14:16 2008 +1100
     1.3 @@ -889,7 +889,9 @@ XenPci_Pnp_QueryBusRelationsCallback(PDE
     1.4    int i, j;
     1.5    CHAR path[128];
     1.6    PDEVICE_OBJECT pdo;
     1.7 -  
     1.8 +  PDEVICE_RELATIONS oldRelations;
     1.9 +  int prevcount, length;
    1.10 +
    1.11    FUNCTION_ENTER();
    1.12  
    1.13    msg = XenBus_List(xpdd, XBT_NIL, "device", &devices);
    1.14 @@ -898,7 +900,9 @@ XenPci_Pnp_QueryBusRelationsCallback(PDE
    1.15      for (child = (PXEN_CHILD)xpdd->child_list.Flink; child != (PXEN_CHILD)&xpdd->child_list; child = (PXEN_CHILD)child->entry.Flink)
    1.16      {
    1.17        if (child->state == CHILD_STATE_DELETED)
    1.18 +      {
    1.19          KdPrint((__DRIVER_NAME "     Found deleted child - this shouldn't happen\n" ));
    1.20 +      }
    1.21        child->state = CHILD_STATE_DELETED;
    1.22      }
    1.23  
    1.24 @@ -911,7 +915,7 @@ XenPci_Pnp_QueryBusRelationsCallback(PDE
    1.25          for (j = 0; instances[j]; j++)
    1.26          {
    1.27            RtlStringCbPrintfA(path, ARRAY_SIZE(path), "device/%s/%s", devices[i], instances[j]);
    1.28 -        
    1.29 +
    1.30            for (child = (PXEN_CHILD)xpdd->child_list.Flink; child != (PXEN_CHILD)&xpdd->child_list; child = (PXEN_CHILD)child->entry.Flink)
    1.31            {
    1.32              if (strcmp(child->context->path, path) == 0)
    1.33 @@ -938,7 +942,9 @@ XenPci_Pnp_QueryBusRelationsCallback(PDE
    1.34                FALSE,
    1.35                &pdo);
    1.36              if (!NT_SUCCESS(status))
    1.37 +            {
    1.38                KdPrint((__DRIVER_NAME "     IoCreateDevice status = %08X\n", status));
    1.39 +            }
    1.40              RtlZeroMemory(pdo->DeviceExtension, sizeof(XENPCI_PDO_DEVICE_DATA));
    1.41              child->context = xppdd = pdo->DeviceExtension;
    1.42              xppdd->common.fdo = NULL;
    1.43 @@ -967,16 +973,57 @@ XenPci_Pnp_QueryBusRelationsCallback(PDE
    1.44        XenPci_FreeMem(devices[i]);
    1.45      }
    1.46      XenPci_FreeMem(devices);
    1.47 -    dev_relations = ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVICE_RELATIONS) + sizeof(PDEVICE_OBJECT) * (device_count - 1), XENPCI_POOL_TAG);
    1.48 +
    1.49 +    //
    1.50 +    // Keep track of old relations structure
    1.51 +    //
    1.52 +    oldRelations = (PDEVICE_RELATIONS) irp->IoStatus.Information;
    1.53 +    if (oldRelations)
    1.54 +    {
    1.55 +      prevcount = oldRelations->Count;
    1.56 +    }
    1.57 +    else
    1.58 +    {
    1.59 +      prevcount = 0;
    1.60 +    }
    1.61 +
    1.62 +    //
    1.63 +    // Need to allocate a new relations structure and add our
    1.64 +    // PDOs to it.
    1.65 +    //
    1.66 +
    1.67 +    length = sizeof(DEVICE_RELATIONS) + ((device_count + prevcount) * sizeof (PDEVICE_OBJECT)) -1;
    1.68 +
    1.69 +    dev_relations = (PDEVICE_RELATIONS) ExAllocatePoolWithTag (PagedPool, length, XENPCI_POOL_TAG);
    1.70 +    if (!dev_relations)
    1.71 +    {
    1.72 +      KdPrint((__DRIVER_NAME "**** Failed to allocate a new buffer for query device relations\n"));
    1.73 +      //
    1.74 +      // Fail the IRP
    1.75 +      //
    1.76 +      irp->IoStatus.Status = status = STATUS_INSUFFICIENT_RESOURCES;
    1.77 +      IoCompleteRequest (irp, IO_NO_INCREMENT);
    1.78 +      return;
    1.79 +    }
    1.80 +
    1.81 +    //
    1.82 +    // Copy in the device objects so far
    1.83 +    //
    1.84 +    if (prevcount)
    1.85 +    {
    1.86 +      RtlCopyMemory (dev_relations->Objects, oldRelations->Objects, prevcount * sizeof (PDEVICE_OBJECT));
    1.87 +    }
    1.88 +
    1.89      for (child = (PXEN_CHILD)xpdd->child_list.Flink, device_count = 0; child != (PXEN_CHILD)&xpdd->child_list; child = (PXEN_CHILD)child->entry.Flink)
    1.90      {
    1.91        if (child->state == CHILD_STATE_ADDED)
    1.92        {
    1.93          ObReferenceObject(child->context->common.pdo);
    1.94 -        dev_relations->Objects[device_count++] = child->context->common.pdo;
    1.95 +        dev_relations->Objects[prevcount++] = child->context->common.pdo;
    1.96        }
    1.97      }
    1.98 -    dev_relations->Count = device_count;
    1.99 +
   1.100 +    dev_relations->Count = prevcount + device_count;
   1.101  
   1.102      child = (PXEN_CHILD)xpdd->child_list.Flink;
   1.103      while (child != (PXEN_CHILD)&xpdd->child_list)
   1.104 @@ -993,20 +1040,32 @@ XenPci_Pnp_QueryBusRelationsCallback(PDE
   1.105          ExFreePoolWithTag(old_child, XENPCI_POOL_TAG);
   1.106        }
   1.107        else
   1.108 +      {
   1.109          child = (PXEN_CHILD)child->entry.Flink;
   1.110 +      }
   1.111      }
   1.112      
   1.113      status = STATUS_SUCCESS;
   1.114    }
   1.115    else
   1.116    {
   1.117 -    /* this should probably fail in an even worse way - a failure here means we failed to do an ls in xenbus so something is really really wrong */
   1.118 -    device_count = 0;
   1.119 -    dev_relations = ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVICE_RELATIONS) + sizeof(PDEVICE_OBJECT) * (device_count - 1), XENPCI_POOL_TAG);
   1.120 -    dev_relations->Count = device_count;
   1.121 +    //
   1.122 +    // Fail the IRP
   1.123 +    //
   1.124 +    irp->IoStatus.Status = status = STATUS_INSUFFICIENT_RESOURCES;
   1.125 +    IoCompleteRequest (irp, IO_NO_INCREMENT);
   1.126 +    return;
   1.127    }
   1.128  
   1.129    irp->IoStatus.Status = status;
   1.130 +  //
   1.131 +  // Replace the relations structure in the IRP with the new
   1.132 +  // one.
   1.133 +  //
   1.134 +  if (oldRelations)
   1.135 +  {
   1.136 +      ExFreePool (oldRelations);
   1.137 +  }
   1.138    irp->IoStatus.Information = (ULONG_PTR)dev_relations;
   1.139  
   1.140    IoCompleteRequest (irp, IO_NO_INCREMENT);