Changeset 3243 for trunk/src/shell32/shell.cpp
- Timestamp:
- Mar 26, 2000, 6:34:57 PM (25 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/shell32/shell.cpp
r2534 r3243 1 /* $Id: shell.cpp,v 1. 4 2000-01-27 21:50:45 sandervlExp $ */1 /* $Id: shell.cpp,v 1.5 2000-03-26 16:34:43 cbratschi Exp $ */ 2 2 3 3 /* … … 10 10 * 11 11 * 1998 Marcus Meissner 12 * 13 * Corel WINE 20000324 level 12 14 */ 13 15 … … 48 50 #include "imagelist.h" 49 51 #include "shell32_main.h" 52 #include "winversion.h" 50 53 51 54 #include <heapstring.h> … … 90 93 static const char* lpstrMsgShellActivate = "ACTIVATESHELLWINDOW"; 91 94 92 static HWND16 SHELL_hWnd = 0; 93 static HHOOK SHELL_hHook = 0; 94 static UINT16 uMsgWndCreated = 0; 95 static UINT16 uMsgWndDestroyed = 0; 96 static UINT16 uMsgShellActivate = 0; 97 HINSTANCE16 SHELL_hInstance = 0; 95 static HWND SHELL_hWnd = 0; 96 static HHOOK SHELL_hHook = 0; 97 static UINT uMsgWndCreated = 0; 98 static UINT uMsgWndDestroyed = 0; 99 static UINT uMsgShellActivate = 0; 98 100 HINSTANCE SHELL_hInstance32; 99 101 static int SHELL_Attach = 0; … … 377 379 &commandlen ) == ERROR_SUCCESS ) 378 380 { 381 LPSTR tmp; 382 char param[256]; 383 LONG paramlen = 256; 384 385 /* Get the parameters needed by the application 386 from the associated ddeexec key */ 387 tmp = strstr(filetype,"command"); 388 tmp[0] = '\0'; 389 strcat(filetype,"ddeexec"); 390 391 if(RegQueryValueA( HKEY_CLASSES_ROOT, filetype, param,¶mlen ) == ERROR_SUCCESS) 392 { 393 strcat(command," "); 394 strcat(command,param); 395 commandlen += paramlen; 396 } 397 379 398 /* Is there a replace() function anywhere? */ 380 399 command[commandlen]='\0'; … … 472 491 473 492 //@@@PH no NE support 474 #if 0493 #if 1 475 494 if( size > sizeof(NE_TYPEINFO) ) 476 495 { pTypeInfo = (BYTE*)HeapAlloc( GetProcessHeap(), 0, size); … … 490 509 return 0; /* failed */ 491 510 } 492 511 #if 0 //CB: DirectResAlloc16 not yet ported 512 /************************************************************************* 513 * SHELL_LoadResource 514 */ 515 static HGLOBAL SHELL_LoadResource(HINSTANCE hInst, HFILE hFile, NE_NAMEINFO* pNInfo, WORD sizeShift) 516 { BYTE* ptr; 517 HGLOBAL handle = DirectResAlloc( hInst, 0x10, (DWORD)pNInfo->length << sizeShift); 518 519 TRACE("\n"); 520 521 if( (ptr = (BYTE*)GlobalLock( handle )) ) 522 { _llseek( hFile, (DWORD)pNInfo->offset << sizeShift, SEEK_SET); 523 _lread( hFile, (char*)ptr, pNInfo->length << sizeShift); 524 return handle; 525 } 526 return 0; 527 } 528 529 /************************************************************************* 530 * ICO_LoadIcon 531 */ 532 static HGLOBAL ICO_LoadIcon(HINSTANCE hInst, HFILE hFile, LPicoICONDIRENTRY lpiIDE) 533 { BYTE* ptr; 534 HGLOBAL handle = DirectResAlloc( hInst, 0x10, lpiIDE->dwBytesInRes); 535 TRACE("\n"); 536 if( (ptr = (BYTE*)GlobalLock( handle )) ) 537 { _llseek( hFile, lpiIDE->dwImageOffset, SEEK_SET); 538 _lread( hFile, (char*)ptr, lpiIDE->dwBytesInRes); 539 return handle; 540 } 541 return 0; 542 } 543 544 /************************************************************************* 545 * ICO_GetIconDirectory 546 * 547 * Read .ico file and build phony ICONDIR struct for GetIconID 548 */ 549 static HGLOBAL ICO_GetIconDirectory(HINSTANCE hInst, HFILE hFile, LPicoICONDIR* lplpiID ) 550 { WORD id[3]; /* idReserved, idType, idCount */ 551 LPicoICONDIR lpiID; 552 int i; 553 554 TRACE("\n"); 555 _llseek( hFile, 0, SEEK_SET ); 556 if( _lread(hFile,(char*)id,sizeof(id)) != sizeof(id) ) return 0; 557 558 /* check .ICO header 559 * 560 * - see http://www.microsoft.com/win32dev/ui/icons.htm 561 */ 562 563 if( id[0] || id[1] != 1 || !id[2] ) return 0; 564 565 i = id[2]*sizeof(icoICONDIRENTRY) ; 566 567 lpiID = (LPicoICONDIR)HeapAlloc( GetProcessHeap(), 0, i + sizeof(id)); 568 569 if( _lread(hFile,(char*)lpiID->idEntries,i) == i ) 570 { HGLOBAL handle = DirectResAlloc( hInst, 0x10, 571 id[2]*sizeof(CURSORICONDIRENTRY) + sizeof(id) ); 572 if( handle ) 573 { CURSORICONDIR* lpID = (CURSORICONDIR*)GlobalLock( handle ); 574 lpID->idReserved = lpiID->idReserved = id[0]; 575 lpID->idType = lpiID->idType = id[1]; 576 lpID->idCount = lpiID->idCount = id[2]; 577 for( i=0; i < lpiID->idCount; i++ ) 578 { memcpy((void*)(lpID->idEntries + i), 579 (void*)(lpiID->idEntries + i), sizeof(CURSORICONDIRENTRY) - 2); 580 lpID->idEntries[i].wResId = i; 581 } 582 *lplpiID = lpiID; 583 return handle; 584 } 585 } 586 /* fail */ 587 588 HeapFree( GetProcessHeap(), 0, lpiID); 589 return 0; 590 } 591 #endif 592 /************************************************************************* 593 * InternalExtractIcon [SHELL.39] 594 * 595 * This abortion is called directly by Progman 596 */ 597 HGLOBAL WINAPI InternalExtractIcon(HINSTANCE hInstance, 598 LPCSTR lpszExeFileName, UINT nIconIndex, WORD n ) 599 { HGLOBAL hRet = 0; 600 HGLOBAL* RetPtr = NULL; 601 LPBYTE pData; 602 OFSTRUCT ofs; 603 DWORD sig; 604 HFILE hFile = OpenFile( lpszExeFileName, &ofs, OF_READ ); 605 UINT iconDirCount = 0,iconCount = 0; 606 LPBYTE peimage; 607 HANDLE fmapping; 608 609 TRACE("(%04x,file %s,start %d,extract %d\n", 610 hInstance, lpszExeFileName, nIconIndex, n); 611 612 if( hFile == HFILE_ERROR || !n ) 613 return 0; 614 615 hRet = GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT, sizeof(HICON16)*n); 616 RetPtr = (HGLOBAL*)GlobalLock(hRet); 617 618 *RetPtr = (n == 0xFFFF)? 0: 1; /* error return values */ 619 620 sig = SHELL_GetResourceTable(hFile,&pData); 621 #if 0 //CB: some functions not (yet) supported 622 if( sig==IMAGE_OS2_SIGNATURE || sig==1 ) /* .ICO file */ 623 { HICON hIcon = 0; 624 NE_TYPEINFO* pTInfo = (NE_TYPEINFO*)(pData + 2); 625 NE_NAMEINFO* pIconStorage = NULL; 626 NE_NAMEINFO* pIconDir = NULL; 627 LPicoICONDIR lpiID = NULL; 628 629 if( pData == (BYTE*)-1 ) 630 { hIcon = ICO_GetIconDirectory(hInstance, hFile, &lpiID); /* check for .ICO file */ 631 if( hIcon ) 632 { iconDirCount = 1; iconCount = lpiID->idCount; 633 } 634 } 635 else while( pTInfo->type_id && !(pIconStorage && pIconDir) ) 636 { if( pTInfo->type_id == NE_RSCTYPE_GROUP_ICON ) /* find icon directory and icon repository */ 637 { iconDirCount = pTInfo->count; 638 pIconDir = ((NE_NAMEINFO*)(pTInfo + 1)); 639 TRACE("\tfound directory - %i icon families\n", iconDirCount); 640 } 641 if( pTInfo->type_id == NE_RSCTYPE_ICON ) 642 { iconCount = pTInfo->count; 643 pIconStorage = ((NE_NAMEINFO*)(pTInfo + 1)); 644 TRACE("\ttotal icons - %i\n", iconCount); 645 } 646 pTInfo = (NE_TYPEINFO *)((char*)(pTInfo+1)+pTInfo->count*sizeof(NE_NAMEINFO)); 647 } 648 649 /* load resources and create icons */ 650 651 if( (pIconStorage && pIconDir) || lpiID ) 652 { if( nIconIndex == (UINT16)-1 ) 653 { RetPtr[0] = iconDirCount; 654 } 655 else if( nIconIndex < iconDirCount ) 656 { UINT i, icon; 657 if( n > iconDirCount - nIconIndex ) 658 n = iconDirCount - nIconIndex; 659 660 for( i = nIconIndex; i < nIconIndex + n; i++ ) 661 { /* .ICO files have only one icon directory */ 662 663 if( lpiID == NULL ) 664 hIcon = SHELL_LoadResource( hInstance, hFile, pIconDir + i, *(WORD*)pData ); 665 RetPtr[i-nIconIndex] = GetIconID( hIcon, 3 ); 666 GlobalFree(hIcon); 667 } 668 669 for( icon = nIconIndex; icon < nIconIndex + n; icon++ ) 670 { hIcon = 0; 671 if( lpiID ) 672 { hIcon = ICO_LoadIcon( hInstance, hFile, lpiID->idEntries + RetPtr[icon-nIconIndex]); 673 } 674 else 675 { for( i = 0; i < iconCount; i++ ) 676 { if( pIconStorage[i].id == (RetPtr[icon-nIconIndex] | 0x8000) ) 677 { hIcon = SHELL_LoadResource( hInstance, hFile, pIconStorage + i,*(WORD*)pData ); 678 } 679 } 680 } 681 if( hIcon ) 682 { RetPtr[icon-nIconIndex] = LoadIconHandler16( hIcon, TRUE ); 683 FarSetOwner16( RetPtr[icon-nIconIndex], GetExePtr(hInstance) ); 684 } 685 else 686 { RetPtr[icon-nIconIndex] = 0; 687 } 688 } 689 } 690 } 691 if( lpiID ) 692 HeapFree( GetProcessHeap(), 0, lpiID); 693 else 694 HeapFree( GetProcessHeap(), 0, pData); 695 } 696 #endif 697 if( sig == IMAGE_NT_SIGNATURE) 698 { LPBYTE idata,igdata; 699 PIMAGE_DOS_HEADER dheader; 700 PIMAGE_NT_HEADERS pe_header; 701 PIMAGE_SECTION_HEADER pe_sections; 702 PIMAGE_RESOURCE_DIRECTORY rootresdir,iconresdir,icongroupresdir; 703 PIMAGE_RESOURCE_DATA_ENTRY idataent,igdataent; 704 int i,j; 705 PIMAGE_RESOURCE_DIRECTORY_ENTRY xresent; 706 CURSORICONDIR **cids; 707 708 fmapping = CreateFileMappingA(hFile,NULL,PAGE_READONLY|SEC_COMMIT,0,0,NULL); 709 if (fmapping == 0) 710 { /* FIXME, INVALID_HANDLE_VALUE? */ 711 WARN("failed to create filemap.\n"); 712 hRet = 0; 713 goto end_2; /* failure */ 714 } 715 peimage = (BYTE*)MapViewOfFile(fmapping,FILE_MAP_READ,0,0,0); 716 if (!peimage) 717 { WARN("failed to mmap filemap.\n"); 718 hRet = 0; 719 goto end_2; /* failure */ 720 } 721 dheader = (PIMAGE_DOS_HEADER)peimage; 722 723 /* it is a pe header, SHELL_GetResourceTable checked that */ 724 pe_header = (PIMAGE_NT_HEADERS)(peimage+dheader->e_lfanew); 725 726 /* probably makes problems with short PE headers... but I haven't seen 727 * one yet... 728 */ 729 pe_sections = (PIMAGE_SECTION_HEADER)(((char*)pe_header)+sizeof(*pe_header)); 730 rootresdir = NULL; 731 732 for (i=0;i<pe_header->FileHeader.NumberOfSections;i++) 733 { if (pe_sections[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA) 734 continue; 735 /* FIXME: doesn't work when the resources are not in a seperate section */ 736 if (pe_sections[i].VirtualAddress == pe_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress) 737 { rootresdir = (PIMAGE_RESOURCE_DIRECTORY)((char*)peimage+pe_sections[i].PointerToRawData); 738 break; 739 } 740 } 741 742 if (!rootresdir) 743 { WARN("haven't found section for resource directory.\n"); 744 goto end_4; /* failure */ 745 } 746 747 icongroupresdir = GetResDirEntryW(rootresdir,RT_GROUP_ICONW, (DWORD)rootresdir,FALSE); 748 749 if (!icongroupresdir) 750 { WARN("No Icongroupresourcedirectory!\n"); 751 goto end_4; /* failure */ 752 } 753 754 iconDirCount = icongroupresdir->NumberOfNamedEntries+icongroupresdir->NumberOfIdEntries; 755 756 if( nIconIndex == (UINT)-1 ) 757 { RetPtr[0] = iconDirCount; 758 goto end_3; /* success */ 759 } 760 761 if (nIconIndex >= iconDirCount) 762 { WARN("nIconIndex %d is larger than iconDirCount %d\n",nIconIndex,iconDirCount); 763 GlobalFree(hRet); 764 goto end_4; /* failure */ 765 } 766 767 cids = (CURSORICONDIR**)HeapAlloc(GetProcessHeap(),0,n*sizeof(CURSORICONDIR*)); 768 769 /* caller just wanted the number of entries */ 770 xresent = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(icongroupresdir+1); 771 772 /* assure we don't get too much ... */ 773 if( n > iconDirCount - nIconIndex ) 774 { n = iconDirCount - nIconIndex; 775 } 776 777 /* starting from specified index ... */ 778 xresent = xresent+nIconIndex; 779 780 for (i=0;i<n;i++,xresent++) 781 { CURSORICONDIR *cid; 782 PIMAGE_RESOURCE_DIRECTORY resdir; 783 784 /* go down this resource entry, name */ 785 resdir = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)rootresdir+(xresent->u2.s.OffsetToDirectory)); 786 787 /* default language (0) */ 788 resdir = GetResDirEntryW(resdir,(LPWSTR)0,(DWORD)rootresdir,TRUE); 789 igdataent = (PIMAGE_RESOURCE_DATA_ENTRY)resdir; 790 791 /* lookup address in mapped image for virtual address */ 792 igdata = NULL; 793 794 for (j=0;j<pe_header->FileHeader.NumberOfSections;j++) 795 { if (igdataent->OffsetToData < pe_sections[j].VirtualAddress) 796 continue; 797 if (igdataent->OffsetToData+igdataent->Size > pe_sections[j].VirtualAddress+pe_sections[j].SizeOfRawData) 798 continue; 799 igdata = peimage+(igdataent->OffsetToData-pe_sections[j].VirtualAddress+pe_sections[j].PointerToRawData); 800 } 801 802 if (!igdata) 803 { WARN("no matching real address for icongroup!\n"); 804 goto end_4; /* failure */ 805 } 806 /* found */ 807 cid = (CURSORICONDIR*)igdata; 808 cids[i] = cid; 809 RetPtr[i] = LookupIconIdFromDirectoryEx(igdata,TRUE,GetSystemMetrics(SM_CXICON),GetSystemMetrics(SM_CYICON),0); 810 } 811 812 iconresdir=GetResDirEntryW(rootresdir,RT_ICONW,(DWORD)rootresdir,FALSE); 813 814 if (!iconresdir) 815 { WARN("No Iconresourcedirectory!\n"); 816 goto end_4; /* failure */ 817 } 818 819 for (i=0;i<n;i++) 820 { PIMAGE_RESOURCE_DIRECTORY xresdir; 821 xresdir = GetResDirEntryW(iconresdir,(LPWSTR)(DWORD)RetPtr[i],(DWORD)rootresdir,FALSE); 822 xresdir = GetResDirEntryW(xresdir,(LPWSTR)0,(DWORD)rootresdir,TRUE); 823 idataent = (PIMAGE_RESOURCE_DATA_ENTRY)xresdir; 824 idata = NULL; 825 826 /* map virtual to address in image */ 827 for (j=0;j<pe_header->FileHeader.NumberOfSections;j++) 828 { if (idataent->OffsetToData < pe_sections[j].VirtualAddress) 829 continue; 830 if (idataent->OffsetToData+idataent->Size > pe_sections[j].VirtualAddress+pe_sections[j].SizeOfRawData) 831 continue; 832 idata = peimage+(idataent->OffsetToData-pe_sections[j].VirtualAddress+pe_sections[j].PointerToRawData); 833 } 834 if (!idata) 835 { WARN("no matching real address found for icondata!\n"); 836 RetPtr[i]=0; 837 continue; 838 } 839 RetPtr[i] = CreateIconFromResourceEx(idata,idataent->Size,TRUE,0x00030000,GetSystemMetrics(SM_CXICON),GetSystemMetrics(SM_CYICON),0); 840 } 841 goto end_3; /* sucess */ 842 } 843 goto end_1; /* return array with icon handles */ 844 845 /* cleaning up (try & catch would be nicer) */ 846 end_4: hRet = 0; /* failure */ 847 end_3: UnmapViewOfFile(peimage); /* success */ 848 end_2: CloseHandle(fmapping); 849 end_1: _lclose( hFile); 850 return hRet; 851 } 493 852 494 853 /************************************************************************* … … 510 869 { if( hIcon == 1 ) /* no icons found in given file */ 511 870 { char tempPath[0x104]; 512 UINT 16uRet = FindExecutableA(lpIconPath,NULL,tempPath);871 UINT uRet = FindExecutableA(lpIconPath,NULL,tempPath); 513 872 514 873 if( uRet > 32 && tempPath[0] )
Note:
See TracChangeset
for help on using the changeset viewer.