/*
 * Wininet - Url Cache functions
 *
 * Copyright 2001,2002 CodeWeavers
 * Copyright 2003-2008 Robert Shearman
 *
 * Eric Kohl
 * Aric Stewart
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"
#include "wine/port.h"

#define NONAMELESSUNION
#define NONAMELESSSTRUCT

#if defined(__MINGW32__) || defined (_MSC_VER)
#include <ws2tcpip.h>
#endif

#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#include <time.h>

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "wininet.h"
#include "winineti.h"
#include "winerror.h"
#include "winreg.h"
#include "shlwapi.h"
#include "shlobj.h"
#include "shellapi.h"

#include "internet.h"

#include "wine/unicode.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(wininet);

static const char urlcache_ver_prefix[] = "WINE URLCache Ver ";
static const char urlcache_ver[] = "0.2012001";

#ifndef CHAR_BIT
#define CHAR_BIT    (8 * sizeof(CHAR))
#endif

#define ENTRY_START_OFFSET      0x4000
#define DIR_LENGTH              8
#define MAX_DIR_NO              0x20
#define BLOCKSIZE               128
#define HASHTABLE_SIZE          448
#define HASHTABLE_NUM_ENTRIES   64 /* this needs to be power of 2, that divides HASHTABLE_SIZE */
#define HASHTABLE_BLOCKSIZE     (HASHTABLE_SIZE / HASHTABLE_NUM_ENTRIES)
#define ALLOCATION_TABLE_OFFSET 0x250
#define ALLOCATION_TABLE_SIZE   (ENTRY_START_OFFSET - ALLOCATION_TABLE_OFFSET)
#define MIN_BLOCK_NO            0x80
#define MAX_BLOCK_NO            (ALLOCATION_TABLE_SIZE * CHAR_BIT)
#define FILE_SIZE(blocks)       ((blocks) * BLOCKSIZE + ENTRY_START_OFFSET)

#define HASHTABLE_URL           0
#define HASHTABLE_DEL           1
#define HASHTABLE_LOCK          2
#define HASHTABLE_FREE          3
#define HASHTABLE_REDR          5
#define HASHTABLE_FLAG_BITS     6

#define PENDING_DELETE_CACHE_ENTRY  0x00400000
#define INSTALLED_CACHE_ENTRY       0x10000000
#define GET_INSTALLED_ENTRY         0x200
#define CACHE_CONTAINER_NO_SUBDIR   0xFE

#define CACHE_HEADER_DATA_ROOT_LEAK_OFFSET 0x16

#define FILETIME_SECOND 10000000

#define DWORD_SIG(a,b,c,d)  (a | (b << 8) | (c << 16) | (d << 24))
#define URL_SIGNATURE   DWORD_SIG('U','R','L',' ')
#define REDR_SIGNATURE  DWORD_SIG('R','E','D','R')
#define LEAK_SIGNATURE  DWORD_SIG('L','E','A','K')
#define HASH_SIGNATURE  DWORD_SIG('H','A','S','H')

#define DWORD_ALIGN(x) ( (DWORD)(((DWORD)(x)+sizeof(DWORD)-1)/sizeof(DWORD))*sizeof(DWORD) )

#define URLCACHE_FIND_ENTRY_HANDLE_MAGIC 0xF389ABCD

typedef struct
{
    DWORD signature;
    DWORD blocks_used; /* number of 128byte blocks used by this entry */
} entry_header;

typedef struct
{
    entry_header header;
    FILETIME modification_time;
    FILETIME access_time;
    WORD expire_date; /* expire date in dos format */
    WORD expire_time; /* expire time in dos format */
    DWORD unk1; /* usually zero */
    ULARGE_INTEGER size; /* see INTERNET_CACHE_ENTRY_INFO::dwSizeLow/High */
    DWORD unk2; /* usually zero */
    DWORD exempt_delta; /* see INTERNET_CACHE_ENTRY_INFO::dwExemptDelta */
    DWORD unk3; /* usually 0x60 */
    DWORD url_off; /* offset of start of url from start of entry */
    BYTE cache_dir; /* index of cache directory this url is stored in */
    BYTE unk4; /* usually zero */
    WORD unk5; /* usually 0x1010 */
    DWORD local_name_off; /* offset of start of local filename from start of entry */
    DWORD cache_entry_type; /* see INTERNET_CACHE_ENTRY_INFO::CacheEntryType */
    DWORD header_info_off; /* offset of start of header info from start of entry */
    DWORD header_info_size;
    DWORD file_extension_off; /* offset of start of file extension from start of entry */
    WORD sync_date; /* last sync date in dos format */
    WORD sync_time; /* last sync time in dos format */
    DWORD hit_rate; /* see INTERNET_CACHE_ENTRY_INFO::dwHitRate */
    DWORD use_count; /* see INTERNET_CACHE_ENTRY_INFO::dwUseCount */
    WORD write_date;
    WORD write_time;
    DWORD unk7; /* usually zero */
    DWORD unk8; /* usually zero */
    /* packing to dword align start of next field */
    /* CHAR szSourceUrlName[]; (url) */
    /* packing to dword align start of next field */
    /* CHAR szLocalFileName[]; (local file name excluding path) */
    /* packing to dword align start of next field */
    /* CHAR szHeaderInfo[]; (header info) */
} entry_url;

struct hash_entry
{
    DWORD key;
    DWORD offset;
};

typedef struct
{
    entry_header header;
    DWORD next;
    DWORD id;
    struct hash_entry hash_table[HASHTABLE_SIZE];
} entry_hash_table;

typedef struct
{
    char signature[28];
    DWORD size;
    DWORD hash_table_off;
    DWORD capacity_in_blocks;
    DWORD blocks_in_use;
    DWORD unk1;
    ULARGE_INTEGER cache_limit;
    ULARGE_INTEGER cache_usage;
    ULARGE_INTEGER exempt_usage;
    DWORD dirs_no;
    struct _directory_data
    {
        DWORD files_no;
        char name[DIR_LENGTH];
    } directory_data[MAX_DIR_NO];
    DWORD options[0x21];
    BYTE allocation_table[ALLOCATION_TABLE_SIZE];
} urlcache_header;

typedef struct
{
    HANDLE file;
    CHAR url[1];
} stream_handle;

typedef struct
{
    struct list entry; /* part of a list */
    char *cache_prefix; /* string that has to be prefixed for this container to be used */
    LPWSTR path; /* path to url container directory */
    HANDLE mapping; /* handle of file mapping */
    DWORD file_size; /* size of file when mapping was opened */
    HANDLE mutex; /* handle of mutex */
    DWORD default_entry_type;
} cache_container;

typedef struct
{
    DWORD magic;
    char *url_search_pattern;
    DWORD container_idx;
    DWORD hash_table_idx;
    DWORD hash_entry_idx;
} find_handle;

/* List of all containers available */
static struct list UrlContainers = LIST_INIT(UrlContainers);

static inline char *heap_strdupWtoUTF8(LPCWSTR str)
{
    char *ret = NULL;

    if(str) {
        DWORD size = WideCharToMultiByte(CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL);
        ret = heap_alloc(size);
        if(ret)
            WideCharToMultiByte(CP_UTF8, 0, str, -1, ret, size, NULL, NULL);
    }

    return ret;
}

/***********************************************************************
 *           urlcache_block_is_free (Internal)
 *
 *  Is the specified block number free?
 *
 * RETURNS
 *    zero if free
 *    non-zero otherwise
 *
 */
static inline BYTE urlcache_block_is_free(BYTE *allocation_table, DWORD block_number)
{
    BYTE mask = 1 << (block_number%CHAR_BIT);
    return (allocation_table[block_number/CHAR_BIT] & mask) == 0;
}

/***********************************************************************
 *           urlcache_block_free (Internal)
 *
 *  Marks the specified block as free
 *
 * CAUTION
 *    this function is not updating used blocks count
 *
 * RETURNS
 *    nothing
 *
 */
static inline void urlcache_block_free(BYTE *allocation_table, DWORD block_number)
{
    BYTE mask = ~(1 << (block_number%CHAR_BIT));
    allocation_table[block_number/CHAR_BIT] &= mask;
}

/***********************************************************************
 *           urlcache_block_alloc (Internal)
 *
 *  Marks the specified block as allocated
 *
 * CAUTION
 *     this function is not updating used blocks count
 *
 * RETURNS
 *    nothing
 *
 */
static inline void urlcache_block_alloc(BYTE *allocation_table, DWORD block_number)
{
    BYTE mask = 1 << (block_number%CHAR_BIT);
    allocation_table[block_number/CHAR_BIT] |= mask;
}

/***********************************************************************
 *           urlcache_entry_alloc (Internal)
 *
 *  Finds and allocates the first block of free space big enough and
 * sets entry to point to it.
 *
 * RETURNS
 *    ERROR_SUCCESS when free memory block was found
 *    Any other Win32 error code if the entry could not be added
 *
 */
static DWORD urlcache_entry_alloc(urlcache_header *header, DWORD blocks_needed, entry_header **entry)
{
    DWORD block, block_size;

    for(block=0; block<header->capacity_in_blocks; block+=block_size+1)
    {
        block_size = 0;
        while(block_size<blocks_needed && block_size+block<header->capacity_in_blocks
                && urlcache_block_is_free(header->allocation_table, block+block_size))
            block_size++;

        if(block_size == blocks_needed)
        {
            DWORD index;

            TRACE("Found free blocks starting at no. %d (0x%x)\n", block, ENTRY_START_OFFSET+block*BLOCKSIZE);

            for(index=0; index<blocks_needed; index++)
                urlcache_block_alloc(header->allocation_table, block+index);

            *entry = (entry_header*)((BYTE*)header+ENTRY_START_OFFSET+block*BLOCKSIZE);
            for(index=0; index<blocks_needed*BLOCKSIZE/sizeof(DWORD); index++)
                ((DWORD*)*entry)[index] = 0xdeadbeef;
            (*entry)->blocks_used = blocks_needed;

            header->blocks_in_use += blocks_needed;
            return ERROR_SUCCESS;
        }
    }

    return ERROR_HANDLE_DISK_FULL;
}

/***********************************************************************
 *           urlcache_entry_free (Internal)
 *
 *  Deletes the specified entry and frees the space allocated to it
 *
 * RETURNS
 *    TRUE if it succeeded
 *    FALSE if it failed
 *
 */
static BOOL urlcache_entry_free(urlcache_header *header, entry_header *entry)
{
    DWORD start_block, block;

    /* update allocation table */
    start_block = ((DWORD)((BYTE*)entry - (BYTE*)header) - ENTRY_START_OFFSET) / BLOCKSIZE;
    for(block = start_block; block < start_block+entry->blocks_used; block++)
        urlcache_block_free(header->allocation_table, block);

    header->blocks_in_use -= entry->blocks_used;
    return TRUE;
}

/***********************************************************************
 *           urlcache_create_hash_table (Internal)
 *
 *  Creates a new hash table in free space and adds it to the chain of existing
 * hash tables.
 *
 * RETURNS
 *    ERROR_SUCCESS if the hash table was created
 *    ERROR_DISK_FULL if the hash table could not be created
 *
 */
static DWORD urlcache_create_hash_table(urlcache_header *header, entry_hash_table *hash_table_prev, entry_hash_table **hash_table)
{
    DWORD dwOffset, error;
    int i;

    if((error = urlcache_entry_alloc(header, 0x20, (entry_header**)hash_table)) != ERROR_SUCCESS)
        return error;

    dwOffset = (BYTE*)*hash_table-(BYTE*)header;

    if(hash_table_prev)
        hash_table_prev->next = dwOffset;
    else
        header->hash_table_off = dwOffset;

    (*hash_table)->header.signature = HASH_SIGNATURE;
    (*hash_table)->next = 0;
    (*hash_table)->id = hash_table_prev ? hash_table_prev->id+1 : 0;
    for(i = 0; i < HASHTABLE_SIZE; i++) {
        (*hash_table)->hash_table[i].offset = HASHTABLE_FREE;
        (*hash_table)->hash_table[i].key = HASHTABLE_FREE;
    }
    return ERROR_SUCCESS;
}

/***********************************************************************
 *           cache_container_create_object_name (Internal)
 *
 *  Converts a path to a name suitable for use as a Win32 object name.
 * Replaces '\\' characters in-place with the specified character
 * (usually '_' or '!')
 *
 * RETURNS
 *    nothing
 *
 */
static void cache_container_create_object_name(LPWSTR lpszPath, WCHAR replace)
{
    for (; *lpszPath; lpszPath++)
    {
        if (*lpszPath == '\\')
            *lpszPath = replace;
    }
}

/* Caller must hold container lock */
static HANDLE cache_container_map_index(HANDLE file, const WCHAR *path, DWORD size, BOOL *validate)
{
    static const WCHAR mapping_name_format[]
        = {'%','s','i','n','d','e','x','.','d','a','t','_','%','l','u',0};
    WCHAR mapping_name[MAX_PATH];
    HANDLE mapping;

    wsprintfW(mapping_name, mapping_name_format, path, size);
    cache_container_create_object_name(mapping_name, '_');

    mapping = OpenFileMappingW(FILE_MAP_WRITE, FALSE, mapping_name);
    if(mapping) {
        if(validate) *validate = FALSE;
        return mapping;
    }

    if(validate) *validate = TRUE;
    return CreateFileMappingW(file, NULL, PAGE_READWRITE, 0, 0, mapping_name);
}

