Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

430 lines
7.6 KiB

  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 pull 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 pull 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 pull 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 pull 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 pull 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. }