2
votes

Basically, when I call DeleteUrlCacheEntry (which is part of the Wininet.dll API) I either get returned the number 1 (which means, deletion successful) or the number 0 (which meant, deletion didn't work).

My question is, how can I find out why a deletion did not work? (that is, when a 0 is returned). I heard there is a GetLastError() function in C++, however I am using VB6 and apparently the GetLastError equivalent in VB6 is the Err.LastDllError property.

After a DeleteUrlCacheEntry attempted deletion fails (returns 0) I call/query the Err.LastDllError and it always returns 0 - no matter what. It returns 0 even if DeleteUrlCacheEntry returns 0 (deletion didn't work) and even when it returns 1 (deletion did work). I also make the call/query to Err.LastDllError as soon as possible (as in, right after the DeleteUrlCacheEntry call).

I am really confused, because I don't even get a runtime error or any typical exception (or any exception for that matter). I do not have On Error Resume Next to ignore exception anywhere in my application, so every means of an error being reported to me is available but I cannot for the life of me figure out why a particular DeleteUrlCacheEntry() attempt will fail and return 0 (there doesn't seem to be a way for me to find out).

So, my question is, how do I get extended error information from the DeleteUrlCacheEntry() function (residing in the wininet.dll API)?

If you would like more information on the reason why I am looking for extended error information from the DeleteUrlCacheEntry() function, I have another question which details this (together with actual examples of cache items that work and don't work when a deletion is attempted): https://stackguides.com/questions/12096546/deleteurlcacheentry-function-of-wininet-api-not-deleting-some-internet-explo

Also, just to add, I am using VB6 - but principally it should be the same across most languages as it is an API call. Here is my declaration in VB6:

Public Declare Function DeleteUrlCacheEntry Lib "WININET" Alias "DeleteUrlCacheEntryA" (ByVal lpszUrlName As String) As Long

Also, I am calling it like this:

Dim lReturnValue As Long

Dim cacheFileString As String

' GetStrFromPtrA turns Pointer (Long) to String. cacheFileString is the actual text/string of the lpszSourceUrlName turned from Pointer (Long) to String (human readable cache file name/string). Also, cacheFileString is retreived from FindFirst/NextEntry functions in a loop, so can't be incorrectly formatted or anything, as it also works when deleting most other items.

cacheFileString = GetStrFromPtrA(icei.lpszSourceUrlName)

lReturnValue = DeleteUrlCacheEntry(cacheFileString)

The lReturnValue ends up being 0 if deletion didn't work, and 1 when deletion does work, and that is it. Also, Err.LastDllError always returns 0.

Thank you for your anticipated assistance.

4
@KenWhite The reason for the tags is because it applies to both C++ and Delphi as well (usage scenario is the same since it's a wininet.dll api call with error codes usually residing in a c++ .h file. So, it applies to people using these languages and those using these languages will also be able to make a contribution to this post. - Erx_VB.NExT.Coder
@KenWhite it is not random, this is not a "code" issue just because some people wanted to see the code, it is an error codes issue, which applies to Delphi and C++ especially, notice i didn't include javascript, .NET or Java! Those would be random tags! API is universal across many languages which can hook into the Windows API, such as delphi and C++, which is why I seek the support of those people (getting extended error codes using API, not VB6-specific code). This is why people who are not closely involved in understanding the question should not edit tags or suggest close/delete etc. - Erx_VB.NExT.Coder
You can call API functions from assembler, too; that doesn't make it an assembly question. And I'm quite familiar, thank you - I'm not exactly new here, if you view my profile and the tags for which I've answered questions. :-) - Ken White
@KenWhite You're right, many languages do WinAPI calls, however, I am familiar with delphi, vb.net and c# which is why I was open to solutions in those languages to get a better grasp on the problem, hence my tagging was also a way to make that inference (of me being open to solutions in those languages). I do not know how to use assembler - however, I wish I did :). - Erx_VB.NExT.Coder
No, you don't. :-) It's pretty nasty to work in. (I'm going to clean up some of the noise here to reduce the clutter.) - Ken White

4 Answers

1
votes

Personally I would set a break point on the call to DeleteUrlCacheEntry(), and step through it observing what the values in the call stack are.

Other than that, there is not much that can be said without a code snippet.

1
votes

If Err.LastDllError is returning 0 than either GetLastError() really is returning 0, which is unlikely, or VB is not calling GetLastError(), which is more likely. Such as if the VB declaration of DeleteUrlCacheEntry() is wrong, like it is not setting the DllImport.SetLastError property to true under .NET PInvoke.

1
votes

This might not be directly relevant, but it seems to me that you are doing an unecessary string copy here. Why not directly use the string pointer you already have:

Public Declare Function DeleteUrlCacheEntry Lib "WININET" Alias "DeleteUrlCacheEntryA" (ByVal lpszUrlName As Long) As Long

Dim lReturnValue As Long

lReturnValue = DeleteUrlCacheEntry(icei.lpszSourceUrlName)

(This is assuming that icei.lpszSourceUrlName is a pointer to an ANSI string.)

Also, you do realise that Err.LastDllError is overwritten everytime a command called via a VB declare or type library declare with usesgetlasterror = true? So, for instance, if I declared APIFunc1() and APIFunc2(), and then called them like this;

nRet = APIFunc1(APIFunc2)

... then LastDllError would reflect only APIFunc1().

-1
votes

It's a bit dated ... but I am interested by the subject, so I thought I would share my limited knowledge.

For me, when I called DeleteUrlCacheEntry with a wrong URL, I get an error and Err.LastDllError is set to 2 !