/* Caller must hold container lock */
static DWORD cache_container_set_size(cache_container *container, HANDLE file, DWORD blocks_no)
{
    static const WCHAR cache_content_key[] = {'S','o','f','t','w','a','r','e','\\',
        'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
        'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
        'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\',
        'C','a','c','h','e','\\','C','o','n','t','e','n','t',0};
    static const WCHAR cache_limit[] = {'C','a','c','h','e','L','i','m','i','t',0};

    DWORD file_size = FILE_SIZE(blocks_no);
    WCHAR dir_path[MAX_PATH], *dir_name;
    entry_hash_table *hashtable_entry;
    urlcache_header *header;
    HANDLE mapping;
    FILETIME ft;
    HKEY key;
    int i, j;

    if(SetFilePointer(file, file_size, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
        return GetLastError();

    if(!SetEndOfFile(file))
        return GetLastError();

    mapping = cache_container_map_index(file, container->path, file_size, NULL);
    if(!mapping)
        return GetLastError();

    header = MapViewOfFile(mapping, FILE_MAP_WRITE, 0, 0, 0);
    if(!header) {
        CloseHandle(mapping);
        return GetLastError();
    }

    if(blocks_no != MIN_BLOCK_NO) {
        if(file_size > header->size)
            memset((char*)header+header->size, 0, file_size-header->size);
        header->size = file_size;
        header->capacity_in_blocks = blocks_no;

        UnmapViewOfFile(header);
        CloseHandle(container->mapping);
        container->mapping = mapping;
        container->file_size = file_size;
        return ERROR_SUCCESS;
    }

    memset(header, 0, file_size);
    /* First set some constants and defaults in the header */
    memcpy(header->signature, urlcache_ver_prefix, sizeof(urlcache_ver_prefix)-1);
    memcpy(header->signature+sizeof(urlcache_ver_prefix)-1, urlcache_ver, sizeof(urlcache_ver)-1);
    header->size = file_size;
    header->capacity_in_blocks = blocks_no;
    /* 127MB - taken from default for Windows 2000 */
    header->cache_limit.QuadPart = 0x07ff5400;
    /* Copied from a Windows 2000 cache index */
    header->dirs_no = container->default_entry_type==NORMAL_CACHE_ENTRY ? 4 : 0;

    /* If the registry has a cache size set, use the registry value */
    if(RegOpenKeyW(HKEY_CURRENT_USER, cache_content_key, &key) == ERROR_SUCCESS) {
        DWORD dw, len = sizeof(dw), keytype;

        if(RegQueryValueExW(key, cache_limit, NULL, &keytype, (BYTE*)&dw, &len) == ERROR_SUCCESS &&
                keytype == REG_DWORD)
            header->cache_limit.QuadPart = (ULONGLONG)dw * 1024;
        RegCloseKey(key);
    }

    urlcache_create_hash_table(header, NULL, &hashtable_entry);

    /* Last step - create the directories */
    strcpyW(dir_path, container->path);
    dir_name = dir_path + strlenW(dir_path);
    dir_name[8] = 0;

    GetSystemTimeAsFileTime(&ft);

    for(i=0; i<header->dirs_no; ++i) {
        header->directory_data[i].files_no = 0;
        for(j=0;; ++j) {
            ULONGLONG n = ft.dwHighDateTime;
            int k;

            /* Generate a file name to attempt to create.
             * This algorithm will create what will appear
             * to be random and unrelated directory names
             * of up to 9 characters in length.
             */
            n <<= 32;
            n += ft.dwLowDateTime;
            n ^= ((ULONGLONG) i << 56) | ((ULONGLONG) j << 48);

            for(k = 0; k < 8; ++k) {
                int r = (n % 36);

                /* Dividing by a prime greater than 36 helps
                 * with the appearance of randomness
                 */
                n /= 37;

                if(r < 10)
                    dir_name[k] = '0' + r;
                else
                    dir_name[k] = 'A' + (r - 10);
            }

            if(CreateDirectoryW(dir_path, 0)) {
                /* The following is OK because we generated an
                 * 8 character directory name made from characters
                 * [A-Z0-9], which are equivalent for all code
                 * pages and for UTF-16
                 */
                for (k = 0; k < 8; ++k)
                    header->directory_data[i].name[k] = dir_name[k];
                break;
            }else if(j >= 255) {
                /* Give up. The most likely cause of this
                 * is a full disk, but whatever the cause
                 * is, it should be more than apparent that
                 * we won't succeed.
                 */
                UnmapViewOfFile(header);
                CloseHandle(mapping);
                return GetLastError();
            }
        }
    }

    UnmapViewOfFile(header);
    CloseHandle(container->mapping);
    container->mapping = mapping;
    container->file_size = file_size;
    return ERROR_SUCCESS;
}

static BOOL cache_container_is_valid(urlcache_header *header, DWORD file_size)
{
    DWORD allocation_size, count_bits, i;

    if(file_size < FILE_SIZE(MIN_BLOCK_NO))
        return FALSE;

    if(file_size != header->size)
        return FALSE;

    if (!memcmp(header->signature, urlcache_ver_prefix, sizeof(urlcache_ver_prefix)-1) &&
            memcmp(header->signature+sizeof(urlcache_ver_prefix)-1, urlcache_ver, sizeof(urlcache_ver)-1))
        return FALSE;

    if(FILE_SIZE(header->capacity_in_blocks) != file_size)
        return FALSE;

    allocation_size = 0;
    for(i=0; i<header->capacity_in_blocks/8; i++) {
        for(count_bits = header->allocation_table[i]; count_bits!=0; count_bits>>=1) {
            if(count_bits & 1)
                allocation_size++;
        }
    }
    if(allocation_size != header->blocks_in_use)
        return FALSE;

    for(; i<ALLOCATION_TABLE_SIZE; i++) {
        if(header->allocation_table[i])
            return FALSE;
    }

    return TRUE;
}

/***********************************************************************
 *           cache_container_open_index (Internal)
 *
 *  Opens the index file and saves mapping handle
 *
 * RETURNS
 *    ERROR_SUCCESS if succeeded
 *    Any other Win32 error code if failed
 *
 */
static DWORD cache_container_open_index(cache_container *container, DWORD blocks_no)
{
    static const WCHAR index_dat[] = {'i','n','d','e','x','.','d','a','t',0};

    HANDLE file;
    WCHAR index_path[MAX_PATH];
    DWORD file_size;
    BOOL validate;

    WaitForSingleObject(container->mutex, INFINITE);

    if(container->mapping) {
        ReleaseMutex(container->mutex);
        return ERROR_SUCCESS;
    }

    strcpyW(index_path, container->path);
    strcatW(index_path, index_dat);

    file = CreateFileW(index_path, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, 0, NULL);
    if(file == INVALID_HANDLE_VALUE) {
	/* Maybe the directory wasn't there? Try to create it */
	if(CreateDirectoryW(container->path, 0))
            file = CreateFileW(index_path, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, 0, NULL);
    }
    if(file == INVALID_HANDLE_VALUE) {
        TRACE("Could not open or create cache index file \"%s\"\n", debugstr_w(index_path));
        ReleaseMutex(container->mutex);
        return GetLastError();
    }

    file_size = GetFileSize(file, NULL);
    if(file_size == INVALID_FILE_SIZE) {
        CloseHandle(file);
	ReleaseMutex(container->mutex);
        return GetLastError();
    }

    if(blocks_no < MIN_BLOCK_NO)
        blocks_no = MIN_BLOCK_NO;
    else if(blocks_no > MAX_BLOCK_NO)
        blocks_no = MAX_BLOCK_NO;

    if(file_size < FILE_SIZE(blocks_no)) {
        DWORD ret = cache_container_set_size(container, file, blocks_no);
        CloseHandle(file);
        ReleaseMutex(container->mutex);
        return ret;
    }

    container->file_size = file_size;
    container->mapping = cache_container_map_index(file, container->path, file_size, &validate);
    CloseHandle(file);
    if(container->mapping && validate) {
        urlcache_header *header = MapViewOfFile(container->mapping, FILE_MAP_WRITE, 0, 0, 0);

        if(header && !cache_container_is_valid(header, file_size)) {
            WARN("detected old or broken index.dat file\n");
            UnmapViewOfFile(header);
            FreeUrlCacheSpaceW(container->path, 100, 0);
        }else if(header) {
            UnmapViewOfFile(header);
        }else {
            CloseHandle(container->mapping);
            container->mapping = NULL;
        }
    }

    if(!container->mapping)
    {
        ERR("Couldn't create file mapping (error is %d)\n", GetLastError());
        ReleaseMutex(container->mutex);
        return GetLastError();
    }

    ReleaseMutex(container->mutex);
    return ERROR_SUCCESS;
}

/***********************************************************************
 *           cache_container_close_index (Internal)
 *
 *  Closes the index
 *
 * RETURNS
 *    nothing
 *
 */
static void cache_container_close_index(cache_container *pContainer)
{
    CloseHandle(pContainer->mapping);
    pContainer->mapping = NULL;
}

static BOOL cache_containers_add(const char *cache_prefix, LPCWSTR path,
        DWORD default_entry_type, LPWSTR mutex_name)
{
    cache_container *pContainer = heap_alloc(sizeof(cache_container));
    int cache_prefix_len = strlen(cache_prefix);

    if (!pContainer)
    {
        return FALSE;
    }

    pContainer->mapping = NULL;
    pContainer->file_size = 0;
    pContainer->default_entry_type = default_entry_type;

    pContainer->path = heap_strdupW(path);
    if (!pContainer->path)
    {
        heap_free(pContainer);
        return FALSE;
    }

    pContainer->cache_prefix = heap_alloc(cache_prefix_len+1);
    if (!pContainer->cache_prefix)
    {
        heap_free(pContainer->path);
        heap_free(pContainer);
        return FALSE;
    }

    memcpy(pContainer->cache_prefix, cache_prefix, cache_prefix_len+1);

    CharLowerW(mutex_name);
    cache_container_create_object_name(mutex_name, '!');

    if ((pContainer->mutex = CreateMutexW(NULL, FALSE, mutex_name)) == NULL)
    {
        ERR("couldn't create mutex (error is %d)\n", GetLastError());
        heap_free(pContainer->path);
        heap_free(pContainer);
        return FALSE;
    }

    list_add_head(&UrlContainers, &pContainer->entry);

    return TRUE;
}

static void cache_container_delete_container(cache_container *pContainer)
{
    list_remove(&pContainer->entry);

    cache_container_close_index(pContainer);
    CloseHandle(pContainer->mutex);
    heap_free(pContainer->path);
    heap_free(pContainer->cache_prefix);
    heap_free(pContainer);
}

static void cache_containers_init(void)
{
    static const WCHAR UrlSuffix[] = {'C','o','n','t','e','n','t','.','I','E','5',0};
    static const WCHAR HistorySuffix[] = {'H','i','s','t','o','r','y','.','I','E','5',0};
    static const WCHAR CookieSuffix[] = {0};
    static const struct
    {
        int nFolder; /* CSIDL_* constant */
        const WCHAR *shpath_suffix; /* suffix on path returned by SHGetSpecialFolderPath */
        const char *cache_prefix; /* prefix used to reference the container */
        DWORD default_entry_type;
    } DefaultContainerData[] = 
    {
        { CSIDL_INTERNET_CACHE, UrlSuffix, "", NORMAL_CACHE_ENTRY },
        { CSIDL_HISTORY, HistorySuffix, "Visited:", URLHISTORY_CACHE_ENTRY },
        { CSIDL_COOKIES, CookieSuffix, "Cookie:", COOKIE_CACHE_ENTRY },
    };
    DWORD i;

    for (i = 0; i < sizeof(DefaultContainerData) / sizeof(DefaultContainerData[0]); i++)
    {
        WCHAR wszCachePath[MAX_PATH];
        WCHAR wszMutexName[MAX_PATH];
        int path_len, suffix_len;
        BOOL def_char;

        if (!SHGetSpecialFolderPathW(NULL, wszCachePath, DefaultContainerData[i].nFolder, TRUE))
        {
            ERR("Couldn't get path for default container %u\n", i);
            continue;
        }
        path_len = strlenW(wszCachePath);
        suffix_len = strlenW(DefaultContainerData[i].shpath_suffix);

        if (path_len + suffix_len + 2 > MAX_PATH)
        {
            ERR("Path too long\n");
            continue;
        }

        wszCachePath[path_len] = '\\';
        wszCachePath[path_len+1] = 0;

        strcpyW(wszMutexName, wszCachePath);
        
        if (suffix_len)
        {
            memcpy(wszCachePath + path_len + 1, DefaultContainerData[i].shpath_suffix, (suffix_len + 1) * sizeof(WCHAR));
            wszCachePath[path_len + suffix_len + 1] = '\\';
            wszCachePath[path_len + suffix_len + 2] = '\0';
        }

        if (!WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, wszCachePath, path_len,
                    NULL, 0, NULL, &def_char) || def_char)
        {
            WCHAR tmp[MAX_PATH];

            /* cannot convert path to ANSI code page */
            if (!(path_len = GetShortPathNameW(wszCachePath, tmp, MAX_PATH)) ||
                !WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, tmp, path_len,
                    NULL, 0, NULL, &def_char) || def_char)
                ERR("Can't create container path accessible by ANSI functions\n");
            else
                memcpy(wszCachePath, tmp, (path_len+1)*sizeof(WCHAR));
        }

        cache_containers_add(DefaultContainerData[i].cache_prefix, wszCachePath,
                DefaultContainerData[i].default_entry_type, wszMutexName);
    }
}

static void cache_containers_free(void)
{
    while(!list_empty(&UrlContainers))
        cache_container_delete_container(
            LIST_ENTRY(list_head(&UrlContainers), cache_container, entry)
        );
}

static DWORD cache_containers_find(const char *url, cache_container **ret)
{
    cache_container *container;

    TRACE("searching for prefix for URL: %s\n", debugstr_a(url));

    if(!url)
        return ERROR_INVALID_PARAMETER;

    LIST_FOR_EACH_ENTRY(container, &UrlContainers, cache_container, entry)
    {
        int prefix_len = strlen(container->cache_prefix);

        if(!strncmp(container->cache_prefix, url, prefix_len)) {
            TRACE("found container with prefix %s\n", debugstr_a(container->cache_prefix));
            *ret = container;
            return ERROR_SUCCESS;
        }
    }

    ERR("no container found\n");
    return ERROR_FILE_NOT_FOUND;
}

static BOOL cache_containers_enum(char *search_pattern, DWORD index, cache_container **ret)
{
    DWORD i = 0;
    cache_container *container;

    TRACE("searching for prefix: %s\n", debugstr_a(search_pattern));

    /* non-NULL search pattern only returns one container ever */
    if (search_pattern && index > 0)
        return FALSE;

    LIST_FOR_EACH_ENTRY(container, &UrlContainers, cache_container, entry)
    {
        if (search_pattern)
        {
            if (!strcmp(container->cache_prefix, search_pattern))
            {
                TRACE("found container with prefix %s\n", debugstr_a(container->cache_prefix));
                *ret = container;
                return TRUE;
            }
        }
        else
        {
            if (i == index)
            {
                TRACE("found container with prefix %s\n", debugstr_a(container->cache_prefix));
                *ret = container;
                return TRUE;
            }
        }
        i++;
    }
    return FALSE;
}

/***********************************************************************
 *           cache_container_lock_index (Internal)
 *
 * Locks the index for system-wide exclusive access.
 *
 * RETURNS
 *  Cache file header if successful
 *  NULL if failed and calls SetLastError.
 */
static urlcache_header* cache_container_lock_index(cache_container *pContainer)
{
    BYTE index;
    LPVOID pIndexData;
    urlcache_header* pHeader;
    DWORD error;

    /* acquire mutex */
    WaitForSingleObject(pContainer->mutex, INFINITE);

    pIndexData = MapViewOfFile(pContainer->mapping, FILE_MAP_WRITE, 0, 0, 0);

    if (!pIndexData)
    {
        ReleaseMutex(pContainer->mutex);
        ERR("Couldn't MapViewOfFile. Error: %d\n", GetLastError());
        return NULL;
    }
    pHeader = (urlcache_header*)pIndexData;

    /* file has grown - we need to remap to prevent us getting
     * access violations when we try and access beyond the end
     * of the memory mapped file */
    if (pHeader->size != pContainer->file_size)
    {
        UnmapViewOfFile( pHeader );
        cache_container_close_index(pContainer);
        error = cache_container_open_index(pContainer, MIN_BLOCK_NO);
        if (error != ERROR_SUCCESS)
        {
            ReleaseMutex(pContainer->mutex);
            SetLastError(error);
            return NULL;
        }
        pIndexData = MapViewOfFile(pContainer->mapping, FILE_MAP_WRITE, 0, 0, 0);

        if (!pIndexData)
        {
            ReleaseMutex(pContainer->mutex);
            ERR("Couldn't MapViewOfFile. Error: %d\n", GetLastError());
            return NULL;
        }
        pHeader = (urlcache_header*)pIndexData;
    }

    TRACE("Signature: %s, file size: %d bytes\n", pHeader->signature, pHeader->size);

    for (index = 0; index < pHeader->dirs_no; index++)
    {
        TRACE("Directory[%d] = \"%.8s\"\n", index, pHeader->directory_data[index].name);
    }
    
    return pHeader;
}

/***********************************************************************
 *           cache_container_unlock_index (Internal)
 *
 */
static BOOL cache_container_unlock_index(cache_container *pContainer, urlcache_header *pHeader)
{
    /* release mutex */
    ReleaseMutex(pContainer->mutex);
    return UnmapViewOfFile(pHeader);
}

/***********************************************************************
 *           urlcache_create_file_pathW (Internal)
 *
 *  Copies the full path to the specified buffer given the local file
 * name and the index of the directory it is in. Always sets value in
 * lpBufferSize to the required buffer size (in bytes).
 *
 * RETURNS
 *    TRUE if the buffer was big enough
 *    FALSE if the buffer was too small
 *
 */
static BOOL urlcache_create_file_pathW(
    const cache_container *pContainer,
    const urlcache_header *pHeader,
    LPCSTR szLocalFileName,
    BYTE Directory,
    LPWSTR wszPath,
    LPLONG lpBufferSize)
{
    LONG nRequired;
    int path_len = strlenW(pContainer->path);
    int file_name_len = MultiByteToWideChar(CP_ACP, 0, szLocalFileName, -1, NULL, 0);
    if (Directory!=CACHE_CONTAINER_NO_SUBDIR && Directory>=pHeader->dirs_no)
    {
        *lpBufferSize = 0;
        return FALSE;
    }

    nRequired = (path_len + file_name_len) * sizeof(WCHAR);
    if(Directory != CACHE_CONTAINER_NO_SUBDIR)
        nRequired += (DIR_LENGTH + 1) * sizeof(WCHAR);
    if (nRequired <= *lpBufferSize)
    {
        int dir_len;

        memcpy(wszPath, pContainer->path, path_len * sizeof(WCHAR));
        if (Directory != CACHE_CONTAINER_NO_SUBDIR)
        {
            dir_len = MultiByteToWideChar(CP_ACP, 0, pHeader->directory_data[Directory].name, DIR_LENGTH, wszPath + path_len, DIR_LENGTH);
            wszPath[dir_len + path_len] = '\\';
            dir_len++;
        }
        else
        {
            dir_len = 0;
        }
        MultiByteToWideChar(CP_ACP, 0, szLocalFileName, -1, wszPath + dir_len + path_len, file_name_len);
        *lpBufferSize = nRequired;
        return TRUE;
    }
    *lpBufferSize = nRequired;
    return FALSE;
}

/***********************************************************************
 *           urlcache_create_file_pathA (Internal)
 *
 *  Copies the full path to the specified buffer given the local file
 * name and the index of the directory it is in. Always sets value in
 * lpBufferSize to the required buffer size.
 *
 * RETURNS
 *    TRUE if the buffer was big enough
 *    FALSE if the buffer was too small
 *
 */
static BOOL urlcache_create_file_pathA(
    const cache_container *pContainer,
    const urlcache_header *pHeader,
    LPCSTR szLocalFileName,
    BYTE Directory,
    LPSTR szPath,
    LPLONG lpBufferSize)
{
    LONG nRequired;
    int path_len, file_name_len, dir_len;

    if (Directory!=CACHE_CONTAINER_NO_SUBDIR && Directory>=pHeader->dirs_no)
    {
        *lpBufferSize = 0;
        return FALSE;
    }

    path_len = WideCharToMultiByte(CP_ACP, 0, pContainer->path, -1, NULL, 0, NULL, NULL) - 1;
    file_name_len = strlen(szLocalFileName) + 1 /* for nul-terminator */;
    if (Directory!=CACHE_CONTAINER_NO_SUBDIR)
        dir_len = DIR_LENGTH+1;
    else
        dir_len = 0;

    nRequired = (path_len + dir_len + file_name_len) * sizeof(char);
    if (nRequired <= *lpBufferSize)
    {
        WideCharToMultiByte(CP_ACP, 0, pContainer->path, -1, szPath, path_len, NULL, NULL);
        if(dir_len) {
            memcpy(szPath+path_len, pHeader->directory_data[Directory].name, dir_len-1);
            szPath[path_len + dir_len-1] = '\\';
        }
        memcpy(szPath + path_len + dir_len, szLocalFileName, file_name_len);
        *lpBufferSize = nRequired;
        return TRUE;
    }
    *lpBufferSize = nRequired;
    return FALSE;
}

/* Just like FileTimeToDosDateTime, except that it also maps the special
 * case of a filetime of (0,0) to a DOS date/time of (0,0).
 */
static void file_time_to_dos_date_time(const FILETIME *ft, WORD *fatdate,
                                           WORD *fattime)
{
    if (!ft->dwLowDateTime && !ft->dwHighDateTime)
        *fatdate = *fattime = 0;
    else
        FileTimeToDosDateTime(ft, fatdate, fattime);
}

/***********************************************************************
 *           urlcache_delete_file (Internal)
 */
static DWORD urlcache_delete_file(const cache_container *container,
        urlcache_header *header, entry_url *url_entry)
{
    WIN32_FILE_ATTRIBUTE_DATA attr;
    WCHAR path[MAX_PATH];
    LONG path_size = sizeof(path);
    DWORD err;
    WORD date, time;

    if(!url_entry->local_name_off)
        goto succ;

    if(!urlcache_create_file_pathW(container, header,
                (LPCSTR)url_entry+url_entry->local_name_off,
                url_entry->cache_dir, path, &path_size))
        goto succ;

    if(!GetFileAttributesExW(path, GetFileExInfoStandard, &attr))
        goto succ;
    file_time_to_dos_date_time(&attr.ftLastWriteTime, &date, &time);
    if(date != url_entry->write_date || time != url_entry->write_time)
        goto succ;

    err = (DeleteFileW(path) ? ERROR_SUCCESS : GetLastError());
    if(err == ERROR_ACCESS_DENIED || err == ERROR_SHARING_VIOLATION)
        return err;

succ:
    if (url_entry->cache_dir < header->dirs_no)
    {
        if (header->directory_data[url_entry->cache_dir].files_no)
            header->directory_data[url_entry->cache_dir].files_no--;
    }
    if (url_entry->cache_entry_type & STICKY_CACHE_ENTRY)
    {
        if (url_entry->size.QuadPart < header->exempt_usage.QuadPart)
            header->exempt_usage.QuadPart -= url_entry->size.QuadPart;
        else
            header->exempt_usage.QuadPart = 0;
    }
    else
    {
        if (url_entry->size.QuadPart < header->cache_usage.QuadPart)
            header->cache_usage.QuadPart -= url_entry->size.QuadPart;
        else
            header->cache_usage.QuadPart = 0;
    }

    return ERROR_SUCCESS;
}

