11.3 The PIDL

only for RuBoard - do not distribute or recompile

11.3 The PIDL

Explorer needs a way to uniquely identify each item in the namespace unambiguously in relation to other items in the namespace. It must be able to enumerate these items in a consistent, generic manner, even though these items represent a wide variety of data. It does this with a PIDL.

A PIDL is a pointer to an item identifier list, or ITEMIDLIST . An ITEMIDLIST is an array of shell item IDs. Each one of these identifiers is an array of bytes that contains information that is specific to the namespace extension using it.

How can Explorer use PIDLs if they are different in respect to every extension? Well, as it turns out PIDLs are pretty simple creatures . Let's look at how a PIDL is defined, and you'll be able to see this for yourself. Here is what an ITEMIDLIST (just remember a PIDL is a pointer to one of these) looks like, as defined by the Platform SDK:

 typedef struct _ITEMIDLIST {     SHITEMID mkid; } ITEMIDLIST, * LPITEMIDLIST; 

As you can see, an ITEMIDLIST is nothing more than a structure that contains one member of type SHITEMID . This structure looks like so:

 typedef struct _SHITEMID {      USHORT cb;      BYTE abID[1];  } SHITEMID, * LPSHITEMID; 

The first member of SHITEMID , cb , contains the number of bytes of the SHITEMID structure. SHITEMID is a variable-length structure, and cb contains two bytes specifying its size . For those of you who have never done any C programming, you probably have never seen this technique before: the first member of a structure is used to define the total length of a variable-length structure. The abID parameter is not a pointer, of course, because it is only 1 byte. It is a placeholder. It marks the first byte of an unknown number of bytes. One member of a variable length structure contains the number of bytes that begins at the location abID[0] . This is an efficient way to maintain a collection (a linked list perhaps) of like structures that are of different sizes. Without this technique, you would have to reallocate memory like this:

 typedef struct _SHITEMID {      USHORT cb;      BYTE abID[1024];  } SHITEMID, * LPSHITEMID; 

This is very inefficient, because you may have one instance of this structure that contains 1024 bytes of data and several hundred that contain only 10 bytes. Also, you are limited as to how large your structure can be. Because SHITEMID is of variable length, it can be as large or as small as needed.

Anyway, the data that follows can be in any format that is required by the namespace extension. Well, almost, but we'll talk about that in a second. This format allows IEnumIDList to enumerate a list of PIDLs in a generic fashion.

A PIDL is just a pointer to one or more ITEMIDLIST s that is terminated by an empty ITEMIDLIST (two 0s). Some PIDLs point to only one ITEMIDLIST, followed by an empty ITEMIDLIST . These are called simple PIDLs. A PIDL that points to more than one ITEMIDLIST is called a complex PIDL. Regardless of the type, the last ITEMIDLIST must contain all NULL values. This is shown in Figure 11.5.

Figure 11.5. Simple and complex PIDLs
figs/vshl.1105.gif

A PIDL always points to at least two ITEMIDLIST s (remember, there's always an empty ITEMIDLIST at the end). In other words, it's an array. So if you read something like "the last item in the PIDL," this means the last ITEMIDLIST in the array. So don't just think of a PIDL as a pointer to an ITEMIDLIST . It's easier to think about it in terms of an array, because that's what it really is. There is never just one ITEMIDLIST . Also, not to make things more confusing, but, by convention, the term PIDL is often used when referring to the underlying ITEMIDLIST structure. For instance, you'll never hear someone say, "What is the format of your ITEMIDLIST ?" They'll just call it a PIDL. So when you read about the "format of a PIDL," you now know that what is being discussed is the ITEMIDLIST itself. With that said, let's talk about the format of a PIDL.

There is an important rule that must be followed when creating a PIDL. The data contained in your PIDLs ( ITEMIDLIST s) cannot contain pointers . This is because PIDLs can be persisted (saved to disk) and then read back into memory at some point in the future (shortcut files are persisted ID lists). ITEMIDLIST s can also be copied into another memory block before they are used by Explorer. So a PIDL cannot contain a handle to an icon, for example; it must contain all the actual bits that make up the icon. A PIDL can't contain a pointer to a path, it must contain the actual path itself. Everything a PIDL needs to describe itself must be contained within it.

only for RuBoard - do not distribute or recompile


Visual Basic Shell Programming
Visual Basic Shell Programming
ISBN: B00007FY99
EAN: N/A
Year: 2000
Pages: 128

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net