Wrox Programmer Forums
Go Back   Wrox Programmer Forums > .NET > Other .NET > General .NET
|
General .NET For general discussion of MICROSOFT .NET topics that don't fall within any of the other .NET forum subcategories or .NET language forums.  If your question is specific to a language (C# or Visual Basic) or type of application (Windows Forms or ASP.Net) try an applicable forum category. ** PLEASE BE SPECIFIC WITH YOUR QUESTION ** When posting here, provide details regarding the Microsoft .NET language you are using and/or what type of application (Windows/Web Forms, etc) you are working in, if applicable to the question. This will help others answer the question without having to ask.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the General .NET section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old January 10th, 2005, 10:33 AM
Authorized User
 
Join Date: May 2004
Posts: 73
Thanks: 0
Thanked 1 Time in 1 Post
Default Accessing browser (IE) cache programatically

I have put this problem at so many forums on the net and explored lot's of discussion forums for the same but in vain. I wanna access all contents (the source html and its associated files like jpeg, swf, css etc) of a specified url from IE cache. After all IE does it itself when we click the History button from the browser and click any url from the History pane, it fetches the entire url. I know that there is an option in .NET to work with Special Folders but i don't know exactly how could i use them for this particular purpose. This has become very important for my project. Please anybody help me out, i'll really appreciate it.


Thankyou



BaburMan
__________________
BaburMan
 
Old January 10th, 2005, 12:41 PM
Imar's Avatar
Wrox Author
 
Join Date: Jun 2003
Posts: 17,089
Thanks: 80
Thanked 1,576 Times in 1,552 Posts
Default

From what kind of app are you trying to access this folder??
 
Old January 11th, 2005, 04:52 AM
Authorized User
 
Join Date: May 2004
Posts: 73
Thanks: 0
Thanked 1 Time in 1 Post
Default

I am working in Windows .NET application and the abovementioned requirement is for capturing the downloaded items from IE cache to show it offline later on. thanks

BaburMan
 
Old January 11th, 2005, 05:17 PM
Imar's Avatar
Wrox Author
 
Join Date: Jun 2003
Posts: 17,089
Thanks: 80
Thanked 1,576 Times in 1,552 Posts
Default

AFAIK, the Cache is not a special folder, but I could be wrong.

You could do a search for your cache's foldername in the Registry, and see if you get any info about it being a special folder.

You could also try to retrieve the HOMEPATH variable, and try to build the Cache location from it, but I am not sure how cross platform that is.

Other than that, I am out of ideas. Never needed such a thing....

Cheers,

Imar
---------------------------------------
Imar Spaanjaars
Everyone is unique, except for me.
 
Old February 10th, 2005, 02:11 AM
Authorized User
 
Join Date: May 2004
Posts: 73
Thanks: 0
Thanked 1 Time in 1 Post
Default

Sorry, I was away for a long time due to some other issues, however m still working on this and not succeeded so far. I have found a code example in VB 6 somewhere from the net. It fetches all entries from the cache and displays them in a list box in a Form. It works just fine and the code is not much difficult to understand for a Win API geek. I have been trying to convert this code to c# using PInvoke, not succeeded so far. I am not so strong on the issues like data type compliance and pointer manipulation, so find it hard to diagnose where the problem exists. I have pasted the VB code and its (so far) 'translated' c# code. The code in C# is not complete. Also added comments where the problem seems to be. In short, either i am not getting the actual address of the struct or the handle of the cache entry, or rtlmovememory() doesn't work. Remember, there's no compile/run-time error but i can't get the required result either. Hope a C# geek who has worked with PInvoke could help getting rid of this.



Thankyou





Here's the VB 6 example.

'This project requries a form with a listbox (List1) on it
'and a class module (MemoryBlock)

'In the form:
Option Explicit
Private Type FILETIME
    dwLowDateTime As Long
    dwHighDateTime As Long
