Changeset 6176 for trunk/src/kernel32/heap.cpp
- Timestamp:
- Jul 5, 2001, 8:10:08 PM (24 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kernel32/heap.cpp
r6092 r6176 1 /* $Id: heap.cpp,v 1.2 7 2001-06-24 15:45:36sandervl Exp $ */1 /* $Id: heap.cpp,v 1.28 2001-07-05 18:10:08 sandervl Exp $ */ 2 2 3 3 /* 4 4 * Win32 heap API functions for OS/2 5 5 * 6 * Copyright 1999 Sander van Leeuwen 6 * Copyright 1999-2001 Sander van Leeuwen 7 * 8 * Global memory functions ported from Wine 9 * Copyright 1995 Alexandre Julliard 7 10 * 8 11 * Project Odin Software License can be found in LICENSE.TXT … … 114 117 //****************************************************************************** 115 118 //****************************************************************************** 116 ODINFUNCTIONNODBG3(DWORD, HeapSize, HANDLE, hHeap, DWORD, arg2, PVOID, arg3)119 ODINFUNCTIONNODBG3(DWORD, HeapSize, HANDLE, hHeap, DWORD, arg2, PVOID, lpMem) 117 120 { 118 121 OS2Heap *curheap = OS2Heap::find(hHeap); 119 122 120 dprintf2(("HeapSize %X %x ", hHeap, arg2));123 dprintf2(("HeapSize %X %x %x", hHeap, arg2, lpMem)); 121 124 if(curheap == NULL) 122 125 return(0); 123 return curheap->Size(arg2, arg3);126 return curheap->Size(arg2, lpMem); 124 127 } 125 128 //****************************************************************************** … … 182 185 return(processheap); 183 186 } 184 //****************************************************************************** 185 //****************************************************************************** 186 HLOCAL WIN32API LocalAlloc(UINT fuFlags, DWORD cbBytes) 187 { 188 HLOCAL lmem; 189 DWORD dwFlags = 0; 190 191 if(processheap == NULL) { 192 if(GetProcessHeap() == NULL) 193 return(NULL); 194 } 195 if(fuFlags & LMEM_ZEROINIT) 196 dwFlags = HEAP_ZERO_MEMORY; 197 198 lmem = (HLOCAL)OS2ProcessHeap->Alloc(dwFlags, cbBytes, fuFlags); 199 200 dprintf(("KERNEL32: LocalAlloc flags %X, size %d returned %X\n", dwFlags, cbBytes, lmem)); 201 202 return(lmem); 203 } 204 //****************************************************************************** 205 //****************************************************************************** 206 HLOCAL WIN32API LocalDiscard(HLOCAL hMem) 207 { 208 dprintf(("KERNEL32: LocalDiscard NOT IMPLEMENTED\n")); 209 210 // return O32_LocalDiscard(arg1); 211 return(hMem); //TODO: Possible memory leak 212 } 213 //****************************************************************************** 214 //****************************************************************************** 215 UINT WIN32API LocalFlags(HLOCAL hMem) 216 { 217 dprintf(("KERNEL32: LocalFlags %X\n", hMem)); 218 219 return OS2ProcessHeap->GetFlags((LPVOID)hMem); 220 } 221 //****************************************************************************** 222 //****************************************************************************** 223 HLOCAL WIN32API LocalFree(HLOCAL hMem) 224 { 225 dprintf(("KERNEL32: LocalFree %X\n", hMem)); 226 227 if(OS2ProcessHeap->GetLockCnt((LPVOID)hMem) != 0) { 228 dprintf(("LocalFree, lock count != 0\n")); 229 return(hMem); //TODO: SetLastError 230 } 231 if(OS2ProcessHeap->Free(0, (LPVOID)hMem) == FALSE) { 232 return(hMem); //TODO: SetLastError 233 } 234 return NULL; //success 235 } 236 //****************************************************************************** 237 //****************************************************************************** 238 HLOCAL WIN32API LocalHandle(PCVOID lpMem) 239 { 240 dprintf(("KERNEL32: LocalHandle\n")); 241 242 return (HLOCAL)lpMem; 243 } 244 //****************************************************************************** 245 //****************************************************************************** 246 BOOL WIN32API LocalUnlock(HLOCAL hMem) 247 { 248 dprintf(("KERNEL32: LocalUnlock %X\n", hMem)); 249 250 return OS2ProcessHeap->Unlock((LPVOID)hMem); 251 } 252 //****************************************************************************** 253 //TODO: cbBytes==0 && fuFlags & LMEM_MOVEABLE not handled!! 254 //****************************************************************************** 255 HLOCAL WIN32API LocalReAlloc(HLOCAL hMem, DWORD cbBytes, UINT fuFlags) 256 { 257 HLOCAL hLocalNew; 258 LPVOID lpMem; 259 260 dprintf(("KERNEL32: LocalReAlloc %X %d %X\n", hMem, cbBytes, fuFlags)); 261 262 //SvL: 8-8-'98: Notepad bugfix (assumes address is identical when new size < old size) 263 if(OS2ProcessHeap->Size(0, (LPVOID)hMem) > cbBytes) 264 return hMem; 265 266 hLocalNew = LocalAlloc(fuFlags, cbBytes); 267 if (hLocalNew != 0) 268 { 269 lpMem = LocalLock(hLocalNew); 270 271 if (lpMem != NULL) /* copy memory if successful */ 272 memcpy(lpMem, 273 (LPVOID)hMem, 274 min(cbBytes, OS2ProcessHeap->Size(0, (LPVOID)hMem)) 275 ); 276 277 LocalUnlock(hLocalNew); 278 OS2ProcessHeap->Free(0, (LPVOID)hMem); 279 } 280 return(hLocalNew); 281 } 282 //****************************************************************************** 283 //****************************************************************************** 284 UINT WIN32API LocalSize(HLOCAL hMem) 285 { 286 dprintf(("KERNEL32: LocalSize %X\n", hMem)); 287 288 return OS2ProcessHeap->Size(0, (PVOID)hMem); 289 } 290 //****************************************************************************** 291 //****************************************************************************** 292 PVOID WIN32API LocalLock(HLOCAL hMem) 293 { 294 dprintf(("KERNEL32: LocalLock %X\n", hMem)); 295 296 if(OS2ProcessHeap->Lock((LPVOID)hMem) == FALSE) { 297 return NULL; 187 #if 1 188 /* 189 * Win32 Global heap functions (GlobalXXX). 190 * These functions included in Win32 for compatibility with 16 bit Windows 191 * Especially the moveable blocks and handles are oldish. 192 * But the ability to directly allocate memory with GPTR and LPTR is widely 193 * used. 194 * 195 * The handle stuff looks horrible, but it's implemented almost like Win95 196 * does it. 197 * 198 */ 199 200 #define MAGIC_GLOBAL_USED 0x5342 201 #define GLOBAL_LOCK_MAX 0xFF 202 #define HANDLE_TO_INTERN(h) ((PGLOBAL32_INTERN)(((char *)(h))-2)) 203 #define INTERN_TO_HANDLE(i) ((HGLOBAL) &((i)->Pointer)) 204 #define POINTER_TO_HANDLE(p) (*(((HGLOBAL *)(p))-1)) 205 #define ISHANDLE(h) (((DWORD)(h)&2)!=0) 206 #define ISPOINTER(h) (((DWORD)(h)&2)==0) 207 208 #pragma pack(1) 209 210 typedef struct __GLOBAL32_INTERN 211 { 212 WORD Magic; 213 LPVOID Pointer; 214 BYTE Flags; 215 BYTE LockCount; 216 } GLOBAL32_INTERN, *PGLOBAL32_INTERN; 217 218 #pragma pack() 219 220 /*********************************************************************** 221 * GlobalAlloc (KERNEL32.@) 222 * RETURNS 223 * Handle: Success 224 * NULL: Failure 225 */ 226 HGLOBAL WINAPI GlobalAlloc( 227 UINT flags, /* [in] Object allocation attributes */ 228 DWORD size /* [in] Number of bytes to allocate */ 229 ) { 230 PGLOBAL32_INTERN pintern; 231 DWORD hpflags; 232 LPVOID palloc; 233 234 if(flags&GMEM_ZEROINIT) 235 hpflags=HEAP_ZERO_MEMORY; 236 else 237 hpflags=0; 238 239 if((flags & GMEM_MOVEABLE)==0) /* POINTER */ 240 { 241 palloc=HeapAlloc(GetProcessHeap(), hpflags, size); 242 dprintf(("KERNEL32: GlobalAlloc %x %d returned %x", flags, size, palloc)); 243 return (HGLOBAL) palloc; 244 } 245 else /* HANDLE */ 246 { 247 /* HeapLock(heap); */ 248 249 pintern=(PGLOBAL32_INTERN)HeapAlloc(GetProcessHeap(), 0, sizeof(GLOBAL32_INTERN)); 250 if (!pintern) return 0; 251 if(size) 252 { 253 if (!(palloc=HeapAlloc(GetProcessHeap(), hpflags, size+sizeof(HGLOBAL)))) { 254 HeapFree(GetProcessHeap(), 0, pintern); 255 return 0; 256 } 257 *(HGLOBAL *)palloc=INTERN_TO_HANDLE(pintern); 258 pintern->Pointer=(char *) palloc+sizeof(HGLOBAL); 259 } 260 else 261 pintern->Pointer=NULL; 262 pintern->Magic=MAGIC_GLOBAL_USED; 263 pintern->Flags=flags>>8; 264 pintern->LockCount=0; 265 266 /* HeapUnlock(heap); */ 267 268 dprintf(("KERNEL32: GlobalAlloc %x %d returned %x", flags, size, INTERN_TO_HANDLE(pintern))); 269 return INTERN_TO_HANDLE(pintern); 270 } 271 } 272 /*********************************************************************** 273 * GlobalLock (KERNEL32.@) 274 * RETURNS 275 * Pointer to first byte of block 276 * NULL: Failure 277 */ 278 LPVOID WINAPI GlobalLock( 279 HGLOBAL hmem /* [in] Handle of global memory object */ 280 ) { 281 PGLOBAL32_INTERN pintern; 282 LPVOID palloc; 283 284 285 if(ISPOINTER(hmem)) { 286 dprintf(("KERNEL32: GlobalLock %x returned %x", hmem, hmem)); 287 return (LPVOID) hmem; 288 } 289 290 /* HeapLock(GetProcessHeap()); */ 291 292 pintern=HANDLE_TO_INTERN(hmem); 293 if(pintern->Magic==MAGIC_GLOBAL_USED) 294 { 295 if(pintern->LockCount<GLOBAL_LOCK_MAX) 296 pintern->LockCount++; 297 palloc=pintern->Pointer; 298 } 299 else 300 { 301 dprintf(("ERROR: GlobalLock invalid handle %x", hmem)); 302 palloc=(LPVOID) NULL; 303 SetLastError(ERROR_INVALID_HANDLE); 304 } 305 /* HeapUnlock(GetProcessHeap()); */; 306 307 dprintf(("KERNEL32: GlobalLock %x returned %x", hmem, palloc)); 308 return palloc; 309 } 310 311 312 /*********************************************************************** 313 * GlobalUnlock (KERNEL32.@) 314 * RETURNS 315 * TRUE: Object is still locked 316 * FALSE: Object is unlocked 317 */ 318 BOOL WINAPI GlobalUnlock( 319 HGLOBAL hmem /* [in] Handle of global memory object */ 320 ) { 321 PGLOBAL32_INTERN pintern; 322 BOOL locked; 323 324 dprintf(("KERNEL32: GlobalUnlock %x", hmem)); 325 326 if(ISPOINTER(hmem)) 327 return FALSE; 328 329 /* HeapLock(GetProcessHeap()); */ 330 pintern=HANDLE_TO_INTERN(hmem); 331 332 if(pintern->Magic==MAGIC_GLOBAL_USED) 333 { 334 if((pintern->LockCount<GLOBAL_LOCK_MAX)&&(pintern->LockCount>0)) 335 pintern->LockCount--; 336 337 locked = (pintern->LockCount != 0); 338 if (!locked) SetLastError(NO_ERROR); 339 } 340 else 341 { 342 dprintf(("ERROR: GlobalUnlock invalid handle %x", hmem)); 343 SetLastError(ERROR_INVALID_HANDLE); 344 locked=FALSE; 345 } 346 /* HeapUnlock(GetProcessHeap()); */ 347 return locked; 348 } 349 350 351 /*********************************************************************** 352 * GlobalHandle (KERNEL32.@) 353 * Returns the handle associated with the specified pointer. 354 * 355 * RETURNS 356 * Handle: Success 357 * NULL: Failure 358 */ 359 HGLOBAL WINAPI GlobalHandle( 360 LPCVOID pmem /* [in] Pointer to global memory block */ 361 ) { 362 HGLOBAL handle; 363 PGLOBAL32_INTERN maybe_intern; 364 LPCVOID test; 365 366 dprintf(("KERNEL32: GlobalHandle %x", pmem)); 367 368 if (!pmem) 369 { 370 SetLastError( ERROR_INVALID_PARAMETER ); 371 return 0; 298 372 } 299 return (PVOID)hMem; 300 } 301 //****************************************************************************** 302 303 //****************************************************************************** 304 //* this function is here for completeness, some stupid software requires it. 305 UINT WIN32API LocalShrink(HLOCAL hMem, 306 UINT cbNewSize) 307 { 308 dprintf(("KERNEL32: LocalShrink %X, %08xh - stub (cbNewSize)\n", 309 hMem, 310 cbNewSize)); 311 312 return cbNewSize; 313 } 314 //****************************************************************************** 315 316 //****************************************************************************** 317 //* this function is here for completeness, mIRC/32 requires it. 318 UINT WIN32API LocalCompact(UINT cbNewSize) 319 { 320 dprintf(("KERNEL32: LocalCompact %08xh - stub (cbNewSize)\n", 321 cbNewSize)); 322 323 return cbNewSize; 324 } 373 374 #ifdef __WIN32OS2__ 375 handle = 0; 376 377 /* note that if pmem is a pointer to a a block allocated by */ 378 /* GlobalAlloc with GMEM_MOVEABLE then magic test in HeapValidate */ 379 /* will fail. */ 380 if (ISPOINTER(pmem)) { 381 if (HeapValidate( GetProcessHeap(), 0, pmem )) { 382 handle = (HGLOBAL)pmem; /* valid fixed block */ 383 return handle; 384 } 385 handle = POINTER_TO_HANDLE(pmem); 386 } else 387 handle = (HGLOBAL)pmem; 388 389 /* Now test handle either passed in or retrieved from pointer */ 390 maybe_intern = HANDLE_TO_INTERN( handle ); 391 if(IsBadReadPtr(maybe_intern, sizeof(GLOBAL32_INTERN))) { 392 SetLastError( ERROR_INVALID_HANDLE ); 393 return 0; 394 } 395 396 if (maybe_intern->Magic == MAGIC_GLOBAL_USED) { 397 test = maybe_intern->Pointer; 398 if (HeapValidate( GetProcessHeap(), 0, ((HGLOBAL *)test)-1 ) && /* obj(-handle) valid arena? */ 399 HeapValidate( GetProcessHeap(), 0, maybe_intern )) /* intern valid arena? */ 400 { 401 return handle; 402 } 403 } 404 handle = 0; 405 SetLastError( ERROR_INVALID_HANDLE ); 406 #else 407 __TRY 408 { 409 handle = 0; 410 411 /* note that if pmem is a pointer to a a block allocated by */ 412 /* GlobalAlloc with GMEM_MOVEABLE then magic test in HeapValidate */ 413 /* will fail. */ 414 if (ISPOINTER(pmem)) { 415 if (HeapValidate( GetProcessHeap(), 0, pmem )) { 416 handle = (HGLOBAL)pmem; /* valid fixed block */ 417 break; 418 } 419 handle = POINTER_TO_HANDLE(pmem); 420 } else 421 handle = (HGLOBAL)pmem; 422 423 /* Now test handle either passed in or retrieved from pointer */ 424 maybe_intern = HANDLE_TO_INTERN( handle ); 425 if (maybe_intern->Magic == MAGIC_GLOBAL_USED) { 426 test = maybe_intern->Pointer; 427 if (HeapValidate( GetProcessHeap(), 0, ((HGLOBAL *)test)-1 ) && /* obj(-handle) valid arena? */ 428 HeapValidate( GetProcessHeap(), 0, maybe_intern )) /* intern valid arena? */ 429 break; /* valid moveable block */ 430 } 431 handle = 0; 432 SetLastError( ERROR_INVALID_HANDLE ); 433 } 434 __EXCEPT(page_fault) 435 { 436 SetLastError( ERROR_INVALID_HANDLE ); 437 return 0; 438 } 439 __ENDTRY 440 #endif 441 return handle; 442 } 443 444 445 /*********************************************************************** 446 * GlobalReAlloc (KERNEL32.@) 447 * RETURNS 448 * Handle: Success 449 * NULL: Failure 450 */ 451 HGLOBAL WINAPI GlobalReAlloc( 452 HGLOBAL hmem, /* [in] Handle of global memory object */ 453 DWORD size, /* [in] New size of block */ 454 UINT flags /* [in] How to reallocate object */ 455 ) { 456 LPVOID palloc; 457 HGLOBAL hnew; 458 PGLOBAL32_INTERN pintern; 459 DWORD heap_flags = (flags & GMEM_ZEROINIT) ? HEAP_ZERO_MEMORY : 0; 460 461 hnew = 0; 462 /* HeapLock(heap); */ 463 if(flags & GMEM_MODIFY) /* modify flags */ 464 { 465 if( ISPOINTER(hmem) && (flags & GMEM_MOVEABLE)) 466 { 467 /* make a fixed block moveable 468 * actually only NT is able to do this. But it's soo simple 469 */ 470 if (hmem == 0) 471 { 472 dprintf(("ERROR: GlobalReAlloc32 with null handle!\n")); 473 SetLastError( ERROR_NOACCESS ); 474 return 0; 475 } 476 size=HeapSize(GetProcessHeap(), 0, (LPVOID) hmem); 477 hnew=GlobalAlloc( flags, size); 478 palloc=GlobalLock(hnew); 479 memcpy(palloc, (LPVOID) hmem, size); 480 GlobalUnlock(hnew); 481 GlobalFree(hmem); 482 } 483 else if( ISPOINTER(hmem) &&(flags & GMEM_DISCARDABLE)) 484 { 485 /* change the flags to make our block "discardable" */ 486 pintern=HANDLE_TO_INTERN(hmem); 487 pintern->Flags = pintern->Flags | (GMEM_DISCARDABLE >> 8); 488 hnew=hmem; 489 } 490 else 491 { 492 SetLastError(ERROR_INVALID_PARAMETER); 493 hnew = 0; 494 } 495 } 496 else 497 { 498 if(ISPOINTER(hmem)) 499 { 500 /* reallocate fixed memory */ 501 hnew=(HGLOBAL)HeapReAlloc(GetProcessHeap(), heap_flags, (LPVOID) hmem, size); 502 } 503 else 504 { 505 /* reallocate a moveable block */ 506 pintern=HANDLE_TO_INTERN(hmem); 507 508 #if 0 509 /* Apparently Windows doesn't care whether the handle is locked at this point */ 510 /* See also the same comment in GlobalFree() */ 511 if(pintern->LockCount>1) { 512 ERR("handle 0x%08lx is still locked, cannot realloc!\n",(DWORD)hmem); 513 SetLastError(ERROR_INVALID_HANDLE); 514 } else 515 #endif 516 if(size!=0) 517 { 518 hnew=hmem; 519 if(pintern->Pointer) 520 { 521 if((palloc = HeapReAlloc(GetProcessHeap(), heap_flags, 522 (char *) pintern->Pointer-sizeof(HGLOBAL), 523 size+sizeof(HGLOBAL))) == NULL) 524 return 0; /* Block still valid */ 525 pintern->Pointer=(char *) palloc+sizeof(HGLOBAL); 526 } 527 else 528 { 529 if((palloc=HeapAlloc(GetProcessHeap(), heap_flags, size+sizeof(HGLOBAL))) 530 == NULL) 531 return 0; 532 *(HGLOBAL *)palloc=hmem; 533 pintern->Pointer=(char *) palloc+sizeof(HGLOBAL); 534 } 535 } 536 else 537 { 538 if(pintern->Pointer) 539 { 540 HeapFree(GetProcessHeap(), 0, (char *) pintern->Pointer-sizeof(HGLOBAL)); 541 pintern->Pointer=NULL; 542 } 543 } 544 } 545 } 546 /* HeapUnlock(heap); */ 547 return hnew; 548 } 549 550 551 /*********************************************************************** 552 * GlobalFree (KERNEL32.@) 553 * RETURNS 554 * NULL: Success 555 * Handle: Failure 556 */ 557 HGLOBAL WINAPI GlobalFree( 558 HGLOBAL hmem /* [in] Handle of global memory object */ 559 ) { 560 PGLOBAL32_INTERN pintern; 561 HGLOBAL hreturned = 0; 562 563 dprintf(("KERNEL32: GlobalFree %x", hmem)); 564 565 if(ISPOINTER(hmem)) /* POINTER */ 566 { 567 if(!HeapFree(GetProcessHeap(), 0, (LPVOID) hmem)) hmem = 0; 568 } 569 else /* HANDLE */ 570 { 571 /* HeapLock(heap); */ 572 pintern=HANDLE_TO_INTERN(hmem); 573 574 if(pintern->Magic==MAGIC_GLOBAL_USED) 575 { 576 577 /* WIN98 does not make this test. That is you can free a */ 578 /* block you have not unlocked. Go figure!! */ 579 /* if(pintern->LockCount!=0) */ 580 /* SetLastError(ERROR_INVALID_HANDLE); */ 581 582 if(pintern->Pointer) 583 if(!HeapFree(GetProcessHeap(), 0, (char *)(pintern->Pointer)-sizeof(HGLOBAL))) 584 hreturned=hmem; 585 if(!HeapFree(GetProcessHeap(), 0, pintern)) 586 hreturned=hmem; 587 } 588 /* HeapUnlock(heap); */ 589 } 590 return hreturned; 591 } 592 593 594 /*********************************************************************** 595 * GlobalSize (KERNEL32.@) 596 * RETURNS 597 * Size in bytes of the global memory object 598 * 0: Failure 599 */ 600 DWORD WINAPI GlobalSize( 601 HGLOBAL hmem /* [in] Handle of global memory object */ 602 ) { 603 DWORD retval; 604 PGLOBAL32_INTERN pintern; 605 606 dprintf(("KERNEL32: GlobalSize %x", hmem)); 607 608 if(ISPOINTER(hmem)) 609 { 610 retval=HeapSize(GetProcessHeap(), 0, (LPVOID) hmem); 611 } 612 else 613 { 614 /* HeapLock(heap); */ 615 pintern=HANDLE_TO_INTERN(hmem); 616 617 if(pintern->Magic==MAGIC_GLOBAL_USED) 618 { 619 if (!pintern->Pointer) /* handle case of GlobalAlloc( ??,0) */ 620 return 0; 621 retval=HeapSize(GetProcessHeap(), 0, 622 (char *)(pintern->Pointer)-sizeof(HGLOBAL))-4; 623 if (retval == 0xffffffff-4) retval = 0; 624 } 625 else 626 { 627 dprintf(("ERROR: GlobalSize invalid handle %x", hmem)); 628 retval=0; 629 } 630 /* HeapUnlock(heap); */ 631 } 632 /* HeapSize returns 0xffffffff on failure */ 633 if (retval == 0xffffffff) retval = 0; 634 return retval; 635 } 636 637 638 /*********************************************************************** 639 * GlobalWire (KERNEL32.@) 640 */ 641 LPVOID WINAPI GlobalWire(HGLOBAL hmem) 642 { 643 return GlobalLock( hmem ); 644 } 645 646 647 /*********************************************************************** 648 * GlobalUnWire (KERNEL32.@) 649 */ 650 BOOL WINAPI GlobalUnWire(HGLOBAL hmem) 651 { 652 return GlobalUnlock( hmem); 653 } 654 655 656 /*********************************************************************** 657 * GlobalFix (KERNEL32.@) 658 */ 659 VOID WINAPI GlobalFix(HGLOBAL hmem) 660 { 661 GlobalLock( hmem ); 662 } 663 664 665 /*********************************************************************** 666 * GlobalUnfix (KERNEL32.@) 667 */ 668 VOID WINAPI GlobalUnfix(HGLOBAL hmem) 669 { 670 GlobalUnlock( hmem); 671 } 672 673 674 /*********************************************************************** 675 * GlobalFlags (KERNEL32.@) 676 * Returns information about the specified global memory object 677 * 678 * NOTES 679 * Should this return GMEM_INVALID_HANDLE on invalid handle? 680 * 681 * RETURNS 682 * Value specifying allocation flags and lock count 683 * GMEM_INVALID_HANDLE: Failure 684 */ 685 UINT WINAPI GlobalFlags( 686 HGLOBAL hmem /* [in] Handle to global memory object */ 687 ) { 688 DWORD retval; 689 PGLOBAL32_INTERN pintern; 690 691 dprintf(("KERNEL32: GlobalFlags %x", hmem)); 692 693 if(ISPOINTER(hmem)) 694 { 695 retval=0; 696 } 697 else 698 { 699 /* HeapLock(GetProcessHeap()); */ 700 pintern=HANDLE_TO_INTERN(hmem); 701 if(pintern->Magic==MAGIC_GLOBAL_USED) 702 { 703 retval=pintern->LockCount + (pintern->Flags<<8); 704 if(pintern->Pointer==0) 705 retval|= GMEM_DISCARDED; 706 } 707 else 708 { 709 dprintf(("ERROR: GlobalFlags invalid handle %x", hmem)); 710 retval=0; 711 } 712 /* HeapUnlock(GetProcessHeap()); */ 713 } 714 return retval; 715 } 716 717 718 /*********************************************************************** 719 * GlobalCompact (KERNEL32.@) 720 */ 721 DWORD WINAPI GlobalCompact( DWORD minfree ) 722 { 723 dprintf(("KERNEL32: GlobalCompact %d OBSOLETE", minfree)); 724 725 return 0; /* GlobalCompact does nothing in Win32 */ 726 } 727 #else 325 728 //****************************************************************************** 326 729 #ifdef DEBUG … … 354 757 //****************************************************************************** 355 758 //****************************************************************************** 356 HGLOBAL WIN32API GlobalHandle( LPCVOID arg1)357 { 358 dprintf(("KERNEL32: OS2GlobalHandle\n"));359 360 return O32_GlobalHandle((LPVOID) arg1);361 } 362 //****************************************************************************** 363 //****************************************************************************** 364 UINT WIN32API GlobalFlags(HGLOBAL arg1)365 { 366 dprintf(("KERNEL32: OS2GlobalFlags\n"));367 368 return O32_GlobalFlags( arg1);759 HGLOBAL WIN32API GlobalHandle( LPCVOID lpMem) 760 { 761 dprintf(("KERNEL32: GlobalHandle %x", lpMem)); 762 763 return O32_GlobalHandle((LPVOID)lpMem); 764 } 765 //****************************************************************************** 766 //****************************************************************************** 767 UINT WIN32API GlobalFlags(HGLOBAL hMem) 768 { 769 dprintf(("KERNEL32: GlobalFlags %x", hMem)); 770 771 return O32_GlobalFlags(hMem); 369 772 } 370 773 //****************************************************************************** … … 378 781 //****************************************************************************** 379 782 //****************************************************************************** 380 PVOID WIN32API GlobalLock(HGLOBAL arg1)783 PVOID WIN32API GlobalLock(HGLOBAL hMem) 381 784 { 382 785 PVOID ret; 383 786 384 ret = O32_GlobalLock( arg1);385 dprintf(("KERNEL32: GlobalLock %x returned %x", arg1, ret));787 ret = O32_GlobalLock(hMem); 788 dprintf(("KERNEL32: GlobalLock %x returned %x", hMem, ret)); 386 789 return ret; 387 790 } … … 422 825 return GlobalLock( hmem ); 423 826 } 424 425 426 827 /*********************************************************************** 427 828 * GlobalUnWire … … 438 839 //****************************************************************************** 439 840 //****************************************************************************** 841 HGLOBAL WIN32API GlobalDiscard(HGLOBAL hGlobal) 842 { 843 dprintf(("KERNEL32: GlobalDiscard %x", hGlobal)); 844 845 return O32_GlobalDiscard(hGlobal); 846 } 847 /*********************************************************************** 848 * GlobalFix (KERNEL32.@) 849 */ 850 VOID WINAPI GlobalFix(HGLOBAL hmem) 851 { 852 GlobalLock( hmem ); 853 } 854 /*********************************************************************** 855 * GlobalUnfix (KERNEL32.@) 856 */ 857 VOID WINAPI GlobalUnfix(HGLOBAL hmem) 858 { 859 GlobalUnlock( hmem); 860 } 861 #endif 862 //****************************************************************************** 863 //****************************************************************************** 864 HLOCAL WIN32API LocalAlloc(UINT fuFlags, DWORD cbBytes) 865 { 866 HLOCAL hLocal; 867 868 // Check flags 869 if(fuFlags & (~(LMEM_MOVEABLE | LMEM_DISCARDABLE | LMEM_NOCOMPACT | 870 LMEM_NODISCARD | LMEM_ZEROINIT))) 871 { 872 dprintf(("LocalAlloc %x %x: INVALID flags!", fuFlags, cbBytes)); 873 SetLastError(ERROR_INVALID_PARAMETER); 874 return 0; 875 } 876 // Note: local & global flags are the same (the ones used here), so no need for conversion 877 hLocal = GlobalAlloc(fuFlags, cbBytes); 878 dprintf(("KERNEL32: LocalAlloc flags %X, size %d returned %X", fuFlags, cbBytes, hLocal)); 879 return hLocal; 880 } 881 //****************************************************************************** 882 //****************************************************************************** 883 UINT WIN32API LocalFlags(HLOCAL hMem) 884 { 885 UINT ret, retG; 886 dprintf(("KERNEL32: LocalFlags %X\n", hMem)); 887 888 retG = GlobalFlags(hMem); 889 890 if(retG == GMEM_INVALID_HANDLE) 891 { 892 return LMEM_INVALID_HANDLE; 893 } 894 // Low byte holds lock count. 895 // Hi byte of low word contains some flags. 896 ret = retG & 0xff; // Keep lock count. 897 if (retG & GMEM_DISCARDABLE) ret |= LMEM_DISCARDABLE; 898 if (retG & GMEM_DISCARDED) ret |= LMEM_DISCARDED; 899 900 return ret; 901 } 902 //****************************************************************************** 903 //****************************************************************************** 904 HLOCAL WIN32API LocalFree(HLOCAL hMem) 905 { 906 dprintf(("KERNEL32: LocalFree %X", hMem)); 907 908 return GlobalFree(hMem); 909 } 910 //****************************************************************************** 911 //****************************************************************************** 912 HLOCAL WIN32API LocalHandle(PCVOID lpMem) 913 { 914 dprintf(("KERNEL32: LocalHandle %x", lpMem)); 915 916 return GlobalHandle(lpMem); 917 } 918 //****************************************************************************** 919 //****************************************************************************** 920 BOOL WIN32API LocalUnlock(HLOCAL hMem) 921 { 922 dprintf(("KERNEL32: LocalUnlock %X", hMem)); 923 924 return GlobalUnlock(hMem); 925 } 926 //****************************************************************************** 927 //TODO: cbBytes==0 && fuFlags & LMEM_MOVEABLE not handled!! 928 //****************************************************************************** 929 HLOCAL WIN32API LocalReAlloc(HLOCAL hMem, DWORD cbBytes, UINT fuFlags) 930 { 931 HLOCAL hLocalNew; 932 LPVOID lpMem; 933 DWORD cbOldSize; 934 935 dprintf(("KERNEL32: LocalReAlloc %X %d %X\n", hMem, cbBytes, fuFlags)); 936 937 // Check flags 938 if(fuFlags & (~(LMEM_MOVEABLE | LMEM_DISCARDABLE | LMEM_NOCOMPACT | 939 LMEM_MODIFY | LMEM_ZEROINIT))) 940 { 941 dprintf(("LocalAlloc %x %x: INVALID flags!", fuFlags, cbBytes)); 942 SetLastError(ERROR_INVALID_PARAMETER); 943 return 0; 944 } 945 946 //SvL: 8-8-'98: Notepad bugfix (assumes address is identical when new size < old size) 947 cbOldSize = LocalSize(hMem); 948 if(cbOldSize > cbBytes) 949 return hMem; 950 951 hLocalNew = LocalAlloc(fuFlags, cbBytes); 952 if(hLocalNew != 0) 953 { 954 lpMem = LocalLock(hLocalNew); 955 956 if (lpMem != NULL) /* copy memory if successful */ 957 memcpy(lpMem, (LPVOID)hMem, min(cbBytes, cbOldSize)); 958 959 LocalUnlock(hLocalNew); 960 LocalFree(hMem); 961 } 962 return(hLocalNew); 963 } 964 //****************************************************************************** 965 //****************************************************************************** 966 UINT WIN32API LocalSize(HLOCAL hMem) 967 { 968 dprintf(("KERNEL32: LocalSize %X", hMem)); 969 970 return GlobalSize(hMem); 971 } 972 //****************************************************************************** 973 //****************************************************************************** 974 PVOID WIN32API LocalLock(HLOCAL hMem) 975 { 976 dprintf(("KERNEL32: LocalLock %X\n", hMem)); 977 978 return GlobalLock(hMem); 979 } 980 //****************************************************************************** 981 //* this function is here for completeness, some stupid software requires it. 982 //****************************************************************************** 983 UINT WIN32API LocalShrink(HLOCAL hMem, UINT cbNewSize) 984 { 985 dprintf(("KERNEL32: LocalShrink %X, %08xh - OBSOLETE", hMem, cbNewSize)); 986 987 return cbNewSize; 988 } 989 //****************************************************************************** 990 //* this function is here for completeness, mIRC/32 requires it. 991 //****************************************************************************** 992 UINT WIN32API LocalCompact(UINT cbNewSize) 993 { 994 dprintf(("KERNEL32: LocalCompact %08xh - OBSOLETE", cbNewSize)); 995 996 return cbNewSize; 997 } 998 //****************************************************************************** 999 //******************************************************************************
Note:
See TracChangeset
for help on using the changeset viewer.