On Jul 8, 2014, at 1:02 PM, Sergey Isakov <[email protected]> wrote:

> 
> On 08 июля 2014 г., at 23:56, Andrew Fish <[email protected]> wrote:
> 
>>   ASSERT(Buffer != NULL);
>>   //
>>   // Get the head & tail of the pool entry
>>   //
>>   Head = CR (Buffer, POOL_HEAD, Data, POOL_HEAD_SIGNATURE);
>>   ASSERT(Head != NULL);
>> 
> CR macro will not find POOL_HEAD structure. It assumes buffer contain it.

Buffer is the pointer returned by gBS->AllocatePool() and that same pointer 
must be passed into gBS->FreePool().

The BASE_CR() macro does the pointer magic in the CR() macro: 
https://svn.code.sf.net/p/edk2/code/trunk/edk2/MdePkg/Include/Base.h
/**
  Macro that returns a pointer to the data structure that contains a specified 
field of
  that data structure.  This is a lightweight method to hide information by 
placing a
  public data structure inside a larger private data structure and using a 
pointer to
  the public data structure to retrieve a pointer to the private data structure.

  This function computes the offset, in bytes, of field specified by Field from 
the beginning
  of the  data structure specified by TYPE.  This offset is subtracted from 
Record, and is
  used to return a pointer to a data structure of the type specified by TYPE. 
If the data type
  specified by TYPE does not contain the field specified by Field, then the 
module will not compile.

  @param   Record   Pointer to the field specified by Field within a data 
structure of type TYPE.
  @param   TYPE     The name of the data structure type to return.  This data 
structure must
                    contain the field specified by Field.
  @param   Field    The name of the field in the data structure specified by 
TYPE to which Record points.

  @return  A pointer to the structure from one of it's elements.

**/
#define BASE_CR(Record, TYPE, Field)  ((TYPE *) ((CHAR8 *) (Record) - (CHAR8 *) 
&(((TYPE *) 0)->Field))

So in our case:
Record == Buffer
TYPE == POOL_HEAD
Field == Data

So basically “&(((TYPE *) 0)->Field)” figures out the offset of Data in the 
POOL_HEAD struct. This offset is subtracted from Buffer, so that a pointer to 
POOL_HEAD is returned. 


The CR() macro is used in a lot of protocol implementations to get the drivers 
private data back from the pointer to the protocol instance. The memory for the 
protocol data structure is part of the drivers larger private data. 

Thanks,

Andrew Fish

> ------------------------------------------------------------------------------
> Open source business process management suite built on Java and Eclipse
> Turn processes into business applications with Bonita BPM Community Edition
> Quickly connect people, data, and systems into organized workflows
> Winner of BOSSIE, CODIE, OW2 and Gartner awards
> http://p.sf.net/sfu/Bonitasoft_______________________________________________
> edk2-devel mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/edk2-devel

------------------------------------------------------------------------------
Open source business process management suite built on Java and Eclipse
Turn processes into business applications with Bonita BPM Community Edition
Quickly connect people, data, and systems into organized workflows
Winner of BOSSIE, CODIE, OW2 and Gartner awards
http://p.sf.net/sfu/Bonitasoft
_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to