End Type
Private Type INTERNET_CACHE_ENTRY_INFO
    dwStructSize As Long
    lpszSourceUrlName As Long
    lpszLocalFileName As Long
    CacheEntryType As Long
    dwUseCount As Long
    dwHitRate As Long
    dwSizeLow As Long
    dwSizeHigh As Long
    LastModifiedTime As FILETIME
    ExpireTime As FILETIME
    LastAccessTime As FILETIME
    LastSyncTime As FILETIME
    lpHeaderInfo As Long
    dwHeaderInfoSize As Long
    lpszFileExtension As Long
    dwReserved As Long
    dwExemptDelta As Long
    'szRestOfData() As Byte
End Type
Private Declare Function FindFirstUrlCacheEntry Lib "wininet.dll" Alias "FindFirstUrlCacheEntryA" (ByVal lpszUrlSearchPattern As String, ByVal lpFirstCacheEntryInfo As Long, ByRef lpdwFirstCacheEntryInfoBufferSize As Long) As Long
Private Declare Function FindNextUrlCacheEntry Lib "wininet.dll" Alias "FindNextUrlCacheEntryA" (ByVal hEnumHandle As Long, ByVal lpNextCacheEntryInfo As Long, ByRef lpdwNextCacheEntryInfoBufferSize As Long) As Long
Private Declare Sub FindCloseUrlCache Lib "wininet.dll" (ByVal hEnumHandle As Long)
Private Declare Function DeleteUrlCacheEntry Lib "wininet.dll" Alias "DeleteUrlCacheEntryA" (ByVal lpszUrlName As String) As Long
Private Sub Form_Load()
    'KPD-Team 2001
    'URL: http://www.allapi.net/
    'E-Mail: [email protected]
    Dim ICEI As INTERNET_CACHE_ENTRY_INFO, Ret As Long
    Dim hEntry As Long, Msg As VbMsgBoxResult
    Dim MemBlock As New MemoryBlock
    'Start enumerating the visited URLs
    FindFirstUrlCacheEntry vbNullString, ByVal 0&, Ret
    'If Ret is larger than 0...
    If Ret > 0 Then
        '... allocate a buffer
        MemBlock.Allocate Ret
        'call FindFirstUrlCacheEntry
        hEntry = FindFirstUrlCacheEntry(vbNullString, MemBlock.Handle, Ret)
        'copy from the buffer to the INTERNET_CACHE_ENTRY_INFO structure
        MemBlock.ReadFrom VarPtr(ICEI), LenB(ICEI)
        'Add the lpszSourceUrlName string to the listbox
        If ICEI.lpszSourceUrlName <> 0 Then List1.AddItem MemBlock.ExtractString(ICEI.lpszSourceUrlName, Ret)
    End If
    'Loop until there are no more items
    Do While hEntry <> 0
        'Initialize Ret
        Ret = 0
        'Find out the required size for the next item
        FindNextUrlCacheEntry hEntry, ByVal 0&, Ret
        'If we need to allocate a buffer...
        If Ret > 0 Then
            '... do it
            MemBlock.Allocate Ret
            'and retrieve the next item
            FindNextUrlCacheEntry hEntry, MemBlock.Handle, Ret
            'copy from the buffer to the INTERNET_CACHE_ENTRY_INFO structure
            MemBlock.ReadFrom VarPtr(ICEI), LenB(ICEI)
            'Add the lpszSourceUrlName string to the listbox
            If ICEI.lpszSourceUrlName <> 0 Then List1.AddItem MemBlock.ExtractString(ICEI.lpszSourceUrlName, Ret)
        'Else = no more items
        Else
            Exit Do
        End If
    Loop
    'Close enumeration handle
    FindCloseUrlCache hEntry
    'Delete our memory block
    Set MemBlock = Nothing
    Msg = MsgBox("Do you wish to delete the Internet Explorer cache?", vbYesNo + vbDefaultButton2 + vbQuestion)
    If Msg = vbYes Then
        'loop trough the entries...
        For Ret = 0 To List1.ListCount - 1
            '...and delete them
            DeleteUrlCacheEntry List1.List(Ret)
        Next Ret
        MsgBox "Cache deleted..."
    End If
End Sub

