Hi, This patch contains a bug fix for the Internet{Set,Query}Option functions. The hInternet parameter can be NULL for certain options, so we shouldn't do a global check. Also, I've added traces to all of the publicly callable functions. This patch also contains a large number of Url Cache improvements. It now has a lot cleaner interface and support for multiple cache 'containers'. This allows support for retrieving info on cookies and history data from the relevant caches. Also supported are a lot of the unicode version of the functions. Rob Changelog: - Url Cache Improvements - In Internet{Set,Query}Option functions, hInternet can be NULL - Add traces to Internet* functions
? wine/dlls/wininet/diff Index: wine/dlls/wininet/internet.c =================================================================== RCS file: /home/wine/wine/dlls/wininet/internet.c,v retrieving revision 1.71 diff -u -r1.71 internet.c --- wine/dlls/wininet/internet.c 27 Nov 2003 00:59:36 -0000 1.71 +++ wine/dlls/wininet/internet.c 6 Dec 2003 02:22:35 -0000 @@ -102,6 +102,9 @@ LPWORKREQUEST lpHeadWorkQueue; LPWORKREQUEST lpWorkQueueTail; +extern void URLCacheContainers_CreateDefaults(); +extern void URLCacheContainers_DeleteAll(); + /*********************************************************************** * DllMain [Internal] Initializes the internal 'WININET.DLL'. * @@ -131,6 +134,8 @@ hWorkEvent = CreateEventA(0, FALSE, FALSE, NULL); InitializeCriticalSection(&csQueue); + URLCacheContainers_CreateDefaults(); + dwNumThreads = 0; dwNumIdleThreads = 0; dwNumJobs = 0; @@ -156,6 +161,8 @@ case DLL_PROCESS_DETACH: + URLCacheContainers_DeleteAll(); + if (g_dwTlsErrIndex != TLS_OUT_OF_INDEXES) { HeapFree(GetProcessHeap(), 0, TlsGetValue(g_dwTlsErrIndex)); @@ -360,6 +367,8 @@ CHAR *szProxy = (CHAR *)HeapAlloc(GetProcessHeap(), 0, lenProxy*sizeof(CHAR)); CHAR *szBypass = (CHAR *)HeapAlloc(GetProcessHeap(), 0, lenBypass*sizeof(CHAR)); + TRACE("(%s, 0x%08lx, %s, %s, 0x%08lx)\n", debugstr_w(lpszAgent), dwAccessType, debugstr_w(lpszProxy), debugstr_w(lpszProxyBypass), dwFlags); + if (!szAgent || !szProxy || !szBypass) { if (szAgent) @@ -430,6 +439,8 @@ */ BOOL WINAPI InternetGetConnectedState(LPDWORD lpdwStatus, DWORD dwReserved) { + TRACE("(%p, 0x%08lx)\n", lpdwStatus, dwReserved); + if (lpdwStatus) { FIXME("always returning LAN connection.\n"); *lpdwStatus = INTERNET_CONNECTION_LAN; @@ -451,6 +462,8 @@ BOOL WINAPI InternetGetConnectedStateExW(LPDWORD lpdwStatus, LPWSTR lpszConnectionName, DWORD dwNameLen, DWORD dwReserved) { + TRACE("(%p, %s, %ld, 0x%08lx)\n", lpdwStatus, debugstr_w(lpszConnectionName), dwNameLen, dwReserved); + /* Must be zero */ if(dwReserved) return FALSE; @@ -1458,12 +1471,6 @@ TRACE("(%p, 0x%08lx, %p, %p)\n", hInternet, dwOption, lpBuffer, lpdwBufferLength); - if (NULL == hInternet) - { - INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE); - return FALSE; - } - lpwhh = (LPWININETHANDLEHEADER) hInternet; switch (dwOption) @@ -1538,6 +1545,9 @@ bSuccess = TRUE; break; } + case INTERNET_OPTION_SECURITY_FLAGS: + FIXME("INTERNET_OPTION_SECURITY_FLAGS: Stub\n"); + break; default: FIXME("Stub! %ld \n",dwOption); @@ -1597,12 +1607,6 @@ TRACE("0x%08lx\n", dwOption); - if (NULL == hInternet) - { - INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE); - return FALSE; - } - lpwhh = (LPWININETHANDLEHEADER) hInternet; switch (dwOption) @@ -1631,6 +1635,15 @@ FIXME("Option INTERNET_OPTION_REQUEST_PRIORITY (%ld): STUB\n",priority); } break; + case INTERNET_OPTION_RESET_URLCACHE_SESSION: + FIXME("Option INTERNET_OPTION_RESET_URLCACHE_SESSION: STUB\n"); + break; + case INTERNET_OPTION_END_BROWSER_SESSION: + FIXME("Option INTERNET_OPTION_END_BROWSER_SESSION: STUB\n"); + break; + case INTERNET_OPTION_CONNECTED_STATE: + FIXME("Option INTERNET_OPTION_CONNECTED_STATE: STUB\n"); + break; default: FIXME("Option %ld STUB\n",dwOption); INTERNET_SetLastError(ERROR_INVALID_PARAMETER); @@ -1932,6 +1945,8 @@ CHAR *szUrl = (CHAR *)HeapAlloc(GetProcessHeap(), 0, lenUrl*sizeof(CHAR)); CHAR *szHeaders = (CHAR *)HeapAlloc(GetProcessHeap(), 0, lenHeaders*sizeof(CHAR)); + TRACE("\n"); + if (!szUrl || !szHeaders) { if (szUrl) @@ -2508,6 +2523,9 @@ DWORD dwFlags) { HRESULT hr=S_OK; + + TRACE("(%s, %s, %p, %p, 0x%08lx)\n", debugstr_a(lpszBaseUrl), debugstr_a(lpszRelativeUrl), lpszBuffer, lpdwBufferLength, dwFlags); + /* Flip this bit to correspond to URL_ESCAPE_UNSAFE */ dwFlags ^= ICU_NO_ENCODE; hr=UrlCombineA(lpszBaseUrl,lpszRelativeUrl,lpszBuffer,lpdwBufferLength,dwFlags); @@ -2532,6 +2550,9 @@ DWORD dwFlags) { HRESULT hr=S_OK; + + TRACE("(%s, %s, %p, %p, 0x%08lx)\n", debugstr_w(lpszBaseUrl), debugstr_w(lpszRelativeUrl), lpszBuffer, lpdwBufferLength, dwFlags); + /* Flip this bit to correspond to URL_ESCAPE_UNSAFE */ dwFlags ^= ICU_NO_ENCODE; hr=UrlCombineW(lpszBaseUrl,lpszRelativeUrl,lpszBuffer,lpdwBufferLength,dwFlags); Index: wine/dlls/wininet/urlcache.c =================================================================== RCS file: /home/wine/wine/dlls/wininet/urlcache.c,v retrieving revision 1.13 diff -u -r1.13 urlcache.c --- wine/dlls/wininet/urlcache.c 5 Sep 2003 23:08:28 -0000 1.13 +++ wine/dlls/wininet/urlcache.c 6 Dec 2003 02:22:38 -0000 @@ -42,6 +42,8 @@ #include "wingdi.h" #include "shlobj.h" +#include "wine/unicode.h" +#include "wine/list.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(wininet); @@ -49,9 +51,9 @@ #define ENTRY_START_OFFSET 0x4000 #define DIR_LENGTH 8 #define BLOCKSIZE 128 -#define CONTENT_DIRECTORY "\\Content.IE5\\" #define HASHTABLE_SIZE 448 #define HASHTABLE_BLOCKSIZE 7 +#define HASHTABLE_FREE 3 #define ALLOCATION_TABLE_OFFSET 0x250 #define ALLOCATION_TABLE_SIZE (0x1000 - ALLOCATION_TABLE_OFFSET) #define HASHTABLE_NUM_ENTRIES (HASHTABLE_SIZE / HASHTABLE_BLOCKSIZE) @@ -62,7 +64,7 @@ #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) + 3) >> 2) << 2) +#define DWORD_ALIGN(x) ( (DWORD)(((DWORD)(x)+sizeof(DWORD)-1)/sizeof(DWORD))*sizeof(DWORD) ) typedef struct _CACHEFILE_ENTRY { @@ -151,17 +153,26 @@ } URLCACHE_HEADER, *LPURLCACHE_HEADER; typedef const URLCACHE_HEADER *LPCURLCACHE_HEADER; - typedef struct _STREAM_HANDLE { HANDLE hFile; CHAR lpszUrl[1]; } STREAM_HANDLE; -/**** File Global Variables ****/ -static HANDLE hCacheIndexMapping = NULL; /* handle to file mapping */ -static LPSTR szCacheContentPath = NULL; /* path to content index */ -static HANDLE hMutex = NULL; +typedef struct _URLCACHECONTAINER +{ + struct list entry; /* part of a list */ + LPWSTR cache_prefix; /* string that has to be prefixed for this container to be used */ + LPWSTR path; /* path to url container directory */ + HANDLE hMapping; /* handle of file mapping */ + DWORD file_size; /* size of file when mapping was opened */ + HANDLE hMutex; /* hande of mutex */ +} URLCACHECONTAINER; + + +/* List of all containers available */ +static struct list UrlContainers = LIST_INIT(UrlContainers); + /*********************************************************************** * URLCache_PathToObjectName (Internal) @@ -174,16 +185,313 @@ * nothing * */ -static void URLCache_PathToObjectName(LPSTR lpszPath, char replace) +static void URLCache_PathToObjectName(LPWSTR lpszPath, WCHAR replace) { - char ch; - for (ch = *lpszPath; (ch = *lpszPath); lpszPath++) + for (; *lpszPath; lpszPath++) { - if (ch == '\\') + if (*lpszPath == '\\') *lpszPath = replace; } } +/*********************************************************************** + * URLCacheContainer_OpenIndex (Internal) + * + * Opens the index file and saves mapping handle in hCacheIndexMapping + * + * RETURNS + * TRUE if succeeded + * FALSE if failed + * + */ +static BOOL URLCacheContainer_OpenIndex(URLCACHECONTAINER * pContainer) +{ + HANDLE hFile; + WCHAR wszFilePath[MAX_PATH]; + DWORD dwFileSize; + + static const WCHAR wszIndex[] = {'i','n','d','e','x','.','d','a','t',0}; + static const WCHAR wszMappingFormat[] = {'%','s','%','s','_','%','l','u',0}; + + if (pContainer->hMapping) + return TRUE; + + strcpyW(wszFilePath, pContainer->path); + strcatW(wszFilePath, wszIndex); + + hFile = CreateFileW(wszFilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + if (hFile == INVALID_HANDLE_VALUE) + { + FIXME("need to create cache index file\n"); + return FALSE; + } + + dwFileSize = GetFileSize(hFile, NULL); + if (dwFileSize == INVALID_FILE_SIZE) + return FALSE; + + if (dwFileSize == 0) + { + FIXME("need to create cache index file\n"); + return FALSE; + } + + wsprintfW(wszFilePath, wszMappingFormat, pContainer->path, wszIndex, dwFileSize); + URLCache_PathToObjectName(wszFilePath, '_'); + pContainer->hMapping = OpenFileMappingW(FILE_MAP_WRITE, FALSE, wszFilePath); + if (!pContainer->hMapping) + pContainer->hMapping = CreateFileMappingW(hFile, NULL, PAGE_READWRITE, 0, 0, wszFilePath); + CloseHandle(hFile); + if (!pContainer->hMapping) + { + ERR("Couldn't create file mapping (error is %ld)\n", GetLastError()); + return FALSE; + } + + return TRUE; +} + +/*********************************************************************** + * URLCacheContainer_CloseIndex (Internal) + * + * Closes the index + * + * RETURNS + * nothing + * + */ +static void URLCacheContainer_CloseIndex(URLCACHECONTAINER * pContainer) +{ + CloseHandle(pContainer->hMapping); + pContainer->hMapping = NULL; +} + +static BOOL URLCacheContainers_AddContainer(LPCWSTR cache_prefix, LPCWSTR path, LPWSTR mutex_name) +{ + URLCACHECONTAINER * pContainer = HeapAlloc(GetProcessHeap(), 0, sizeof(URLCACHECONTAINER)); + int path_len = strlenW(path); + int cache_prefix_len = strlenW(cache_prefix); + + if (!pContainer) + { + return FALSE; + } + + pContainer->hMapping = NULL; + pContainer->file_size = 0; + + pContainer->path = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, (path_len + 1) * sizeof(WCHAR)); + if (!pContainer->path) + { + HeapFree(GetProcessHeap(), 0, pContainer); + return FALSE; + } + + memcpy(pContainer->path, path, (path_len + 1) * sizeof(WCHAR)); + + pContainer->cache_prefix = HeapAlloc(GetProcessHeap(), 0, (cache_prefix_len + 1) * sizeof(WCHAR)); + if (!pContainer->cache_prefix) + { + HeapFree(GetProcessHeap(), 0, pContainer->path); + HeapFree(GetProcessHeap(), 0, pContainer); + return FALSE; + } + + memcpy(pContainer->cache_prefix, cache_prefix, (cache_prefix_len + 1) * sizeof(WCHAR)); + + CharLowerW(mutex_name); + URLCache_PathToObjectName(mutex_name, '!'); + + if ((pContainer->hMutex = CreateMutexW(NULL, FALSE, mutex_name)) == NULL) + { + ERR("couldn't create mutex (error is %ld)\n", GetLastError()); + return FALSE; + } + + list_add_head(&UrlContainers, &pContainer->entry); + + return TRUE; +} + +static void URLCacheContainer_DeleteContainer(URLCACHECONTAINER * pContainer) +{ + list_remove(&pContainer->entry); + + URLCacheContainer_CloseIndex(pContainer); + CloseHandle(pContainer->hMutex); + HeapFree(GetProcessHeap(), 0, pContainer->path); + HeapFree(GetProcessHeap(), 0, pContainer->cache_prefix); + HeapFree(GetProcessHeap(), 0, pContainer); +} + +void URLCacheContainers_CreateDefaults() +{ + static const WCHAR UrlSuffix[] = {'C','o','n','t','e','n','t','.','I','E','5',0}; + static const WCHAR UrlPrefix[] = {0}; + static const WCHAR HistorySuffix[] = {'H','i','s','t','o','r','y','.','I','E','5',0}; + static const WCHAR HistoryPrefix[] = {'V','i','s','i','t','e','d',':',0}; + static const WCHAR CookieSuffix[] = {0}; + static const WCHAR CookiePrefix[] = {'C','o','o','k','i','e',':',0}; + static const struct + { + int nFolder; /* CSIDL_* constant */ + const WCHAR * shpath_suffix; /* suffix on path returned by SHGetSpecialFolderPath */ + const WCHAR * cache_prefix; /* prefix used to reference the container */ + } DefaultContainerData[] = + { + { CSIDL_INTERNET_CACHE, UrlSuffix, UrlPrefix }, + { CSIDL_HISTORY, HistorySuffix, HistoryPrefix }, + { CSIDL_COOKIES, CookieSuffix, CookiePrefix }, + }; + int i; + + for (i = 0; i < sizeof(DefaultContainerData) / sizeof(DefaultContainerData[0]); i++) + { + WCHAR wszCachePath[MAX_PATH]; + WCHAR wszMutexName[MAX_PATH]; + int path_len, suffix_len; + + if (FAILED(SHGetSpecialFolderPathW(NULL, wszCachePath, DefaultContainerData[i].nFolder, TRUE))) + { + ERR("Couldn't get path for default container %d\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] = '\\'; + + 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'; + } + + URLCacheContainers_AddContainer(DefaultContainerData[i].cache_prefix, wszCachePath, wszMutexName); + } +} + +void URLCacheContainers_DeleteAll() +{ + while(!list_empty(&UrlContainers)) + URLCacheContainer_DeleteContainer( + LIST_ENTRY(list_head(&UrlContainers), URLCACHECONTAINER, entry) + ); +} + +static BOOL URLCacheContainers_FindContainerW(LPCWSTR lpwszUrl, URLCACHECONTAINER ** ppContainer) +{ + struct list * cursor; + + TRACE("searching for prefix for URL: %s\n", debugstr_w(lpwszUrl)); + + LIST_FOR_EACH(cursor, &UrlContainers) + { + URLCACHECONTAINER * pContainer = LIST_ENTRY(cursor, URLCACHECONTAINER, entry); + int prefix_len = strlenW(pContainer->cache_prefix); + if (!strncmpW(pContainer->cache_prefix, lpwszUrl, prefix_len)) + { + TRACE("found container with prefx %s for URL %s\n", debugstr_w(pContainer->cache_prefix), debugstr_w(lpwszUrl)); + *ppContainer = pContainer; + return TRUE; + } + } + ERR("no container found\n"); + SetLastError(ERROR_FILE_NOT_FOUND); + return FALSE; +} + +static BOOL URLCacheContainers_FindContainerA(LPCSTR lpszUrl, URLCACHECONTAINER ** ppContainer) +{ + BOOL ret; + LPWSTR lpwszUrl; + int url_len = MultiByteToWideChar(CP_ACP, 0, lpszUrl, -1, NULL, 0); + if (url_len && (lpwszUrl = HeapAlloc(GetProcessHeap(), 0, url_len * sizeof(WCHAR)))) + { + MultiByteToWideChar(CP_ACP, 0, lpszUrl, -1, lpwszUrl, url_len); + ret = URLCacheContainers_FindContainerW(lpwszUrl, ppContainer); + HeapFree(GetProcessHeap(), 0, lpwszUrl); + return ret; + } + return FALSE; +} + +/*********************************************************************** + * URLCacheContainer_LockIndex (Internal) + * + */ +static LPURLCACHE_HEADER URLCacheContainer_LockIndex(URLCACHECONTAINER * pContainer) +{ + BYTE index; + LPVOID pIndexData; + URLCACHE_HEADER * pHeader; + + /* acquire mutex */ + WaitForSingleObject(pContainer->hMutex, INFINITE); + + pIndexData = MapViewOfFile(pContainer->hMapping, FILE_MAP_WRITE, 0, 0, 0); + + if (!pIndexData) + { + ReleaseMutex(pContainer->hMutex); + ERR("Couldn't MapViewOfFile. Error: %ld\n", GetLastError()); + return FALSE; + } + 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->dwFileSize != pContainer->file_size) + { + URLCacheContainer_CloseIndex(pContainer); + if (!URLCacheContainer_OpenIndex(pContainer)) + { + ReleaseMutex(pContainer->hMutex); + return FALSE; + } + pIndexData = MapViewOfFile(pContainer->hMapping, FILE_MAP_WRITE, 0, 0, 0); + + if (!pIndexData) + { + ReleaseMutex(pContainer->hMutex); + ERR("Couldn't MapViewOfFile. Error: %ld\n", GetLastError()); + return FALSE; + } + pHeader = (URLCACHE_HEADER *)pIndexData; + } + + TRACE("Signature: %s, file size: %ld bytes\n", pHeader->szSignature, pHeader->dwFileSize); + + for (index = 0; index < pHeader->DirectoryCount; index++) + { + TRACE("Directory[%d] = \"%.8s\"\n", index, pHeader->directory_data[index].filename); + } + + return pHeader; +} + +/*********************************************************************** + * URLCacheContainer_UnlockIndex (Internal) + * + */ +static BOOL URLCacheContainer_UnlockIndex(URLCACHECONTAINER * pContainer, LPURLCACHE_HEADER pHeader) +{ + /* release mutex */ + ReleaseMutex(pContainer->hMutex); + return UnmapViewOfFile(pHeader); +} + + #ifndef CHAR_BIT #define CHAR_BIT (8 * sizeof(CHAR)) #endif @@ -291,104 +599,6 @@ } /*********************************************************************** - * URLCache_OpenIndex (Internal) - * - * Opens the index file and saves mapping handle in hCacheIndexMapping - * - * RETURNS - * TRUE if succeeded - * FALSE if failed - * - */ -static BOOL URLCache_OpenIndex() -{ - HANDLE hFile; - CHAR szFullPath[MAX_PATH]; - CHAR szFileMappingName[MAX_PATH+10]; - CHAR szMutexName[MAX_PATH+1]; - DWORD dwFileSize; - - if (!szCacheContentPath) - { - szCacheContentPath = (LPSTR)HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(CHAR)); - *szCacheContentPath = '\0'; - } - - if (*szCacheContentPath == '\0') - { - if (FAILED(SHGetSpecialFolderPathA(NULL, szCacheContentPath, CSIDL_INTERNET_CACHE, TRUE))) - return FALSE; - strcat(szCacheContentPath, CONTENT_DIRECTORY); - } - - strcpy(szFullPath, szCacheContentPath); - strcat(szFullPath, "index.dat"); - - if (hCacheIndexMapping) - return TRUE; - - hFile = CreateFileA(szFullPath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); - if (hFile == INVALID_HANDLE_VALUE) - { - FIXME("need to create cache index file\n"); - return FALSE; - } - - dwFileSize = GetFileSize(hFile, NULL); - if (dwFileSize == INVALID_FILE_SIZE) - return FALSE; - - if (dwFileSize == 0) - { - FIXME("need to create cache index file\n"); - return FALSE; - } - - strcpy(szFileMappingName, szFullPath); - sprintf(szFileMappingName + strlen(szFileMappingName), "\\%lu", dwFileSize); - URLCache_PathToObjectName(szFileMappingName, '_'); - hCacheIndexMapping = OpenFileMappingA(FILE_MAP_WRITE, FALSE, szFileMappingName); - if (!hCacheIndexMapping) - hCacheIndexMapping = CreateFileMappingA(hFile, NULL, PAGE_READWRITE, 0, 0, szFileMappingName); - CloseHandle(hFile); - if (!hCacheIndexMapping) - { - ERR("Couldn't create file mapping (error is %ld)\n", GetLastError()); - return FALSE; - } - - strcpy(szMutexName, szFullPath); - CharLowerA(szMutexName); - URLCache_PathToObjectName(szMutexName, '!'); - strcat(szMutexName, "!"); - - if ((hMutex = CreateMutexA(NULL, FALSE, szMutexName)) == NULL) - { - ERR("couldn't create mutex (error is %ld)\n", GetLastError()); - CloseHandle(hCacheIndexMapping); - return FALSE; - } - - return TRUE; -} - -/*********************************************************************** - * URLCache_CloseIndex (Internal) - * - * Closes the index - * - * RETURNS - * nothing - * - */ -#if 0 /* not used at the moment */ -static BOOL URLCache_CloseIndex() -{ - return CloseHandle(hCacheIndexMapping); -} -#endif - -/*********************************************************************** * URLCache_FindFirstFreeEntry (Internal) * * Finds and allocates the first block of free space big enough and @@ -424,6 +634,7 @@ return TRUE; } } + FIXME("Grow file\n"); return FALSE; } @@ -444,43 +655,52 @@ } /*********************************************************************** - * URLCache_LockIndex (Internal) + * URLCache_LocalFileNameToPathW (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 LPURLCACHE_HEADER URLCache_LockIndex() +static BOOL URLCache_LocalFileNameToPathW( + const URLCACHECONTAINER * pContainer, + LPCURLCACHE_HEADER pHeader, + LPCSTR szLocalFileName, + BYTE Directory, + LPWSTR wszPath, + LPLONG lpBufferSize) { - BYTE index; - LPVOID pIndexData = MapViewOfFile(hCacheIndexMapping, FILE_MAP_WRITE, 0, 0, 0); - URLCACHE_HEADER * pHeader = (URLCACHE_HEADER *)pIndexData; - if (!pIndexData) - return FALSE; - - TRACE("Signature: %s, file size: %ld bytes\n", pHeader->szSignature, pHeader->dwFileSize); - - for (index = 0; index < pHeader->DirectoryCount; index++) + LONG nRequired; + int path_len = strlenW(pContainer->path); + int file_name_len = MultiByteToWideChar(CP_ACP, 0, szLocalFileName, -1, NULL, 0); + if (Directory >= pHeader->DirectoryCount) { - TRACE("Directory[%d] = \"%.8s\"\n", index, pHeader->directory_data[index].filename); + *lpBufferSize = 0; + return FALSE; } - - /* acquire mutex */ - WaitForSingleObject(hMutex, INFINITE); - return pHeader; -} + nRequired = (path_len + DIR_LENGTH + file_name_len + 1) * sizeof(WCHAR); + if (nRequired < *lpBufferSize) + { + int dir_len; -/*********************************************************************** - * URLCache_UnlockIndex (Internal) - * - */ -static BOOL URLCache_UnlockIndex(LPURLCACHE_HEADER pHeader) -{ - /* release mutex */ - ReleaseMutex(hMutex); - return UnmapViewOfFile(pHeader); + memcpy(wszPath, pContainer->path, path_len * sizeof(WCHAR)); + dir_len = MultiByteToWideChar(CP_ACP, 0, pHeader->directory_data[Directory].filename, DIR_LENGTH, wszPath + path_len, DIR_LENGTH); + wszPath[dir_len + path_len] = '\\'; + MultiByteToWideChar(CP_ACP, 0, szLocalFileName, -1, wszPath + dir_len + path_len + 1, file_name_len); + *lpBufferSize = nRequired; + return TRUE; + } + *lpBufferSize = nRequired; + return FALSE; } /*********************************************************************** - * URLCache_LocalFileNameToPath (Internal) + * URLCache_LocalFileNameToPathA (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 @@ -491,22 +711,31 @@ * FALSE if the buffer was too small * */ -static BOOL URLCache_LocalFileNameToPath(LPCURLCACHE_HEADER pHeader, LPCSTR szLocalFileName, BYTE Directory, LPSTR szPath, LPLONG lpBufferSize) +static BOOL URLCache_LocalFileNameToPathA( + const URLCACHECONTAINER * pContainer, + LPCURLCACHE_HEADER pHeader, + LPCSTR szLocalFileName, + BYTE Directory, + LPSTR szPath, + LPLONG lpBufferSize) { LONG nRequired; + int path_len = WideCharToMultiByte(CP_ACP, 0, pContainer->path, -1, NULL, 0, NULL, NULL); + int file_name_len = strlen(szLocalFileName); + int dir_len = DIR_LENGTH; if (Directory >= pHeader->DirectoryCount) { *lpBufferSize = 0; return FALSE; } - nRequired = (strlen(szCacheContentPath) + DIR_LENGTH + strlen(szLocalFileName) + 1) * sizeof(CHAR); + nRequired = (path_len + dir_len + file_name_len + 1) * sizeof(WCHAR); if (nRequired < *lpBufferSize) { - strcpy(szPath, szCacheContentPath); - strncat(szPath, pHeader->directory_data[Directory].filename, DIR_LENGTH); - strcat(szPath, "\\"); - strcat(szPath, szLocalFileName); + WideCharToMultiByte(CP_ACP, 0, pContainer->path, -1, szPath, -1, NULL, NULL); + strncpy(szPath, pHeader->directory_data[Directory].filename, DIR_LENGTH); + szPath[dir_len + path_len] = '\\'; + strcpy(szPath + dir_len + path_len + 1, szLocalFileName); *lpBufferSize = nRequired; return TRUE; } @@ -524,12 +753,16 @@ * FALSE if the buffer was too small * */ -static BOOL URLCache_CopyEntry(LPCURLCACHE_HEADER pHeader, LPINTERNET_CACHE_ENTRY_INFOA lpCacheEntryInfo, LPDWORD lpdwBufferSize, URL_CACHEFILE_ENTRY * pUrlEntry) +static BOOL URLCache_CopyEntry( + URLCACHECONTAINER * pContainer, + LPCURLCACHE_HEADER pHeader, + LPINTERNET_CACHE_ENTRY_INFOA lpCacheEntryInfo, + LPDWORD lpdwBufferSize, + URL_CACHEFILE_ENTRY * pUrlEntry, + BOOL bUnicode) { - int lenUrl = strlen(pUrlEntry->szSourceUrlName); + int lenUrl; DWORD dwRequiredSize = sizeof(*lpCacheEntryInfo); - LONG nLocalFilePathSize; - LPSTR lpszLocalFileName; if (*lpdwBufferSize >= dwRequiredSize) { @@ -556,29 +789,43 @@ if ((dwRequiredSize % 4) && (dwRequiredSize < *lpdwBufferSize)) ZeroMemory((LPBYTE)lpCacheEntryInfo + dwRequiredSize, 4 - (dwRequiredSize % 4)); dwRequiredSize = DWORD_ALIGN(dwRequiredSize); + if (bUnicode) + lenUrl = MultiByteToWideChar(CP_ACP, 0, pUrlEntry->szSourceUrlName, -1, NULL, 0); + else + lenUrl = strlen(pUrlEntry->szSourceUrlName); dwRequiredSize += lenUrl + 1; + /* FIXME: is source url optional? */ if (*lpdwBufferSize >= dwRequiredSize) { lpCacheEntryInfo->lpszSourceUrlName = (LPSTR)lpCacheEntryInfo + dwRequiredSize - lenUrl - 1; - strcpy(lpCacheEntryInfo->lpszSourceUrlName, pUrlEntry->szSourceUrlName); + if (bUnicode) + MultiByteToWideChar(CP_ACP, 0, pUrlEntry->szSourceUrlName, -1, (LPWSTR)lpCacheEntryInfo->lpszSourceUrlName, lenUrl + 1); + else + memcpy(lpCacheEntryInfo->lpszSourceUrlName, pUrlEntry->szSourceUrlName, (lenUrl + 1) * sizeof(CHAR)); } if ((dwRequiredSize % 4) && (dwRequiredSize < *lpdwBufferSize)) ZeroMemory((LPBYTE)lpCacheEntryInfo + dwRequiredSize, 4 - (dwRequiredSize % 4)); dwRequiredSize = DWORD_ALIGN(dwRequiredSize); - lpszLocalFileName = (LPSTR)lpCacheEntryInfo + dwRequiredSize; - nLocalFilePathSize = *lpdwBufferSize - dwRequiredSize; - if (URLCache_LocalFileNameToPath(pHeader, (LPSTR)pUrlEntry + pUrlEntry->dwOffsetLocalName, pUrlEntry->CacheDir, lpszLocalFileName, &nLocalFilePathSize)) + if (pUrlEntry->dwOffsetLocalName) { - lpCacheEntryInfo->lpszLocalFileName = lpszLocalFileName; - } - dwRequiredSize += nLocalFilePathSize; + LONG nLocalFilePathSize; + LPSTR lpszLocalFileName; + lpszLocalFileName = (LPSTR)lpCacheEntryInfo + dwRequiredSize; + nLocalFilePathSize = *lpdwBufferSize - dwRequiredSize; + if ((bUnicode && URLCache_LocalFileNameToPathW(pContainer, pHeader, (LPCSTR)pUrlEntry + pUrlEntry->dwOffsetLocalName, pUrlEntry->CacheDir, (LPWSTR)lpszLocalFileName, &nLocalFilePathSize)) || + URLCache_LocalFileNameToPathA(pContainer, pHeader, (LPCSTR)pUrlEntry + pUrlEntry->dwOffsetLocalName, pUrlEntry->CacheDir, lpszLocalFileName, &nLocalFilePathSize)) + { + lpCacheEntryInfo->lpszLocalFileName = lpszLocalFileName; + } + dwRequiredSize += nLocalFilePathSize; - if ((dwRequiredSize % 4) && (dwRequiredSize < *lpdwBufferSize)) - ZeroMemory((LPBYTE)lpCacheEntryInfo + dwRequiredSize, 4 - (dwRequiredSize % 4)); - dwRequiredSize = DWORD_ALIGN(dwRequiredSize); + if ((dwRequiredSize % 4) && (dwRequiredSize < *lpdwBufferSize)) + ZeroMemory((LPBYTE)lpCacheEntryInfo + dwRequiredSize, 4 - (dwRequiredSize % 4)); + dwRequiredSize = DWORD_ALIGN(dwRequiredSize); + } dwRequiredSize += pUrlEntry->dwHeaderInfoSize + 1; if (*lpdwBufferSize >= dwRequiredSize) @@ -601,6 +848,40 @@ return TRUE; } + +/*********************************************************************** + * URLCache_SetEntryInfo (Internal) + * + * Helper for SetUrlCacheEntryInfo{A,W}. Sets fields in URL entry + * according the the flags set by dwFieldControl. + * + * RETURNS + * TRUE if the buffer was big enough + * FALSE if the buffer was too small + * + */ +static BOOL URLCache_SetEntryInfo(URL_CACHEFILE_ENTRY * pUrlEntry, const INTERNET_CACHE_ENTRY_INFOW * lpCacheEntryInfo, DWORD dwFieldControl) +{ + if (dwFieldControl & CACHE_ENTRY_ACCTIME_FC) + pUrlEntry->LastAccessTime = lpCacheEntryInfo->LastAccessTime; + if (dwFieldControl & CACHE_ENTRY_ATTRIBUTE_FC) + pUrlEntry->CacheEntryType = lpCacheEntryInfo->CacheEntryType; + if (dwFieldControl & CACHE_ENTRY_EXEMPT_DELTA_FC) + pUrlEntry->dwExemptDelta = lpCacheEntryInfo->u.dwExemptDelta; + if (dwFieldControl & CACHE_ENTRY_EXPTIME_FC) + FIXME("CACHE_ENTRY_EXPTIME_FC unimplemented\n"); + if (dwFieldControl & CACHE_ENTRY_HEADERINFO_FC) + FIXME("CACHE_ENTRY_HEADERINFO_FC unimplemented\n"); + if (dwFieldControl & CACHE_ENTRY_HITRATE_FC) + pUrlEntry->dwHitRate = lpCacheEntryInfo->dwHitRate; + if (dwFieldControl & CACHE_ENTRY_MODTIME_FC) + pUrlEntry->LastModifiedTime = lpCacheEntryInfo->LastModifiedTime; + if (dwFieldControl & CACHE_ENTRY_SYNCTIME_FC) + FileTimeToDosDateTime(&lpCacheEntryInfo->LastAccessTime, &pUrlEntry->wLastSyncDate, &pUrlEntry->wLastSyncTime); + + return TRUE; +} + /*********************************************************************** * URLCache_HashKey (Internal) * @@ -676,18 +957,7 @@ return (HASH_CACHEFILE_ENTRY *)((LPBYTE)pHeader + dwOffset); } -/*********************************************************************** - * URLCache_FindEntryInHash (Internal) - * - * Searches all the hash tables in the index for the given URL and - * returns the entry, if it was found, in ppEntry - * - * RETURNS - * TRUE if the entry was found - * FALSE if the entry could not be found - * - */ -static BOOL URLCache_FindEntryInHash(LPCURLCACHE_HEADER pHeader, LPCSTR lpszUrl, CACHEFILE_ENTRY ** ppEntry) +static BOOL URLCache_FindHash(LPCURLCACHE_HEADER pHeader, LPCSTR lpszUrl, struct _HASH_ENTRY ** ppHashEntry) { /* structure of hash table: * 448 entries divided into 64 blocks @@ -730,7 +1000,13 @@ struct _HASH_ENTRY * pHashElement = &pHashEntry->HashTable[offset + i]; if (key == (DWORD)(pHashElement->dwHashKey / HASHTABLE_NUM_ENTRIES) * HASHTABLE_NUM_ENTRIES) { - *ppEntry = (CACHEFILE_ENTRY *)((LPBYTE)pHeader + pHashElement->dwOffsetEntry); + /* 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; } } @@ -739,6 +1015,28 @@ } /*********************************************************************** + * URLCache_FindEntryInHash (Internal) + * + * Searches all the hash tables in the index for the given URL and + * returns the entry, if it was found, in ppEntry + * + * RETURNS + * TRUE if the entry was found + * FALSE if the entry could not be found + * + */ +static BOOL URLCache_FindEntryInHash(LPCURLCACHE_HEADER pHeader, LPCSTR lpszUrl, CACHEFILE_ENTRY ** ppEntry) +{ + struct _HASH_ENTRY * pHashEntry; + if (URLCache_FindHash(pHeader, lpszUrl, &pHashEntry)) + { + *ppEntry = (CACHEFILE_ENTRY *)((LPBYTE)pHeader + pHashEntry->dwOffsetEntry); + return TRUE; + } + return FALSE; +} + +/*********************************************************************** * URLCache_HashEntrySetUse (Internal) * * Searches all the hash tables in the index for the given URL and @@ -751,47 +1049,34 @@ */ static BOOL URLCache_HashEntrySetUse(LPCURLCACHE_HEADER pHeader, LPCSTR lpszUrl, DWORD dwUseCount) { - /* see URLCache_FindEntryInHash for structure of hash tables */ - - DWORD key = URLCache_HashKey(lpszUrl); - DWORD offset = (key % HASHTABLE_NUM_ENTRIES) * sizeof(struct _HASH_ENTRY); - HASH_CACHEFILE_ENTRY * pHashEntry; - DWORD dwHashTableNumber = 0; - - if (dwUseCount >= HASHTABLE_NUM_ENTRIES) + struct _HASH_ENTRY * pHashEntry; + if (URLCache_FindHash(pHeader, lpszUrl, &pHashEntry)) { - ERR("don't know what to do when use count exceeds %d, guessing\n", HASHTABLE_NUM_ENTRIES); - dwUseCount = HASHTABLE_NUM_ENTRIES - 1; + pHashEntry->dwHashKey = dwUseCount | (DWORD)(pHashEntry->dwHashKey / HASHTABLE_NUM_ENTRIES) * HASHTABLE_NUM_ENTRIES; + return TRUE; } + return FALSE; +} - key = (DWORD)(key / HASHTABLE_NUM_ENTRIES) * HASHTABLE_BLOCKSIZE; - - for (pHashEntry = URLCache_HashEntryFromOffset(pHeader, pHeader->dwOffsetFirstHashTable); - ((DWORD)((LPBYTE)pHashEntry - (LPBYTE)pHeader) >= ENTRY_START_OFFSET) && ((DWORD)((LPBYTE)pHashEntry - (LPBYTE)pHeader) < pHeader->dwFileSize); - pHashEntry = URLCache_HashEntryFromOffset(pHeader, pHashEntry->dwAddressNext)) +/*********************************************************************** + * URLCache_DeleteEntryFromHash (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_DeleteEntryFromHash(LPCURLCACHE_HEADER pHeader, LPCSTR lpszUrl) +{ + struct _HASH_ENTRY * pHashEntry; + if (URLCache_FindHash(pHeader, lpszUrl, &pHashEntry)) { - int i; - if (pHashEntry->dwHashTableNumber != dwHashTableNumber++) - { - ERR("not right hash table number (%ld) expected %ld\n", pHashEntry->dwHashTableNumber, dwHashTableNumber); - continue; - } - /* make sure that it is in fact a hash entry */ - if (pHashEntry->CacheFileEntry.dwSignature != HASH_SIGNATURE) - { - ERR("not right signature (\"%.4s\") - expected \"HASH\"\n", (LPCSTR)&pHashEntry->CacheFileEntry.dwSignature); - continue; - } - - for (i = 0; i < 7; i++) - { - struct _HASH_ENTRY * pHashElement = &pHashEntry->HashTable[offset + i]; - if (key == (DWORD)(pHashElement->dwHashKey / HASHTABLE_NUM_ENTRIES) * HASHTABLE_NUM_ENTRIES) - { - pHashElement->dwOffsetEntry = dwUseCount | (DWORD)(pHashElement->dwHashKey / HASHTABLE_NUM_ENTRIES) * HASHTABLE_NUM_ENTRIES; - return TRUE; - } - } + pHashEntry->dwHashKey = HASHTABLE_FREE; + pHashEntry->dwOffsetEntry = HASHTABLE_FREE; + return TRUE; } return FALSE; } @@ -836,36 +1121,220 @@ break; } - for (i = 0; i < 7; i++) - { - struct _HASH_ENTRY * pHashElement = &pHashEntry->HashTable[offset + i]; - if (pHashElement->dwHashKey == 3 /* FIXME: just 3? */) /* if the slot is free */ - { - pHashElement->dwHashKey = key; - pHashElement->dwOffsetEntry = dwOffsetEntry; - return TRUE; - } - } + for (i = 0; i < HASHTABLE_BLOCKSIZE; i++) + { + struct _HASH_ENTRY * pHashElement = &pHashEntry->HashTable[offset + i]; + if (pHashElement->dwHashKey == HASHTABLE_FREE) /* if the slot is free */ + { + pHashElement->dwHashKey = key; + pHashElement->dwOffsetEntry = dwOffsetEntry; + return TRUE; + } + } + } + FIXME("need to create another hash table\n"); + return FALSE; +} + +/*********************************************************************** + * GetUrlCacheEntryInfoExA (WININET.@) + * + */ +BOOL WINAPI GetUrlCacheEntryInfoExA( + LPCSTR lpszUrl, + LPINTERNET_CACHE_ENTRY_INFOA lpCacheEntryInfo, + LPDWORD lpdwCacheEntryInfoBufSize, + LPSTR lpszReserved, + LPDWORD lpdwReserved, + LPVOID lpReserved, + DWORD dwFlags) +{ + TRACE("(%s, %p, %p, %p, %p, %p, %lx)\n", + debugstr_a(lpszUrl), + lpCacheEntryInfo, + lpdwCacheEntryInfoBufSize, + lpszReserved, + lpdwReserved, + lpReserved, + dwFlags); + + if ((lpszReserved != NULL) || + (lpdwReserved != NULL) || + (lpReserved != NULL)) + { + ERR("Reserved value was not 0\n"); + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + if (dwFlags != 0) + FIXME("Undocumented flag(s): %lx\n", dwFlags); + return GetUrlCacheEntryInfoA(lpszUrl, lpCacheEntryInfo, lpdwCacheEntryInfoBufSize); +} + +/*********************************************************************** + * GetUrlCacheEntryInfoA (WININET.@) + * + */ +BOOL WINAPI GetUrlCacheEntryInfoA( + IN LPCSTR lpszUrlName, + IN LPINTERNET_CACHE_ENTRY_INFOA lpCacheEntryInfo, + IN OUT LPDWORD lpdwCacheEntryInfoBufferSize +) +{ + LPURLCACHE_HEADER pHeader; + CACHEFILE_ENTRY * pEntry; + URL_CACHEFILE_ENTRY * pUrlEntry; + URLCACHECONTAINER * pContainer; + + TRACE("(%s, %p, %p)\n", debugstr_a(lpszUrlName), lpCacheEntryInfo, lpdwCacheEntryInfoBufferSize); + + if (!URLCacheContainers_FindContainerA(lpszUrlName, &pContainer)) + return FALSE; + + if (!URLCacheContainer_OpenIndex(pContainer)) + return FALSE; + + if (!(pHeader = URLCacheContainer_LockIndex(pContainer))) + return FALSE; + + if (!URLCache_FindEntryInHash(pHeader, lpszUrlName, &pEntry)) + { + URLCacheContainer_UnlockIndex(pContainer, pHeader); + WARN("entry %s not found!\n", debugstr_a(lpszUrlName)); + SetLastError(ERROR_FILE_NOT_FOUND); + return FALSE; + } + + if (pEntry->dwSignature != URL_SIGNATURE) + { + URLCacheContainer_UnlockIndex(pContainer, pHeader); + FIXME("Trying to retrieve entry of unknown format %s\n", debugstr_an((LPSTR)&pEntry->dwSignature, sizeof(DWORD))); + SetLastError(ERROR_FILE_NOT_FOUND); + return FALSE; + } + + pUrlEntry = (URL_CACHEFILE_ENTRY *)pEntry; + TRACE("Found URL: %s\n", debugstr_a(pUrlEntry->szSourceUrlName)); + if (pUrlEntry->dwOffsetHeaderInfo) + TRACE("Header info: %s\n", debugstr_a((LPBYTE)pUrlEntry + pUrlEntry->dwOffsetHeaderInfo)); + + if (!URLCache_CopyEntry( + pContainer, + pHeader, + lpCacheEntryInfo, + lpdwCacheEntryInfoBufferSize, + pUrlEntry, + FALSE /* ANSI */)) + { + URLCacheContainer_UnlockIndex(pContainer, pHeader); + return FALSE; + } + TRACE("Local File Name: %s\n", debugstr_a(lpCacheEntryInfo->lpszLocalFileName)); + + URLCacheContainer_UnlockIndex(pContainer, pHeader); + + return TRUE; +} + +/*********************************************************************** + * GetUrlCacheEntryInfoW (WININET.@) + * + */ +BOOL WINAPI GetUrlCacheEntryInfoW(LPCWSTR lpszUrl, + LPINTERNET_CACHE_ENTRY_INFOW lpCacheEntryInfo, + LPDWORD lpdwCacheEntryInfoBufferSize) +{ + LPURLCACHE_HEADER pHeader; + CACHEFILE_ENTRY * pEntry; + URL_CACHEFILE_ENTRY * pUrlEntry; + URLCACHECONTAINER * pContainer; + LPSTR lpszUrlA; + int url_len; + + TRACE("(%s, %p, %p)\n", debugstr_w(lpszUrl), lpCacheEntryInfo, lpdwCacheEntryInfoBufferSize); + + url_len = WideCharToMultiByte(CP_ACP, 0, lpszUrl, -1, NULL, 0, NULL, NULL); + lpszUrlA = HeapAlloc(GetProcessHeap(), 0, url_len * sizeof(CHAR)); + if (!lpszUrlA) + { + SetLastError(ERROR_OUTOFMEMORY); + return FALSE; + } + WideCharToMultiByte(CP_ACP, 0, lpszUrl, -1, lpszUrlA, url_len, NULL, NULL); + + if (!URLCacheContainers_FindContainerW(lpszUrl, &pContainer)) + { + HeapFree(GetProcessHeap(), 0, lpszUrlA); + return FALSE; + } + + if (!URLCacheContainer_OpenIndex(pContainer)) + { + HeapFree(GetProcessHeap(), 0, lpszUrlA); + return FALSE; + } + + if (!(pHeader = URLCacheContainer_LockIndex(pContainer))) + { + HeapFree(GetProcessHeap(), 0, lpszUrlA); + return FALSE; + } + + if (!URLCache_FindEntryInHash(pHeader, lpszUrlA, &pEntry)) + { + URLCacheContainer_UnlockIndex(pContainer, pHeader); + HeapFree(GetProcessHeap(), 0, lpszUrlA); + WARN("entry %s not found!\n", debugstr_a(lpszUrlA)); + SetLastError(ERROR_FILE_NOT_FOUND); + return FALSE; + } + HeapFree(GetProcessHeap(), 0, lpszUrlA); + + if (pEntry->dwSignature != URL_SIGNATURE) + { + URLCacheContainer_UnlockIndex(pContainer, pHeader); + FIXME("Trying to retrieve entry of unknown format %s\n", debugstr_an((LPSTR)&pEntry->dwSignature, sizeof(DWORD))); + SetLastError(ERROR_FILE_NOT_FOUND); + return FALSE; + } + + pUrlEntry = (URL_CACHEFILE_ENTRY *)pEntry; + TRACE("Found URL: %s\n", debugstr_a(pUrlEntry->szSourceUrlName)); + TRACE("Header info: %s\n", debugstr_a((LPBYTE)pUrlEntry + pUrlEntry->dwOffsetHeaderInfo)); + + if (!URLCache_CopyEntry( + pContainer, + pHeader, + (LPINTERNET_CACHE_ENTRY_INFOA)lpCacheEntryInfo, + lpdwCacheEntryInfoBufferSize, + pUrlEntry, + TRUE /* UNICODE */)) + { + URLCacheContainer_UnlockIndex(pContainer, pHeader); + return FALSE; } - FIXME("need to create another hash table\n"); - return FALSE; + TRACE("Local File Name: %s\n", debugstr_w(lpCacheEntryInfo->lpszLocalFileName)); + + URLCacheContainer_UnlockIndex(pContainer, pHeader); + + return TRUE; } /*********************************************************************** - * GetUrlCacheEntryInfoExA (WININET.@) + * GetUrlCacheEntryInfoExW (WININET.@) * */ -BOOL WINAPI GetUrlCacheEntryInfoExA( - LPCSTR lpszUrl, - LPINTERNET_CACHE_ENTRY_INFOA lpCacheEntryInfo, +BOOL WINAPI GetUrlCacheEntryInfoExW( + LPCWSTR lpszUrl, + LPINTERNET_CACHE_ENTRY_INFOW lpCacheEntryInfo, LPDWORD lpdwCacheEntryInfoBufSize, - LPSTR lpszReserved, + LPWSTR lpszReserved, LPDWORD lpdwReserved, LPVOID lpReserved, DWORD dwFlags) { TRACE("(%s, %p, %p, %p, %p, %p, %lx)\n", - debugstr_a(lpszUrl), + debugstr_w(lpszUrl), lpCacheEntryInfo, lpdwCacheEntryInfoBufSize, lpszReserved, @@ -883,54 +1352,122 @@ } if (dwFlags != 0) FIXME("Undocumented flag(s): %lx\n", dwFlags); - return GetUrlCacheEntryInfoA(lpszUrl, lpCacheEntryInfo, lpdwCacheEntryInfoBufSize); + return GetUrlCacheEntryInfoW(lpszUrl, lpCacheEntryInfo, lpdwCacheEntryInfoBufSize); } /*********************************************************************** - * GetUrlCacheEntryInfoA (WININET.@) - * + * SetUrlCacheEntryInfoA (WININET.@) */ -BOOL WINAPI GetUrlCacheEntryInfoA( - IN LPCSTR lpszUrlName, - IN LPINTERNET_CACHE_ENTRY_INFOA lpCacheEntryInfo, - IN OUT LPDWORD lpdwCacheEntryInfoBufferSize -) +BOOL WINAPI SetUrlCacheEntryInfoA( + LPCSTR lpszUrlName, + LPINTERNET_CACHE_ENTRY_INFOA lpCacheEntryInfo, + DWORD dwFieldControl) { LPURLCACHE_HEADER pHeader; CACHEFILE_ENTRY * pEntry; - URL_CACHEFILE_ENTRY * pUrlEntry; + URLCACHECONTAINER * pContainer; - if (!URLCache_OpenIndex()) + TRACE("(%s, %p, 0x%08lx)\n", debugstr_a(lpszUrlName), lpCacheEntryInfo, dwFieldControl); + + if (!URLCacheContainers_FindContainerA(lpszUrlName, &pContainer)) + return FALSE; + + if (!URLCacheContainer_OpenIndex(pContainer)) return FALSE; - if (!(pHeader = URLCache_LockIndex())) + if (!(pHeader = URLCacheContainer_LockIndex(pContainer))) return FALSE; if (!URLCache_FindEntryInHash(pHeader, lpszUrlName, &pEntry)) { - if (!URLCache_FindEntry(pHeader, lpszUrlName, &pEntry)) - { - URLCache_UnlockIndex(pHeader); - WARN("entry %s not found!\n", debugstr_a(lpszUrlName)); - SetLastError(ERROR_FILE_NOT_FOUND); - return FALSE; - } + URLCacheContainer_UnlockIndex(pContainer, pHeader); + WARN("entry %s not found!\n", debugstr_a(lpszUrlName)); + SetLastError(ERROR_FILE_NOT_FOUND); + return FALSE; + } + + if (pEntry->dwSignature != URL_SIGNATURE) + { + URLCacheContainer_UnlockIndex(pContainer, pHeader); + FIXME("Trying to retrieve entry of unknown format %s\n", debugstr_an((LPSTR)&pEntry->dwSignature, sizeof(DWORD))); + SetLastError(ERROR_FILE_NOT_FOUND); + return FALSE; } - /* FIXME: check signature */ + URLCache_SetEntryInfo( + (URL_CACHEFILE_ENTRY *)pEntry, + (const INTERNET_CACHE_ENTRY_INFOW *)lpCacheEntryInfo, + dwFieldControl); - pUrlEntry = (URL_CACHEFILE_ENTRY *)pEntry; - TRACE("Found URL: %s\n", pUrlEntry->szSourceUrlName); - TRACE("Header info: %s\n", (LPBYTE)pUrlEntry + pUrlEntry->dwOffsetHeaderInfo); + URLCacheContainer_UnlockIndex(pContainer, pHeader); + + return TRUE; +} + +/*********************************************************************** + * SetUrlCacheEntryInfoW (WININET.@) + */ +BOOL WINAPI SetUrlCacheEntryInfoW(LPCWSTR lpszUrl, LPINTERNET_CACHE_ENTRY_INFOW lpCacheEntryInfo, DWORD dwFieldControl) +{ + LPURLCACHE_HEADER pHeader; + CACHEFILE_ENTRY * pEntry; + URLCACHECONTAINER * pContainer; + LPSTR lpszUrlA; + int url_len; + + TRACE("(%s, %p, 0x%08lx)\n", debugstr_w(lpszUrl), lpCacheEntryInfo, dwFieldControl); + + url_len = WideCharToMultiByte(CP_ACP, 0, lpszUrl, -1, NULL, 0, NULL, NULL); + lpszUrlA = HeapAlloc(GetProcessHeap(), 0, url_len * sizeof(CHAR)); + if (!lpszUrlA) + { + SetLastError(ERROR_OUTOFMEMORY); + return FALSE; + } + WideCharToMultiByte(CP_ACP, 0, lpszUrl, -1, lpszUrlA, url_len, NULL, NULL); - if (!URLCache_CopyEntry(pHeader, lpCacheEntryInfo, lpdwCacheEntryInfoBufferSize, pUrlEntry)) + if (!URLCacheContainers_FindContainerW(lpszUrl, &pContainer)) { - URLCache_UnlockIndex(pHeader); + HeapFree(GetProcessHeap(), 0, lpszUrlA); return FALSE; } - TRACE("Local File Name: %s\n", lpCacheEntryInfo->lpszLocalFileName); - URLCache_UnlockIndex(pHeader); + if (!URLCacheContainer_OpenIndex(pContainer)) + { + HeapFree(GetProcessHeap(), 0, lpszUrlA); + return FALSE; + } + + if (!(pHeader = URLCacheContainer_LockIndex(pContainer))) + { + HeapFree(GetProcessHeap(), 0, lpszUrlA); + return FALSE; + } + + if (!URLCache_FindEntryInHash(pHeader, lpszUrlA, &pEntry)) + { + URLCacheContainer_UnlockIndex(pContainer, pHeader); + HeapFree(GetProcessHeap(), 0, lpszUrlA); + WARN("entry %s not found!\n", debugstr_a(lpszUrlA)); + SetLastError(ERROR_FILE_NOT_FOUND); + return FALSE; + } + HeapFree(GetProcessHeap(), 0, lpszUrlA); + + if (pEntry->dwSignature != URL_SIGNATURE) + { + URLCacheContainer_UnlockIndex(pContainer, pHeader); + FIXME("Trying to retrieve entry of unknown format %s\n", debugstr_an((LPSTR)&pEntry->dwSignature, sizeof(DWORD))); + SetLastError(ERROR_FILE_NOT_FOUND); + return FALSE; + } + + URLCache_SetEntryInfo( + (URL_CACHEFILE_ENTRY *)pEntry, + lpCacheEntryInfo, + dwFieldControl); + + URLCacheContainer_UnlockIndex(pContainer, pHeader); return TRUE; } @@ -949,25 +1486,38 @@ LPURLCACHE_HEADER pHeader; CACHEFILE_ENTRY * pEntry; URL_CACHEFILE_ENTRY * pUrlEntry; + URLCACHECONTAINER * pContainer; + + TRACE("(%s, %p, %p, 0x%08lx)\n", + debugstr_a(lpszUrlName), + lpCacheEntryInfo, + lpdwCacheEntryInfoBufferSize, + dwReserved); - if (!URLCache_OpenIndex()) + if (!URLCacheContainers_FindContainerA(lpszUrlName, &pContainer)) return FALSE; - if (!(pHeader = URLCache_LockIndex())) + if (!URLCacheContainer_OpenIndex(pContainer)) + return FALSE; + + if (!(pHeader = URLCacheContainer_LockIndex(pContainer))) return FALSE; if (!URLCache_FindEntryInHash(pHeader, lpszUrlName, &pEntry)) { - if (!URLCache_FindEntry(pHeader, lpszUrlName, &pEntry)) - { - URLCache_UnlockIndex(pHeader); - TRACE("entry %s not found!\n", lpszUrlName); - SetLastError(ERROR_FILE_NOT_FOUND); - return FALSE; - } + URLCacheContainer_UnlockIndex(pContainer, pHeader); + TRACE("entry %s not found!\n", lpszUrlName); + SetLastError(ERROR_FILE_NOT_FOUND); + return FALSE; } - /* FIXME: check signature */ + if (pEntry->dwSignature != URL_SIGNATURE) + { + URLCacheContainer_UnlockIndex(pContainer, pHeader); + FIXME("Trying to retrieve entry of unknown format %s\n", debugstr_an((LPSTR)&pEntry->dwSignature, sizeof(DWORD))); + SetLastError(ERROR_FILE_NOT_FOUND); + return FALSE; + } pUrlEntry = (URL_CACHEFILE_ENTRY *)pEntry; TRACE("Found URL: %s\n", pUrlEntry->szSourceUrlName); @@ -977,14 +1527,14 @@ pUrlEntry->dwUseCount++; URLCache_HashEntrySetUse(pHeader, lpszUrlName, pUrlEntry->dwUseCount); - if (!URLCache_CopyEntry(pHeader, lpCacheEntryInfo, lpdwCacheEntryInfoBufferSize, pUrlEntry)) + if (!URLCache_CopyEntry(pContainer, pHeader, lpCacheEntryInfo, lpdwCacheEntryInfoBufferSize, pUrlEntry, FALSE)) { - URLCache_UnlockIndex(pHeader); + URLCacheContainer_UnlockIndex(pContainer, pHeader); return FALSE; } TRACE("Local File Name: %s\n", lpCacheEntryInfo->lpszLocalFileName); - URLCache_UnlockIndex(pHeader); + URLCacheContainer_UnlockIndex(pContainer, pHeader); return TRUE; } @@ -1001,6 +1551,9 @@ LPURLCACHE_HEADER pHeader; CACHEFILE_ENTRY * pEntry; URL_CACHEFILE_ENTRY * pUrlEntry; + URLCACHECONTAINER * pContainer; + + TRACE("(%s, 0x%08lx)\n", debugstr_a(lpszUrlName), dwReserved); if (dwReserved) { @@ -1009,36 +1562,42 @@ return FALSE; } - if (!URLCache_OpenIndex()) + if (!URLCacheContainers_FindContainerA(lpszUrlName, &pContainer)) + return FALSE; + + if (!URLCacheContainer_OpenIndex(pContainer)) return FALSE; - if (!(pHeader = URLCache_LockIndex())) + if (!(pHeader = URLCacheContainer_LockIndex(pContainer))) return FALSE; if (!URLCache_FindEntryInHash(pHeader, lpszUrlName, &pEntry)) { - if (!URLCache_FindEntry(pHeader, lpszUrlName, &pEntry)) - { - URLCache_UnlockIndex(pHeader); - TRACE("entry %s not found!\n", lpszUrlName); - SetLastError(ERROR_FILE_NOT_FOUND); - return FALSE; - } + URLCacheContainer_UnlockIndex(pContainer, pHeader); + TRACE("entry %s not found!\n", lpszUrlName); + SetLastError(ERROR_FILE_NOT_FOUND); + return FALSE; } - /* FIXME: check signature */ + if (pEntry->dwSignature != URL_SIGNATURE) + { + URLCacheContainer_UnlockIndex(pContainer, pHeader); + FIXME("Trying to retrieve entry of unknown format %s\n", debugstr_an((LPSTR)&pEntry->dwSignature, sizeof(DWORD))); + SetLastError(ERROR_FILE_NOT_FOUND); + return FALSE; + } pUrlEntry = (URL_CACHEFILE_ENTRY *)pEntry; if (pUrlEntry->dwUseCount == 0) { - URLCache_UnlockIndex(pHeader); + URLCacheContainer_UnlockIndex(pContainer, pHeader); return FALSE; } pUrlEntry->dwUseCount--; URLCache_HashEntrySetUse(pHeader, lpszUrlName, pUrlEntry->dwUseCount); - URLCache_UnlockIndex(pHeader); + URLCacheContainer_UnlockIndex(pContainer, pHeader); return TRUE; } @@ -1055,6 +1614,7 @@ IN DWORD dwReserved ) { + URLCACHECONTAINER * pContainer; LPURLCACHE_HEADER pHeader; CHAR szFile[MAX_PATH]; CHAR szExtension[MAX_PATH]; @@ -1065,10 +1625,17 @@ int i; int countnoextension; BYTE CacheDir; - LONG lBufferSize = MAX_PATH * sizeof(CHAR); + LONG lBufferSize; BOOL bFound = FALSE; int count; + TRACE("(%s, 0x%08lx, %s, %p, 0x%08lx)\n", + debugstr_a(lpszUrlName), + dwExpectedFileSize, + debugstr_a(lpszFileExtension), + lpszFileName, + dwReserved); + if (dwReserved) { ERR("dwReserved != 0\n"); @@ -1113,19 +1680,23 @@ TRACE("File name: %s\n", szFile); - if (!URLCache_OpenIndex()) + if (!URLCacheContainers_FindContainerA(lpszUrlName, &pContainer)) + return FALSE; + + if (!URLCacheContainer_OpenIndex(pContainer)) return FALSE; - if (!(pHeader = URLCache_LockIndex())) + if (!(pHeader = URLCacheContainer_LockIndex(pContainer))) return FALSE; CacheDir = (BYTE)(rand() % pHeader->DirectoryCount); - URLCache_LocalFileNameToPath(pHeader, szFile, CacheDir, lpszFileName, &lBufferSize); + lBufferSize = MAX_PATH * sizeof(CHAR); + URLCache_LocalFileNameToPathA(pContainer, pHeader, szFile, CacheDir, lpszFileName, &lBufferSize); - URLCache_UnlockIndex(pHeader); + URLCacheContainer_UnlockIndex(pContainer, pHeader); - lpszFileNameNoPath = lpszFileName + strlen(szCacheContentPath) + DIR_LENGTH + 1; + lpszFileNameNoPath = lpszFileName + lBufferSize / sizeof(CHAR) + DIR_LENGTH + 1; countnoextension = strlen(lpszFileNameNoPath); lpszFileNameExtension = PathFindExtensionA(lpszFileNameNoPath); @@ -1172,17 +1743,16 @@ IN LPCSTR dwReserved ) { + URLCACHECONTAINER * pContainer; LPURLCACHE_HEADER pHeader; CACHEFILE_ENTRY * pEntry; URL_CACHEFILE_ENTRY * pUrlEntry; DWORD dwBytesNeeded = sizeof(*pUrlEntry) - sizeof(pUrlEntry->szSourceUrlName); - BYTE cDirectory; - BOOL bFound = FALSE; - DWORD dwOffsetLocalFileName; - DWORD dwOffsetHeader; - DWORD dwFileSizeLow; - DWORD dwFileSizeHigh; - HANDLE hFile; + DWORD dwOffsetLocalFileName = 0; + DWORD dwOffsetHeader = 0; + DWORD dwFileSizeLow = 0; + DWORD dwFileSizeHigh = 0; + BYTE cDirectory = 0; TRACE("(%s, %s, ..., ..., %lx, %p, %ld, %s, %p)\n", debugstr_a(lpszUrlName), @@ -1203,72 +1773,103 @@ { FIXME("lpHeaderInfo == NULL - will crash at the moment\n"); } - - hFile = CreateFileA(lpszLocalFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); - if (hFile == INVALID_HANDLE_VALUE) - { - ERR("couldn't open file (error is %ld)\n", GetLastError()); - return FALSE; - } - - /* Get file size */ - dwFileSizeLow = GetFileSize(hFile, &dwFileSizeHigh); - if ((dwFileSizeLow == -1) && (GetLastError() != NO_ERROR)) + + if (lpszLocalFileName) { - ERR("couldn't get file size (error is %ld)\n", GetLastError()); + HANDLE hFile; + hFile = CreateFileA(lpszLocalFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); + if (hFile == INVALID_HANDLE_VALUE) + { + ERR("couldn't open file %s (error is %ld)\n", debugstr_a(lpszLocalFileName), GetLastError()); + return FALSE; + } + + /* Get file size */ + dwFileSizeLow = GetFileSize(hFile, &dwFileSizeHigh); + if ((dwFileSizeLow == -1) && (GetLastError() != NO_ERROR)) + { + ERR("couldn't get file size (error is %ld)\n", GetLastError()); + CloseHandle(hFile); + return FALSE; + } + CloseHandle(hFile); - return FALSE; } - CloseHandle(hFile); + if (!URLCacheContainers_FindContainerA(lpszUrlName, &pContainer)) + return FALSE; - if (!URLCache_OpenIndex()) + if (!URLCacheContainer_OpenIndex(pContainer)) return FALSE; - if (!(pHeader = URLCache_LockIndex())) + if (!(pHeader = URLCacheContainer_LockIndex(pContainer))) return FALSE; - if (URLCache_FindEntryInHash(pHeader, lpszUrlName, &pEntry) || URLCache_FindEntry(pHeader, lpszUrlName, &pEntry)) + if (URLCache_FindEntryInHash(pHeader, lpszUrlName, &pEntry)) { - URLCache_UnlockIndex(pHeader); + URLCacheContainer_UnlockIndex(pContainer, pHeader); FIXME("entry already in cache - don't know what to do!\n"); - SetLastError(ERROR_FILE_NOT_FOUND); - return FALSE; +// SetLastError(ERROR_FILE_NOT_FOUND); +// return FALSE; + return TRUE; } - if (memcmp(lpszLocalFileName, szCacheContentPath, strlen(szCacheContentPath))) + if (lpszLocalFileName) { - URLCache_UnlockIndex(pHeader); - ERR("path must begin with cache content path\n"); - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } + BOOL bFound = FALSE; + char szContainerPath[MAX_PATH]; + int container_path_len; + container_path_len = WideCharToMultiByte(CP_ACP, 0, pContainer->path, -1, szContainerPath, sizeof(szContainerPath), NULL, NULL); + if (!container_path_len) + { + /* WideCharToMultiByte should have called SetLastError */ + return FALSE; + } + + if (strncmp(lpszLocalFileName, szContainerPath, container_path_len)) + { + URLCacheContainer_UnlockIndex(pContainer, pHeader); + ERR("path %s must begin with cache content path %s\n", debugstr_a(lpszLocalFileName), debugstr_a(szContainerPath)); + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } - lpszLocalFileName += strlen(szCacheContentPath); + /* skip container path prefix */ + lpszLocalFileName += container_path_len; - for (cDirectory = 0; cDirectory < pHeader->DirectoryCount; cDirectory++) - { - if (!strncmp(pHeader->directory_data[cDirectory].filename, lpszLocalFileName, DIR_LENGTH)) + for (cDirectory = 0; cDirectory < pHeader->DirectoryCount; cDirectory++) { - bFound = TRUE; - break; + if (!strncmp(pHeader->directory_data[cDirectory].filename, lpszLocalFileName, DIR_LENGTH)) + { + bFound = TRUE; + break; + } + } + + if (!bFound) + { + URLCacheContainer_UnlockIndex(pContainer, pHeader); + ERR("cache directory not found in path %s\n", lpszLocalFileName); + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; } + + lpszLocalFileName += (DIR_LENGTH + 1); /* "1234WXYZ\" */ } - if (!bFound) + dwBytesNeeded = DWORD_ALIGN(dwBytesNeeded + strlen(lpszUrlName) + 1); + if (lpszLocalFileName) { - URLCache_UnlockIndex(pHeader); - ERR("cache directory not found in path %s\n", lpszLocalFileName); - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; + dwOffsetLocalFileName = dwBytesNeeded; + dwBytesNeeded = DWORD_ALIGN(dwBytesNeeded + strlen(lpszLocalFileName) + 1); + } + if (lpHeaderInfo) + { + dwOffsetHeader = dwBytesNeeded; + dwBytesNeeded = DWORD_ALIGN(dwBytesNeeded + dwHeaderSize); } - lpszLocalFileName += (DIR_LENGTH + 1); /* "1234WXYZ\" */ - - dwOffsetLocalFileName = DWORD_ALIGN(dwBytesNeeded + strlen(lpszUrlName) + 1); /* + 1 for NULL terminating char */ - dwOffsetHeader = DWORD_ALIGN(dwOffsetLocalFileName + strlen(lpszLocalFileName) + 1); - dwBytesNeeded = DWORD_ALIGN(dwBytesNeeded + dwHeaderSize); - + /* round up to next block */ if (dwBytesNeeded % BLOCKSIZE) { dwBytesNeeded -= dwBytesNeeded % BLOCKSIZE; @@ -1277,9 +1878,8 @@ if (!URLCache_FindFirstFreeEntry(pHeader, dwBytesNeeded / BLOCKSIZE, &pEntry)) { - /* we should grow the index file here */ - URLCache_UnlockIndex(pHeader); - FIXME("no free entries\n"); + URLCacheContainer_UnlockIndex(pContainer, pHeader); + ERR("no free entries\n"); return FALSE; } @@ -1316,16 +1916,18 @@ pUrlEntry->dwUnknown8 = 0; strcpy(pUrlEntry->szSourceUrlName, lpszUrlName); - strcpy((LPSTR)((LPBYTE)pUrlEntry + dwOffsetLocalFileName), lpszLocalFileName); - memcpy((LPSTR)((LPBYTE)pUrlEntry + dwOffsetHeader), lpHeaderInfo, dwHeaderSize); + if (dwOffsetLocalFileName) + strcpy((LPSTR)((LPBYTE)pUrlEntry + dwOffsetLocalFileName), lpszLocalFileName); + if (dwOffsetHeader) + memcpy((LPSTR)((LPBYTE)pUrlEntry + dwOffsetHeader), lpHeaderInfo, dwHeaderSize); if (!URLCache_AddEntryToHash(pHeader, lpszUrlName, (DWORD)((LPBYTE)pUrlEntry - (LPBYTE)pHeader))) { - URLCache_UnlockIndex(pHeader); + URLCacheContainer_UnlockIndex(pContainer, pHeader); return FALSE; } - URLCache_UnlockIndex(pHeader); + URLCacheContainer_UnlockIndex(pContainer, pHeader); return TRUE; } @@ -1455,27 +2057,30 @@ */ BOOL WINAPI DeleteUrlCacheEntryA(LPCSTR lpszUrlName) { + URLCACHECONTAINER * pContainer; LPURLCACHE_HEADER pHeader; CACHEFILE_ENTRY * pEntry; DWORD dwStartBlock; DWORD dwBlock; BYTE * AllocationTable; - if (!URLCache_OpenIndex()) + TRACE("(%s)\n", debugstr_a(lpszUrlName)); + + if (!URLCacheContainers_FindContainerA(lpszUrlName, &pContainer)) + return FALSE; + + if (!URLCacheContainer_OpenIndex(pContainer)) return FALSE; - if (!(pHeader = URLCache_LockIndex())) + if (!(pHeader = URLCacheContainer_LockIndex(pContainer))) return FALSE; if (!URLCache_FindEntryInHash(pHeader, lpszUrlName, &pEntry)) { - if (!URLCache_FindEntry(pHeader, lpszUrlName, &pEntry)) - { - URLCache_UnlockIndex(pHeader); - TRACE("entry %s not found!\n", lpszUrlName); - SetLastError(ERROR_FILE_NOT_FOUND); - return FALSE; - } + URLCacheContainer_UnlockIndex(pContainer, pHeader); + TRACE("entry %s not found!\n", lpszUrlName); + SetLastError(ERROR_FILE_NOT_FOUND); + return FALSE; } AllocationTable = (LPBYTE)pHeader + ALLOCATION_TABLE_OFFSET; @@ -1487,25 +2092,14 @@ URLCache_DeleteEntry(pEntry); - /* FIXME: update hash table */ + URLCache_DeleteEntryFromHash(pHeader, lpszUrlName); - URLCache_UnlockIndex(pHeader); + URLCacheContainer_UnlockIndex(pContainer, pHeader); return TRUE; } /*********************************************************************** - * CreateUrlCacheGroup (WININET.@) - * - */ -INTERNETAPI GROUPID WINAPI CreateUrlCacheGroup(DWORD dwFlags, LPVOID -lpReserved) -{ - FIXME("(%lx, %p): stub\n", dwFlags, lpReserved); - return FALSE; -} - -/*********************************************************************** * FindFirstUrlCacheEntryA (WININET.@) * */ @@ -1513,6 +2107,7 @@ LPINTERNET_CACHE_ENTRY_INFOA lpFirstCacheEntryInfo, LPDWORD lpdwFirstCacheEntryInfoBufferSize) { FIXME("(%s, %p, %p): stub\n", debugstr_a(lpszUrlSearchPattern), lpFirstCacheEntryInfo, lpdwFirstCacheEntryInfoBufferSize); + SetLastError(ERROR_FILE_NOT_FOUND); return 0; } @@ -1528,6 +2123,17 @@ } /*********************************************************************** + * CreateUrlCacheGroup (WININET.@) + * + */ +INTERNETAPI GROUPID WINAPI CreateUrlCacheGroup(DWORD dwFlags, LPVOID +lpReserved) +{ + FIXME("(%lx, %p): stub\n", dwFlags, lpReserved); + return FALSE; +} + +/*********************************************************************** * DeleteUrlCacheGroup (WININET.@) * */ @@ -1551,33 +2157,12 @@ } /*********************************************************************** - * GetUrlCacheEntryInfoW (WININET.@) - * - */ -BOOL WINAPI GetUrlCacheEntryInfoW(LPCWSTR lpszUrl, - LPINTERNET_CACHE_ENTRY_INFOW lpCacheEntry, - LPDWORD lpCacheEntrySize) -{ - FIXME("(%s) stub\n",debugstr_w(lpszUrl)); - SetLastError(ERROR_FILE_NOT_FOUND); - return FALSE; -} - -/*********************************************************************** - * GetUrlCacheEntryInfoExW (WININET.@) - * + * GetUrlCacheConfigInfoW (WININET.@) */ -BOOL WINAPI GetUrlCacheEntryInfoExW( - LPCWSTR lpszUrl, - LPINTERNET_CACHE_ENTRY_INFOW lpCacheEntryInfo, - LPDWORD lpdwCacheEntryInfoBufSize, - LPWSTR lpszReserved, - LPDWORD lpdwReserved, - LPVOID lpReserved, - DWORD dwFlags) +BOOL WINAPI GetUrlCacheConfigInfoW(LPDWORD CacheInfo, LPDWORD size, DWORD bitmask) { - FIXME(" url=%s, flags=%ld\n",debugstr_w(lpszUrl),dwFlags); - INTERNET_SetLastError(ERROR_FILE_NOT_FOUND); + FIXME("(%p, %p, %lx)\n", CacheInfo, size, bitmask); + INTERNET_SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } @@ -1590,34 +2175,5 @@ { FIXME("(%p, %p, %lx)\n", CacheInfo, size, bitmask); INTERNET_SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; -} - -/*********************************************************************** - * GetUrlCacheConfigInfoW (WININET.@) - */ -BOOL WINAPI GetUrlCacheConfigInfoW(LPDWORD CacheInfo, LPDWORD size, DWORD bitmask) -{ - FIXME("(%p, %p, %lx)\n", CacheInfo, size, bitmask); - INTERNET_SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; -} - - -/*********************************************************************** - * SetUrlCacheEntryInfoA (WININET.@) - */ -BOOL WINAPI SetUrlCacheEntryInfoA(LPCSTR lpszUrlName, LPINTERNET_CACHE_ENTRY_INFOA lpCacheEntryInfo, DWORD dwFieldControl) -{ - FIXME("stub\n"); - return FALSE; -} - -/*********************************************************************** - * SetUrlCacheEntryInfoW (WININET.@) - */ -BOOL WINAPI SetUrlCacheEntryInfoW(LPCWSTR lpszUrlName, LPINTERNET_CACHE_ENTRY_INFOW lpCacheEntryInfo, DWORD dwFieldControl) -{ - FIXME("stub\n"); return FALSE; } Index: wine/dlls/wininet/wininet.spec =================================================================== RCS file: /home/wine/wine/dlls/wininet/wininet.spec,v retrieving revision 1.44 diff -u -r1.44 wininet.spec --- wine/dlls/wininet/wininet.spec 9 Nov 2003 01:23:32 -0000 1.44 +++ wine/dlls/wininet/wininet.spec 6 Dec 2003 02:22:38 -0000 @@ -1,3 +1,21 @@ +101 stub -noname DoConnectoidsExist +102 stub -noname GetDiskInfoA +103 stub -noname PerformOperationOverUrlCacheA +104 stub -noname HttpCheckDavComplianceA +105 stub -noname HttpCheckDavComplianceW +108 stub -noname ImportCookieFileA +109 stub -noname ExportCookieFileA +110 stub -noname ImportCookieFileW +111 stub -noname ExportCookieFileW +112 stub -noname IsProfilesEnabled +116 stub -noname IsDomainlegalCookieDomainA +117 stub -noname IsDomainLegalCookieDomainW +118 stub -noname FindP3PPolicySymbol +120 stub -noname MapResourceToPolicy +121 stub -noname GetP3PPolicy +122 stub -noname FreeP3PObject +123 stub -noname GetP3PRequestStatus + @ stdcall InternetInitializeAutoProxyDll(long) @ stub ShowCertificate @ stdcall CommitUrlCacheEntryA(str str double double long str long str str)