Thread: DeleteUrlCacheEntry() returning ERROR_SHARING_VIOLATION

  1. #1
    Registered User
    Join Date
    Aug 2007
    Posts
    40

    DeleteUrlCacheEntry() returning ERROR_SHARING_VIOLATION

    Code is at bottom of post. The thing I want to do is make a download class which downloads a URL and places it somewhere. It should be uses for html source as well as binary files, so I'm using URLDownloadToFile from UrlMon.h. The thing is that this will keep a copy in the cache of internet explorer, and I want that when I download something, I always get the newest version, and that I don't have alot of wasted HDD space in those cache folders after a while. Calling DeleteUrlCacheEntry() after the download works like a charm in most cases, but I've been doing some testing and sometimes I get an ERROR_SHARING_VIOLATION. I'm getting these when I download an MP3 file, about 3MB in size and it has tags which state the artists and such. However I don't get them on another downloaded MP3 file which is about 40MB in size and doesn't has those tags. I also have been testing with html files and rar files of various sizes, and these also don't cause any error. Further more no exporer browsers or instances of internet explorer are running at the moment of getting the error.
    So I'm looking for a reason why this is happening and a solution to it.

    EDIt: some further testing has brought to my attention that the same mp3 file but from another server doesn't have the error. So the answer must be in this direction.

    Code:
    DWORD Download::DownloadProc()
    {
    	tstring fullsavepath = m_Savepath + m_Filename;
    	HRESULT hr = URLDownloadToFile(NULL,m_Url.c_str(),fullsavepath.c_str(),0,&m_StatusCallback);
    	if (DeleteUrlCacheEntry(m_Url.c_str()) == FALSE)
    	{
    		DWORD err = GetLastError();
    		if (err != ERROR_ACCESS_DENIED && err != ERROR_FILE_NOT_FOUND)
    		{
    			tstringstream buf;
    			buf << _T("DeleteUrlCacheEntry() returned error code ") << err << endl;
    			OutputDebugString(buf.str());
    		}
    	}
    	if (hr != S_OK)
    		DeleteFile(fullsavepath.c_str());
    
    	m_IsFinished = true;
    	CloseHandle(m_hThread);
    	return 0;
    }
    Last edited by s-men; 01-27-2009 at 09:56 AM.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Seems like a race condition.

    Try waiting a few seconds after a sharing error, and try again.

    My guess would be a rather enthusiastic explorer is busy indexing the file you just downloaded "for your convenience".

    > Further more no exporer browsers or instances of internet explorer are running at the moment
    Are you sure?
    Because the parent process (on Vista at least, and IIRC, it's similar on XP) of things like the desktop and the systray is also explorer.exe (it's a SUV with many uses apparently).

    Perhaps turn off indexing, and try again?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Aug 2007
    Posts
    40
    I've put in an sleep of 10000ms if it fails, and then retry but gives the same result. Also turned off search indexing in the entire C drive and killed explorer.exe but I still get the same result. It's just weird because that file that gave me trouble, when I hosted it on my own server and grabbed it from there by the app, the problem didn't occur, and I ran it about 20 times.

    I have also tried downloading other mp3 from the same directory as that one that's giving me trouble, and those also work like they should, it's like this one link is the only one that I can manage to get the error with. So I know that it isn't the file itself and I know it isn't the server.
    Why are there always these weird things

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Given that it persists for many seconds, I would suggest using something like process explorer from sysinternals.com

    One of the nice tools it has is to find all open files. Use that to see who else has their grubby mitts on your file.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Salem View Post
    Given that it persists for many seconds, I would suggest using something like process explorer from sysinternals.com

    One of the nice tools it has is to find all open files. Use that to see who else has their grubby mitts on your file.
    And better yet, you can SEARCH for a filename being open by any process - so in this case, that would be the file used by DeleteUrlCacheEntry() - I'm not sure what the name of that file is, but if you use process explorer to see what files you hold open are, then see if any other process holds it open - or perhaps your own process is blocking itself?

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #6
    Registered User
    Join Date
    Aug 2007
    Posts
    40
    I've tried it, but the only process having handles to the file are is the one that is my own app, and three times as well. And it seems to be released before the DeleteUrlCacheEntry is called. It's just weird that every other file, same filetype, smaller and bigger, different filetype smaller and bigger work fine, and even that exact same file from another server too, but just that one file from that one server goes wrong. Now I've converted my code a bit, instead of de DeleteUrlCacheEntry, I just do a delete file now, since the cachefilename is send to my IBindStatusCallback implementation. The same error pops up in the same situation, but it seems that if I wait a while that it get's deleteted eventually. I still find it very weird, but well it seems to work now.

    New piece of code:
    Code:
    for (int i = 0; i < 100; ++i)
    	{
    		if (DeleteFile(m_StatusCallback.GetCacheFile().c_str()) == TRUE)
    		{
    			OutputDebugString(_T("delete cache file successful.\n"));
    			break;
    		}
    		if (GetLastError() == ERROR_FILE_NOT_FOUND)
    		{
    			OutputDebugString(_T("cache file not found.\n"));
    			break;
    		}
    		OutputDebugString(_T("delete cache file not successful.\n"));
    		Sleep(2000);
    	}

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. importance of returning reference in operator overloading.
    By vaibhavs17 in forum C++ Programming
    Replies: 20
    Last Post: 05-13-2009, 12:28 PM
  2. function returning hour in either 12 or 24 hour format
    By stanlvw in forum C Programming
    Replies: 4
    Last Post: 01-01-2008, 06:02 AM
  3. Recursion: base case returning 1, function returning 0
    By yougene in forum C Programming
    Replies: 5
    Last Post: 09-07-2007, 05:38 PM
  4. Function returning incorrect value
    By CHurst in forum C Programming
    Replies: 3
    Last Post: 12-13-2005, 01:27 PM
  5. Please Help - Problem with Compilers
    By toonlover in forum C++ Programming
    Replies: 5
    Last Post: 07-23-2005, 10:03 AM