Thread: SHFileOperation exception

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

    SHFileOperation exception

    Hi!
    I have a problem using SHFileOperator in the code below. It gives a “Cannot read from the source” exception on execution.
    Please could anyone show me why?
    Code:
    void CFileOperatorDlg::FileOperation()
    {
    	BROWSEINFO bi;
    	::ZeroMemory(&bi, sizeof(bi));
    
    	TCHAR szSelPath[MAX_PATH];
    	bi.pszDisplayName = szSelPath;
    	
    	bi.lpszTitle = "Select the folder/file";
    
    	bi.ulFlags = 
    		BIF_BROWSEINCLUDEFILES |
    		BIF_EDITBOX |
    		BIF_RETURNFSANCESTORS |
    		BIF_STATUSTEXT |
    		BIF_VALIDATE ;
    
    	LPITEMIDLIST pidlSrc = ::SHBrowseForFolder(&bi); 
    	char pathSrc[50];
    	SHGetPathFromIDList(pidlSrc,pathSrc);
    	
    	SHFILEOPSTRUCT shfos;
    	shfos.hwnd = m_hWnd;
    	shfos.wFunc = FO_COPY;
    	shfos.pFrom = pathSrc; // a txt file
    	shfos.fFlags = FOF_ALLOWUNDO;
    	shfos.pTo = "D:\\h2.txt";
    
    	::SHFileOperation(&shfos);
    }
    Thanks in advance.

  2. #2
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    That error usually means there is a problem with the shfos.pFrom field. There are a couple things you should be doing:

    First make sure and validate the return value from SHGetPathFromIDList(). Next, make sure that the pathSrc buffer ends in two null terminated characters in a row - not just one. Lastly, make sure that pFrom is a fully qualified path name, and not a relative path name.

  3. #3
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    Also:
    Code:
    	char pathSrc[50];
    	SHGetPathFromIDList(pidlSrc,pathSrc);
    Quote Originally Posted by MSDN
    Address of a buffer to receive the file system path. This buffer must be at least MAX_PATH characters in size.

  4. #4
    Android geek@02's Avatar
    Join Date
    Mar 2004
    Location
    Kurunegala Colony, Sri Lanka, Sri Lanka
    Posts
    470
    OK. I set the size of pathSrc to MAX_PATH. And tried to put a double null terminator at the end –don’t know whether it’s the right way to do that. But still I get the same warning. But when I debug the code the path in pathSrc seems alright.

    Modified code:

    char pathSrc[MAX_PATH];
    SHGetPathFromIDList(pidlSrc,pathSrc);

    int i=0;
    while(pathSrc[i]!='\0'){
    i++;
    }
    pathSrc[i]='\0\0';

    SHFILEOPSTRUCT shfos;
    shfos.hwnd = m_hWnd;
    shfos.wFunc = FO_COPY;
    shfos.pFrom = pathSrc;
    shfos.fFlags = FOF_ALLOWUNDO;
    shfos.pTo = "D:\\hi.txt";

    ::SHFileOperation(&shfos);

  5. #5
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    Well lets see...

    You still are not checking the return value from SHGetPathFromIDList(). If that function fails, your code is going to do some weird things. Also, your code to place another null terminator is wrong. Try this instead:
    Code:
    int i = strlen(pathSrc);
    if(i > (MAX_PATH - 2) )
    {
        MessageBox(NULL,"Path is too long","ERROR",MB_OK);
        return;
    }
    pathSrc[i+1] = 0;

  6. #6
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    You also need to double null terminate pTo. Study the following.

    Code:
    void CFileOperatorDlg::FileOperation()
    {
    	BROWSEINFO bi = { 0 };
    
    	TCHAR szSelPath[MAX_PATH];
    	bi.pszDisplayName = szSelPath;
    	bi.hwndOwner      = m_hwnd;
    	bi.lpszTitle      = TEXT("Select the folder/file");
    
    	bi.ulFlags = 
    		BIF_BROWSEINCLUDEFILES |
    		BIF_EDITBOX |
    		BIF_RETURNFSANCESTORS |
    		BIF_STATUSTEXT |
    		BIF_VALIDATE ;
    
    	TCHAR pathSrc[MAX_PATH + 1];
    	LPITEMIDLIST pidlSrc = ::SHBrowseForFolder(&bi);
    
    	if ( !pidlSrc || 
    	     !::SHGetPathFromIDList(pidlSrc, pathSrc) )
    	{
    		// Cancel or Error
    		return;
    	}
    	
    	// Double null terminate source string...
    	pathSrc[lstrlen[pathSrc] + 1] = TEXT('\0');
    
    	SHFILEOPSTRUCT shfos = { 0 };
    	shfos.hwnd   = m_hWnd;
    	shfos.wFunc  = FO_COPY;
    	shfos.pFrom  = pathSrc;
    	shfos.fFlags = FOF_ALLOWUNDO;
    	shfos.pTo    = TEXT("D:\\h2.txt\0"); // Also double terminated
    
    	if ( !::SHFileOperation(&shfos) )
    	{
    		// Error
    	}
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Exception handling in a large project
    By EVOEx in forum C++ Programming
    Replies: 7
    Last Post: 01-25-2009, 07:33 AM
  2. exception handling
    By coletek in forum C++ Programming
    Replies: 2
    Last Post: 01-12-2009, 05:28 PM
  3. Handle C++ exception and structured exception together
    By George2 in forum C++ Programming
    Replies: 2
    Last Post: 01-24-2008, 09:21 PM
  4. Signal and exception handling
    By nts in forum C++ Programming
    Replies: 23
    Last Post: 11-15-2007, 02:36 PM
  5. Problem with the exception class in MINGW
    By indigo0086 in forum C++ Programming
    Replies: 6
    Last Post: 01-20-2007, 01:12 PM