Commit cd0219e9 authored by Michael Stefaniuc's avatar Michael Stefaniuc Committed by Alexandre Julliard

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.
parent 8e9dcb66
...@@ -1023,9 +1023,15 @@ DWORD WINAPI GetFreeMemInfo16(void) ...@@ -1023,9 +1023,15 @@ DWORD WINAPI GetFreeMemInfo16(void)
#define GLOBAL_LOCK_MAX 0xFF #define GLOBAL_LOCK_MAX 0xFF
#define HANDLE_TO_INTERN(h) ((PGLOBAL32_INTERN)(((char *)(h))-2)) #define HANDLE_TO_INTERN(h) ((PGLOBAL32_INTERN)(((char *)(h))-2))
#define INTERN_TO_HANDLE(i) ((HGLOBAL) &((i)->Pointer)) #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 ISHANDLE(h) (((DWORD)(h)&2)!=0)
#define ISPOINTER(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 typedef struct __GLOBAL32_INTERN
{ {
...@@ -1070,12 +1076,12 @@ HGLOBAL WINAPI GlobalAlloc( ...@@ -1070,12 +1076,12 @@ HGLOBAL WINAPI GlobalAlloc(
if (!pintern) return 0; if (!pintern) return 0;
if(size) if(size)
{ {
if (!(palloc=HeapAlloc(GetProcessHeap(), hpflags, size+sizeof(HGLOBAL)))) { if (!(palloc=HeapAlloc(GetProcessHeap(), hpflags, size+HGLOBAL_STORAGE))) {
HeapFree(GetProcessHeap(), 0, pintern); HeapFree(GetProcessHeap(), 0, pintern);
return 0; return 0;
} }
*(HGLOBAL *)palloc=INTERN_TO_HANDLE(pintern); *(HGLOBAL *)palloc=INTERN_TO_HANDLE(pintern);
pintern->Pointer=(char *) palloc+sizeof(HGLOBAL); pintern->Pointer=(char *) palloc+HGLOBAL_STORAGE;
} }
else else
pintern->Pointer=NULL; pintern->Pointer=NULL;
...@@ -1211,7 +1217,7 @@ HGLOBAL WINAPI GlobalHandle( ...@@ -1211,7 +1217,7 @@ HGLOBAL WINAPI GlobalHandle(
maybe_intern = HANDLE_TO_INTERN( handle ); maybe_intern = HANDLE_TO_INTERN( handle );
if (maybe_intern->Magic == MAGIC_GLOBAL_USED) { if (maybe_intern->Magic == MAGIC_GLOBAL_USED) {
test = maybe_intern->Pointer; 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? */ HeapValidate( GetProcessHeap(), 0, maybe_intern )) /* intern valid arena? */
break; /* valid moveable block */ break; /* valid moveable block */
} }
...@@ -1306,25 +1312,25 @@ HGLOBAL WINAPI GlobalReAlloc( ...@@ -1306,25 +1312,25 @@ HGLOBAL WINAPI GlobalReAlloc(
if(pintern->Pointer) if(pintern->Pointer)
{ {
if((palloc = HeapReAlloc(GetProcessHeap(), heap_flags, if((palloc = HeapReAlloc(GetProcessHeap(), heap_flags,
(char *) pintern->Pointer-sizeof(HGLOBAL), (char *) pintern->Pointer-HGLOBAL_STORAGE,
size+sizeof(HGLOBAL))) == NULL) size+HGLOBAL_STORAGE)) == NULL)
return 0; /* Block still valid */ return 0; /* Block still valid */
pintern->Pointer=(char *) palloc+sizeof(HGLOBAL); pintern->Pointer=(char *) palloc+HGLOBAL_STORAGE;
} }
else else
{ {
if((palloc=HeapAlloc(GetProcessHeap(), heap_flags, size+sizeof(HGLOBAL))) if((palloc=HeapAlloc(GetProcessHeap(), heap_flags, size+HGLOBAL_STORAGE))
== NULL) == NULL)
return 0; return 0;
*(HGLOBAL *)palloc=hmem; *(HGLOBAL *)palloc=hmem;
pintern->Pointer=(char *) palloc+sizeof(HGLOBAL); pintern->Pointer=(char *) palloc+HGLOBAL_STORAGE;
} }
} }
else else
{ {
if(pintern->Pointer) if(pintern->Pointer)
{ {
HeapFree(GetProcessHeap(), 0, (char *) pintern->Pointer-sizeof(HGLOBAL)); HeapFree(GetProcessHeap(), 0, (char *) pintern->Pointer-HGLOBAL_STORAGE);
pintern->Pointer=NULL; pintern->Pointer=NULL;
} }
} }
...@@ -1368,7 +1374,7 @@ HGLOBAL WINAPI GlobalFree( ...@@ -1368,7 +1374,7 @@ HGLOBAL WINAPI GlobalFree(
/* SetLastError(ERROR_INVALID_HANDLE); */ /* SetLastError(ERROR_INVALID_HANDLE); */
if(pintern->Pointer) if(pintern->Pointer)
if(!HeapFree(GetProcessHeap(), 0, (char *)(pintern->Pointer)-sizeof(HGLOBAL))) if(!HeapFree(GetProcessHeap(), 0, (char *)(pintern->Pointer)-HGLOBAL_STORAGE))
hreturned=hmem; hreturned=hmem;
if(!HeapFree(GetProcessHeap(), 0, pintern)) if(!HeapFree(GetProcessHeap(), 0, pintern))
hreturned=hmem; hreturned=hmem;
...@@ -1413,8 +1419,8 @@ SIZE_T WINAPI GlobalSize( ...@@ -1413,8 +1419,8 @@ SIZE_T WINAPI GlobalSize(
if (!pintern->Pointer) /* handle case of GlobalAlloc( ??,0) */ if (!pintern->Pointer) /* handle case of GlobalAlloc( ??,0) */
return 0; return 0;
retval=HeapSize(GetProcessHeap(), 0, retval=HeapSize(GetProcessHeap(), 0,
(char *)(pintern->Pointer)-sizeof(HGLOBAL))-4; (char *)(pintern->Pointer) - HGLOBAL_STORAGE );
if (retval == 0xffffffff-4) retval = 0; if (retval != (DWORD)-1) retval -= HGLOBAL_STORAGE;
} }
else else
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment