kernel32: Remove incorrect and incomplete implementation of BeginResourceUpdate.

This commit is contained in:
Mike McCormack 2006-12-28 19:58:35 +09:00 committed by Alexandre Julliard
parent 1cd16ed7f3
commit 794dbe4f93
2 changed files with 135 additions and 188 deletions

View file

@ -616,60 +616,111 @@ DWORD WINAPI SizeofResource( HINSTANCE hModule, HRSRC hRsrc )
return ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->Size; return ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->Size;
} }
typedef struct typedef struct
{ {
LPWSTR pFileName; LPWSTR pFileName;
struct list resources_list;
} QUEUEDUPDATES; } QUEUEDUPDATES;
typedef struct BOOL update_add_resource( QUEUEDUPDATES *updates, LPCWSTR Type, LPCWSTR Name,
WORD Language, DWORD codepage, LPCVOID lpData, DWORD cbData )
{ {
struct list entry; FIXME("%p %s %s %04x %p %d bytes\n", updates, debugstr_w(Type), debugstr_w(Name), Language, lpData, cbData);
LPWSTR lpType; return FALSE;
LPWSTR lpName;
WORD wLanguage;
LPVOID lpData;
DWORD cbData;
} QUEUEDRESOURCE;
static BOOL CALLBACK enum_resources_languages_delete_all(HMODULE hModule, LPCWSTR lpType, LPCWSTR lpName, WORD wLang, LONG_PTR lParam)
{
return UpdateResourceW((HANDLE)lParam, lpType, lpName, wLang, NULL, 0);
} }
static BOOL CALLBACK enum_resources_names_delete_all(HMODULE hModule, LPCWSTR lpType, LPWSTR lpName, LONG_PTR lParam) IMAGE_NT_HEADERS *get_nt_header( void *base, DWORD mapping_size )
{ {
return EnumResourceLanguagesW(hModule, lpType, lpName, enum_resources_languages_delete_all, lParam); IMAGE_NT_HEADERS *nt;
IMAGE_DOS_HEADER *dos;
if (mapping_size<sizeof (*dos))
return NULL;
dos = base;
if (dos->e_magic != IMAGE_DOS_SIGNATURE)
return NULL;
if ((dos->e_lfanew + sizeof (*nt)) > mapping_size)
return NULL;
nt = (void*) ((BYTE*)base + dos->e_lfanew);
if (nt->Signature != IMAGE_NT_SIGNATURE)
return NULL;
return nt;
} }
static BOOL CALLBACK enum_resources_types_delete_all(HMODULE hModule, LPWSTR lpType, LONG_PTR lParam) IMAGE_SECTION_HEADER *get_section_header( void *base, DWORD mapping_size, DWORD *num_sections )
{ {
return EnumResourceNamesW(hModule, lpType, enum_resources_names_delete_all, lParam); IMAGE_NT_HEADERS *nt;
IMAGE_SECTION_HEADER *sec;
DWORD section_ofs;
nt = get_nt_header( base, mapping_size );
if (!nt)
return NULL;
/* check that we don't go over the end of the file accessing the sections */
section_ofs = FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader) + nt->FileHeader.SizeOfOptionalHeader;
if ((nt->FileHeader.NumberOfSections * sizeof (*sec) + section_ofs) > mapping_size)
return NULL;
if (num_sections)
*num_sections = nt->FileHeader.NumberOfSections;
/* from here we have a valid PE exe to update */
return (void*) ((BYTE*)nt + section_ofs);
} }
static BOOL CALLBACK enum_resources_languages_add_all(HMODULE hModule, LPCWSTR lpType, LPCWSTR lpName, WORD wLang, LONG_PTR lParam) static BOOL load_raw_resources( HANDLE file, QUEUEDUPDATES *updates )
{ {
DWORD size; const IMAGE_NT_HEADERS *nt;
HRSRC hResource = FindResourceExW(hModule, lpType, lpName, wLang); const IMAGE_SECTION_HEADER *sec;
HGLOBAL hGlobal; BOOL ret = FALSE;
LPVOID lpData; HANDLE mapping;
DWORD mapping_size, num_sections = 0;
void *base = NULL;
if(hResource == NULL) return FALSE; mapping_size = GetFileSize( file, NULL );
if(!(hGlobal = LoadResource(hModule, hResource))) return FALSE;
if(!(lpData = LockResource(hGlobal))) return FALSE; mapping = CreateFileMappingW( file, NULL, PAGE_READONLY, 0, 0, NULL );
if(!(size = SizeofResource(hModule, hResource))) return FALSE; if (!mapping)
return UpdateResourceW((HANDLE)lParam, lpType, lpName, wLang, lpData, size); goto done;
base = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, mapping_size );
if (!base)
goto done;
nt = get_nt_header( base, mapping_size );
if (!nt)
goto done;
TRACE("resources: %08x %08x\n",
nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress,
nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size);
sec = get_section_header( base, mapping_size, &num_sections );
if (!sec)
goto done;
ret = TRUE;
FIXME("not implemented\n");
done:
if (base)
UnmapViewOfFile( base );
if (mapping)
CloseHandle( mapping );
return ret;
} }
static BOOL CALLBACK enum_resources_names_add_all(HMODULE hModule, LPCWSTR lpType, LPWSTR lpName, LONG_PTR lParam) BOOL write_raw_resources( QUEUEDUPDATES *updates )
{ {
return EnumResourceLanguagesW(hModule, lpType, lpName, enum_resources_languages_add_all, lParam); FIXME("not implemented\n");
} return FALSE;
static BOOL CALLBACK enum_resources_types_add_all(HMODULE hModule, LPWSTR lpType, LONG_PTR lParam)
{
return EnumResourceNamesW(hModule, lpType, enum_resources_names_add_all, lParam);
} }
/*********************************************************************** /***********************************************************************
@ -677,76 +728,41 @@ static BOOL CALLBACK enum_resources_types_add_all(HMODULE hModule, LPWSTR lpType
*/ */
HANDLE WINAPI BeginUpdateResourceW( LPCWSTR pFileName, BOOL bDeleteExistingResources ) HANDLE WINAPI BeginUpdateResourceW( LPCWSTR pFileName, BOOL bDeleteExistingResources )
{ {
HANDLE hFile = NULL; QUEUEDUPDATES *updates = NULL;
WIN32_FIND_DATAW fd; HANDLE hUpdate, file, ret = NULL;
HANDLE hModule = NULL;
HANDLE hUpdate = NULL;
QUEUEDUPDATES *current_updates = NULL;
HANDLE ret = NULL;
TRACE("%s, %d\n",debugstr_w(pFileName),bDeleteExistingResources); TRACE("%s, %d\n", debugstr_w(pFileName), bDeleteExistingResources);
hFile = FindFirstFileW(pFileName, &fd); hUpdate = GlobalAlloc(GHND, sizeof(QUEUEDUPDATES));
if(hFile == INVALID_HANDLE_VALUE) if (!hUpdate)
{ return ret;
hFile = NULL;
SetLastError(ERROR_FILE_NOT_FOUND);
goto done;
}
if(fd.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
{
SetLastError(ERROR_FILE_READ_ONLY);
goto done;
}
hModule = LoadLibraryW(pFileName); updates = GlobalLock(hUpdate);
if(hModule == NULL) if (updates)
{ {
SetLastError(ERROR_INVALID_PARAMETER); updates->pFileName = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(pFileName)+1)*sizeof(WCHAR));
goto done; if (updates->pFileName)
} {
lstrcpyW(updates->pFileName, pFileName);
if(!(hUpdate = GlobalAlloc(GHND, sizeof(QUEUEDUPDATES)))) file = CreateFileW( pFileName, GENERIC_READ | GENERIC_WRITE,
{ 0, NULL, OPEN_EXISTING, 0, 0 );
SetLastError(ERROR_OUTOFMEMORY);
goto done;
}
if(!(current_updates = GlobalLock(hUpdate)))
{
SetLastError(ERROR_INVALID_HANDLE);
goto done;
}
if(!(current_updates->pFileName = HeapAlloc(GetProcessHeap(), 0, (strlenW(pFileName)+1)*sizeof(WCHAR))))
{
SetLastError(ERROR_OUTOFMEMORY);
goto done;
}
strcpyW(current_updates->pFileName, pFileName);
list_init(&current_updates->resources_list);
if(bDeleteExistingResources) /* if resources are deleted, only the file's presence is checked */
{ if (file != INVALID_HANDLE_VALUE &&
if(!EnumResourceTypesW(hModule, enum_resources_types_delete_all, (LONG_PTR)hUpdate)) (bDeleteExistingResources || load_raw_resources( file, updates )))
goto done; ret = hUpdate;
} else
else HeapFree( GetProcessHeap(), 0, updates->pFileName );
{
if(!EnumResourceTypesW(hModule, enum_resources_types_add_all, (LONG_PTR)hUpdate))
goto done;
}
ret = hUpdate;
done: CloseHandle( file );
if(!ret && current_updates) }
{
HeapFree(GetProcessHeap(), 0, current_updates->pFileName);
GlobalUnlock(hUpdate); GlobalUnlock(hUpdate);
GlobalFree(hUpdate);
hUpdate = NULL;
} }
if(hUpdate) GlobalUnlock(hUpdate);
if(hModule) FreeLibrary(hModule); if (!ret)
if(hFile) FindClose(hFile); GlobalFree(hUpdate);
return ret; return ret;
} }
@ -770,46 +786,21 @@ HANDLE WINAPI BeginUpdateResourceA( LPCSTR pFileName, BOOL bDeleteExistingResour
*/ */
BOOL WINAPI EndUpdateResourceW( HANDLE hUpdate, BOOL fDiscard ) BOOL WINAPI EndUpdateResourceW( HANDLE hUpdate, BOOL fDiscard )
{ {
QUEUEDUPDATES *current_updates = NULL; QUEUEDUPDATES *updates;
BOOL found = TRUE; BOOL ret;
BOOL ret = FALSE;
struct list *ptr = NULL;
QUEUEDRESOURCE *current_resource = NULL;
FIXME("(%p,%d): stub\n",hUpdate,fDiscard); TRACE("%p %d\n", hUpdate, fDiscard);
if(!(current_updates = GlobalLock(hUpdate))) updates = GlobalLock(hUpdate);
{ if (!updates)
SetLastError(ERROR_INVALID_HANDLE); return FALSE;
found = FALSE;
goto done;
}
if(fDiscard) ret = fDiscard || write_raw_resources( updates );
ret = TRUE;
else HeapFree( GetProcessHeap(), 0, updates->pFileName );
{ GlobalUnlock( hUpdate );
/* FIXME: This is the only missing part, an actual implementation */ GlobalFree( hUpdate );
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
ret = FALSE;
}
done:
if(found)
{
while ((ptr = list_head(&current_updates->resources_list)) != NULL)
{
current_resource = LIST_ENTRY(ptr, QUEUEDRESOURCE, entry);
list_remove(&current_resource->entry);
if(HIWORD(current_resource->lpType)) HeapFree(GetProcessHeap(), 0, current_resource->lpType);
if(HIWORD(current_resource->lpName)) HeapFree(GetProcessHeap(), 0, current_resource->lpName);
HeapFree(GetProcessHeap(), 0, current_resource->lpData);
HeapFree(GetProcessHeap(), 0, current_resource);
}
HeapFree(GetProcessHeap(), 0, current_updates->pFileName);
GlobalUnlock(hUpdate);
GlobalFree(hUpdate);
}
return ret; return ret;
} }
@ -829,63 +820,19 @@ BOOL WINAPI EndUpdateResourceA( HANDLE hUpdate, BOOL fDiscard )
BOOL WINAPI UpdateResourceW( HANDLE hUpdate, LPCWSTR lpType, LPCWSTR lpName, BOOL WINAPI UpdateResourceW( HANDLE hUpdate, LPCWSTR lpType, LPCWSTR lpName,
WORD wLanguage, LPVOID lpData, DWORD cbData) WORD wLanguage, LPVOID lpData, DWORD cbData)
{ {
QUEUEDUPDATES *current_updates = NULL; QUEUEDUPDATES *updates;
BOOL found = TRUE;
QUEUEDRESOURCE *current_resource = NULL;
BOOL ret = FALSE; BOOL ret = FALSE;
TRACE("%p %s %s %08x %p %d\n",hUpdate,debugstr_w(lpType),debugstr_w(lpName),wLanguage,lpData,cbData); TRACE("%p %s %s %08x %p %d\n", hUpdate,
debugstr_w(lpType), debugstr_w(lpName), wLanguage, lpData, cbData);
if(!(current_updates = GlobalLock(hUpdate))) updates = GlobalLock(hUpdate);
if (updates)
{ {
SetLastError(ERROR_INVALID_HANDLE); ret = update_add_resource( updates, lpType, lpName,
found = FALSE; wLanguage, GetACP(), lpData, cbData );
goto done; GlobalUnlock(hUpdate);
} }
if(!(current_resource = HeapAlloc(GetProcessHeap(), 0, sizeof(QUEUEDRESOURCE))))
{
SetLastError(ERROR_OUTOFMEMORY);
goto done;
}
if(!HIWORD(lpType))
current_resource->lpType = (LPWSTR)lpType;
else if((current_resource->lpType = HeapAlloc(GetProcessHeap(), 0, (strlenW(lpType)+1)*sizeof(WCHAR))))
strcpyW(current_resource->lpType, lpType);
else
{
SetLastError(ERROR_OUTOFMEMORY);
goto done;
}
if(!HIWORD(lpName))
current_resource->lpName = (LPWSTR)lpName;
else if((current_resource->lpName = HeapAlloc(GetProcessHeap(), 0, (strlenW(lpName)+1)*sizeof(WCHAR))))
strcpyW(current_resource->lpName, lpName);
else
{
SetLastError(ERROR_OUTOFMEMORY);
goto done;
}
if(!(current_resource->lpData = HeapAlloc(GetProcessHeap(), 0, cbData)))
{
SetLastError(ERROR_OUTOFMEMORY);
goto done;
}
current_resource->wLanguage = wLanguage;
memcpy(current_resource->lpData, lpData, cbData);
current_resource->cbData = cbData;
list_add_tail(&current_updates->resources_list, &current_resource->entry);
ret = TRUE;
done:
if(!ret && current_resource)
{
if(HIWORD(current_resource->lpType)) HeapFree(GetProcessHeap(), 0, current_resource->lpType);
if(HIWORD(current_resource->lpName)) HeapFree(GetProcessHeap(), 0, current_resource->lpName);
HeapFree(GetProcessHeap(), 0, current_resource->lpData);
HeapFree(GetProcessHeap(), 0, current_resource);
}
if(found) GlobalUnlock(hUpdate);
return ret; return ret;
} }

View file

@ -122,7 +122,7 @@ static void update_empty_exe( void )
CloseHandle( file ); CloseHandle( file );
res = BeginUpdateResource( filename, TRUE ); res = BeginUpdateResource( filename, TRUE );
todo_wine ok( res != NULL, "BeginUpdateResource failed\n"); ok( res != NULL, "BeginUpdateResource failed\n");
/* check if it's possible to open the file now */ /* check if it's possible to open the file now */
test = CreateFile(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0); test = CreateFile(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);
@ -143,7 +143,7 @@ static void update_resources_none( void )
BOOL r; BOOL r;
res = BeginUpdateResource( filename, FALSE ); res = BeginUpdateResource( filename, FALSE );
todo_wine ok( res != NULL, "BeginUpdateResource failed\n"); ok( res != NULL, "BeginUpdateResource failed\n");
r = EndUpdateResource( res, FALSE ); r = EndUpdateResource( res, FALSE );
todo_wine ok( r, "EndUpdateResouce failed\n"); todo_wine ok( r, "EndUpdateResouce failed\n");
@ -155,7 +155,7 @@ static void update_resources_delete( void )
BOOL r; BOOL r;
res = BeginUpdateResource( filename, TRUE ); res = BeginUpdateResource( filename, TRUE );
todo_wine ok( res != NULL, "BeginUpdateResource failed\n"); ok( res != NULL, "BeginUpdateResource failed\n");
r = EndUpdateResource( res, FALSE ); r = EndUpdateResource( res, FALSE );
todo_wine ok( r, "EndUpdateResouce failed\n"); todo_wine ok( r, "EndUpdateResouce failed\n");
@ -175,10 +175,10 @@ void update_resources_version(void)
struct verhdr hdr; struct verhdr hdr;
char foo[] = "red and white"; char foo[] = "red and white";
todo_wine {
res = BeginUpdateResource( filename, TRUE ); res = BeginUpdateResource( filename, TRUE );
ok( res != NULL, "BeginUpdateResource failed\n"); ok( res != NULL, "BeginUpdateResource failed\n");
todo_wine {
memset( &hdr, 0, sizeof hdr ); memset( &hdr, 0, sizeof hdr );
r = UpdateResource( res, r = UpdateResource( res,
RT_VERSION, RT_VERSION,