/************************************************
   THIS CODE AND INFORMATION IS PROVIDED 'AS IS' 
   WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO
   THE IMPLIED WARRANTIES OF MERCHANTABILITY 
   AND/OR FITNESS FOR A PARTICULAR PURPOSE.
   Author: Barretto VN  7/2002
*************************************************/


#include <stdio.h>
#include <shlobj.h>

#include "ShellFunc.h"

BOOL GetName (LPSHELLFOLDER lpsf, 
			  LPITEMIDLIST lpi,
		      DWORD dwFlags, 
			  LPSTR lpFriendlyName)
{

	
	BOOL bSuccess = TRUE;
	STRRET str;

	if (NOERROR == lpsf->lpVtbl->GetDisplayNameOf(lpsf, lpi, dwFlags, &str))
	{

	
		switch (str.uType)
		{
			case STRRET_WSTR:
			WideCharToMultiByte (CP_ACP, // code page
									0, // dwFlags
									str.pOleStr, // lpWideCharStr
									-1, // cchWideChar
									lpFriendlyName, // lpMultiByteStr
							//		sizeof (lpFriendlyName), // cchMultiByte
							        sizeof(str), 
									NULL, // lpDefaultChar
									NULL); // lpUsedDefaultChar
			break;

			case STRRET_OFFSET:
				lstrcpy (lpFriendlyName, (LPSTR)lpi + str.uOffset);
				break;

			case STRRET_CSTR:
				lstrcpy (lpFriendlyName, (LPSTR) str.cStr);
				break;

			default:
				bSuccess = FALSE;
				break;
		}
	}
	else
		bSuccess = FALSE;

return bSuccess;
} 

void GetNormalAndSelectedIcons(LPITEMIDLIST lpifq, LPTV_ITEM lptvitem)
{
	// Don't check the return value here. 
	// If GetIcon() fails, you're in big trouble.

	lptvitem->iImage = GetIcon (lpifq, 
								SHGFI_PIDL | 
								CSIDL_DESKTOP |
								SHGFI_ICON |
								SHGFI_SYSICONINDEX | 
								SHGFI_SMALLICON);

	lptvitem->iSelectedImage = GetIcon (lpifq, 
										SHGFI_PIDL | 
										SHGFI_SYSICONINDEX | 
										SHGFI_SMALLICON | 
										SHGFI_OPENICON);

	return;
}

int GetIcon (LPITEMIDLIST lpi, UINT uFlags)
{
	SHFILEINFO sfi;
	SHGetFileInfo ((LPCSTR)lpi, 0, &sfi, sizeof (SHFILEINFO), uFlags);
	return sfi.iIcon;
} 

LPITEMIDLIST CopyItemID(LPMALLOC pMalloc , LPITEMIDLIST pidl) 
   { 

	// Get the size of the specified item identifier. 
   int cb = pidl->mkid.cb; 

   // Allocate a new item identifier list. 
   LPITEMIDLIST pidlNew = (LPITEMIDLIST) 
   pMalloc->lpVtbl->Alloc(pMalloc, cb + sizeof(USHORT)); 
   if (pidlNew == NULL) 
      return NULL; 

   // Copy the specified item identifier. 
   CopyMemory(pidlNew, pidl, cb); 

   // Append a terminating zero. 
   *((USHORT *) (((LPBYTE) pidlNew) + cb)) = 0; 

   return pidlNew; 
} 

LPITEMIDLIST Concatenate(LPMALLOC pMalloc ,LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2) 
{ 

	LPITEMIDLIST   pidlNew; 
	UINT           cb1 = 0,	cb2 = 0;  //are both of these NULL? 
	if(!pidl1 && !pidl2)    
		return NULL;  
	//if pidl1 is NULL, just return a copy of pidl2 

	if(!pidl1)    
	{    
		pidlNew = Copy(pMalloc , pidl2);     
		return pidlNew;    
	}  
	//if pidl2 is NULL, just return a copy of pidl1 

	if(!pidl2)    
	{    
		pidlNew = Copy(pMalloc, pidl1);     
		return pidlNew;    
	}  
	cb1 = GetSize(pidl1) - sizeof(ITEMIDLIST);  
	cb2 = GetSize(pidl2);  
	//create the new PIDL 
	pidlNew = (LPITEMIDLIST)pMalloc->lpVtbl->Alloc(pMalloc, cb1 + cb2);  
	if(pidlNew)    
	{    
		//copy the first PIDL    
		CopyMemory(pidlNew, pidl1, cb1);       
		//copy the second PIDL    
		CopyMemory(((LPBYTE)pidlNew) + cb1, pidl2, cb2);    
	}  
	return pidlNew; 
}  

UINT GetSize(LPCITEMIDLIST pidl) 
{ 
	UINT cbTotal = 0; 
	LPITEMIDLIST pidlTemp = (LPITEMIDLIST) pidl;  
	if(pidlTemp)    
	{    
		while(pidlTemp->mkid.cb)       
		{       
			cbTotal += pidlTemp->mkid.cb;       
			pidlTemp = GetNextItem(pidlTemp);       
		}      
		//add the size of the NULL terminating ITEMIDLIST    
		cbTotal += sizeof(ITEMIDLIST);   
	 } 
	return (cbTotal); 
}  

LPITEMIDLIST GetNextItem(LPCITEMIDLIST pidl) 
{ 
	if(pidl)    
		return (LPITEMIDLIST)(LPBYTE)(((LPBYTE)pidl) + pidl->mkid.cb); 
	else    
		return 	(NULL); 
}  

LPITEMIDLIST Copy(LPMALLOC pMalloc , LPCITEMIDLIST pidlSource)
{ 

	LPITEMIDLIST pidlTarget = NULL; 
	UINT cbSource = 0;  
	if(NULL == pidlSource)    
		return (NULL);  
	// Allocate the new pidl
	cbSource = GetSize(pidlSource); 
	pidlTarget = (LPITEMIDLIST)pMalloc->lpVtbl->Alloc(pMalloc, cbSource); 
	if(!pidlTarget)    
		return (NULL); 
	// Copy the source to the target 
	CopyMemory(pidlTarget, pidlSource, cbSource);  
	return pidlTarget; 
}  

int GetNormalIcon(LPITEMIDLIST lpifq)
{
	int nIconIndex;
	nIconIndex = GetIcon (lpifq, 
				 		SHGFI_PIDL | 
						CSIDL_DESKTOP |
						SHGFI_ICON |
						SHGFI_SYSICONINDEX | 
						SHGFI_SMALLICON);

	return nIconIndex;
}


/********************************************************************************/
/* End of file									*/
/********************************************************************************/
