From c58317b5b4adbccfe093ea00c93cade79f0b491f Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Fri, 4 Oct 2013 16:52:43 +0200 Subject: [PATCH] wininet: Moved request file info to separated struct. --- dlls/wininet/http.c | 40 +++++++++++++++++++++++++--------------- dlls/wininet/internet.c | 30 ++++++++++++++++++++++++++++++ dlls/wininet/internet.h | 19 +++++++++++++++++-- 3 files changed, 72 insertions(+), 17 deletions(-) diff --git a/dlls/wininet/http.c b/dlls/wininet/http.c index 2d110408113..d2bd2d47302 100644 --- a/dlls/wininet/http.c +++ b/dlls/wininet/http.c @@ -1912,11 +1912,10 @@ static void HTTPREQ_Destroy(object_header_t *hdr) TRACE("\n"); - if(request->hCacheFile) { + if(request->hCacheFile) CloseHandle(request->hCacheFile); - DeleteFileW(request->cacheFile); - } - heap_free(request->cacheFile); + if(request->req_file) + req_file_release(request->req_file); request->read_section.DebugInfo->Spare[0] = 0; DeleteCriticalSection( &request->read_section ); @@ -2194,25 +2193,25 @@ static DWORD HTTPREQ_QueryOption(object_header_t *hdr, DWORD option, void *buffe TRACE("INTERNET_OPTION_DATAFILE_NAME\n"); - if(!req->cacheFile) { + if(!req->req_file) { *size = 0; return ERROR_INTERNET_ITEM_NOT_FOUND; } if(unicode) { - req_size = (lstrlenW(req->cacheFile)+1) * sizeof(WCHAR); + req_size = (lstrlenW(req->req_file->file_name)+1) * sizeof(WCHAR); if(*size < req_size) return ERROR_INSUFFICIENT_BUFFER; *size = req_size; - memcpy(buffer, req->cacheFile, *size); + memcpy(buffer, req->req_file->file_name, *size); return ERROR_SUCCESS; }else { - req_size = WideCharToMultiByte(CP_ACP, 0, req->cacheFile, -1, NULL, 0, NULL, NULL); + req_size = WideCharToMultiByte(CP_ACP, 0, req->req_file->file_name, -1, NULL, 0, NULL, NULL); if (req_size > *size) return ERROR_INSUFFICIENT_BUFFER; - *size = WideCharToMultiByte(CP_ACP, 0, req->cacheFile, + *size = WideCharToMultiByte(CP_ACP, 0, req->req_file->file_name, -1, buffer, *size, NULL, NULL); return ERROR_SUCCESS; } @@ -2376,12 +2375,17 @@ static void commit_cache_entry(http_request_t *req) if(HTTP_GetRequestURL(req, url)) { WCHAR *header; DWORD header_len; + BOOL res; header = build_response_header(req, TRUE); header_len = (header ? strlenW(header) : 0); - CommitUrlCacheEntryW(url, req->cacheFile, req->expires, + res = CommitUrlCacheEntryW(url, req->req_file->file_name, req->expires, req->last_modified, NORMAL_CACHE_ENTRY, header, header_len, NULL, 0); + if(res) + req->req_file->is_committed = TRUE; + else + WARN("CommitUrlCacheEntry failed: %u\n", GetLastError()); heap_free(header); } } @@ -2396,9 +2400,14 @@ static void create_cache_entry(http_request_t *req) BOOL b = TRUE; /* FIXME: We should free previous cache file earlier */ - heap_free(req->cacheFile); - CloseHandle(req->hCacheFile); - req->hCacheFile = NULL; + if(req->req_file) { + req_file_release(req->req_file); + req->req_file = NULL; + } + if(req->hCacheFile) { + CloseHandle(req->hCacheFile); + req->hCacheFile = NULL; + } if(req->hdr.dwFlags & INTERNET_FLAG_NO_CACHE_WRITE) b = FALSE; @@ -2450,8 +2459,9 @@ static void create_cache_entry(http_request_t *req) return; } - req->cacheFile = heap_strdupW(file_name); - req->hCacheFile = CreateFileW(req->cacheFile, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, + create_req_file(file_name, &req->req_file); + + req->hCacheFile = CreateFileW(file_name, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if(req->hCacheFile == INVALID_HANDLE_VALUE) { WARN("Could not create file: %u\n", GetLastError()); diff --git a/dlls/wininet/internet.c b/dlls/wininet/internet.c index a54a3dfc732..ace1bfacef2 100644 --- a/dlls/wininet/internet.c +++ b/dlls/wininet/internet.c @@ -3901,6 +3901,36 @@ BOOL WINAPI InternetQueryDataAvailable( HINTERNET hFile, return res == ERROR_SUCCESS; } +DWORD create_req_file(const WCHAR *file_name, req_file_t **ret) +{ + req_file_t *req_file; + + req_file = heap_alloc_zero(sizeof(*req_file)); + if(!req_file) + return ERROR_NOT_ENOUGH_MEMORY; + + req_file->ref = 1; + + req_file->file_name = heap_strdupW(file_name); + if(!req_file->file_name) { + heap_free(req_file); + return ERROR_NOT_ENOUGH_MEMORY; + } + + *ret = req_file; + return ERROR_SUCCESS; +} + +void req_file_release(req_file_t *req_file) +{ + if(InterlockedDecrement(&req_file->ref)) + return; + + if(!req_file->is_committed) + DeleteFileW(req_file->file_name); + heap_free(req_file->file_name); + heap_free(req_file); +} /*********************************************************************** * InternetLockRequestFile (WININET.@) diff --git a/dlls/wininet/internet.h b/dlls/wininet/internet.h index 246eb95b25e..8cde45ef188 100644 --- a/dlls/wininet/internet.h +++ b/dlls/wininet/internet.h @@ -247,6 +247,13 @@ typedef enum #define INET_OPENURL 0x0001 #define INET_CALLBACKW 0x0002 +typedef struct +{ + LONG ref; + WCHAR *file_name; + BOOL is_committed; +} req_file_t; + typedef struct _object_header_t object_header_t; typedef struct { @@ -280,7 +287,6 @@ struct _object_header_t struct list children; }; - typedef struct { object_header_t hdr; @@ -357,7 +363,7 @@ typedef struct DWORD nCustHeaders; FILETIME last_modified; HANDLE hCacheFile; - LPWSTR cacheFile; + req_file_t *req_file; FILETIME expires; struct HttpAuthInfo *authInfo; struct HttpAuthInfo *proxyAuthInfo; @@ -444,6 +450,15 @@ int sock_get_error(int) DECLSPEC_HIDDEN; server_t *get_server(const WCHAR*,INTERNET_PORT,BOOL,BOOL); +DWORD create_req_file(const WCHAR*,req_file_t**) DECLSPEC_HIDDEN; +void req_file_release(req_file_t*) DECLSPEC_HIDDEN; + +static inline req_file_t *req_file_addref(req_file_t *req_file) +{ + InterlockedIncrement(&req_file->ref); + return req_file; +} + BOOL init_urlcache(void) DECLSPEC_HIDDEN; void free_urlcache(void) DECLSPEC_HIDDEN; void free_cookie(void) DECLSPEC_HIDDEN;