Thread: SHELL - path problem

  1. #1
    Android geek@02's Avatar
    Join Date
    Mar 2004
    Location
    Kurunegala Colony, Sri Lanka, Sri Lanka
    Posts
    470

    SHELL - path problem

    Hi.
    I tired to enumerate trough all cookie files to get paths to each cookie. I used SHGetPathFromIDList() to retrieve the paths.
    The problem is that I receive all the paths, as the cookies are existing on the desktop. It’s something like this:
    Code:
    C: Documant and Settings\username\Desktop\cookie file1.txt
    C: Documant and Settings\username\Desktop\cookie file2.txt
    C: Documant and Settings\username\Desktop\cookie file3.txt
    while the actual path is something like :
    Code:
    C:\Documents and Settings\username\Cookies\cookie file1.txt
    So I tried to get to other special folders using flags like CSIDL_COMMON_DOCUMENTS, CSIDL_COMMON_FAVORITES, on SHGetSpecialFolderLocation(). But the same thing happened. The paths says that every file’s are on the desktop.
    Why is this?

    Code:
    	
    ....................
    ....................
    if(SUCCEEDED(::SHGetSpecialFolderLocation(NULL, CSIDL_COOKIES, &pidlCookieF)))
    		{
    		// fetch the ShellFolder interface of the cookie folder
    		CComPtr<IShellFolder> sfiCookieF;
    		if(SUCCEEDED(sfiDesktop->BindToObject(
    			pidlCookieF, // PIDL to sub folder
    			NULL, // must be NULL
    			IID_IShellFolder, // just get non-folders
    			reinterpret_cast<LPVOID*>(&sfiCookieF)))) // buffer
    			{
    			// get the enumerator
    			CComPtr<IEnumIDList> spenumCookie;
    			if(SUCCEEDED(sfiCookieF->EnumObjects(
    				NULL, // parent window
    				SHCONTF_NONFOLDERS, // just get non-folders
    				&spenumCookie))) // buffer
    				{   
    			// fetch each PIDL
    			LPITEMIDLIST pidlCookie = NULL;
    			int x=0;
    			char cookiePath[MAX_PATH + 1];
    			while(spenumCookie->Next(1, &pidlCookie, NULL) == NOERROR)
    				{
    			
    				// ******** file operation ************
    				if (SHGetPathFromIDList (pidlCookie, cookiePath)) 
    					{
    					cookiePath[lstrlen(cookiePath)+1] = '\0';    
    					SHFILEOPSTRUCT fopstruct = { 0 };  
    					fopstruct.hwnd   = NULL;           
    					fopstruct.wFunc  = FO_COPY;        
    					fopstruct.fFlags = 0;              
    					fopstruct.pFrom  = cookiePath;           
    					fopstruct.pTo    = "E:\\cookies\0"; 
    					
    					BOOL foCheck = SHFileOperation (&fopstruct);
    					
    					if (foCheck) 
    						MessageBox(NULL, "SHFileOperation failed!", NULL, MB_ICONSTOP);
       				     }
    .....................
    .....................
    Thanks.

  2. #2
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    IEnumIDList::Next Method
    The ITEMIDLISTs returned in the rgelt array are relative to the IShellFolder being enumerated.
    Like normal paths there are relative and absolute pidls. The desktop folder is the root folder, so when you pass a relative pidl to SHGetPathFromIDList() you get "root\relative path".

    So, the question becomes, how to combine two pidls. One way is to use the ILCombine() function to create an absolute pidl before passing it to SHGetPathFromIDList():
    Code:
    LPITEMIDLIST pidlAbsolute = ILCombine(pidlCookieF, pidlCookie);
    However, this function, although around since Win95, has only become officially available since Win2000.

    Another way is to use GetDisplayNameOf() from the parent folder:
    Code:
       STRRET strDispName;
       sfiCookieF->GetDisplayNameOf(pidlCookie, SHGDN_NORMAL | SHGDN_FORPARSING, &strDispName);
       StrRetToBuf(&strDispName, pidlCookie, cookiePath,  MAX_PATH);
    This page may be useful:
    http://netez.com/2xExplorer/shellFAQ/bas_xplore2.html

    Alternatively, we can write our own implementation of ILCombine().
    Code:
    DWORD GetPidlSize(LPITEMIDLIST pidl)
    {
    	DWORD cbSize = 0;
    
    	if (!pidl) return 0;
    
    	// We walk the pidl list to get each element's size...
    	while (pidl->mkid.cb != 0)
    	{
    		cbSize += pidl->mkid.cb;
    		pidl = (LPITEMIDLIST) ((LPBYTE) pidl + pidl->mkid.cb);
    	}
    
    	// We add space for the two null characters that terminate a pidl...
    	return cbSize + 2;
    }
    
    
    LPITEMIDLIST ILCombineImp(LPITEMIDLIST pidlA, LPITEMIDLIST pidlB)
    {  // Untested code.
    
    	if (pidlA && pidlB)
    	{
    		LPITEMIDLIST pidlRet;
    		DWORD cbPidlA = GetPidlSize(pidlA) - 2; // Don't include null terminator
    		DWORD cbPidlB = GetPidlSize(pidlB);
    
    		if (!(pidlRet = CoTaskMemAlloc(cbPidlA + cbPidlB))) return NULL;
    
    		CopyMemory(pidlRet,                    pidlA, cbPidlA);
    		CopyMemory((LPBYTE) pidlRet + cbPidlA, pidlB, cbPidlB);
    
    		return pidlRet;
    	}
    	else
    	{
    		return (pidlA ? pidlA : pidlB);
    	}
    }
    Last edited by anonytmouse; 04-27-2004 at 04:11 PM.

  3. #3
    Android geek@02's Avatar
    Join Date
    Mar 2004
    Location
    Kurunegala Colony, Sri Lanka, Sri Lanka
    Posts
    470
    Thanks for the code and the explanation anonytmouse.
    But, I'm unclear about ILCombine() - don't understand how it gets an absolute PIDL by combining 2 PIDLs. Somebody please explain a bit more about ILCombine()?

  4. #4
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    It just combines two pidls, like combining two path strings. For example, if you have the strings, "C:\Cookies\" and "Cookie File 1.txt", combining them will give "C:\Cookies\Cookie File 1.txt" Combining pidls works in the same way.

  5. #5
    Android geek@02's Avatar
    Join Date
    Mar 2004
    Location
    Kurunegala Colony, Sri Lanka, Sri Lanka
    Posts
    470
    I see.
    THANKS.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. a file path problem
    By fighter92 in forum C++ Programming
    Replies: 1
    Last Post: 06-21-2008, 05:50 AM
  2. Simulating a shell problem
    By Galileo in forum Linux Programming
    Replies: 1
    Last Post: 06-06-2008, 04:41 AM
  3. cross platform semaphore problem
    By jet-plane in forum C Programming
    Replies: 0
    Last Post: 05-24-2008, 01:59 PM
  4. Path Problem
    By AndyBomstad in forum C++ Programming
    Replies: 6
    Last Post: 05-05-2005, 02:17 PM
  5. System.ini Shell Problems
    By (TNT) in forum Windows Programming
    Replies: 2
    Last Post: 08-26-2001, 01:05 PM