The Minolta DiMAGE Image Viewer relies on Global{,Re}Alloc called with

the GMEM_MOVEABLE flag set, to allocate the exact specified size and
no byte more when size is a multiple of 8. To achieve this align the
storage needed for the HGLOBAL in the heap to 8byte boundary.
This commit is contained in:
Michael Stefaniuc 2003-01-16 00:21:04 +00:00 committed by Alexandre Julliard
parent 8e9dcb6655
commit cd0219e941
1 changed files with 19 additions and 13 deletions

View File

@ -1023,9 +1023,15 @@ DWORD WINAPI GetFreeMemInfo16(void)
#define GLOBAL_LOCK_MAX 0xFF
#define HANDLE_TO_INTERN(h) ((PGLOBAL32_INTERN)(((char *)(h))-2))
#define INTERN_TO_HANDLE(i) ((HGLOBAL) &((i)->Pointer))
#define POINTER_TO_HANDLE(p) (*(((HGLOBAL *)(p))-1))
#define POINTER_TO_HANDLE(p) (*(((HGLOBAL *)(p))-2))
#define ISHANDLE(h) (((DWORD)(h)&2)!=0)
#define ISPOINTER(h) (((DWORD)(h)&2)==0)
/* allign the storage needed for the HGLOBAL on an 8byte boundary thus
* GlobalAlloc/GlobalReAlloc'ing with GMEM_MOVEABLE of memory with
* size = 8*k, where k=1,2,3,... alloc's exactly the given size.
* The Minolta DiMAGE Image Viewer heavily relies on this, corrupting
* the output jpeg's > 1 MB if not */
#define HGLOBAL_STORAGE 8 /* sizeof(HGLOBAL)*2 */
typedef struct __GLOBAL32_INTERN
{
@ -1070,12 +1076,12 @@ HGLOBAL WINAPI GlobalAlloc(
if (!pintern) return 0;
if(size)
{
if (!(palloc=HeapAlloc(GetProcessHeap(), hpflags, size+sizeof(HGLOBAL)))) {
if (!(palloc=HeapAlloc(GetProcessHeap(), hpflags, size+HGLOBAL_STORAGE))) {
HeapFree(GetProcessHeap(), 0, pintern);
return 0;
}
*(HGLOBAL *)palloc=INTERN_TO_HANDLE(pintern);
pintern->Pointer=(char *) palloc+sizeof(HGLOBAL);
pintern->Pointer=(char *) palloc+HGLOBAL_STORAGE;
}
else
pintern->Pointer=NULL;
@ -1211,7 +1217,7 @@ HGLOBAL WINAPI GlobalHandle(
maybe_intern = HANDLE_TO_INTERN( handle );
if (maybe_intern->Magic == MAGIC_GLOBAL_USED) {
test = maybe_intern->Pointer;
if (HeapValidate( GetProcessHeap(), 0, ((HGLOBAL *)test)-1 ) && /* obj(-handle) valid arena? */
if (HeapValidate( GetProcessHeap(), 0, (char *)test - HGLOBAL_STORAGE ) && /* obj(-handle) valid arena? */
HeapValidate( GetProcessHeap(), 0, maybe_intern )) /* intern valid arena? */
break; /* valid moveable block */
}
@ -1306,25 +1312,25 @@ HGLOBAL WINAPI GlobalReAlloc(
if(pintern->Pointer)
{
if((palloc = HeapReAlloc(GetProcessHeap(), heap_flags,
(char *) pintern->Pointer-sizeof(HGLOBAL),
size+sizeof(HGLOBAL))) == NULL)
(char *) pintern->Pointer-HGLOBAL_STORAGE,
size+HGLOBAL_STORAGE)) == NULL)
return 0; /* Block still valid */
pintern->Pointer=(char *) palloc+sizeof(HGLOBAL);
pintern->Pointer=(char *) palloc+HGLOBAL_STORAGE;
}
else
{
if((palloc=HeapAlloc(GetProcessHeap(), heap_flags, size+sizeof(HGLOBAL)))
if((palloc=HeapAlloc(GetProcessHeap(), heap_flags, size+HGLOBAL_STORAGE))
== NULL)
return 0;
*(HGLOBAL *)palloc=hmem;
pintern->Pointer=(char *) palloc+sizeof(HGLOBAL);
pintern->Pointer=(char *) palloc+HGLOBAL_STORAGE;
}
}
else
{
if(pintern->Pointer)
{
HeapFree(GetProcessHeap(), 0, (char *) pintern->Pointer-sizeof(HGLOBAL));
HeapFree(GetProcessHeap(), 0, (char *) pintern->Pointer-HGLOBAL_STORAGE);
pintern->Pointer=NULL;
}
}
@ -1368,7 +1374,7 @@ HGLOBAL WINAPI GlobalFree(
/* SetLastError(ERROR_INVALID_HANDLE); */
if(pintern->Pointer)
if(!HeapFree(GetProcessHeap(), 0, (char *)(pintern->Pointer)-sizeof(HGLOBAL)))
if(!HeapFree(GetProcessHeap(), 0, (char *)(pintern->Pointer)-HGLOBAL_STORAGE))
hreturned=hmem;
if(!HeapFree(GetProcessHeap(), 0, pintern))
hreturned=hmem;
@ -1413,8 +1419,8 @@ SIZE_T WINAPI GlobalSize(
if (!pintern->Pointer) /* handle case of GlobalAlloc( ??,0) */
return 0;
retval=HeapSize(GetProcessHeap(), 0,
(char *)(pintern->Pointer)-sizeof(HGLOBAL))-4;
if (retval == 0xffffffff-4) retval = 0;
(char *)(pintern->Pointer) - HGLOBAL_STORAGE );
if (retval != (DWORD)-1) retval -= HGLOBAL_STORAGE;
}
else
{