utility.cpp
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 8k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. #include <windows.h>
  2. #include <shlobj.h>
  3. #include "pstore.h"
  4. #include "utility.h"
  5. #include "enumid.h"
  6. LPCITEMIDLIST
  7. SearchPidlByType(
  8.     LPCITEMIDLIST pidl,
  9.     DWORD dwPidlType
  10.     )
  11. /*++
  12.     This function searches a pidl, looking for an entry of the type specified
  13.     by the dwPidlType argument.
  14.     On success, the return value in non-NULL.
  15. --*/
  16. {
  17.     if(pidl == NULL)
  18.         return NULL;
  19.     //
  20.     // travel through pidls in list, then suck out the type and compare
  21.     //
  22.     LPCITEMIDLIST pidlTemp = pidl;
  23.     LPCITEMIDLIST pidlResult = NULL;
  24.     while(pidlTemp->mkid.cb)
  25.     {
  26.         if(GetPidlType(pidlTemp) == dwPidlType) {
  27.             pidlResult = pidlTemp;
  28.             break;
  29.         }
  30.         pidlTemp = GetPidlNextItem(pidlTemp);
  31.     }
  32.     return pidlResult;
  33. }
  34. DWORD
  35. GetLastPidlType(
  36.     LPCITEMIDLIST pidl
  37.     )
  38. /*++
  39.     This function traverses the items in the specified pidl until the end of
  40.     the list, returning the type value associated with the last valid entry.
  41. --*/
  42. {
  43.     if(pidl == NULL)
  44.         return 0;
  45.     //
  46.     // travel to last pidl in list, then suck out the type
  47.     //
  48.     LPCITEMIDLIST pidlTemp = pidl;
  49.     LPCITEMIDLIST pidlLast = pidlTemp;
  50.     while(pidlTemp->mkid.cb)
  51.     {
  52.         pidlLast = pidlTemp;
  53.         pidlTemp = GetPidlNextItem(pidlTemp);
  54.     }
  55.     return GetPidlType(pidlLast);
  56. }
  57. PST_KEY
  58. GetLastPidlKeyType(
  59.     LPCITEMIDLIST pidl
  60.     )
  61. /*++
  62.     This function traverses the items in the specified pidl until the end of
  63.     the list, returning the key type (PST_KEY) value associated with the last
  64.     valid entry.
  65. --*/
  66. {
  67.     if(pidl == NULL)
  68.         return 0;
  69.     //
  70.     // travel to last pidl in list, then suck out the type
  71.     //
  72.     LPCITEMIDLIST pidlTemp = pidl;
  73.     LPCITEMIDLIST pidlLast = pidlTemp;
  74.     while(pidlTemp->mkid.cb)
  75.     {
  76.         pidlLast = pidlTemp;
  77.         pidlTemp = GetPidlNextItem(pidlTemp);
  78.     }
  79.     return GetPidlKeyType(pidlLast);
  80. }
  81. GUID *
  82. GetLastPidlGuid(
  83.     LPCITEMIDLIST pidl
  84.     )
  85. /*++
  86.     This function traverses the items in the specified pidl until the end of
  87.     the list, returning a pointer to the GUID data associated with the last
  88.     valid entry.
  89.     The caller should make a copy of the data if it is to be used persistently.
  90. --*/
  91. {
  92.     if(pidl == NULL)
  93.         return 0;
  94.     //
  95.     // travel to last pidl in list, then suck out the guid
  96.     //
  97.     LPCITEMIDLIST pidlTemp = pidl;
  98.     LPCITEMIDLIST pidlLast = pidlTemp;
  99.     while(pidlTemp->mkid.cb)
  100.     {
  101.         pidlLast = pidlTemp;
  102.         pidlTemp = GetPidlNextItem(pidlTemp);
  103.     }
  104.     return GetPidlGuid(pidlLast);
  105. }
  106. LPCWSTR
  107. GetLastPidlText(
  108.     LPCITEMIDLIST pidl
  109.     )
  110. /*++
  111.     This function traverses the items in the specified pidl until the end of
  112.     the list, returning a pointer to the text data associated with the last
  113.     valid entry.
  114.     The caller should make a copy of the data if it is to be used persistently.
  115. --*/
  116. {
  117.     if(pidl == NULL)
  118.         return 0;
  119.     //
  120.     // travel to last pidl in list, then suck out the guid
  121.     //
  122.     LPCITEMIDLIST pidlTemp = pidl;
  123.     LPCITEMIDLIST pidlLast = pidlTemp;
  124.     while(pidlTemp->mkid.cb)
  125.     {
  126.         pidlLast = pidlTemp;
  127.         pidlTemp = GetPidlNextItem(pidlTemp);
  128.     }
  129.     return GetPidlText(pidlLast);
  130. }
  131. LPCWSTR
  132. GetPidlText(
  133.     LPCITEMIDLIST pidl
  134.     )
  135. /*++
  136.     This helper routine returns the display text associated with the specified
  137.     pidl.
  138.     The caller should make a copy of the string if the string is for persistent
  139.     use.
  140. --*/
  141. {
  142.     LPPIDL_CONTENT pidlContent = (LPPIDL_CONTENT)&(pidl->mkid.abID);
  143.     return (LPCWSTR)(pidlContent + 1);
  144. }
  145. GUID *
  146. GetPidlGuid(
  147.     LPCITEMIDLIST pidl
  148.     )
  149. /*++
  150.     This helper routine is called by IShellFolder::CompareIDs()
  151.     to get the GUID identifiers associated with the specified pidl.
  152.     The caller should make a copy of the output buffer pointer if the item is
  153.     for persistent use.
  154. --*/
  155. {
  156.     LPPIDL_CONTENT pidlContent = (LPPIDL_CONTENT)&(pidl->mkid.abID);
  157.     return &(pidlContent->guid);
  158. }
  159. DWORD
  160. GetPidlType(
  161.     LPCITEMIDLIST pidl
  162.     )
  163. /*++
  164.     This function returns the type value associated with the specified pidl.
  165. --*/
  166. {
  167.     if(pidl == NULL)
  168.         return 0;
  169.     LPPIDL_CONTENT pidlContent = (LPPIDL_CONTENT)&(pidl->mkid.abID);
  170.     return pidlContent->dwType;
  171. }
  172. PST_KEY
  173. GetPidlKeyType(
  174.     LPCITEMIDLIST pidl
  175.     )
  176. /*++
  177.     This function returns the key type associated with the specified pidl.
  178. --*/
  179. {
  180.     if(pidl == NULL)
  181.         return 0;
  182.     LPPIDL_CONTENT pidlContent = (LPPIDL_CONTENT)&(pidl->mkid.abID);
  183.     return pidlContent->KeyType;
  184. }
  185. LPCITEMIDLIST
  186. GetPidlNextItem(
  187.     LPCITEMIDLIST pidl
  188.     )
  189. /*++
  190.     This function examines the specified pidl and returns to the caller
  191.     a pointer to the next pidl entry.
  192. --*/
  193. {
  194.     if(pidl == NULL)
  195.         return NULL;
  196.     return (LPCITEMIDLIST) (LPBYTE)(((LPBYTE)pidl) + pidl->mkid.cb);
  197. }
  198. UINT
  199. GetPidlSize(
  200.     LPCITEMIDLIST pidl
  201.     )
  202. /*++
  203.     This function gets the total size associated with the specified pidl.
  204.     This accounts for all items, item data, and the terminal entry.
  205. --*/
  206. {
  207.     if(pidl == NULL)
  208.         return 0;
  209.     UINT cbTotal = 0;
  210.     LPCITEMIDLIST pidlTemp = pidl;
  211.     while(pidlTemp->mkid.cb)
  212.     {
  213.         cbTotal += pidlTemp->mkid.cb;
  214.         pidlTemp = GetPidlNextItem(pidlTemp);
  215.     }
  216.     //
  217.     // Requires a 16 bit zero value for the NULL terminator
  218.     //
  219.     cbTotal += 2 * sizeof(BYTE);
  220.     return cbTotal;
  221. }
  222. LPITEMIDLIST
  223. CopyPidl(
  224.     LPMALLOC pMalloc,
  225.     LPCITEMIDLIST pidlSource
  226.     )
  227. /*++
  228.     This function copies the specified pidl to new storage allocated by the
  229.     specified allocation interface.
  230.     On success, the return value is non-NULL and points to the copy of the pidl.
  231. --*/
  232. {
  233.     LPITEMIDLIST pidlTarget = NULL;
  234.     UINT cbSource = 0;
  235.     if(NULL == pidlSource)
  236.         return NULL;
  237.     //
  238.     // Allocate the new pidl
  239.     //
  240.     cbSource = GetPidlSize(pidlSource);
  241.     pidlTarget = (LPITEMIDLIST) pMalloc->Alloc(cbSource);
  242.     if(pidlTarget == NULL)
  243.         return NULL;
  244.     // Copy the source to the target
  245.     CopyMemory(pidlTarget, pidlSource, cbSource);
  246.     return pidlTarget;
  247. }
  248. LPITEMIDLIST
  249. CopyCatPidl(
  250.     LPCITEMIDLIST pidl1,
  251.     LPCITEMIDLIST pidl2
  252.     )
  253. /*++
  254.     This function allocated sufficient storage for a copy of:
  255.     the two specified pidls, catanated together.
  256.     On success, the return value is non-NULL and points to the copy of the pidl.
  257. --*/
  258. {
  259.     LPMALLOC pMalloc;
  260.     LPITEMIDLIST pidlTarget;
  261.     UINT cbSource1;
  262.     UINT cbSource2;
  263.     if( NOERROR != SHGetMalloc(&pMalloc) )
  264.         return NULL;
  265.     //
  266.     // Allocate the new pidl
  267.     //
  268.     cbSource1 = GetPidlSize(pidl1);
  269.     cbSource2 = GetPidlSize(pidl2);
  270.     pidlTarget = (LPITEMIDLIST) pMalloc->Alloc(cbSource1 + cbSource2);
  271.     if(pidlTarget != NULL) {
  272.         //
  273.         // Copy first pidl source to the target
  274.         //
  275.         if( cbSource1 )
  276.             CopyMemory(pidlTarget, pidl1, cbSource1);
  277.         else {
  278.             //
  279.             // no source pidl: insure zero termination for search.
  280.             //
  281.             ZeroMemory(pidlTarget, cbSource2);
  282.         }
  283.         //
  284.         // find the null terminator
  285.         //
  286.         if( cbSource2 ) {
  287.             LPCITEMIDLIST pidlTemp = pidlTarget;
  288.             while(pidlTemp->mkid.cb)
  289.             {
  290.                 pidlTemp = GetPidlNextItem(pidlTemp);
  291.             }
  292.             //
  293.             // Copy second pidl source to target.
  294.             //
  295.             CopyMemory((LPBYTE)pidlTemp, pidl2, cbSource2);
  296.         }
  297.     }
  298.     pMalloc->Release();
  299.     return pidlTarget;
  300. }
  301. VOID
  302. FreePidl(
  303.     LPITEMIDLIST pidl
  304.     )
  305. {
  306.     LPMALLOC pMalloc;
  307.     if( NOERROR != SHGetMalloc(&pMalloc) )
  308.         return;
  309.     pMalloc->Free(pidl);
  310.     pMalloc->Release();
  311. }