'In the class module 'MemoryBlock':
Option Explicit
Private Const MEM_DECOMMIT = &H4000
Private Const MEM_RELEASE = &H8000
Private Const MEM_COMMIT = &H1000
Private Const MEM_RESERVE = &H2000
Private Const MEM_RESET = &H80000
Private Const MEM_TOP_DOWN = &H100000
Private Const PAGE_READONLY = &H2
Private Const PAGE_READWRITE = &H4
Private Const PAGE_EXECUTE = &H10
Private Const PAGE_EXECUTE_READ = &H20
Private Const PAGE_EXECUTE_READWRITE = &H40
Private Const PAGE_GUARD = &H100
Private Const PAGE_NOACCESS = &H1
Private Const PAGE_NOCACHE = &H200
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal pDest As Long, ByVal pSrc As Long, ByVal ByteLen As Long)
Private Declare Function VirtualAlloc Lib "kernel32" (ByVal lpAddress As Long, ByVal dwSize As Long, ByVal flAllocationType As Long, ByVal flProtect As Long) As Long
Private Declare Function VirtualFree Lib "kernel32" (ByVal lpAddress As Long, ByVal dwSize As Long, ByVal dwFreeType As Long) As Long
Private Declare Function VirtualLock Lib "kernel32" (ByVal lpAddress As Long, ByVal dwSize As Long) As Long
Private Declare Function VirtualUnlock Lib "kernel32" (ByVal lpAddress As Long, ByVal dwSize As Long) As Long
Private Declare Function IsBadReadPtr Lib "kernel32" (ByVal lp As Long, ByVal ucb As Long) As Long
Private Declare Function IsBadWritePtr Lib "kernel32" (ByVal lp As Long, ByVal ucb As Long) As Long
Private Declare Function IsBadStringPtr Lib "kernel32" Alias "IsBadStringPtrA" (ByVal lpsz As Long, ByVal ucchMax As Long) As Long
Private Declare Function lstrcpy Lib "kernel32" Alias "lstrcpyA" (ByVal lpStringDest As String, ByVal lpStringSrc As Long) As Long
Private Declare Function lstrlen Lib "kernel32" Alias "lstrlenA" (ByVal lpString As Long) As Long
Private m_VirtualMem As Long, lLength As Long
'Returns the handle of the allocated memory
Public Property Get Handle() As Long
    Handle = m_VirtualMem
End Property
'Allocates a specific amount of bytes in the Virtual Memory
Public Sub Allocate(lCount As Long)
    ReleaseMemory
    m_VirtualMem = VirtualAlloc(ByVal 0&, lCount, MEM_COMMIT, PAGE_EXECUTE_READWRITE)
    VirtualLock m_VirtualMem, lCount
End Sub
'Reads from the allocated memory and writes it to a specified pointer
Public Sub ReadFrom(hWritePointer As Long, lLength As Long)
    If IsBadWritePtr(hWritePointer, lLength) = 0 And IsBadReadPtr(Handle, lLength) = 0 Then
        CopyMemory hWritePointer, Handle, lLength
    End If
End Sub
'Writes to the allocated memory and reads it from a specified pointer
Public Sub WriteTo(hReadPointer As Long, lLength As Long)
    If IsBadReadPtr(hReadPointer, lLength) = 0 And IsBadWritePtr(Handle, lLength) = 0 Then
        CopyMemory Handle, hReadPointer, lLength
    End If
End Sub
'Extracts a string from the allocated memory
Public Function ExtractString(hStartPointer As Long, lMax As Long) As String
    Dim Length As Long
    If IsBadStringPtr(hStartPointer, lMax) = 0 Then
        ExtractString = Space(lMax)
        lstrcpy ExtractString, hStartPointer
        Length = lstrlen(hStartPointer)
        If Length >= 0 Then ExtractString = Left$(ExtractString, Length)
    End If
End Function
'Release the allocated memory
Public Sub ReleaseMemory()
    If m_VirtualMem <> 0 Then
        VirtualUnlock m_VirtualMem, lLength
        VirtualFree m_VirtualMem, lLength, MEM_DECOMMIT
        VirtualFree m_VirtualMem, 0, MEM_RELEASE
        m_VirtualMem = 0
    End If
End Sub
Private Sub Class_Terminate()
    ReleaseMemory
End Sub








and the C# version (not complete, eliminated MemoryBolck class to make it simple.)