static BOOL urlcache_clean_leaked_entries(cache_container *container, urlcache_header *header)
{
    DWORD *leak_off;
    BOOL freed = FALSE;

    leak_off = &header->options[CACHE_HEADER_DATA_ROOT_LEAK_OFFSET];
    while(*leak_off) {
        entry_url *url_entry = (entry_url*)((LPBYTE)header + *leak_off);

        if(SUCCEEDED(urlcache_delete_file(container, header, url_entry))) {
            *leak_off = url_entry->exempt_delta;
            urlcache_entry_free(header, &url_entry->header);
            freed = TRUE;
        }else {
            leak_off = &url_entry->exempt_delta;
        }
    }

    return freed;
}

/***********************************************************************
 *           cache_container_clean_index (Internal)
 *
 * This function is meant to make place in index file by removing leaked
 * files entries and resizing the file.
 *
 * CAUTION: file view may get mapped to new memory
 *
 * RETURNS
 *     ERROR_SUCCESS when new memory is available
 *     error code otherwise
 */
static DWORD cache_container_clean_index(cache_container *container, urlcache_header **file_view)
{
    urlcache_header *header = *file_view;
    DWORD ret;

    TRACE("(%s %s)\n", debugstr_a(container->cache_prefix), debugstr_w(container->path));

    if(urlcache_clean_leaked_entries(container, header))
        return ERROR_SUCCESS;

    if(header->size >= ALLOCATION_TABLE_SIZE*8*BLOCKSIZE + ENTRY_START_OFFSET) {
        WARN("index file has maximal size\n");
        return ERROR_NOT_ENOUGH_MEMORY;
    }

    cache_container_close_index(container);
    ret = cache_container_open_index(container, header->capacity_in_blocks*2);
    if(ret != ERROR_SUCCESS)
        return ret;
    header = MapViewOfFile(container->mapping, FILE_MAP_WRITE, 0, 0, 0);
    if(!header)
        return GetLastError();

    UnmapViewOfFile(*file_view);
    *file_view = header;
    return ERROR_SUCCESS;
}

/* Just like DosDateTimeToFileTime, except that it also maps the special
 * case of a DOS date/time of (0,0) to a filetime of (0,0).
 */
static void dos_date_time_to_file_time(WORD fatdate, WORD fattime,
                                           FILETIME *ft)
{
    if (!fatdate && !fattime)
        ft->dwLowDateTime = ft->dwHighDateTime = 0;
    else
        DosDateTimeToFileTime(fatdate, fattime, ft);
}

static int urlcache_decode_url(const char *url, WCHAR *decoded_url, int decoded_len)
{
    URL_COMPONENTSA uc;
    DWORD len, part_len;
    WCHAR *host_name;

    memset(&uc, 0, sizeof(uc));
    uc.dwStructSize = sizeof(uc);
    uc.dwHostNameLength = 1;
    if(!InternetCrackUrlA(url, 0, 0, &uc))
        uc.nScheme = INTERNET_SCHEME_UNKNOWN;

    if(uc.nScheme!=INTERNET_SCHEME_HTTP && uc.nScheme!=INTERNET_SCHEME_HTTPS)
        return MultiByteToWideChar(CP_UTF8, 0, url, -1, decoded_url, decoded_len);

    if(!decoded_url)
        decoded_len = 0;

    len = MultiByteToWideChar(CP_UTF8, 0, url, uc.lpszHostName-url, decoded_url, decoded_len);
    if(!len)
        return 0;
    if(decoded_url)
        decoded_len -= len;

    host_name = heap_alloc(uc.dwHostNameLength*sizeof(WCHAR));
    if(!host_name)
        return 0;
    if(!MultiByteToWideChar(CP_UTF8, 0, uc.lpszHostName, uc.dwHostNameLength,
                host_name, uc.dwHostNameLength)) {
        heap_free(host_name);
        return 0;
    }
    part_len = IdnToUnicode(0, host_name, uc.dwHostNameLength,
            decoded_url ? decoded_url+len : NULL, decoded_len);
    heap_free(host_name);
    if(!part_len) {
        SetLastError(ERROR_INTERNET_INVALID_URL);
        return 0;
    }
    len += part_len;
    if(decoded_url)
        decoded_len -= part_len;

    part_len = MultiByteToWideChar(CP_UTF8, 0,
            uc.lpszHostName+uc.dwHostNameLength,
            -1, decoded_url ? decoded_url+len : NULL, decoded_len);
    if(!part_len)
        return 0;
    len += part_len;

    return len;
}

/***********************************************************************
 *           urlcache_copy_entry (Internal)
 *
 *  Copies an entry from the cache index file to the Win32 structure
 *
 * RETURNS
 *    ERROR_SUCCESS if the buffer was big enough
 *    ERROR_INSUFFICIENT_BUFFER if the buffer was too small
 *
 */
static DWORD urlcache_copy_entry(cache_container *container, const urlcache_header *header,
        INTERNET_CACHE_ENTRY_INFOA *entry_info, DWORD *info_size, const entry_url *url_entry, BOOL unicode)
{
    int url_len;
    DWORD size = sizeof(*entry_info);

    if(*info_size >= size) {
        entry_info->lpHeaderInfo = NULL;
        entry_info->lpszFileExtension = NULL;
        entry_info->lpszLocalFileName = NULL;
        entry_info->lpszSourceUrlName = NULL;
        entry_info->CacheEntryType = url_entry->cache_entry_type;
        entry_info->u.dwExemptDelta = url_entry->exempt_delta;
        entry_info->dwHeaderInfoSize = url_entry->header_info_size;
        entry_info->dwHitRate = url_entry->hit_rate;
        entry_info->dwSizeHigh = url_entry->size.u.HighPart;
        entry_info->dwSizeLow = url_entry->size.u.LowPart;
        entry_info->dwStructSize = sizeof(*entry_info);
        entry_info->dwUseCount = url_entry->use_count;
        dos_date_time_to_file_time(url_entry->expire_date, url_entry->expire_time, &entry_info->ExpireTime);
        entry_info->LastAccessTime = url_entry->access_time;
        entry_info->LastModifiedTime = url_entry->modification_time;
        dos_date_time_to_file_time(url_entry->sync_date, url_entry->sync_time, &entry_info->LastSyncTime);
    }

    if(size%4 && size<*info_size)
        ZeroMemory((LPBYTE)entry_info+size, 4-size%4);
    size = DWORD_ALIGN(size);
    if(unicode)
        url_len = urlcache_decode_url((const char*)url_entry+url_entry->url_off, NULL, 0);
    else
        url_len = strlen((LPCSTR)url_entry+url_entry->url_off) + 1;
    size += url_len * (unicode ? sizeof(WCHAR) : sizeof(CHAR));

    if(*info_size >= size) {
        DWORD url_size = url_len * (unicode ? sizeof(WCHAR) : sizeof(CHAR));

        entry_info->lpszSourceUrlName = (LPSTR)entry_info+size-url_size;
        if(unicode)
            urlcache_decode_url((const char*)url_entry+url_entry->url_off, (WCHAR*)entry_info->lpszSourceUrlName, url_len);
        else
            memcpy(entry_info->lpszSourceUrlName, (LPCSTR)url_entry+url_entry->url_off, url_size);
    }

    if(size%4 && size<*info_size)
        ZeroMemory((LPBYTE)entry_info+size, 4-size%4);
    size = DWORD_ALIGN(size);

    if(url_entry->local_name_off) {
        LONG file_name_size;
        LPSTR file_name;
        file_name = (LPSTR)entry_info+size;
        file_name_size = *info_size-size;
        if((unicode && urlcache_create_file_pathW(container, header, (LPCSTR)url_entry+url_entry->local_name_off, url_entry->cache_dir, (LPWSTR)file_name, &file_name_size)) ||
            (!unicode && urlcache_create_file_pathA(container, header, (LPCSTR)url_entry+url_entry->local_name_off, url_entry->cache_dir, file_name, &file_name_size))) {
            entry_info->lpszLocalFileName = file_name;
        }
        size += file_name_size;

        if(size%4 && size<*info_size)
            ZeroMemory((LPBYTE)entry_info+size, 4-size%4);
        size = DWORD_ALIGN(size);
    }

    if(url_entry->header_info_off) {
        DWORD header_len;

        if(unicode)
            header_len = MultiByteToWideChar(CP_UTF8, 0, (const char*)url_entry+url_entry->header_info_off,
                    url_entry->header_info_size, NULL, 0);
        else
            header_len = url_entry->header_info_size;
        size += header_len * (unicode ? sizeof(WCHAR) : sizeof(CHAR));

        if(*info_size >= size) {
            DWORD header_size = header_len * (unicode ? sizeof(WCHAR) : sizeof(CHAR));
            entry_info->lpHeaderInfo = (LPBYTE)entry_info+size-header_size;
            if(unicode)
                MultiByteToWideChar(CP_UTF8, 0, (const char*)url_entry+url_entry->header_info_off,
                        url_entry->header_info_size, (LPWSTR)entry_info->lpHeaderInfo, header_len);
            else
                memcpy(entry_info->lpHeaderInfo, (LPCSTR)url_entry+url_entry->header_info_off, header_len);
        }
        if(size%4 && size<*info_size)
            ZeroMemory((LPBYTE)entry_info+size, 4-size%4);
        size = DWORD_ALIGN(size);
    }

    if(url_entry->file_extension_off) {
        int ext_len;

        if(unicode)
            ext_len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)url_entry+url_entry->file_extension_off, -1, NULL, 0);
        else
            ext_len = strlen((LPCSTR)url_entry+url_entry->file_extension_off) + 1;
        size += ext_len * (unicode ? sizeof(WCHAR) : sizeof(CHAR));

        if(*info_size >= size) {
            DWORD ext_size = ext_len * (unicode ? sizeof(WCHAR) : sizeof(CHAR));
            entry_info->lpszFileExtension = (LPSTR)entry_info+size-ext_size;
            if(unicode)
                MultiByteToWideChar(CP_ACP, 0, (LPCSTR)url_entry+url_entry->file_extension_off, -1, (LPWSTR)entry_info->lpszFileExtension, ext_len);
            else
                memcpy(entry_info->lpszFileExtension, (LPCSTR)url_entry+url_entry->file_extension_off, ext_len*sizeof(CHAR));
        }

        if(size%4 && size<*info_size)
            ZeroMemory((LPBYTE)entry_info+size, 4-size%4);
        size = DWORD_ALIGN(size);
    }

    if(size > *info_size) {
        *info_size = size;
        return ERROR_INSUFFICIENT_BUFFER;
    }
    *info_size = size;
    return ERROR_SUCCESS;
}

/***********************************************************************
 *           urlcache_set_entry_info (Internal)
 *
 *  Helper for SetUrlCacheEntryInfo{A,W}. Sets fields in URL entry
 * according to the flags set by field_control.
 *
 * RETURNS
 *    ERROR_SUCCESS if the buffer was big enough
 *    ERROR_INSUFFICIENT_BUFFER if the buffer was too small
 *
 */
static DWORD urlcache_set_entry_info(entry_url *url_entry, const INTERNET_CACHE_ENTRY_INFOA *entry_info, DWORD field_control)
{
    if (field_control & CACHE_ENTRY_ACCTIME_FC)
        url_entry->access_time = entry_info->LastAccessTime;
    if (field_control & CACHE_ENTRY_ATTRIBUTE_FC)
        url_entry->cache_entry_type = entry_info->CacheEntryType;
    if (field_control & CACHE_ENTRY_EXEMPT_DELTA_FC)
        url_entry->exempt_delta = entry_info->u.dwExemptDelta;
    if (field_control & CACHE_ENTRY_EXPTIME_FC)
        file_time_to_dos_date_time(&entry_info->ExpireTime, &url_entry->expire_date, &url_entry->expire_time);
    if (field_control & CACHE_ENTRY_HEADERINFO_FC)
        FIXME("CACHE_ENTRY_HEADERINFO_FC unimplemented\n");
    if (field_control & CACHE_ENTRY_HITRATE_FC)
        url_entry->hit_rate = entry_info->dwHitRate;
    if (field_control & CACHE_ENTRY_MODTIME_FC)
        url_entry->modification_time = entry_info->LastModifiedTime;
    if (field_control & CACHE_ENTRY_SYNCTIME_FC)
        file_time_to_dos_date_time(&entry_info->LastAccessTime, &url_entry->sync_date, &url_entry->sync_time);

    return ERROR_SUCCESS;
}

/***********************************************************************
 *           urlcache_hash_key (Internal)
 *
 *  Returns the hash key for a given string
 *
 * RETURNS
 *    hash key for the string
 *
 */
static DWORD urlcache_hash_key(LPCSTR lpszKey)
{
    /* NOTE: this uses the same lookup table as SHLWAPI.UrlHash{A,W}
     * but the algorithm and result are not the same!
     */
    static const unsigned char lookupTable[256] = 
    {
        0x01, 0x0E, 0x6E, 0x19, 0x61, 0xAE, 0x84, 0x77,
        0x8A, 0xAA, 0x7D, 0x76, 0x1B, 0xE9, 0x8C, 0x33,
        0x57, 0xC5, 0xB1, 0x6B, 0xEA, 0xA9, 0x38, 0x44,
        0x1E, 0x07, 0xAD, 0x49, 0xBC, 0x28, 0x24, 0x41,
        0x31, 0xD5, 0x68, 0xBE, 0x39, 0xD3, 0x94, 0xDF,
        0x30, 0x73, 0x0F, 0x02, 0x43, 0xBA, 0xD2, 0x1C,
        0x0C, 0xB5, 0x67, 0x46, 0x16, 0x3A, 0x4B, 0x4E,
        0xB7, 0xA7, 0xEE, 0x9D, 0x7C, 0x93, 0xAC, 0x90,
        0xB0, 0xA1, 0x8D, 0x56, 0x3C, 0x42, 0x80, 0x53,
        0x9C, 0xF1, 0x4F, 0x2E, 0xA8, 0xC6, 0x29, 0xFE,
        0xB2, 0x55, 0xFD, 0xED, 0xFA, 0x9A, 0x85, 0x58,
        0x23, 0xCE, 0x5F, 0x74, 0xFC, 0xC0, 0x36, 0xDD,
        0x66, 0xDA, 0xFF, 0xF0, 0x52, 0x6A, 0x9E, 0xC9,
        0x3D, 0x03, 0x59, 0x09, 0x2A, 0x9B, 0x9F, 0x5D,
        0xA6, 0x50, 0x32, 0x22, 0xAF, 0xC3, 0x64, 0x63,
        0x1A, 0x96, 0x10, 0x91, 0x04, 0x21, 0x08, 0xBD,
        0x79, 0x40, 0x4D, 0x48, 0xD0, 0xF5, 0x82, 0x7A,
        0x8F, 0x37, 0x69, 0x86, 0x1D, 0xA4, 0xB9, 0xC2,
        0xC1, 0xEF, 0x65, 0xF2, 0x05, 0xAB, 0x7E, 0x0B,
        0x4A, 0x3B, 0x89, 0xE4, 0x6C, 0xBF, 0xE8, 0x8B,
        0x06, 0x18, 0x51, 0x14, 0x7F, 0x11, 0x5B, 0x5C,
        0xFB, 0x97, 0xE1, 0xCF, 0x15, 0x62, 0x71, 0x70,
        0x54, 0xE2, 0x12, 0xD6, 0xC7, 0xBB, 0x0D, 0x20,
        0x5E, 0xDC, 0xE0, 0xD4, 0xF7, 0xCC, 0xC4, 0x2B,
        0xF9, 0xEC, 0x2D, 0xF4, 0x6F, 0xB6, 0x99, 0x88,
        0x81, 0x5A, 0xD9, 0xCA, 0x13, 0xA5, 0xE7, 0x47,
        0xE6, 0x8E, 0x60, 0xE3, 0x3E, 0xB3, 0xF6, 0x72,
        0xA2, 0x35, 0xA0, 0xD7, 0xCD, 0xB4, 0x2F, 0x6D,
        0x2C, 0x26, 0x1F, 0x95, 0x87, 0x00, 0xD8, 0x34,
        0x3F, 0x17, 0x25, 0x45, 0x27, 0x75, 0x92, 0xB8,
        0xA3, 0xC8, 0xDE, 0xEB, 0xF8, 0xF3, 0xDB, 0x0A,
        0x98, 0x83, 0x7B, 0xE5, 0xCB, 0x4C, 0x78, 0xD1
    };
    BYTE key[4];
    DWORD i;

    for (i = 0; i < sizeof(key) / sizeof(key[0]); i++)
        key[i] = lookupTable[(*lpszKey + i) & 0xFF];

    for (lpszKey++; *lpszKey && ((lpszKey[0] != '/') || (lpszKey[1] != 0)); lpszKey++)
    {
        for (i = 0; i < sizeof(key) / sizeof(key[0]); i++)
            key[i] = lookupTable[*lpszKey ^ key[i]];
    }

    return *(DWORD *)key;
}

static inline entry_hash_table* urlcache_get_hash_table(const urlcache_header *pHeader, DWORD dwOffset)
{
    if(!dwOffset)
        return NULL;
    return (entry_hash_table*)((LPBYTE)pHeader + dwOffset);
}