public class Test
{
     const int MEM_DECOMMIT = 0x4000;
     const int MEM_COMMIT= 0x1000;
     const int MEM_RELEASE = 0x8000;
     const int MEM_RESERVE = 0x2000;
     const int MEM_RESET = 0x80000;
     const int MEM_TOP_DOWN = 0x100000;
     const int PAGE_READONLY = 0x2;
     const int PAGE_READWRITE = 0x4;
     const int PAGE_EXECUTE = 0x10;
     const int PAGE_EXECUTE_READ = 0x20;
     const int PAGE_EXECUTE_READWRITE = 0x40;
     const int PAGE_GUARD = 0x100;
     const int PAGE_NOACCESS = 0x1;
     const int PAGE_NOCACHE = 0x200;

     public struct FILETIME
     {
          public int dwLowDateTime;
          public int dwHighDateTime;
     }

     public struct INTERNET_CACHE_ENTRY_INFO
     {
          public int dwStructSize;
          public int lpszSourceUrlName;
          public int lpszLocalFileName;
          public int CacheEntryType;
          public int dwUseCount;
          public int dwHitRate;
          public int dwSizeLow;
          public int dwSizeHigh;
          public FILETIME LastModifiedTime;
          public FILETIME ExpireTime;
          public FILETIME LastAccessTime;
          public FILETIME LastSyncTime;
          public int lpHeaderInfo;
          public int dwHeaderInfoSize;
          public int lpszFileExtension;
          public int dwReserved;
          public int dwExemptDelta;
     }


     [DllImport("wininet")]
     public static extern int FindFirstUrlCacheEntryA (string lpszUrlSearchPattern, int lpFirstCacheEntryInfo, ref int lpdwFirstCacheEntryInfoBufferSize);

     [DllImport("wininet")]
     public static extern int FindNextUrlCacheEntryA (int hEnumHandle, int lpNextCacheEntryInfo , ref int lpdwNextCacheEntryInfoBufferSize);

     [DllImport("wininet")]
     public static extern void FindCloseUrlCache (int hEnumHandle);



     [DllImport("kernel32")]
     public static extern void RtlMoveMemory (int pDest, int pSrc, int ByteLen);

     [DllImport("kernel32")]
     public static extern int VirtualAlloc (int lpAddress,int dwSize,int flAllocationType,int flProtect);

     [DllImport("kernel32")]
     public static extern int VirtualFree(int lpAddress,int dwSize,int dwFreeType);

     [DllImport("kernel32")]
     public static extern int VirtualLock(int lpAddress,int dwSize);

     [DllImport("kernel32")]
     public static extern int VirtualUnlock (int lpAddress,int dwSize);

     [DllImport("kernel32")]
     public static extern int IsBadReadPtr(int lp, int ucb);

     [DllImport("kernel32")]
     public static extern int IsBadWritePtr(int lp , int ucb);

     [DllImport("kernel32")]
     public static extern int IsBadStringPtrA(int lpsz,int ucchMax);

     [DllImport("kernel32")]
     public static extern int lstrcpyA(ref string lpStringDest ,int lpStringSrc);


     [DllImport("kernel32")]
     public static extern int lstrlenA(int lpString);

     public static int m_VirtualMem, lLength;
     public static int Ret=0;


     static void Main()
     {
          GetFromBrowserCache();
          return;
     }



     public static void GetFromBrowserCache()
     {
          INTERNET_CACHE_ENTRY_INFO ICEI = new INTERNET_CACHE_ENTRY_INFO();

          int hEntry;

          //Get the total bytes from the first cache entry
          hEntry = FindFirstUrlCacheEntryA("", 0x0, ref Ret);

          if (Ret > 0)
          {
               Allocate(Ret);

        hEntry = FindFirstUrlCacheEntryA("", m_VirtualMem, ref Ret);

               //Get the address of ICEI. In fact we need intptr, i don't know if it is the correct way of getting it.
               System.Runtime.InteropServices.GCHandle GC = System.Runtime.InteropServices.GCHandle.Alloc(ICEI , System.Runtime.InteropServices.GCHandleType.Pinned );
               int addr = (int)GC.AddrOfPinnedObject();

               Console.WriteLine(" addr="+addr);

               GC.Free();

               //read cache entry into the struct. Struct size is 84.
               ReadFrom(ref addr, 84);

          }
     }