static BOOL urlcache_find_hash_entry(const urlcache_header *pHeader, LPCSTR lpszUrl, struct hash_entry **ppHashEntry)
{
    /* structure of hash table:
     *  448 entries divided into 64 blocks
     *  each block therefore contains a chain of 7 key/offset pairs
     * how position in table is calculated:
     *  1. the url is hashed in helper function
     *  2. the key % HASHTABLE_NUM_ENTRIES is the bucket number
     *  3. bucket number * HASHTABLE_BLOCKSIZE is offset of the bucket
     *
     * note:
     *  there can be multiple hash tables in the file and the offset to
     *  the next one is stored in the header of the hash table
     */
    DWORD key = urlcache_hash_key(lpszUrl);
    DWORD offset = (key & (HASHTABLE_NUM_ENTRIES-1)) * HASHTABLE_BLOCKSIZE;
    entry_hash_table* pHashEntry;
    DWORD id = 0;

    key >>= HASHTABLE_FLAG_BITS;

    for (pHashEntry = urlcache_get_hash_table(pHeader, pHeader->hash_table_off);
         pHashEntry; pHashEntry = urlcache_get_hash_table(pHeader, pHashEntry->next))
    {
        int i;
        if (pHashEntry->id != id++)
        {
            ERR("Error: not right hash table number (%d) expected %d\n", pHashEntry->id, id);
            continue;
        }
        /* make sure that it is in fact a hash entry */
        if (pHashEntry->header.signature != HASH_SIGNATURE)
        {
            ERR("Error: not right signature (\"%.4s\") - expected \"HASH\"\n", (LPCSTR)&pHashEntry->header.signature);
            continue;
        }

        for (i = 0; i < HASHTABLE_BLOCKSIZE; i++)
        {
            struct hash_entry *pHashElement = &pHashEntry->hash_table[offset + i];
            if (key == pHashElement->key>>HASHTABLE_FLAG_BITS)
            {
                /* FIXME: we should make sure that this is the right element
                 * before returning and claiming that it is. We can do this
                 * by doing a simple compare between the URL we were given
                 * and the URL stored in the entry. However, this assumes
                 * we know the format of all the entries stored in the
                 * hash table */
                *ppHashEntry = pHashElement;
                return TRUE;
            }
        }
    }
    return FALSE;
}

/***********************************************************************
 *           urlcache_hash_entry_set_flags (Internal)
 *
 *  Sets special bits in hash key
 *
 * RETURNS
 *    nothing
 *
 */
static void urlcache_hash_entry_set_flags(struct hash_entry *pHashEntry, DWORD dwFlag)
{
    pHashEntry->key = (pHashEntry->key >> HASHTABLE_FLAG_BITS << HASHTABLE_FLAG_BITS) | dwFlag;
}

/***********************************************************************
 *           urlcache_hash_entry_delete (Internal)
 *
 *  Searches all the hash tables in the index for the given URL and
 * then if found deletes the entry.
 *
 * RETURNS
 *    TRUE if the entry was found
 *    FALSE if the entry could not be found
 *
 */
static BOOL urlcache_hash_entry_delete(struct hash_entry *pHashEntry)
{
    pHashEntry->key = HASHTABLE_DEL;
    return TRUE;
}

/***********************************************************************
 *           urlcache_hash_entry_create (Internal)
 *
 *  Searches all the hash tables for a free slot based on the offset
 * generated from the hash key. If a free slot is found, the offset and
 * key are entered into the hash table.
 *
 * RETURNS
 *    ERROR_SUCCESS if the entry was added
 *    Any other Win32 error code if the entry could not be added
 *
 */
static DWORD urlcache_hash_entry_create(urlcache_header *pHeader, LPCSTR lpszUrl, DWORD dwOffsetEntry, DWORD dwFieldType)
{
    /* see urlcache_find_hash_entry for structure of hash tables */

    DWORD key = urlcache_hash_key(lpszUrl);
    DWORD offset = (key & (HASHTABLE_NUM_ENTRIES-1)) * HASHTABLE_BLOCKSIZE;
    entry_hash_table* pHashEntry, *pHashPrev = NULL;
    DWORD id = 0;
    DWORD error;

    key = ((key >> HASHTABLE_FLAG_BITS) << HASHTABLE_FLAG_BITS) + dwFieldType;

    for (pHashEntry = urlcache_get_hash_table(pHeader, pHeader->hash_table_off);
         pHashEntry; pHashEntry = urlcache_get_hash_table(pHeader, pHashEntry->next))
    {
        int i;
        pHashPrev = pHashEntry;

        if (pHashEntry->id != id++)
        {
            ERR("not right hash table number (%d) expected %d\n", pHashEntry->id, id);
            break;
        }
        /* make sure that it is in fact a hash entry */
        if (pHashEntry->header.signature != HASH_SIGNATURE)
        {
            ERR("not right signature (\"%.4s\") - expected \"HASH\"\n", (LPCSTR)&pHashEntry->header.signature);
            break;
        }

        for (i = 0; i < HASHTABLE_BLOCKSIZE; i++)
        {
            struct hash_entry *pHashElement = &pHashEntry->hash_table[offset + i];
            if (pHashElement->key==HASHTABLE_FREE || pHashElement->key==HASHTABLE_DEL) /* if the slot is free */
            {
                pHashElement->key = key;
                pHashElement->offset = dwOffsetEntry;
                return ERROR_SUCCESS;
            }
        }
    }
    error = urlcache_create_hash_table(pHeader, pHashPrev, &pHashEntry);
    if (error != ERROR_SUCCESS)
        return error;

    pHashEntry->hash_table[offset].key = key;
    pHashEntry->hash_table[offset].offset = dwOffsetEntry;
    return ERROR_SUCCESS;
}

/***********************************************************************
 *           urlcache_enum_hash_tables (Internal)
 *
 *  Enumerates the hash tables in a container.
 *
 * RETURNS
 *    TRUE if an entry was found
 *    FALSE if there are no more tables to enumerate.
 *
 */
static BOOL urlcache_enum_hash_tables(const urlcache_header *pHeader, DWORD *id, entry_hash_table **ppHashEntry)
{
    for (*ppHashEntry = urlcache_get_hash_table(pHeader, pHeader->hash_table_off);
         *ppHashEntry; *ppHashEntry = urlcache_get_hash_table(pHeader, (*ppHashEntry)->next))
    {
        TRACE("looking at hash table number %d\n", (*ppHashEntry)->id);
        if ((*ppHashEntry)->id != *id)
            continue;
        /* make sure that it is in fact a hash entry */
        if ((*ppHashEntry)->header.signature != HASH_SIGNATURE)
        {
            ERR("Error: not right signature (\"%.4s\") - expected \"HASH\"\n", (LPCSTR)&(*ppHashEntry)->header.signature);
            (*id)++;
            continue;
        }

        TRACE("hash table number %d found\n", *id);
        return TRUE;
    }
    return FALSE;
}

/***********************************************************************
 *           urlcache_enum_hash_table_entries (Internal)
 *
 *  Enumerates entries in a hash table and returns the next non-free entry.
 *
 * RETURNS
 *    TRUE if an entry was found
 *    FALSE if the hash table is empty or there are no more entries to
 *     enumerate.
 *
 */
static BOOL urlcache_enum_hash_table_entries(const urlcache_header *pHeader, const entry_hash_table *pHashEntry,
                                          DWORD * index, const struct hash_entry **ppHashEntry)
{
    for (; *index < HASHTABLE_SIZE ; (*index)++)
    {
        if (pHashEntry->hash_table[*index].key==HASHTABLE_FREE || pHashEntry->hash_table[*index].key==HASHTABLE_DEL)
            continue;

        *ppHashEntry = &pHashEntry->hash_table[*index];
        TRACE("entry found %d\n", *index);
        return TRUE;
    }
    TRACE("no more entries (%d)\n", *index);
    return FALSE;
}

/***********************************************************************
 *           cache_container_delete_dir (Internal)
 *
 *  Erase a directory containing an URL cache.
 *
 * RETURNS
 *    TRUE success, FALSE failure/aborted.
 *
 */
static BOOL cache_container_delete_dir(LPCWSTR lpszPath)
{
    DWORD path_len;
    WCHAR path[MAX_PATH + 1];
    SHFILEOPSTRUCTW shfos;
    int ret;

    path_len = strlenW(lpszPath);
    if (path_len >= MAX_PATH)
        return FALSE;
    strcpyW(path, lpszPath);
    path[path_len + 1] = 0;  /* double-NUL-terminate path */

    shfos.hwnd = NULL;
    shfos.wFunc = FO_DELETE;
    shfos.pFrom = path;
    shfos.pTo = NULL;
    shfos.fFlags = FOF_NOCONFIRMATION;
    shfos.fAnyOperationsAborted = FALSE;
    ret = SHFileOperationW(&shfos);
    if (ret)
        ERR("SHFileOperationW on %s returned %i\n", debugstr_w(path), ret);
    return !(ret || shfos.fAnyOperationsAborted);
}

/***********************************************************************
 *           urlcache_hash_entry_is_locked (Internal)
 *
 *  Checks if entry is locked. Unlocks it if possible.
 */
static BOOL urlcache_hash_entry_is_locked(struct hash_entry *hash_entry, entry_url *url_entry)
{
    FILETIME cur_time;
    ULARGE_INTEGER acc_time, time;

    if ((hash_entry->key & ((1<<HASHTABLE_FLAG_BITS)-1)) != HASHTABLE_LOCK)
        return FALSE;

    GetSystemTimeAsFileTime(&cur_time);
    time.u.LowPart = cur_time.dwLowDateTime;
    time.u.HighPart = cur_time.dwHighDateTime;

    acc_time.u.LowPart = url_entry->access_time.dwLowDateTime;
    acc_time.u.HighPart = url_entry->access_time.dwHighDateTime;

    time.QuadPart -= acc_time.QuadPart;

    /* check if entry was locked for at least a day */
    if(time.QuadPart > (ULONGLONG)24*60*60*FILETIME_SECOND) {
        urlcache_hash_entry_set_flags(hash_entry, HASHTABLE_URL);
        url_entry->use_count = 0;
        return FALSE;
    }

    return TRUE;
}

static BOOL urlcache_get_entry_info(const char *url, void *entry_info,
        DWORD *size, DWORD flags, BOOL unicode)
{
    urlcache_header *header;
    struct hash_entry *hash_entry;
    const entry_url *url_entry;
    cache_container *container;
    DWORD error;

    TRACE("(%s, %p, %p, %x, %x)\n", debugstr_a(url), entry_info, size, flags, unicode);

    if(flags & ~GET_INSTALLED_ENTRY)
        FIXME("ignoring unsupported flags: %x\n", flags);

    error = cache_containers_find(url, &container);
    if(error != ERROR_SUCCESS) {
        SetLastError(error);
        return FALSE;
    }

    error = cache_container_open_index(container, MIN_BLOCK_NO);
    if(error != ERROR_SUCCESS) {
        SetLastError(error);
        return FALSE;
    }

    if(!(header = cache_container_lock_index(container)))
        return FALSE;

    if(!urlcache_find_hash_entry(header, url, &hash_entry)) {
        cache_container_unlock_index(container, header);
        WARN("entry %s not found!\n", debugstr_a(url));
        SetLastError(ERROR_FILE_NOT_FOUND);
        return FALSE;
    }

    url_entry = (const entry_url*)((LPBYTE)header + hash_entry->offset);
    if(url_entry->header.signature != URL_SIGNATURE) {
        cache_container_unlock_index(container, header);
        FIXME("Trying to retrieve entry of unknown format %s\n",
                debugstr_an((LPCSTR)&url_entry->header.signature, sizeof(DWORD)));
        SetLastError(ERROR_FILE_NOT_FOUND);
        return FALSE;
    }

    TRACE("Found URL: %s\n", debugstr_a((LPCSTR)url_entry + url_entry->url_off));
    TRACE("Header info: %s\n", debugstr_an((LPCSTR)url_entry +
                url_entry->header_info_off, url_entry->header_info_size));

    if((flags & GET_INSTALLED_ENTRY) && !(url_entry->cache_entry_type & INSTALLED_CACHE_ENTRY)) {
        cache_container_unlock_index(container, header);
        SetLastError(ERROR_FILE_NOT_FOUND);
        return FALSE;
    }

    if(size) {
        if(!entry_info)
            *size = 0;

        error = urlcache_copy_entry(container, header, entry_info, size, url_entry, unicode);
        if(error != ERROR_SUCCESS) {
            cache_container_unlock_index(container, header);
            SetLastError(error);
            return FALSE;
        }
        if(url_entry->local_name_off)
            TRACE("Local File Name: %s\n", debugstr_a((LPCSTR)url_entry + url_entry->local_name_off));
    }

    cache_container_unlock_index(container, header);
    return TRUE;
}

/***********************************************************************
 *           GetUrlCacheEntryInfoExA (WININET.@)
 *
 */
BOOL WINAPI GetUrlCacheEntryInfoExA(LPCSTR lpszUrl,
        LPINTERNET_CACHE_ENTRY_INFOA lpCacheEntryInfo,
        LPDWORD lpdwCacheEntryInfoBufSize, LPSTR lpszReserved,
        LPDWORD lpdwReserved, LPVOID lpReserved, DWORD dwFlags)
{
    if(lpszReserved!=NULL || lpdwReserved!=NULL || lpReserved!=NULL) {
        ERR("Reserved value was not 0\n");
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    return urlcache_get_entry_info(lpszUrl, lpCacheEntryInfo,
            lpdwCacheEntryInfoBufSize, dwFlags, FALSE);
}

/***********************************************************************
 *           GetUrlCacheEntryInfoA (WININET.@)
 *
 */
BOOL WINAPI GetUrlCacheEntryInfoA(LPCSTR lpszUrlName,
    LPINTERNET_CACHE_ENTRY_INFOA lpCacheEntryInfo,
    LPDWORD lpdwCacheEntryInfoBufferSize)
{
    return GetUrlCacheEntryInfoExA(lpszUrlName, lpCacheEntryInfo,
            lpdwCacheEntryInfoBufferSize, NULL, NULL, NULL, 0);
}

static int urlcache_encode_url(const WCHAR *url, char *encoded_url, int encoded_len)
{
    URL_COMPONENTSW uc;
    DWORD len, part_len;
    WCHAR *punycode;

    TRACE("%s\n", debugstr_w(url));

    memset(&uc, 0, sizeof(uc));
    uc.dwStructSize = sizeof(uc);
    uc.dwHostNameLength = 1;
    if(!InternetCrackUrlW(url, 0, 0, &uc))
        uc.nScheme = INTERNET_SCHEME_UNKNOWN;

    if(uc.nScheme!=INTERNET_SCHEME_HTTP && uc.nScheme!=INTERNET_SCHEME_HTTPS)
        return WideCharToMultiByte(CP_UTF8, 0, url, -1, encoded_url, encoded_len, NULL, NULL);

    len = WideCharToMultiByte(CP_UTF8, 0, url, uc.lpszHostName-url,
            encoded_url, encoded_len, NULL, NULL);
    if(!len)
        return 0;
    if(encoded_url)
        encoded_len -= len;

    part_len = IdnToAscii(0, uc.lpszHostName, uc.dwHostNameLength, NULL, 0);
    if(!part_len) {
        SetLastError(ERROR_INTERNET_INVALID_URL);
        return 0;
    }

    punycode = heap_alloc(part_len*sizeof(WCHAR));
    if(!punycode)
        return 0;

    part_len = IdnToAscii(0, uc.lpszHostName, uc.dwHostNameLength, punycode, part_len);
    if(!part_len) {
        heap_free(punycode);
        return 0;
    }

    part_len = WideCharToMultiByte(CP_UTF8, 0, punycode, part_len,
            encoded_url ? encoded_url+len : NULL, encoded_len, NULL, NULL);
    heap_free(punycode);
    if(!part_len)
        return 0;
    if(encoded_url)
        encoded_len -= part_len;
    len += part_len;

    part_len = WideCharToMultiByte(CP_UTF8, 0, uc.lpszHostName+uc.dwHostNameLength,
            -1, encoded_url ? encoded_url+len : NULL, encoded_len, NULL, NULL);
    if(!part_len)
        return 0;
    len += part_len;

    TRACE("got (%d)%s\n", len, debugstr_a(encoded_url));
    return len;
}

static BOOL urlcache_encode_url_alloc(const WCHAR *url, char **encoded_url)
{
    DWORD encoded_len;
    char *ret;

    encoded_len = urlcache_encode_url(url, NULL, 0);
    if(!encoded_len)
        return FALSE;

    ret = heap_alloc(encoded_len*sizeof(WCHAR));
    if(!ret)
        return FALSE;

    encoded_len = urlcache_encode_url(url, ret, encoded_len);
    if(!encoded_len) {
        heap_free(ret);
        return FALSE;
    }

    *encoded_url = ret;
    return TRUE;
}

/***********************************************************************
 *           GetUrlCacheEntryInfoExW (WININET.@)
 *
 */
BOOL WINAPI GetUrlCacheEntryInfoExW(LPCWSTR lpszUrl,
        LPINTERNET_CACHE_ENTRY_INFOW lpCacheEntryInfo,
        LPDWORD lpdwCacheEntryInfoBufSize, LPWSTR lpszReserved,
        LPDWORD lpdwReserved, LPVOID lpReserved, DWORD dwFlags)
{
    char *url;
    BOOL ret;

    if(lpszReserved!=NULL || lpdwReserved!=NULL || lpReserved!=NULL) {
        ERR("Reserved value was not 0\n");
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    /* Ignore GET_INSTALLED_ENTRY flag in unicode version of function */
    dwFlags &= ~GET_INSTALLED_ENTRY;

    if(!urlcache_encode_url_alloc(lpszUrl, &url))
        return FALSE;

    ret = urlcache_get_entry_info(url, lpCacheEntryInfo,
            lpdwCacheEntryInfoBufSize, dwFlags, TRUE);
    heap_free(url);
    return ret;
}

/***********************************************************************
 *           GetUrlCacheEntryInfoW (WININET.@)
 *
 */
BOOL WINAPI GetUrlCacheEntryInfoW(LPCWSTR lpszUrl,
        LPINTERNET_CACHE_ENTRY_INFOW lpCacheEntryInfo,
        LPDWORD lpdwCacheEntryInfoBufferSize)
{
    return GetUrlCacheEntryInfoExW(lpszUrl, lpCacheEntryInfo,
            lpdwCacheEntryInfoBufferSize, NULL, NULL, NULL, 0);
}

/***********************************************************************
 *           SetUrlCacheEntryInfoA (WININET.@)
 */
BOOL WINAPI SetUrlCacheEntryInfoA(LPCSTR lpszUrlName,
        LPINTERNET_CACHE_ENTRY_INFOA lpCacheEntryInfo,
        DWORD dwFieldControl)
{
    urlcache_header *pHeader;
    struct hash_entry *pHashEntry;
    entry_header *pEntry;
    cache_container *pContainer;
    DWORD error;

    TRACE("(%s, %p, 0x%08x)\n", debugstr_a(lpszUrlName), lpCacheEntryInfo, dwFieldControl);

    error = cache_containers_find(lpszUrlName, &pContainer);
    if (error != ERROR_SUCCESS)
    {
        SetLastError(error);
        return FALSE;
    }

    error = cache_container_open_index(pContainer, MIN_BLOCK_NO);
    if (error != ERROR_SUCCESS)
    {
        SetLastError(error);
        return FALSE;
    }

    if (!(pHeader = cache_container_lock_index(pContainer)))
        return FALSE;

    if (!urlcache_find_hash_entry(pHeader, lpszUrlName, &pHashEntry))
    {
        cache_container_unlock_index(pContainer, pHeader);
        WARN("entry %s not found!\n", debugstr_a(lpszUrlName));
        SetLastError(ERROR_FILE_NOT_FOUND);
        return FALSE;
    }

    pEntry = (entry_header*)((LPBYTE)pHeader + pHashEntry->offset);
    if (pEntry->signature != URL_SIGNATURE)
    {
        cache_container_unlock_index(pContainer, pHeader);
        FIXME("Trying to retrieve entry of unknown format %s\n", debugstr_an((LPSTR)&pEntry->signature, sizeof(DWORD)));
        SetLastError(ERROR_FILE_NOT_FOUND);
        return FALSE;
    }

    urlcache_set_entry_info((entry_url*)pEntry, lpCacheEntryInfo, dwFieldControl);

    cache_container_unlock_index(pContainer, pHeader);

    return TRUE;
}

/***********************************************************************
 *           SetUrlCacheEntryInfoW (WININET.@)
 */
BOOL WINAPI SetUrlCacheEntryInfoW(LPCWSTR lpszUrl,
        LPINTERNET_CACHE_ENTRY_INFOW lpCacheEntryInfo,
        DWORD dwFieldControl)
{
    char *url;
    BOOL ret;

    if(!urlcache_encode_url_alloc(lpszUrl, &url))
        return FALSE;

    ret = SetUrlCacheEntryInfoA(url, (INTERNET_CACHE_ENTRY_INFOA*)lpCacheEntryInfo, dwFieldControl);
    heap_free(url);
    return ret;
}

static BOOL urlcache_entry_get_file(const char *url, void *entry_info, DWORD *size, BOOL unicode)
{
    urlcache_header *header;
    struct hash_entry *hash_entry;
    entry_url *url_entry;
    cache_container *container;
    DWORD error;

    TRACE("(%s, %p, %p, %x)\n", debugstr_a(url), entry_info, size, unicode);

    if(!url || !size || (!entry_info && *size)) {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    error = cache_containers_find(url, &container);
    if(error != ERROR_SUCCESS) {
        SetLastError(error);
        return FALSE;
    }

    error = cache_container_open_index(container, MIN_BLOCK_NO);
    if (error != ERROR_SUCCESS) {
        SetLastError(error);
        return FALSE;
    }

    if (!(header = cache_container_lock_index(container)))
        return FALSE;

    if (!urlcache_find_hash_entry(header, url, &hash_entry)) {
        cache_container_unlock_index(container, header);
        TRACE("entry %s not found!\n", url);
        SetLastError(ERROR_FILE_NOT_FOUND);
        return FALSE;
    }

    url_entry = (entry_url*)((LPBYTE)header + hash_entry->offset);
    if(url_entry->header.signature != URL_SIGNATURE) {
        cache_container_unlock_index(container, header);
        FIXME("Trying to retrieve entry of unknown format %s\n",
                debugstr_an((LPSTR)&url_entry->header.signature, sizeof(DWORD)));
        SetLastError(ERROR_FILE_NOT_FOUND);
        return FALSE;
    }

    if(!url_entry->local_name_off) {
        cache_container_unlock_index(container, header);
        SetLastError(ERROR_INVALID_DATA);
        return FALSE;
    }

    TRACE("Found URL: %s\n", debugstr_a((LPCSTR)url_entry + url_entry->url_off));
    TRACE("Header info: %s\n", debugstr_an((LPCSTR)url_entry + url_entry->header_info_off,
                url_entry->header_info_size));

    error = urlcache_copy_entry(container, header, entry_info,
            size, url_entry, unicode);
    if(error != ERROR_SUCCESS) {
        cache_container_unlock_index(container, header);
        SetLastError(error);
        return FALSE;
    }
    TRACE("Local File Name: %s\n", debugstr_a((LPCSTR)url_entry + url_entry->local_name_off));

    url_entry->hit_rate++;
    url_entry->use_count++;
    urlcache_hash_entry_set_flags(hash_entry, HASHTABLE_LOCK);
    GetSystemTimeAsFileTime(&url_entry->access_time);

    cache_container_unlock_index(container, header);

    return TRUE;
}

/***********************************************************************
 *           RetrieveUrlCacheEntryFileA (WININET.@)
 *
 */
BOOL WINAPI RetrieveUrlCacheEntryFileA(LPCSTR lpszUrlName,
        LPINTERNET_CACHE_ENTRY_INFOA lpCacheEntryInfo,
        LPDWORD lpdwCacheEntryInfoBufferSize, DWORD dwReserved)
{
    return urlcache_entry_get_file(lpszUrlName, lpCacheEntryInfo,
            lpdwCacheEntryInfoBufferSize, FALSE);
}

/***********************************************************************
 *           RetrieveUrlCacheEntryFileW (WININET.@)
 *
 */
BOOL WINAPI RetrieveUrlCacheEntryFileW(LPCWSTR lpszUrlName,
        LPINTERNET_CACHE_ENTRY_INFOW lpCacheEntryInfo,
        LPDWORD lpdwCacheEntryInfoBufferSize, DWORD dwReserved)
{
    char *url;
    BOOL ret;

    if(!urlcache_encode_url_alloc(lpszUrlName, &url))
        return FALSE;

    ret = urlcache_entry_get_file(url, lpCacheEntryInfo,
            lpdwCacheEntryInfoBufferSize, TRUE);
    heap_free(url);
    return ret;
}

static BOOL urlcache_entry_delete(const cache_container *pContainer,
        urlcache_header *pHeader, struct hash_entry *pHashEntry)
{
    entry_header *pEntry;
    entry_url * pUrlEntry;

    pEntry = (entry_header*)((LPBYTE)pHeader + pHashEntry->offset);
    if (pEntry->signature != URL_SIGNATURE)
    {
        FIXME("Trying to delete entry of unknown format %s\n",
              debugstr_an((LPCSTR)&pEntry->signature, sizeof(DWORD)));
        SetLastError(ERROR_FILE_NOT_FOUND);
        return FALSE;
    }

    pUrlEntry = (entry_url *)pEntry;
    if(urlcache_hash_entry_is_locked(pHashEntry, pUrlEntry))
    {
        TRACE("Trying to delete locked entry\n");
        pUrlEntry->cache_entry_type |= PENDING_DELETE_CACHE_ENTRY;
        SetLastError(ERROR_SHARING_VIOLATION);
        return FALSE;
    }

    if(!urlcache_delete_file(pContainer, pHeader, pUrlEntry))
    {
        urlcache_entry_free(pHeader, pEntry);
    }
    else
    {
        /* Add entry to leaked files list */
        pUrlEntry->header.signature = LEAK_SIGNATURE;
        pUrlEntry->exempt_delta = pHeader->options[CACHE_HEADER_DATA_ROOT_LEAK_OFFSET];
        pHeader->options[CACHE_HEADER_DATA_ROOT_LEAK_OFFSET] = pHashEntry->offset;
    }

    urlcache_hash_entry_delete(pHashEntry);
    return TRUE;
}

static HANDLE free_cache_running;
static HANDLE dll_unload_event;
static DWORD WINAPI handle_full_cache_worker(void *param)
{
    FreeUrlCacheSpaceW(NULL, 20, 0);
    ReleaseSemaphore(free_cache_running, 1, NULL);
    return 0;
}

static void handle_full_cache(void)
{
    if(WaitForSingleObject(free_cache_running, 0) == WAIT_OBJECT_0) {
        if(!QueueUserWorkItem(handle_full_cache_worker, NULL, 0))
            ReleaseSemaphore(free_cache_running, 1, NULL);
    }
}

/* Enumerates entries in cache, allows cache unlocking between calls. */
static BOOL urlcache_next_entry(urlcache_header *header, DWORD *hash_table_off, DWORD *hash_table_entry,
        struct hash_entry **hash_entry, entry_header **entry)
{
    entry_hash_table *hashtable_entry;

    *hash_entry = NULL;
    *entry = NULL;

    if(!*hash_table_off) {
        *hash_table_off = header->hash_table_off;
        *hash_table_entry = 0;

        hashtable_entry = urlcache_get_hash_table(header, *hash_table_off);
    }else {
        if(*hash_table_off >= header->size) {
            *hash_table_off = 0;
            return FALSE;
        }

        hashtable_entry = urlcache_get_hash_table(header, *hash_table_off);
    }

    if(hashtable_entry->header.signature != HASH_SIGNATURE) {
        *hash_table_off = 0;
        return FALSE;
    }

    while(1) {
        if(*hash_table_entry >= HASHTABLE_SIZE) {
            *hash_table_off = hashtable_entry->next;
            if(!*hash_table_off) {
                *hash_table_off = 0;
                return FALSE;
            }

            hashtable_entry = urlcache_get_hash_table(header, *hash_table_off);
            *hash_table_entry = 0;
        }

        if(hashtable_entry->hash_table[*hash_table_entry].key != HASHTABLE_DEL &&
            hashtable_entry->hash_table[*hash_table_entry].key != HASHTABLE_FREE) {
            *hash_entry = &hashtable_entry->hash_table[*hash_table_entry];
            *entry = (entry_header*)((LPBYTE)header + hashtable_entry->hash_table[*hash_table_entry].offset);
            (*hash_table_entry)++;
            return TRUE;
        }

        (*hash_table_entry)++;
    }

    *hash_table_off = 0;
    return FALSE;
}

/* Rates an urlcache entry to determine if it can be deleted.
 *
 * Score 0 means that entry can safely be removed, the bigger rating
 * the smaller chance of entry being removed.
 * DWORD_MAX means that entry can't be deleted at all.
 *
 * Rating system is currently not fully compatible with native implementation.
 */
static DWORD urlcache_rate_entry(entry_url *url_entry, FILETIME *cur_time)
{
    ULARGE_INTEGER time, access_time;
    DWORD rating;

    access_time.u.LowPart = url_entry->access_time.dwLowDateTime;
    access_time.u.HighPart = url_entry->access_time.dwHighDateTime;

    time.u.LowPart = cur_time->dwLowDateTime;
    time.u.HighPart = cur_time->dwHighDateTime;

    /* Don't touch entries that were added less than 10 minutes ago */
    if(time.QuadPart < access_time.QuadPart + (ULONGLONG)10*60*FILETIME_SECOND)
        return -1;

    if(url_entry->cache_entry_type & STICKY_CACHE_ENTRY)
        if(time.QuadPart < access_time.QuadPart + (ULONGLONG)url_entry->exempt_delta*FILETIME_SECOND)
            return -1;

    time.QuadPart = (time.QuadPart-access_time.QuadPart)/FILETIME_SECOND;
    rating = 400*60*60*24/(60*60*24+time.QuadPart);

    if(url_entry->hit_rate > 100)
        rating += 100;
    else
        rating += url_entry->hit_rate;

    return rating;
}

static int dword_cmp(const void *p1, const void *p2)
{
    return *(const DWORD*)p1 - *(const DWORD*)p2;
}

/***********************************************************************
 *           FreeUrlCacheSpaceW (WININET.@)
 *
 * Frees up some cache.
 *
 * PARAMETERS
 *   cache_path    [I] Which volume to free up from, or NULL if you don't care.
 *   size          [I] Percentage of the cache that should be free.
 *   filter        [I] Which entries can't be deleted (CacheEntryType)
 *
 * RETURNS
 *   TRUE success. FALSE failure.
 *
 * IMPLEMENTATION
 *   This implementation just retrieves the path of the cache directory, and
 *   deletes its contents from the filesystem. The correct approach would
 *   probably be to implement and use {FindFirst,FindNext,Delete}UrlCacheGroup().
 */
BOOL WINAPI FreeUrlCacheSpaceW(LPCWSTR cache_path, DWORD size, DWORD filter)
{
    cache_container *container;
    DWORD path_len, err;

    TRACE("(%s, %x, %x)\n", debugstr_w(cache_path), size, filter);

    if(size<1 || size>100) {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    if(cache_path) {
        path_len = strlenW(cache_path);
        if(cache_path[path_len-1] == '\\')
            path_len--;
    }else {
        path_len = 0;
    }

    if(size==100 && !filter) {
        LIST_FOR_EACH_ENTRY(container, &UrlContainers, cache_container, entry)
        {
            /* When cache_path==NULL only clean Temporary Internet Files */
            if((!path_len && container->cache_prefix[0]==0) ||
                    (path_len && !strncmpiW(container->path, cache_path, path_len) &&
                     (container->path[path_len]=='\0' || container->path[path_len]=='\\')))
            {
                BOOL ret_del;

                WaitForSingleObject(container->mutex, INFINITE);

                /* unlock, delete, recreate and lock cache */
                cache_container_close_index(container);
                ret_del = cache_container_delete_dir(container->path);
                err = cache_container_open_index(container, MIN_BLOCK_NO);

                ReleaseMutex(container->mutex);
                if(!ret_del || (err != ERROR_SUCCESS))
                    return FALSE;
            }
        }

        return TRUE;
    }

    LIST_FOR_EACH_ENTRY(container, &UrlContainers, cache_container, entry)
    {
        urlcache_header *header;
        struct hash_entry *hash_entry;
        entry_header *entry;
        entry_url *url_entry;
        ULONGLONG desired_size, cur_size;
        DWORD delete_factor, hash_table_off, hash_table_entry;
        DWORD rate[100], rate_no;
        FILETIME cur_time;

        if((path_len || container->cache_prefix[0]!=0) &&
                (!path_len || strncmpiW(container->path, cache_path, path_len) ||
                 (container->path[path_len]!='\0' && container->path[path_len]!='\\')))
            continue;

        err = cache_container_open_index(container, MIN_BLOCK_NO);
        if(err != ERROR_SUCCESS)
            continue;

        header = cache_container_lock_index(container);
        if(!header)
            continue;

        urlcache_clean_leaked_entries(container, header);

        desired_size = header->cache_limit.QuadPart*(100-size)/100;
        cur_size = header->cache_usage.QuadPart+header->exempt_usage.QuadPart;
        if(cur_size <= desired_size)
            delete_factor = 0;
        else
            delete_factor = (cur_size-desired_size)*100/cur_size;

        if(!delete_factor) {
            cache_container_unlock_index(container, header);
            continue;
        }

        hash_table_off = 0;
        hash_table_entry = 0;
        rate_no = 0;
        GetSystemTimeAsFileTime(&cur_time);
        while(rate_no<sizeof(rate)/sizeof(*rate) &&
                urlcache_next_entry(header, &hash_table_off, &hash_table_entry, &hash_entry, &entry)) {
            if(entry->signature != URL_SIGNATURE) {
                WARN("only url entries are currently supported\n");
                continue;
            }

            url_entry = (entry_url*)entry;
            if(url_entry->cache_entry_type & filter)
                continue;

            rate[rate_no] = urlcache_rate_entry(url_entry, &cur_time);
            if(rate[rate_no] != -1)
                rate_no++;
        }

        if(!rate_no) {
            TRACE("nothing to delete\n");
            cache_container_unlock_index(container, header);
            continue;
        }

        qsort(rate, rate_no, sizeof(DWORD), dword_cmp);

        delete_factor = delete_factor*rate_no/100;
        delete_factor = rate[delete_factor];
        TRACE("deleting files with rating %d or less\n", delete_factor);

        hash_table_off = 0;
        while(urlcache_next_entry(header, &hash_table_off, &hash_table_entry, &hash_entry, &entry)) {
            if(entry->signature != URL_SIGNATURE)
                continue;

            url_entry = (entry_url*)entry;
            if(url_entry->cache_entry_type & filter)
                continue;

            if(urlcache_rate_entry(url_entry, &cur_time) <= delete_factor) {
                TRACE("deleting file: %s\n", debugstr_a((char*)url_entry+url_entry->local_name_off));
                urlcache_entry_delete(container, header, hash_entry);

                if(header->cache_usage.QuadPart+header->exempt_usage.QuadPart <= desired_size)
                    break;

                /* Allow other threads to use cache while cleaning */
                cache_container_unlock_index(container, header);
                if(WaitForSingleObject(dll_unload_event, 0) == WAIT_OBJECT_0) {
                    TRACE("got dll_unload_event - finishing\n");
                    return TRUE;
                }
                Sleep(0);
                header = cache_container_lock_index(container);
            }
        }

        TRACE("cache size after cleaning 0x%s/0x%s\n",
                wine_dbgstr_longlong(header->cache_usage.QuadPart+header->exempt_usage.QuadPart),
                wine_dbgstr_longlong(header->cache_limit.QuadPart));
        cache_container_unlock_index(container, header);
    }

    return TRUE;
}

/***********************************************************************
 *           FreeUrlCacheSpaceA (WININET.@)
 *
 * See FreeUrlCacheSpaceW.
 */
BOOL WINAPI FreeUrlCacheSpaceA(LPCSTR lpszCachePath, DWORD dwSize, DWORD dwFilter)
{
    BOOL ret = FALSE;
    LPWSTR path = heap_strdupAtoW(lpszCachePath);
    if (lpszCachePath == NULL || path != NULL)
        ret = FreeUrlCacheSpaceW(path, dwSize, dwFilter);
    heap_free(path);
    return ret;
}

/***********************************************************************
 *           UnlockUrlCacheEntryFileA (WININET.@)
 *
 */
BOOL WINAPI UnlockUrlCacheEntryFileA(LPCSTR lpszUrlName, DWORD dwReserved)
{
    urlcache_header *pHeader;
    struct hash_entry *pHashEntry;
    entry_header *pEntry;
    entry_url * pUrlEntry;
    cache_container *pContainer;
    DWORD error;

    TRACE("(%s, 0x%08x)\n", debugstr_a(lpszUrlName), dwReserved);

    if (dwReserved)
    {
        ERR("dwReserved != 0\n");
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    error = cache_containers_find(lpszUrlName, &pContainer);
    if (error != ERROR_SUCCESS)
    {
       SetLastError(error);
       return FALSE;
    }

    error = cache_container_open_index(pContainer, MIN_BLOCK_NO);
    if (error != ERROR_SUCCESS)
    {
        SetLastError(error);
        return FALSE;
    }

    if (!(pHeader = cache_container_lock_index(pContainer)))
        return FALSE;

    if (!urlcache_find_hash_entry(pHeader, lpszUrlName, &pHashEntry))
    {
        cache_container_unlock_index(pContainer, pHeader);
        TRACE("entry %s not found!\n", lpszUrlName);
        SetLastError(ERROR_FILE_NOT_FOUND);
        return FALSE;
    }

    pEntry = (entry_header*)((LPBYTE)pHeader + pHashEntry->offset);
    if (pEntry->signature != URL_SIGNATURE)
    {
        cache_container_unlock_index(pContainer, pHeader);
        FIXME("Trying to retrieve entry of unknown format %s\n", debugstr_an((LPSTR)&pEntry->signature, sizeof(DWORD)));
        SetLastError(ERROR_FILE_NOT_FOUND);
        return FALSE;
    }

    pUrlEntry = (entry_url *)pEntry;

    if (pUrlEntry->use_count == 0)
    {
        cache_container_unlock_index(pContainer, pHeader);
        return FALSE;
    }
    pUrlEntry->use_count--;
    if (!pUrlEntry->use_count)
    {
        urlcache_hash_entry_set_flags(pHashEntry, HASHTABLE_URL);
        if (pUrlEntry->cache_entry_type & PENDING_DELETE_CACHE_ENTRY)
            urlcache_entry_delete(pContainer, pHeader, pHashEntry);
    }

    cache_container_unlock_index(pContainer, pHeader);

    return TRUE;
}

/***********************************************************************
 *           UnlockUrlCacheEntryFileW (WININET.@)
 *
 */
BOOL WINAPI UnlockUrlCacheEntryFileW(LPCWSTR lpszUrlName, DWORD dwReserved)
{
    char *url;
    BOOL ret;

    if(!urlcache_encode_url_alloc(lpszUrlName, &url))
        return FALSE;

    ret = UnlockUrlCacheEntryFileA(url, dwReserved);
    heap_free(url);
    return ret;
}

static BOOL urlcache_entry_create(const char *url, const char *ext, WCHAR *full_path)
{
    cache_container *container;
    urlcache_header *header;
    char file_name[MAX_PATH];
    WCHAR extW[MAX_PATH];
    BYTE cache_dir;
    LONG full_path_len;
    BOOL generate_name = FALSE;
    DWORD error;
    HANDLE file;
    FILETIME ft;
    URL_COMPONENTSA uc;
    int i;

    TRACE("(%s, %s, %p)\n", debugstr_a(url), debugstr_a(ext), full_path);

    memset(&uc, 0, sizeof(uc));
    uc.dwStructSize = sizeof(uc);
    uc.dwUrlPathLength = 1;
    uc.dwExtraInfoLength = 1;
    if(!InternetCrackUrlA(url, 0, 0, &uc))
        uc.dwUrlPathLength = 0;

    if(!uc.dwUrlPathLength) {
        file_name[0] = 0;
    }else {
        char *p, *e;

        p = e = uc.lpszUrlPath+uc.dwUrlPathLength;
        while(p>uc.lpszUrlPath && *(p-1)!='/' && *(p-1)!='\\' && *(p-1)!='.')
            p--;
        if(p>uc.lpszUrlPath && *(p-1)=='.') {
            e = p-1;
            while(p>uc.lpszUrlPath && *(p-1)!='/' && *(p-1)!='\\')
                p--;
        }

        memcpy(file_name, p, e-p);
        file_name[e-p] = 0;

        for(p=file_name; *p; p++) {
            switch(*p) {
            case '<': case '>':
            case ':': case '"':
            case '|': case '?':
            case '*':
                *p = '_'; break;
            default: break;
            }
        }
    }

    if(!file_name[0])
        generate_name = TRUE;

    error = cache_containers_find(url, &container);
    if(error != ERROR_SUCCESS) {
        SetLastError(error);
        return FALSE;
    }

    error = cache_container_open_index(container, MIN_BLOCK_NO);
    if(error != ERROR_SUCCESS) {
        SetLastError(error);
        return FALSE;
    }

    if(!(header = cache_container_lock_index(container)))
        return FALSE;

    if(header->dirs_no)
        cache_dir = (BYTE)(rand() % header->dirs_no);
    else
        cache_dir = CACHE_CONTAINER_NO_SUBDIR;

    full_path_len = MAX_PATH * sizeof(WCHAR);
    if(!urlcache_create_file_pathW(container, header, file_name, cache_dir, full_path, &full_path_len)) {
        WARN("Failed to get full path for filename %s, needed %u bytes.\n",
                debugstr_a(file_name), full_path_len);
        cache_container_unlock_index(container, header);
        return FALSE;
    }
    full_path_len = full_path_len/sizeof(WCHAR) - 1;

    cache_container_unlock_index(container, header);

    if(ext) {
        WCHAR *p;

        extW[0] = '.';
        MultiByteToWideChar(CP_ACP, 0, ext, -1, extW+1, MAX_PATH-1);

        for(p=extW; *p; p++) {
            switch(*p) {
            case '<': case '>':
            case ':': case '"':
            case '|': case '?':
            case '*':
                *p = '_'; break;
            default: break;
            }
        }
        if(p[-1]==' ' || p[-1]=='.')
            p[-1] = '_';
    }else {
        extW[0] = '\0';
    }

    for(i=0; i<255 && !generate_name; i++) {
        static const WCHAR format[] = {'[','%','u',']','%','s',0};

        wsprintfW(full_path+full_path_len, format, i, extW);

        TRACE("Trying: %s\n", debugstr_w(full_path));
        file = CreateFileW(full_path, GENERIC_READ, 0, NULL, CREATE_NEW, 0, NULL);
        if(file != INVALID_HANDLE_VALUE) {
            CloseHandle(file);
            return TRUE;
        }
    }

    /* Try to generate random name */
    GetSystemTimeAsFileTime(&ft);
    strcpyW(full_path+full_path_len+8, extW);

    for(i=0; i<255; i++) {
        int j;
        ULONGLONG n = ft.dwHighDateTime;
        n <<= 32;
        n += ft.dwLowDateTime;
        n ^= (ULONGLONG)i<<48;

        for(j=0; j<8; j++) {
            int r = (n % 36);
            n /= 37;
            full_path[full_path_len+j] = (r < 10 ? '0' + r : 'A' + r - 10);
        }

        TRACE("Trying: %s\n", debugstr_w(full_path));
        file = CreateFileW(full_path, GENERIC_READ, 0, NULL, CREATE_NEW, 0, NULL);
        if(file != INVALID_HANDLE_VALUE) {
            CloseHandle(file);
            return TRUE;
        }
    }

    WARN("Could not find a unique filename\n");
    return FALSE;
}

/***********************************************************************
 *           CreateUrlCacheEntryA (WININET.@)
 *
 */
BOOL WINAPI CreateUrlCacheEntryA(LPCSTR lpszUrlName, DWORD dwExpectedFileSize,
        LPCSTR lpszFileExtension, LPSTR lpszFileName, DWORD dwReserved)
{
    WCHAR file_name[MAX_PATH];

    if(dwReserved)
        FIXME("dwReserved 0x%08x\n", dwReserved);

    if(!urlcache_entry_create(lpszUrlName, lpszFileExtension, file_name))
        return FALSE;

    if(!WideCharToMultiByte(CP_ACP, 0, file_name, -1, lpszFileName, MAX_PATH, NULL, NULL))
        return FALSE;
    return TRUE;
}
/***********************************************************************
 *           CreateUrlCacheEntryW (WININET.@)
 *
 */
BOOL WINAPI CreateUrlCacheEntryW(LPCWSTR lpszUrlName, DWORD dwExpectedFileSize,
        LPCWSTR lpszFileExtension, LPWSTR lpszFileName, DWORD dwReserved)
{
    char *url, *ext = NULL;
    BOOL ret;

    if(dwReserved)
        FIXME("dwReserved 0x%08x\n", dwReserved);

    if(lpszFileExtension) {
        ext = heap_strdupWtoUTF8(lpszFileExtension);
        if(!ext)
            return FALSE;
    }

    if(!urlcache_encode_url_alloc(lpszUrlName, &url)) {
        heap_free(ext);
        return FALSE;
    }

    ret = urlcache_entry_create(url, ext, lpszFileName);
    heap_free(ext);
    heap_free(url);
    return ret;
}

static BOOL urlcache_entry_commit(const char *url, const WCHAR *file_name,
    FILETIME expire_time, FILETIME modify_time, DWORD entry_type,
    BYTE *header_info, DWORD header_size, const char *file_ext,
    const char *original_url)
{
    cache_container *container;
    urlcache_header *header;
    struct hash_entry *hash_entry;
    entry_header *entry;
    entry_url *url_entry;
    DWORD url_entry_offset;
    DWORD size = DWORD_ALIGN(sizeof(*url_entry));
    DWORD file_name_off = 0;
    DWORD header_info_off = 0;
    DWORD file_ext_off = 0;
    WIN32_FILE_ATTRIBUTE_DATA file_attr;
    LARGE_INTEGER file_size;
    BYTE dir_id;
    char file_name_no_container[MAX_PATH];
    char *local_file_name = 0;
    DWORD hit_rate = 0;
    DWORD exempt_delta = 0;
    DWORD error;

    TRACE("(%s, %s, ..., ..., %x, %p, %d, %s, %s)\n", debugstr_a(url), debugstr_w(file_name),
            entry_type, header_info, header_size, debugstr_a(file_ext), debugstr_a(original_url));

    if(entry_type & STICKY_CACHE_ENTRY && !file_name) {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }
    if(original_url)
        WARN(": original_url ignored\n");

    memset(&file_attr, 0, sizeof(file_attr));
    if(file_name) {
        if(!GetFileAttributesExW(file_name, GetFileExInfoStandard, &file_attr))
            return FALSE;
    }
    file_size.u.LowPart = file_attr.nFileSizeLow;
    file_size.u.HighPart = file_attr.nFileSizeHigh;

    error = cache_containers_find(url, &container);
    if(error != ERROR_SUCCESS) {
        SetLastError(error);
        return FALSE;
    }

    error = cache_container_open_index(container, MIN_BLOCK_NO);
    if(error != ERROR_SUCCESS) {
        SetLastError(error);
        return FALSE;
    }

    if(!(header = cache_container_lock_index(container)))
        return FALSE;

    if(urlcache_find_hash_entry(header, url, &hash_entry)) {
        entry_url *url_entry = (entry_url*)((LPBYTE)header + hash_entry->offset);

        if(urlcache_hash_entry_is_locked(hash_entry, url_entry)) {
            TRACE("Trying to overwrite locked entry\n");
            cache_container_unlock_index(container, header);
            SetLastError(ERROR_SHARING_VIOLATION);
            return FALSE;
        }

        hit_rate = url_entry->hit_rate;
        exempt_delta = url_entry->exempt_delta;
        urlcache_entry_delete(container, header, hash_entry);
    }

    if(header->dirs_no)
        dir_id = 0;
    else
        dir_id = CACHE_CONTAINER_NO_SUBDIR;

    if(file_name) {
        BOOL bFound = FALSE;

        if(strncmpW(file_name, container->path, lstrlenW(container->path))) {
            ERR("path %s must begin with cache content path %s\n", debugstr_w(file_name), debugstr_w(container->path));
            cache_container_unlock_index(container, header);
            SetLastError(ERROR_INVALID_PARAMETER);
            return FALSE;
        }

        /* skip container path prefix */
        file_name += lstrlenW(container->path);

        WideCharToMultiByte(CP_ACP, 0, file_name, -1, file_name_no_container, MAX_PATH, NULL, NULL);
	local_file_name = file_name_no_container;

        if(header->dirs_no) {
            for(dir_id = 0; dir_id < header->dirs_no; dir_id++) {
                if(!strncmp(header->directory_data[dir_id].name, local_file_name, DIR_LENGTH)) {
                    bFound = TRUE;
                    break;
                }
            }

            if(!bFound) {
                ERR("cache directory not found in path %s\n", debugstr_w(file_name));
                cache_container_unlock_index(container, header);
                SetLastError(ERROR_INVALID_PARAMETER);
                return FALSE;
            }

            file_name += DIR_LENGTH + 1;
            local_file_name += DIR_LENGTH + 1;
        }
    }

    size = DWORD_ALIGN(size + strlen(url) + 1);
    if(file_name) {
        file_name_off = size;
        size = DWORD_ALIGN(size + strlen(local_file_name) + 1);
    }
    if(header_info && header_size) {
        header_info_off = size;
        size = DWORD_ALIGN(size + header_size);
    }
    if(file_ext && (file_ext_off = strlen(file_ext))) {
        DWORD len = file_ext_off;

        file_ext_off = size;
        size = DWORD_ALIGN(size + len + 1);
    }

    /* round up to next block */
    if(size % BLOCKSIZE) {
        size -= size % BLOCKSIZE;
        size += BLOCKSIZE;
    }

    error = urlcache_entry_alloc(header, size / BLOCKSIZE, &entry);
    while(error == ERROR_HANDLE_DISK_FULL) {
        error = cache_container_clean_index(container, &header);
        if(error == ERROR_SUCCESS)
            error = urlcache_entry_alloc(header, size / BLOCKSIZE, &entry);
    }
    if(error != ERROR_SUCCESS) {
        cache_container_unlock_index(container, header);
        SetLastError(error);
        return FALSE;
    }

    /* FindFirstFreeEntry fills in blocks used */
    url_entry = (entry_url *)entry;
    url_entry_offset = (LPBYTE)url_entry - (LPBYTE)header;
    url_entry->header.signature = URL_SIGNATURE;
    url_entry->cache_dir = dir_id;
    url_entry->cache_entry_type = entry_type | container->default_entry_type;
    url_entry->header_info_size = header_size;
    if((entry_type & STICKY_CACHE_ENTRY) && !exempt_delta) {
        /* Sticky entries have a default exempt time of one day */
        exempt_delta = 86400;
    }
    url_entry->exempt_delta = exempt_delta;
    url_entry->hit_rate = hit_rate+1;
    url_entry->file_extension_off = file_ext_off;
    url_entry->header_info_off = header_info_off;
    url_entry->local_name_off = file_name_off;
    url_entry->url_off = DWORD_ALIGN(sizeof(*url_entry));
    url_entry->size.QuadPart = file_size.QuadPart;
    url_entry->use_count = 0;
    GetSystemTimeAsFileTime(&url_entry->access_time);
    url_entry->modification_time = modify_time;
    file_time_to_dos_date_time(&url_entry->access_time, &url_entry->sync_date, &url_entry->sync_time);
    file_time_to_dos_date_time(&expire_time, &url_entry->expire_date, &url_entry->expire_time);
    file_time_to_dos_date_time(&file_attr.ftLastWriteTime, &url_entry->write_date, &url_entry->write_time);

    /*** Unknowns ***/
    url_entry->unk1 = 0;
    url_entry->unk2 = 0;
    url_entry->unk3 = 0x60;
    url_entry->unk4 = 0;
    url_entry->unk5 = 0x1010;
    url_entry->unk7 = 0;
    url_entry->unk8 = 0;


    strcpy((LPSTR)url_entry + url_entry->url_off, url);
    if(file_name_off)
        strcpy((LPSTR)((LPBYTE)url_entry + file_name_off), local_file_name);
    if(header_info_off)
        memcpy((LPBYTE)url_entry + header_info_off, header_info, header_size);
    if(file_ext_off)
        strcpy((LPSTR)((LPBYTE)url_entry + file_ext_off), file_ext);

    error = urlcache_hash_entry_create(header, url, url_entry_offset, HASHTABLE_URL);
    while(error == ERROR_HANDLE_DISK_FULL) {
        error = cache_container_clean_index(container, &header);
        if(error == ERROR_SUCCESS) {
            url_entry = (entry_url *)((LPBYTE)header + url_entry_offset);
            error = urlcache_hash_entry_create(header, url,
                    url_entry_offset, HASHTABLE_URL);
        }
    }
    if(error != ERROR_SUCCESS) {
        urlcache_entry_free(header, &url_entry->header);
        cache_container_unlock_index(container, header);
        SetLastError(error);
        return FALSE;
    }

    if(url_entry->cache_dir < header->dirs_no)
        header->directory_data[url_entry->cache_dir].files_no++;
    if(entry_type & STICKY_CACHE_ENTRY)
        header->exempt_usage.QuadPart += file_size.QuadPart;
    else
        header->cache_usage.QuadPart += file_size.QuadPart;
    if(header->cache_usage.QuadPart+header->exempt_usage.QuadPart > header->cache_limit.QuadPart)
            handle_full_cache();

    cache_container_unlock_index(container, header);
    return TRUE;
}

/***********************************************************************
 *           CommitUrlCacheEntryA (WININET.@)
 */
BOOL WINAPI CommitUrlCacheEntryA(LPCSTR lpszUrlName, LPCSTR lpszLocalFileName,
        FILETIME ExpireTime, FILETIME LastModifiedTime, DWORD CacheEntryType,
        LPBYTE lpHeaderInfo, DWORD dwHeaderSize, LPCSTR lpszFileExtension, LPCSTR lpszOriginalUrl)
{
    WCHAR *file_name = NULL;
    BOOL ret;

    if(lpszLocalFileName) {
        file_name = heap_strdupAtoW(lpszLocalFileName);
        if(!file_name)
            return FALSE;
    }

    ret = urlcache_entry_commit(lpszUrlName, file_name, ExpireTime, LastModifiedTime,
            CacheEntryType, lpHeaderInfo, dwHeaderSize, lpszFileExtension, lpszOriginalUrl);
    heap_free(file_name);
    return ret;
}

/***********************************************************************
 *           CommitUrlCacheEntryW (WININET.@)
 */
BOOL WINAPI CommitUrlCacheEntryW(LPCWSTR lpszUrlName, LPCWSTR lpszLocalFileName,
        FILETIME ExpireTime, FILETIME LastModifiedTime, DWORD CacheEntryType,
        LPWSTR lpHeaderInfo, DWORD dwHeaderSize, LPCWSTR lpszFileExtension, LPCWSTR lpszOriginalUrl)
{
    char *url, *original_url=NULL, *file_ext=NULL, *header_info=NULL;
    BOOL ret;

    if(!urlcache_encode_url_alloc(lpszUrlName, &url))
        return FALSE;

    if(lpHeaderInfo) {
        header_info = heap_strdupWtoUTF8(lpHeaderInfo);
        if(!header_info) {
            heap_free(url);
            return FALSE;
        }
        dwHeaderSize = strlen(header_info);
    }

    if(lpszFileExtension) {
        file_ext = heap_strdupWtoA(lpszFileExtension);
        if(!file_ext) {
            heap_free(url);
            heap_free(header_info);
            return FALSE;
        }
    }

    if(lpszOriginalUrl && !urlcache_encode_url_alloc(lpszOriginalUrl, &original_url)) {
        heap_free(url);
        heap_free(header_info);
        heap_free(file_ext);
        return FALSE;
    }

    ret = urlcache_entry_commit(url, lpszLocalFileName, ExpireTime, LastModifiedTime,
            CacheEntryType, (BYTE*)header_info, dwHeaderSize, file_ext, original_url);
    heap_free(url);
    heap_free(header_info);
    heap_free(file_ext);
    heap_free(original_url);
    return ret;
}

/***********************************************************************
 *           ReadUrlCacheEntryStream (WININET.@)
 *
 */
BOOL WINAPI ReadUrlCacheEntryStream(
    IN HANDLE hUrlCacheStream,
    IN  DWORD dwLocation,
    IN OUT LPVOID lpBuffer,
    IN OUT LPDWORD lpdwLen,
    IN DWORD dwReserved
    )
{
    /* Get handle to file from 'stream' */
    stream_handle *pStream = (stream_handle*)hUrlCacheStream;

    if (dwReserved != 0)
    {
        ERR("dwReserved != 0\n");
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    if (IsBadReadPtr(pStream, sizeof(*pStream)) || IsBadStringPtrA(pStream->url, INTERNET_MAX_URL_LENGTH))
    {
        SetLastError(ERROR_INVALID_HANDLE);
        return FALSE;
    }

    if (SetFilePointer(pStream->file, dwLocation, NULL, FILE_CURRENT) == INVALID_SET_FILE_POINTER)
        return FALSE;
    return ReadFile(pStream->file, lpBuffer, *lpdwLen, lpdwLen, NULL);
}

/***********************************************************************
 *           RetrieveUrlCacheEntryStreamA (WININET.@)
 *
 */
HANDLE WINAPI RetrieveUrlCacheEntryStreamA(LPCSTR lpszUrlName,
        LPINTERNET_CACHE_ENTRY_INFOA lpCacheEntryInfo,
        LPDWORD lpdwCacheEntryInfoBufferSize, BOOL fRandomRead, DWORD dwReserved)
{
    /* NOTE: this is not the same as the way that the native
     * version allocates 'stream' handles. I did it this way
     * as it is much easier and no applications should depend
     * on this behaviour. (Native version appears to allocate
     * indices into a table)
     */
    stream_handle *stream;
    HANDLE file;

    TRACE("(%s, %p, %p, %x, 0x%08x)\n", debugstr_a(lpszUrlName), lpCacheEntryInfo,
            lpdwCacheEntryInfoBufferSize, fRandomRead, dwReserved);

    if(!RetrieveUrlCacheEntryFileA(lpszUrlName, lpCacheEntryInfo,
                lpdwCacheEntryInfoBufferSize, dwReserved))
        return NULL;

    file = CreateFileA(lpCacheEntryInfo->lpszLocalFileName, GENERIC_READ, FILE_SHARE_READ,
            NULL, OPEN_EXISTING, fRandomRead ? FILE_FLAG_RANDOM_ACCESS : 0, NULL);
    if(file == INVALID_HANDLE_VALUE) {
        UnlockUrlCacheEntryFileA(lpszUrlName, 0);
        return NULL;
    }

    /* allocate handle storage space */
    stream = heap_alloc(sizeof(stream_handle) + strlen(lpszUrlName) * sizeof(CHAR));
    if(!stream) {
        CloseHandle(file);
        UnlockUrlCacheEntryFileA(lpszUrlName, 0);
        SetLastError(ERROR_OUTOFMEMORY);
        return NULL;
    }

    stream->file = file;
    strcpy(stream->url, lpszUrlName);
    return stream;
}

/***********************************************************************
 *           RetrieveUrlCacheEntryStreamW (WININET.@)
 *
 */
HANDLE WINAPI RetrieveUrlCacheEntryStreamW(LPCWSTR lpszUrlName,
        LPINTERNET_CACHE_ENTRY_INFOW lpCacheEntryInfo,
        LPDWORD lpdwCacheEntryInfoBufferSize, BOOL fRandomRead, DWORD dwReserved)
{
    DWORD len;
    /* NOTE: this is not the same as the way that the native
     * version allocates 'stream' handles. I did it this way
     * as it is much easier and no applications should depend
     * on this behaviour. (Native version appears to allocate
     * indices into a table)
     */
    stream_handle *stream;
    HANDLE file;

    TRACE("(%s, %p, %p, %x, 0x%08x)\n", debugstr_w(lpszUrlName), lpCacheEntryInfo,
            lpdwCacheEntryInfoBufferSize, fRandomRead, dwReserved);

    if(!(len = urlcache_encode_url(lpszUrlName, NULL, 0)))
        return NULL;

    if(!RetrieveUrlCacheEntryFileW(lpszUrlName, lpCacheEntryInfo,
                lpdwCacheEntryInfoBufferSize, dwReserved))
        return NULL;

    file = CreateFileW(lpCacheEntryInfo->lpszLocalFileName, GENERIC_READ, FILE_SHARE_READ,
            NULL, OPEN_EXISTING, fRandomRead ? FILE_FLAG_RANDOM_ACCESS : 0, NULL);
    if(file == INVALID_HANDLE_VALUE) {
        UnlockUrlCacheEntryFileW(lpszUrlName, 0);
        return NULL;
    }

    /* allocate handle storage space */
    stream = heap_alloc(sizeof(stream_handle) + len*sizeof(WCHAR));
    if(!stream) {
        CloseHandle(file);
        UnlockUrlCacheEntryFileW(lpszUrlName, 0);
        SetLastError(ERROR_OUTOFMEMORY);
        return NULL;
    }

    stream->file = file;
    if(!urlcache_encode_url(lpszUrlName, stream->url, len)) {
        CloseHandle(file);
        UnlockUrlCacheEntryFileW(lpszUrlName, 0);
        heap_free(stream);
        return NULL;
    }
    return stream;
}

/***********************************************************************
 *           UnlockUrlCacheEntryStream (WININET.@)
 *
 */
BOOL WINAPI UnlockUrlCacheEntryStream(
    IN HANDLE hUrlCacheStream,
    IN DWORD dwReserved
)
{
    stream_handle *pStream = (stream_handle*)hUrlCacheStream;

    if (dwReserved != 0)
    {
        ERR("dwReserved != 0\n");
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    if (IsBadReadPtr(pStream, sizeof(*pStream)) || IsBadStringPtrA(pStream->url, INTERNET_MAX_URL_LENGTH))
    {
        SetLastError(ERROR_INVALID_HANDLE);
        return FALSE;
    }

    if (!UnlockUrlCacheEntryFileA(pStream->url, 0))
        return FALSE;

    CloseHandle(pStream->file);
    heap_free(pStream);
    return TRUE;
}


/***********************************************************************
 *           DeleteUrlCacheEntryA (WININET.@)
 *
 */
BOOL WINAPI DeleteUrlCacheEntryA(LPCSTR lpszUrlName)
{
    cache_container *pContainer;
    urlcache_header *pHeader;
    struct hash_entry *pHashEntry;
    DWORD error;
    BOOL ret;

    TRACE("(%s)\n", debugstr_a(lpszUrlName));

    error = cache_containers_find(lpszUrlName, &pContainer);
    if (error != ERROR_SUCCESS)
    {
        SetLastError(error);
        return FALSE;
    }

    error = cache_container_open_index(pContainer, MIN_BLOCK_NO);
    if (error != ERROR_SUCCESS)
    {
        SetLastError(error);
        return FALSE;
    }

    if (!(pHeader = cache_container_lock_index(pContainer)))
        return FALSE;

    if (!urlcache_find_hash_entry(pHeader, lpszUrlName, &pHashEntry))
    {
        cache_container_unlock_index(pContainer, pHeader);
        TRACE("entry %s not found!\n", lpszUrlName);
        SetLastError(ERROR_FILE_NOT_FOUND);
        return FALSE;
    }

    ret = urlcache_entry_delete(pContainer, pHeader, pHashEntry);

    cache_container_unlock_index(pContainer, pHeader);

    return ret;
}

/***********************************************************************
 *           DeleteUrlCacheEntryW (WININET.@)
 *
 */
BOOL WINAPI DeleteUrlCacheEntryW(LPCWSTR lpszUrlName)
{
    char *url;
    BOOL ret;

    if(!urlcache_encode_url_alloc(lpszUrlName, &url))
        return FALSE;

    ret = DeleteUrlCacheEntryA(url);
    heap_free(url);
    return ret;
}

BOOL WINAPI DeleteUrlCacheContainerA(DWORD d1, DWORD d2)
{
    FIXME("(0x%08x, 0x%08x) stub\n", d1, d2);
    return TRUE;
}

BOOL WINAPI DeleteUrlCacheContainerW(DWORD d1, DWORD d2)
{
    FIXME("(0x%08x, 0x%08x) stub\n", d1, d2);
    return TRUE;
}

/***********************************************************************
 *           CreateCacheContainerA (WININET.@)
 */
BOOL WINAPI CreateUrlCacheContainerA(DWORD d1, DWORD d2, DWORD d3, DWORD d4,
                                     DWORD d5, DWORD d6, DWORD d7, DWORD d8)
{
    FIXME("(0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x) stub\n",
          d1, d2, d3, d4, d5, d6, d7, d8);
    return TRUE;
}

/***********************************************************************
 *           CreateCacheContainerW (WININET.@)
 */
BOOL WINAPI CreateUrlCacheContainerW(DWORD d1, DWORD d2, DWORD d3, DWORD d4,
                                     DWORD d5, DWORD d6, DWORD d7, DWORD d8)
{
    FIXME("(0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x) stub\n",
          d1, d2, d3, d4, d5, d6, d7, d8);
    return TRUE;
}

/***********************************************************************
 *           FindFirstUrlCacheContainerA (WININET.@)
 */
HANDLE WINAPI FindFirstUrlCacheContainerA( LPVOID p1, LPVOID p2, LPVOID p3, DWORD d1 )
{
    FIXME("(%p, %p, %p, 0x%08x) stub\n", p1, p2, p3, d1 );
    return NULL;
}

/***********************************************************************
 *           FindFirstUrlCacheContainerW (WININET.@)
 */
HANDLE WINAPI FindFirstUrlCacheContainerW( LPVOID p1, LPVOID p2, LPVOID p3, DWORD d1 )
{
    FIXME("(%p, %p, %p, 0x%08x) stub\n", p1, p2, p3, d1 );
    return NULL;
}

/***********************************************************************
 *           FindNextUrlCacheContainerA (WININET.@)
 */
BOOL WINAPI FindNextUrlCacheContainerA( HANDLE handle, LPVOID p1, LPVOID p2 )
{
    FIXME("(%p, %p, %p) stub\n", handle, p1, p2 );
    return FALSE;
}

/***********************************************************************
 *           FindNextUrlCacheContainerW (WININET.@)
 */
BOOL WINAPI FindNextUrlCacheContainerW( HANDLE handle, LPVOID p1, LPVOID p2 )
{
    FIXME("(%p, %p, %p) stub\n", handle, p1, p2 );
    return FALSE;
}

HANDLE WINAPI FindFirstUrlCacheEntryExA(
  LPCSTR lpszUrlSearchPattern,
  DWORD dwFlags,
  DWORD dwFilter,
  GROUPID GroupId,
  LPINTERNET_CACHE_ENTRY_INFOA lpFirstCacheEntryInfo,
  LPDWORD lpdwFirstCacheEntryInfoBufferSize,
  LPVOID lpReserved,
  LPDWORD pcbReserved2,
  LPVOID lpReserved3
)
{
    FIXME("(%s, 0x%08x, 0x%08x, 0x%08x%08x, %p, %p, %p, %p, %p) stub\n", debugstr_a(lpszUrlSearchPattern),
          dwFlags, dwFilter, (ULONG)(GroupId >> 32), (ULONG)GroupId, lpFirstCacheEntryInfo,
          lpdwFirstCacheEntryInfoBufferSize, lpReserved, pcbReserved2,lpReserved3);
    SetLastError(ERROR_FILE_NOT_FOUND);
    return NULL;
}

HANDLE WINAPI FindFirstUrlCacheEntryExW(
  LPCWSTR lpszUrlSearchPattern,
  DWORD dwFlags,
  DWORD dwFilter,
  GROUPID GroupId,
  LPINTERNET_CACHE_ENTRY_INFOW lpFirstCacheEntryInfo,
  LPDWORD lpdwFirstCacheEntryInfoBufferSize,
  LPVOID lpReserved,
  LPDWORD pcbReserved2,
  LPVOID lpReserved3
)
{
    FIXME("(%s, 0x%08x, 0x%08x, 0x%08x%08x, %p, %p, %p, %p, %p) stub\n", debugstr_w(lpszUrlSearchPattern),
          dwFlags, dwFilter, (ULONG)(GroupId >> 32), (ULONG)GroupId, lpFirstCacheEntryInfo,
          lpdwFirstCacheEntryInfoBufferSize, lpReserved, pcbReserved2,lpReserved3);
    SetLastError(ERROR_FILE_NOT_FOUND);
    return NULL;
}

/***********************************************************************
 *           FindFirstUrlCacheEntryA (WININET.@)
 *
 */
INTERNETAPI HANDLE WINAPI FindFirstUrlCacheEntryA(LPCSTR lpszUrlSearchPattern,
 LPINTERNET_CACHE_ENTRY_INFOA lpFirstCacheEntryInfo, LPDWORD lpdwFirstCacheEntryInfoBufferSize)
{
    find_handle *pEntryHandle;

    TRACE("(%s, %p, %p)\n", debugstr_a(lpszUrlSearchPattern), lpFirstCacheEntryInfo, lpdwFirstCacheEntryInfoBufferSize);

    pEntryHandle = heap_alloc(sizeof(*pEntryHandle));
    if (!pEntryHandle)
        return NULL;

    pEntryHandle->magic = URLCACHE_FIND_ENTRY_HANDLE_MAGIC;
    if (lpszUrlSearchPattern)
    {
        pEntryHandle->url_search_pattern = heap_strdupA(lpszUrlSearchPattern);
        if (!pEntryHandle->url_search_pattern)
        {
            heap_free(pEntryHandle);
            return NULL;
        }
    }
    else
        pEntryHandle->url_search_pattern = NULL;
    pEntryHandle->container_idx = 0;
    pEntryHandle->hash_table_idx = 0;
    pEntryHandle->hash_entry_idx = 0;

    if (!FindNextUrlCacheEntryA(pEntryHandle, lpFirstCacheEntryInfo, lpdwFirstCacheEntryInfoBufferSize))
    {
        heap_free(pEntryHandle);
        return NULL;
    }
    return pEntryHandle;
}

/***********************************************************************
 *           FindFirstUrlCacheEntryW (WININET.@)
 *
 */
INTERNETAPI HANDLE WINAPI FindFirstUrlCacheEntryW(LPCWSTR lpszUrlSearchPattern,
 LPINTERNET_CACHE_ENTRY_INFOW lpFirstCacheEntryInfo, LPDWORD lpdwFirstCacheEntryInfoBufferSize)
{
    find_handle *pEntryHandle;

    TRACE("(%s, %p, %p)\n", debugstr_w(lpszUrlSearchPattern), lpFirstCacheEntryInfo, lpdwFirstCacheEntryInfoBufferSize);

    pEntryHandle = heap_alloc(sizeof(*pEntryHandle));
    if (!pEntryHandle)
        return NULL;

    pEntryHandle->magic = URLCACHE_FIND_ENTRY_HANDLE_MAGIC;
    if (lpszUrlSearchPattern)
    {
        pEntryHandle->url_search_pattern = heap_strdupWtoA(lpszUrlSearchPattern);
        if (!pEntryHandle->url_search_pattern)
        {
            heap_free(pEntryHandle);
            return NULL;
        }
    }
    else
        pEntryHandle->url_search_pattern = NULL;
    pEntryHandle->container_idx = 0;
    pEntryHandle->hash_table_idx = 0;
    pEntryHandle->hash_entry_idx = 0;

    if (!FindNextUrlCacheEntryW(pEntryHandle, lpFirstCacheEntryInfo, lpdwFirstCacheEntryInfoBufferSize))
    {
        heap_free(pEntryHandle);
        return NULL;
    }
    return pEntryHandle;
}

static BOOL urlcache_find_next_entry(
  HANDLE hEnumHandle,
  LPINTERNET_CACHE_ENTRY_INFOA lpNextCacheEntryInfo,
  LPDWORD lpdwNextCacheEntryInfoBufferSize,
  BOOL unicode)
{
    find_handle *pEntryHandle = (find_handle*)hEnumHandle;
    cache_container *pContainer;

    if (pEntryHandle->magic != URLCACHE_FIND_ENTRY_HANDLE_MAGIC)
    {
        SetLastError(ERROR_INVALID_HANDLE);
        return FALSE;
    }

    for (; cache_containers_enum(pEntryHandle->url_search_pattern, pEntryHandle->container_idx, &pContainer);
         pEntryHandle->container_idx++, pEntryHandle->hash_table_idx = 0)
    {
        urlcache_header *pHeader;
        entry_hash_table *pHashTableEntry;
        DWORD error;

        error = cache_container_open_index(pContainer, MIN_BLOCK_NO);
        if (error != ERROR_SUCCESS)
        {
            SetLastError(error);
            return FALSE;
        }

        if (!(pHeader = cache_container_lock_index(pContainer)))
            return FALSE;

        for (; urlcache_enum_hash_tables(pHeader, &pEntryHandle->hash_table_idx, &pHashTableEntry);
             pEntryHandle->hash_table_idx++, pEntryHandle->hash_entry_idx = 0)
        {
            const struct hash_entry *pHashEntry = NULL;
            for (; urlcache_enum_hash_table_entries(pHeader, pHashTableEntry, &pEntryHandle->hash_entry_idx, &pHashEntry);
                 pEntryHandle->hash_entry_idx++)
            {
                const entry_url *pUrlEntry;
                const entry_header *pEntry = (const entry_header*)((LPBYTE)pHeader + pHashEntry->offset);

                if (pEntry->signature != URL_SIGNATURE)
                    continue;

                pUrlEntry = (const entry_url *)pEntry;
                TRACE("Found URL: %s\n",
                      debugstr_a((LPCSTR)pUrlEntry + pUrlEntry->url_off));
                TRACE("Header info: %s\n",
                        debugstr_an((LPCSTR)pUrlEntry + pUrlEntry->header_info_off,
                            pUrlEntry->header_info_size));

                error = urlcache_copy_entry(
                    pContainer,
                    pHeader,
                    lpNextCacheEntryInfo,
                    lpdwNextCacheEntryInfoBufferSize,
                    pUrlEntry,
                    unicode);
                if (error != ERROR_SUCCESS)
                {
                    cache_container_unlock_index(pContainer, pHeader);
                    SetLastError(error);
                    return FALSE;
                }
                if(pUrlEntry->local_name_off)
                    TRACE("Local File Name: %s\n", debugstr_a((LPCSTR)pUrlEntry + pUrlEntry->local_name_off));

                /* increment the current index so that next time the function
                 * is called the next entry is returned */
                pEntryHandle->hash_entry_idx++;
                cache_container_unlock_index(pContainer, pHeader);
                return TRUE;
            }
        }

        cache_container_unlock_index(pContainer, pHeader);
    }

    SetLastError(ERROR_NO_MORE_ITEMS);
    return FALSE;
}

/***********************************************************************
 *           FindNextUrlCacheEntryA (WININET.@)
 */
BOOL WINAPI FindNextUrlCacheEntryA(
  HANDLE hEnumHandle,
  LPINTERNET_CACHE_ENTRY_INFOA lpNextCacheEntryInfo,
  LPDWORD lpdwNextCacheEntryInfoBufferSize)
{
    TRACE("(%p, %p, %p)\n", hEnumHandle, lpNextCacheEntryInfo, lpdwNextCacheEntryInfoBufferSize);

    return urlcache_find_next_entry(hEnumHandle, lpNextCacheEntryInfo,
            lpdwNextCacheEntryInfoBufferSize, FALSE /* not UNICODE */);
}

/***********************************************************************
 *           FindNextUrlCacheEntryW (WININET.@)
 */
BOOL WINAPI FindNextUrlCacheEntryW(
  HANDLE hEnumHandle,
  LPINTERNET_CACHE_ENTRY_INFOW lpNextCacheEntryInfo,
  LPDWORD lpdwNextCacheEntryInfoBufferSize
)
{
    TRACE("(%p, %p, %p)\n", hEnumHandle, lpNextCacheEntryInfo, lpdwNextCacheEntryInfoBufferSize);

    return urlcache_find_next_entry(hEnumHandle,
            (LPINTERNET_CACHE_ENTRY_INFOA)lpNextCacheEntryInfo,
            lpdwNextCacheEntryInfoBufferSize, TRUE /* UNICODE */);
}

/***********************************************************************
 *           FindCloseUrlCache (WININET.@)
 */
BOOL WINAPI FindCloseUrlCache(HANDLE hEnumHandle)
{
    find_handle *pEntryHandle = (find_handle*)hEnumHandle;

    TRACE("(%p)\n", hEnumHandle);

    if (!pEntryHandle || pEntryHandle->magic != URLCACHE_FIND_ENTRY_HANDLE_MAGIC)
    {
        SetLastError(ERROR_INVALID_HANDLE);
        return FALSE;
    }

    pEntryHandle->magic = 0;
    heap_free(pEntryHandle->url_search_pattern);
    heap_free(pEntryHandle);
    return TRUE;
}

HANDLE WINAPI FindFirstUrlCacheGroup( DWORD dwFlags, DWORD dwFilter, LPVOID lpSearchCondition,
                                      DWORD dwSearchCondition, GROUPID* lpGroupId, LPVOID lpReserved )
{
    FIXME("(0x%08x, 0x%08x, %p, 0x%08x, %p, %p) stub\n", dwFlags, dwFilter, lpSearchCondition,
          dwSearchCondition, lpGroupId, lpReserved);
    return NULL;
}

BOOL WINAPI FindNextUrlCacheEntryExA(
  HANDLE hEnumHandle,
  LPINTERNET_CACHE_ENTRY_INFOA lpFirstCacheEntryInfo,
  LPDWORD lpdwFirstCacheEntryInfoBufferSize,
  LPVOID lpReserved,
  LPDWORD pcbReserved2,
  LPVOID lpReserved3
)
{
    FIXME("(%p, %p, %p, %p, %p, %p) stub\n", hEnumHandle, lpFirstCacheEntryInfo, lpdwFirstCacheEntryInfoBufferSize,
          lpReserved, pcbReserved2, lpReserved3);
    return FALSE;
}

BOOL WINAPI FindNextUrlCacheEntryExW(
  HANDLE hEnumHandle,
  LPINTERNET_CACHE_ENTRY_INFOW lpFirstCacheEntryInfo,
  LPDWORD lpdwFirstCacheEntryInfoBufferSize,
  LPVOID lpReserved,
  LPDWORD pcbReserved2,
  LPVOID lpReserved3
)
{
    FIXME("(%p, %p, %p, %p, %p, %p) stub\n", hEnumHandle, lpFirstCacheEntryInfo, lpdwFirstCacheEntryInfoBufferSize,
          lpReserved, pcbReserved2, lpReserved3);
    return FALSE;
}

BOOL WINAPI FindNextUrlCacheGroup( HANDLE hFind, GROUPID* lpGroupId, LPVOID lpReserved )
{
    FIXME("(%p, %p, %p) stub\n", hFind, lpGroupId, lpReserved);
    return FALSE;
}

/***********************************************************************
 *           CreateUrlCacheGroup (WININET.@)
 *
 */
INTERNETAPI GROUPID WINAPI CreateUrlCacheGroup(DWORD dwFlags, LPVOID lpReserved)
{
  FIXME("(0x%08x, %p): stub\n", dwFlags, lpReserved);
  return FALSE;
}

/***********************************************************************
 *           DeleteUrlCacheGroup (WININET.@)
 *
 */
BOOL WINAPI DeleteUrlCacheGroup(GROUPID GroupId, DWORD dwFlags, LPVOID lpReserved)
{
    FIXME("(0x%08x%08x, 0x%08x, %p) stub\n",
          (ULONG)(GroupId >> 32), (ULONG)GroupId, dwFlags, lpReserved);
    return FALSE;
}

/***********************************************************************
 *           DeleteWpadCacheForNetworks (WININET.@)
 *    Undocumented, added in IE8
 */
BOOL WINAPI DeleteWpadCacheForNetworks(DWORD unk1)
{
    FIXME("(%d) stub\n", unk1);
    return FALSE;
}

/***********************************************************************
 *           SetUrlCacheEntryGroupA (WININET.@)
 *
 */
BOOL WINAPI SetUrlCacheEntryGroupA(LPCSTR lpszUrlName, DWORD dwFlags,
  GROUPID GroupId, LPBYTE pbGroupAttributes, DWORD cbGroupAttributes,
  LPVOID lpReserved)
{
    FIXME("(%s, 0x%08x, 0x%08x%08x, %p, 0x%08x, %p) stub\n",
          debugstr_a(lpszUrlName), dwFlags, (ULONG)(GroupId >> 32), (ULONG)GroupId,
          pbGroupAttributes, cbGroupAttributes, lpReserved);
    SetLastError(ERROR_FILE_NOT_FOUND);
    return FALSE;
}

/***********************************************************************
 *           SetUrlCacheEntryGroupW (WININET.@)
 *
 */
BOOL WINAPI SetUrlCacheEntryGroupW(LPCWSTR lpszUrlName, DWORD dwFlags,
  GROUPID GroupId, LPBYTE pbGroupAttributes, DWORD cbGroupAttributes,
  LPVOID lpReserved)
{
    FIXME("(%s, 0x%08x, 0x%08x%08x, %p, 0x%08x, %p) stub\n",
          debugstr_w(lpszUrlName), dwFlags, (ULONG)(GroupId >> 32), (ULONG)GroupId,
          pbGroupAttributes, cbGroupAttributes, lpReserved);
    SetLastError(ERROR_FILE_NOT_FOUND);
    return FALSE;
}

/***********************************************************************
 *           GetUrlCacheConfigInfoW (WININET.@)
 */
BOOL WINAPI GetUrlCacheConfigInfoW(LPINTERNET_CACHE_CONFIG_INFOW CacheInfo, LPDWORD size, DWORD bitmask)
{
    FIXME("(%p, %p, %x)\n", CacheInfo, size, bitmask);
    INTERNET_SetLastError(ERROR_INVALID_PARAMETER);
    return FALSE;
}

/***********************************************************************
 *           GetUrlCacheConfigInfoA (WININET.@)
 */
BOOL WINAPI GetUrlCacheConfigInfoA(LPINTERNET_CACHE_CONFIG_INFOA CacheInfo, LPDWORD size, DWORD bitmask)
{
    FIXME("(%p, %p, %x)\n", CacheInfo, size, bitmask);
    INTERNET_SetLastError(ERROR_INVALID_PARAMETER);
    return FALSE;
}

BOOL WINAPI GetUrlCacheGroupAttributeA( GROUPID gid, DWORD dwFlags, DWORD dwAttributes,
                                        LPINTERNET_CACHE_GROUP_INFOA lpGroupInfo,
                                        LPDWORD lpdwGroupInfo, LPVOID lpReserved )
{
    FIXME("(0x%08x%08x, 0x%08x, 0x%08x, %p, %p, %p) stub\n",
          (ULONG)(gid >> 32), (ULONG)gid, dwFlags, dwAttributes, lpGroupInfo,
          lpdwGroupInfo, lpReserved);
    return FALSE;
}

BOOL WINAPI GetUrlCacheGroupAttributeW( GROUPID gid, DWORD dwFlags, DWORD dwAttributes,
                                        LPINTERNET_CACHE_GROUP_INFOW lpGroupInfo,
                                        LPDWORD lpdwGroupInfo, LPVOID lpReserved )
{
    FIXME("(0x%08x%08x, 0x%08x, 0x%08x, %p, %p, %p) stub\n",
          (ULONG)(gid >> 32), (ULONG)gid, dwFlags, dwAttributes, lpGroupInfo,
          lpdwGroupInfo, lpReserved);
    return FALSE;
}

BOOL WINAPI SetUrlCacheGroupAttributeA( GROUPID gid, DWORD dwFlags, DWORD dwAttributes,
                                        LPINTERNET_CACHE_GROUP_INFOA lpGroupInfo, LPVOID lpReserved )
{
    FIXME("(0x%08x%08x, 0x%08x, 0x%08x, %p, %p) stub\n",
          (ULONG)(gid >> 32), (ULONG)gid, dwFlags, dwAttributes, lpGroupInfo, lpReserved);
    return TRUE;
}

BOOL WINAPI SetUrlCacheGroupAttributeW( GROUPID gid, DWORD dwFlags, DWORD dwAttributes,
                                        LPINTERNET_CACHE_GROUP_INFOW lpGroupInfo, LPVOID lpReserved )
{
    FIXME("(0x%08x%08x, 0x%08x, 0x%08x, %p, %p) stub\n",
          (ULONG)(gid >> 32), (ULONG)gid, dwFlags, dwAttributes, lpGroupInfo, lpReserved);
    return TRUE;
}

BOOL WINAPI SetUrlCacheConfigInfoA( LPINTERNET_CACHE_CONFIG_INFOA lpCacheConfigInfo, DWORD dwFieldControl )
{
    FIXME("(%p, 0x%08x) stub\n", lpCacheConfigInfo, dwFieldControl);
    return TRUE;
}

BOOL WINAPI SetUrlCacheConfigInfoW( LPINTERNET_CACHE_CONFIG_INFOW lpCacheConfigInfo, DWORD dwFieldControl )
{
    FIXME("(%p, 0x%08x) stub\n", lpCacheConfigInfo, dwFieldControl);
    return TRUE;
}

/***********************************************************************
 *           DeleteIE3Cache (WININET.@)
 *
 * Deletes the files used by the IE3 URL caching system.
 *
 * PARAMS
 *   hWnd        [I] A dummy window.
 *   hInst       [I] Instance of process calling the function.
 *   lpszCmdLine [I] Options used by function.
 *   nCmdShow    [I] The nCmdShow value to use when showing windows created, if any.
 */
DWORD WINAPI DeleteIE3Cache(HWND hWnd, HINSTANCE hInst, LPSTR lpszCmdLine, int nCmdShow)
{
    FIXME("(%p, %p, %s, %d)\n", hWnd, hInst, debugstr_a(lpszCmdLine), nCmdShow);
    return 0;
}

static BOOL urlcache_entry_is_expired(const entry_url *pUrlEntry,
        FILETIME *pftLastModified)
{
    BOOL ret;
    FILETIME now, expired;

    *pftLastModified = pUrlEntry->modification_time;
    GetSystemTimeAsFileTime(&now);
    dos_date_time_to_file_time(pUrlEntry->expire_date,
            pUrlEntry->expire_time, &expired);
    /* If the expired time is 0, it's interpreted as not expired */
    if (!expired.dwLowDateTime && !expired.dwHighDateTime)
        ret = FALSE;
    else
        ret = CompareFileTime(&expired, &now) < 0;
    return ret;
}

/***********************************************************************
 *           IsUrlCacheEntryExpiredA (WININET.@)
 *
 * PARAMS
 *   url             [I] Url
 *   dwFlags         [I] Unknown
 *   pftLastModified [O] Last modified time
 */
BOOL WINAPI IsUrlCacheEntryExpiredA(LPCSTR url, DWORD dwFlags, FILETIME* pftLastModified)
{
    urlcache_header *pHeader;
    struct hash_entry *pHashEntry;
    const entry_header *pEntry;
    const entry_url * pUrlEntry;
    cache_container *pContainer;
    BOOL expired;

    TRACE("(%s, %08x, %p)\n", debugstr_a(url), dwFlags, pftLastModified);

    if (!url || !pftLastModified)
        return TRUE;
    if (dwFlags)
        FIXME("unknown flags 0x%08x\n", dwFlags);

    /* Any error implies that the URL is expired, i.e. not in the cache */
    if (cache_containers_find(url, &pContainer))
    {
        memset(pftLastModified, 0, sizeof(*pftLastModified));
        return TRUE;
    }

    if (cache_container_open_index(pContainer, MIN_BLOCK_NO))
    {
        memset(pftLastModified, 0, sizeof(*pftLastModified));
        return TRUE;
    }

    if (!(pHeader = cache_container_lock_index(pContainer)))
    {
        memset(pftLastModified, 0, sizeof(*pftLastModified));
        return TRUE;
    }

    if (!urlcache_find_hash_entry(pHeader, url, &pHashEntry))
    {
        cache_container_unlock_index(pContainer, pHeader);
        memset(pftLastModified, 0, sizeof(*pftLastModified));
        TRACE("entry %s not found!\n", url);
        return TRUE;
    }

    pEntry = (const entry_header*)((LPBYTE)pHeader + pHashEntry->offset);
    if (pEntry->signature != URL_SIGNATURE)
    {
        cache_container_unlock_index(pContainer, pHeader);
        memset(pftLastModified, 0, sizeof(*pftLastModified));
        FIXME("Trying to retrieve entry of unknown format %s\n", debugstr_an((LPCSTR)&pEntry->signature, sizeof(DWORD)));
        return TRUE;
    }

    pUrlEntry = (const entry_url *)pEntry;
    expired = urlcache_entry_is_expired(pUrlEntry, pftLastModified);

    cache_container_unlock_index(pContainer, pHeader);

    return expired;
}

/***********************************************************************
 *           IsUrlCacheEntryExpiredW (WININET.@)
 *
 * PARAMS
 *   url             [I] Url
 *   dwFlags         [I] Unknown
 *   pftLastModified [O] Last modified time
 */
BOOL WINAPI IsUrlCacheEntryExpiredW(LPCWSTR url, DWORD dwFlags, FILETIME* pftLastModified)
{
    char *encoded_url;
    BOOL ret;

    if(!urlcache_encode_url_alloc(url, &encoded_url))
        return FALSE;

    ret = IsUrlCacheEntryExpiredA(encoded_url, dwFlags, pftLastModified);
    heap_free(encoded_url);
    return ret;
}

/***********************************************************************
 *           GetDiskInfoA (WININET.@)
 */
BOOL WINAPI GetDiskInfoA(PCSTR path, PDWORD cluster_size, PDWORDLONG free, PDWORDLONG total)
{
    BOOL ret;
    ULARGE_INTEGER bytes_free, bytes_total;

    TRACE("(%s, %p, %p, %p)\n", debugstr_a(path), cluster_size, free, total);

    if (!path)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    if ((ret = GetDiskFreeSpaceExA(path, NULL, &bytes_total, &bytes_free)))
    {
        if (cluster_size) *cluster_size = 1;
        if (free) *free = bytes_free.QuadPart;
        if (total) *total = bytes_total.QuadPart;
    }
    return ret;
}

/***********************************************************************
 *           RegisterUrlCacheNotification (WININET.@)
 */
DWORD WINAPI RegisterUrlCacheNotification(LPVOID a, DWORD b, DWORD c, DWORD d, DWORD e, DWORD f)
{
    FIXME("(%p %x %x %x %x %x)\n", a, b, c, d, e, f);
    return 0;
}

/***********************************************************************
 *           IncrementUrlCacheHeaderData (WININET.@)
 */
BOOL WINAPI IncrementUrlCacheHeaderData(DWORD index, LPDWORD data)
{
    FIXME("(%u, %p)\n", index, data);
    return FALSE;
}

/***********************************************************************
 *           RunOnceUrlCache (WININET.@)
 */

DWORD WINAPI RunOnceUrlCache(HWND hwnd, HINSTANCE hinst, LPSTR cmd, int cmdshow)
{
    FIXME("(%p, %p, %s, %d): stub\n", hwnd, hinst, debugstr_a(cmd), cmdshow);
    return 0;
}

BOOL init_urlcache(void)
{
    dll_unload_event = CreateEventW(NULL, FALSE, FALSE, NULL);
    if(!dll_unload_event)
        return FALSE;

    free_cache_running = CreateSemaphoreW(NULL, 1, 1, NULL);
    if(!free_cache_running) {
        CloseHandle(dll_unload_event);
        return FALSE;
    }

    cache_containers_init();
    return TRUE;
}

void free_urlcache(void)
{
    SetEvent(dll_unload_event);
    WaitForSingleObject(free_cache_running, INFINITE);
    ReleaseSemaphore(free_cache_running, 1, NULL);
    CloseHandle(free_cache_running);
    CloseHandle(dll_unload_event);

    cache_containers_free();
}

/***********************************************************************
 *           LoadUrlCacheContent (WININET.@)
 */
BOOL WINAPI LoadUrlCacheContent(void)
{
    FIXME("stub!\n");
    return FALSE;
}