     public static void Allocate(int lCount)
     {
          ReleaseMemory();
          m_VirtualMem = VirtualAlloc(0x0, lCount, MEM_COMMIT, PAGE_EXECUTE_READWRITE) ;
          VirtualLock(m_VirtualMem, lCount);
     }


     public static void ReleaseMemory()
     {
          if(m_VirtualMem != 0)
          {
               VirtualUnlock(m_VirtualMem, lLength);
               VirtualFree (m_VirtualMem, lLength, MEM_DECOMMIT);
               VirtualFree (m_VirtualMem, 0, MEM_RELEASE);
               m_VirtualMem = 0;
          }
     }

     public static void ReadFrom(ref int hWritePointer , int lLength)
     {
          if(IsBadWritePtr(hWritePointer, lLength) == 0 && IsBadReadPtr(m_VirtualMem, lLength) == 0 )
          {
               //may be the following line is not functioning correctly because of invalid argument passed (not sure)
               RtlMoveMemory(hWritePointer, m_VirtualMem, lLength);

               //added following two lines only for debugging purpose.
           string str=ExtractString(hWritePointer, Ret);
               Console.WriteLine(str);
          }
     }

     public static string ExtractString(int hStartPointer, int lMax)
     {
          int Length;
          string strReturn="";

          if (IsBadStringPtrA(hStartPointer, lMax) == 0)
          {
               for(int i=0; i<lMax;i++)
                    strReturn+=" ";

               lstrcpyA(ref strReturn, hStartPointer);

               Length = lstrlenA(hStartPointer);
               if (Length >= 0)
                    return strReturn.Substring(0, Length);

               //here i always find strReturn="P" and Length=1, whereas strReturn should have the url

          }

          return strReturn;
     }


}


BaburMan
 
Old February 14th, 2005, 06:54 AM
Authorized User
 
Join Date: May 2004
Posts: 73
Thanks: 0
Thanked 1 Time in 1 Post
Default

Have got some reasonable solution which at least allows to access the specified URL (html, gif,
css, swf etc.) provided the URL exactly matches the one which is kept in the cache. In addition,
the file can be pulled as a text file (html, css, js etc) or a binary (jpg, gif, swf etc) and
be copied to the specified directory (a gr8 success 4 me). Still trying to fine-tune and working on getting all associated files given a URL. Anybody interested in the code please let me know.


thanks


BaburMan
 
Old April 2nd, 2006, 07:18 PM
Registered User
 
Join Date: Apr 2006
Posts: 2
Thanks: 0
Thanked 0 Times in 0 Posts
Default

bab, I would like to see your code if possible ...

I am looking for a VB6 solution so I may be in the wrong place. I have found working VB6 examples of displaying a list of temporary internet files and deleting them, but I also would like to take it a step further and access the contents of the file. Then again, maybe I am misunderstanding what is going on in the background with windows and IE. I know what when I open a URL with IE, I can go to temporary Internet Files in the documents and settings file tree and at the top of the list will be named the file that I am viewing with IE. I can drag that file out to the desktop and it has the HTML of the site I am viewing. I would like to do this programatically with VB 6.

For an experiment I opened a CMD window and looked at Temporary Internet Files and see only a couple of files so the Windows explorer must be creating this list from another source (index.dat???).

Thanks for any pointers and/or examples!

 
Old October 24th, 2006, 09:50 AM
Registered User
 
Join Date: Oct 2006
Posts: 1
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Baburman,
If you still have that C# code around I would be interested in taking a look at it.
Thanks!






Similar Threads
Thread Thread Starter Forum Replies Last Post
Accessing Programatically xlr8 BOOK: Beginning C# 2005 Databases 1 April 30th, 2007 08:56 AM
Browser cache on palm blazer Rick Lim Beginning PHP 0 March 31st, 2006 01:40 PM
Accessing Membership Data Programatically [email protected] ASP.NET 2.0 Basics 11 February 17th, 2006 02:46 PM
Accessing page contents from browser cache baburman .NET Framework 2.0 3 February 10th, 2005 02:42 AM
Accessing page contents from browser cache baburman General .NET 0 December 6th, 2004 01:44 AM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.