Cleanup, small fixes, a few new stubs.
diff --git a/misc/shell.c b/misc/shell.c
index 9c927f2..4d63ed5 100644
--- a/misc/shell.c
+++ b/misc/shell.c
@@ -471,53 +471,59 @@
* SHELL_GetResourceTable
*/
static DWORD SHELL_GetResourceTable(HFILE32 hFile,LPBYTE *retptr)
-{
- IMAGE_DOS_HEADER mz_header;
- char magic[4];
- int size;
- TRACE(shell,"\n");
- *retptr = NULL;
- _llseek32( hFile, 0, SEEK_SET );
- if ( (_lread32(hFile,&mz_header,sizeof(mz_header)) != sizeof(mz_header)) ||
- (mz_header.e_magic != IMAGE_DOS_SIGNATURE)
- ) { /* .ICO file ? */
- if (mz_header.e_cblp == 1) { /* ICONHEADER.idType, must be 1 */
+{ IMAGE_DOS_HEADER mz_header;
+ char magic[4];
+ int size;
+
+ TRACE(shell,"\n");
+
+ *retptr = NULL;
+ _llseek32( hFile, 0, SEEK_SET );
+ if ((_lread32(hFile,&mz_header,sizeof(mz_header)) != sizeof(mz_header)) || (mz_header.e_magic != IMAGE_DOS_SIGNATURE))
+ { /* .ICO file ? */
+ if (mz_header.e_cblp == 1)
+ { /* ICONHEADER.idType, must be 1 */
*retptr = (LPBYTE)-1;
return 1;
- }
- else
+ }
+ else
return 0; /* failed */
- }
- _llseek32( hFile, mz_header.e_lfanew, SEEK_SET );
- if (_lread32( hFile, magic, sizeof(magic) ) != sizeof(magic))
- return 0;
- _llseek32( hFile, mz_header.e_lfanew, SEEK_SET);
-
- if (*(DWORD*)magic == IMAGE_NT_SIGNATURE)
- return IMAGE_NT_SIGNATURE;
- if (*(WORD*)magic == IMAGE_OS2_SIGNATURE) {
- IMAGE_OS2_HEADER ne_header;
- LPBYTE pTypeInfo = (LPBYTE)-1;
-
- if (_lread32(hFile,&ne_header,sizeof(ne_header))!=sizeof(ne_header))
- return 0;
-
- if (ne_header.ne_magic != IMAGE_OS2_SIGNATURE) return 0;
- size = ne_header.rname_tab_offset - ne_header.resource_tab_offset;
- if( size > sizeof(NE_TYPEINFO) )
- {
- pTypeInfo = (BYTE*)HeapAlloc( GetProcessHeap(), 0, size);
- if( pTypeInfo ) {
- _llseek32(hFile, mz_header.e_lfanew+ne_header.resource_tab_offset, SEEK_SET);
- if( _lread32( hFile, (char*)pTypeInfo, size) != size ) {
- HeapFree( GetProcessHeap(), 0, pTypeInfo);
- pTypeInfo = NULL;
- }
- }
}
- *retptr = pTypeInfo;
- return IMAGE_OS2_SIGNATURE;
- } else
+ _llseek32( hFile, mz_header.e_lfanew, SEEK_SET );
+
+ if (_lread32( hFile, magic, sizeof(magic) ) != sizeof(magic))
+ return 0;
+
+ _llseek32( hFile, mz_header.e_lfanew, SEEK_SET);
+
+ if (*(DWORD*)magic == IMAGE_NT_SIGNATURE)
+ return IMAGE_NT_SIGNATURE;
+
+ if (*(WORD*)magic == IMAGE_OS2_SIGNATURE)
+ { IMAGE_OS2_HEADER ne_header;
+ LPBYTE pTypeInfo = (LPBYTE)-1;
+
+ if (_lread32(hFile,&ne_header,sizeof(ne_header))!=sizeof(ne_header))
+ return 0;
+
+ if (ne_header.ne_magic != IMAGE_OS2_SIGNATURE)
+ return 0;
+
+ size = ne_header.rname_tab_offset - ne_header.resource_tab_offset;
+
+ if( size > sizeof(NE_TYPEINFO) )
+ { pTypeInfo = (BYTE*)HeapAlloc( GetProcessHeap(), 0, size);
+ if( pTypeInfo )
+ { _llseek32(hFile, mz_header.e_lfanew+ne_header.resource_tab_offset, SEEK_SET);
+ if( _lread32( hFile, (char*)pTypeInfo, size) != size )
+ { HeapFree( GetProcessHeap(), 0, pTypeInfo);
+ pTypeInfo = NULL;
+ }
+ }
+ }
+ *retptr = pTypeInfo;
+ return IMAGE_OS2_SIGNATURE;
+ }
return 0; /* failed */
}
@@ -525,30 +531,32 @@
* SHELL_LoadResource
*/
static HGLOBAL16 SHELL_LoadResource(HINSTANCE16 hInst, HFILE32 hFile, NE_NAMEINFO* pNInfo, WORD sizeShift)
-{ BYTE* ptr;
- HGLOBAL16 handle = DirectResAlloc( hInst, 0x10, (DWORD)pNInfo->length << sizeShift);
- TRACE(shell,"\n");
- if( (ptr = (BYTE*)GlobalLock16( handle )) )
- { _llseek32( hFile, (DWORD)pNInfo->offset << sizeShift, SEEK_SET);
- _lread32( hFile, (char*)ptr, pNInfo->length << sizeShift);
- return handle;
- }
- return 0;
+{ BYTE* ptr;
+ HGLOBAL16 handle = DirectResAlloc( hInst, 0x10, (DWORD)pNInfo->length << sizeShift);
+
+ TRACE(shell,"\n");
+
+ if( (ptr = (BYTE*)GlobalLock16( handle )) )
+ { _llseek32( hFile, (DWORD)pNInfo->offset << sizeShift, SEEK_SET);
+ _lread32( hFile, (char*)ptr, pNInfo->length << sizeShift);
+ return handle;
+ }
+ return 0;
}
/*************************************************************************
* ICO_LoadIcon
*/
static HGLOBAL16 ICO_LoadIcon(HINSTANCE16 hInst, HFILE32 hFile, LPicoICONDIRENTRY lpiIDE)
-{ BYTE* ptr;
- HGLOBAL16 handle = DirectResAlloc( hInst, 0x10, lpiIDE->dwBytesInRes);
- TRACE(shell,"\n");
- if( (ptr = (BYTE*)GlobalLock16( handle )) )
- { _llseek32( hFile, lpiIDE->dwImageOffset, SEEK_SET);
- _lread32( hFile, (char*)ptr, lpiIDE->dwBytesInRes);
- return handle;
- }
- return 0;
+{ BYTE* ptr;
+ HGLOBAL16 handle = DirectResAlloc( hInst, 0x10, lpiIDE->dwBytesInRes);
+ TRACE(shell,"\n");
+ if( (ptr = (BYTE*)GlobalLock16( handle )) )
+ { _llseek32( hFile, lpiIDE->dwImageOffset, SEEK_SET);
+ _lread32( hFile, (char*)ptr, lpiIDE->dwBytesInRes);
+ return handle;
+ }
+ return 0;
}
/*************************************************************************
@@ -605,274 +613,259 @@
* This abortion is called directly by Progman
*/
HGLOBAL16 WINAPI InternalExtractIcon(HINSTANCE16 hInstance,
- LPCSTR lpszExeFileName, UINT16 nIconIndex,
- WORD n )
-{
- HGLOBAL16 hRet = 0;
- HGLOBAL16* RetPtr = NULL;
- LPBYTE pData;
- OFSTRUCT ofs;
- DWORD sig;
- HFILE32 hFile = OpenFile32( lpszExeFileName, &ofs, OF_READ );
- UINT16 iconDirCount = 0,iconCount = 0;
-
- TRACE(shell,"(%04x,file %s,start %d,extract %d\n",
+ LPCSTR lpszExeFileName, UINT16 nIconIndex, WORD n )
+{ HGLOBAL16 hRet = 0;
+ HGLOBAL16* RetPtr = NULL;
+ LPBYTE pData;
+ OFSTRUCT ofs;
+ DWORD sig;
+ HFILE32 hFile = OpenFile32( lpszExeFileName, &ofs, OF_READ );
+ UINT16 iconDirCount = 0,iconCount = 0;
+ LPBYTE peimage;
+ HANDLE32 fmapping;
+
+ TRACE(shell,"(%04x,file %s,start %d,extract %d\n",
hInstance, lpszExeFileName, nIconIndex, n);
- if( hFile == HFILE_ERROR32 || !n )
- return 0;
+ if( hFile == HFILE_ERROR32 || !n )
+ return 0;
- hRet = GlobalAlloc16( GMEM_FIXED | GMEM_ZEROINIT, sizeof(HICON16)*n);
- RetPtr = (HICON16*)GlobalLock16(hRet);
+ hRet = GlobalAlloc16( GMEM_FIXED | GMEM_ZEROINIT, sizeof(HICON16)*n);
+ RetPtr = (HICON16*)GlobalLock16(hRet);
- *RetPtr = (n == 0xFFFF)? 0: 1; /* error return values */
+ *RetPtr = (n == 0xFFFF)? 0: 1; /* error return values */
- sig = SHELL_GetResourceTable(hFile,&pData);
+ sig = SHELL_GetResourceTable(hFile,&pData);
- if((sig == IMAGE_OS2_SIGNATURE)
- || (sig == 1)) /* .ICO file */
- {
- HICON16 hIcon = 0;
- NE_TYPEINFO* pTInfo = (NE_TYPEINFO*)(pData + 2);
- NE_NAMEINFO* pIconStorage = NULL;
- NE_NAMEINFO* pIconDir = NULL;
- LPicoICONDIR lpiID = NULL;
+ if( sig==IMAGE_OS2_SIGNATURE || sig==1 ) /* .ICO file */
+ { HICON16 hIcon = 0;
+ NE_TYPEINFO* pTInfo = (NE_TYPEINFO*)(pData + 2);
+ NE_NAMEINFO* pIconStorage = NULL;
+ NE_NAMEINFO* pIconDir = NULL;
+ LPicoICONDIR lpiID = NULL;
- if( pData == (BYTE*)-1 )
- {
- /* check for .ICO file */
-
- hIcon = ICO_GetIconDirectory(hInstance, hFile, &lpiID);
- if( hIcon ) { iconDirCount = 1; iconCount = lpiID->idCount; }
- }
- else while( pTInfo->type_id && !(pIconStorage && pIconDir) )
- {
- /* find icon directory and icon repository */
-
- if( pTInfo->type_id == NE_RSCTYPE_GROUP_ICON )
- {
- iconDirCount = pTInfo->count;
- pIconDir = ((NE_NAMEINFO*)(pTInfo + 1));
- TRACE(shell,"\tfound directory - %i icon families\n", iconDirCount);
- }
- if( pTInfo->type_id == NE_RSCTYPE_ICON )
- {
- iconCount = pTInfo->count;
- pIconStorage = ((NE_NAMEINFO*)(pTInfo + 1));
- TRACE(shell,"\ttotal icons - %i\n", iconCount);
- }
- pTInfo = (NE_TYPEINFO *)((char*)(pTInfo+1)+pTInfo->count*sizeof(NE_NAMEINFO));
- }
-
- /* load resources and create icons */
-
- if( (pIconStorage && pIconDir) || lpiID )
- {
- if( nIconIndex == (UINT16)-1 ) RetPtr[0] = iconDirCount;
- else if( nIconIndex < iconDirCount )
- {
- UINT16 i, icon;
-
- if( n > iconDirCount - nIconIndex ) n = iconDirCount - nIconIndex;
-
- for( i = nIconIndex; i < nIconIndex + n; i++ )
- {
- /* .ICO files have only one icon directory */
-
- if( lpiID == NULL )
- hIcon = SHELL_LoadResource( hInstance, hFile, pIconDir + i,
- *(WORD*)pData );
- RetPtr[i-nIconIndex] = GetIconID( hIcon, 3 );
- GlobalFree16(hIcon);
- }
-
- for( icon = nIconIndex; icon < nIconIndex + n; icon++ )
- {
- hIcon = 0;
- if( lpiID )
- hIcon = ICO_LoadIcon( hInstance, hFile,
- lpiID->idEntries + RetPtr[icon-nIconIndex]);
- else
- for( i = 0; i < iconCount; i++ )
- if( pIconStorage[i].id == (RetPtr[icon-nIconIndex] | 0x8000) )
- hIcon = SHELL_LoadResource( hInstance, hFile, pIconStorage + i,
- *(WORD*)pData );
- if( hIcon )
- {
- RetPtr[icon-nIconIndex] = LoadIconHandler( hIcon, TRUE );
- FarSetOwner( RetPtr[icon-nIconIndex], GetExePtr(hInstance) );
- }
- else
- RetPtr[icon-nIconIndex] = 0;
- }
- }
- }
- if( lpiID ) HeapFree( GetProcessHeap(), 0, lpiID);
- else HeapFree( GetProcessHeap(), 0, pData);
- }
- if( sig == IMAGE_NT_SIGNATURE)
- {
- LPBYTE peimage,idata,igdata;
- PIMAGE_DOS_HEADER dheader;
- PIMAGE_NT_HEADERS pe_header;
- PIMAGE_SECTION_HEADER pe_sections;
- PIMAGE_RESOURCE_DIRECTORY rootresdir,iconresdir,icongroupresdir;
- PIMAGE_RESOURCE_DATA_ENTRY idataent,igdataent;
- HANDLE32 fmapping;
- int i,j;
- PIMAGE_RESOURCE_DIRECTORY_ENTRY xresent;
- CURSORICONDIR **cids;
-
- fmapping = CreateFileMapping32A(hFile,NULL,PAGE_READONLY|SEC_COMMIT,0,0,NULL);
- if (fmapping == 0) { /* FIXME, INVALID_HANDLE_VALUE? */
- WARN(shell,"failed to create filemap.\n");
- _lclose32( hFile);
- return 0;
- }
- peimage = MapViewOfFile(fmapping,FILE_MAP_READ,0,0,0);
- if (!peimage) {
- WARN(shell,"failed to mmap filemap.\n");
- CloseHandle(fmapping);
- _lclose32( hFile);
- return 0;
- }
- dheader = (PIMAGE_DOS_HEADER)peimage;
- /* it is a pe header, SHELL_GetResourceTable checked that */
- pe_header = (PIMAGE_NT_HEADERS)(peimage+dheader->e_lfanew);
- /* probably makes problems with short PE headers... but I haven't seen
- * one yet...
- */
- pe_sections = (PIMAGE_SECTION_HEADER)(((char*)pe_header)+sizeof(*pe_header));
- rootresdir = NULL;
- for (i=0;i<pe_header->FileHeader.NumberOfSections;i++) {
- if (pe_sections[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
- continue;
- /* FIXME: doesn't work when the resources are not in a seperate section */
- if (pe_sections[i].VirtualAddress == pe_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress) {
- rootresdir = (PIMAGE_RESOURCE_DIRECTORY)((char*)peimage+pe_sections[i].PointerToRawData);
- break;
- }
- }
-
- if (!rootresdir) {
- WARN(shell,"haven't found section for resource directory.\n");
- UnmapViewOfFile(peimage);
- CloseHandle(fmapping);
- _lclose32( hFile);
- return 0;
- }
- icongroupresdir = GetResDirEntryW(rootresdir,RT_GROUP_ICON32W,
- (DWORD)rootresdir,FALSE);
- if (!icongroupresdir) {
- WARN(shell,"No Icongroupresourcedirectory!\n");
- UnmapViewOfFile(peimage);
- CloseHandle(fmapping);
- _lclose32( hFile);
- return 0;
- }
-
- iconDirCount = icongroupresdir->NumberOfNamedEntries+icongroupresdir->NumberOfIdEntries;
- if( nIconIndex == (UINT16)-1 ) {
- RetPtr[0] = iconDirCount;
- UnmapViewOfFile(peimage);
- CloseHandle(fmapping);
- _lclose32( hFile);
- return hRet;
- }
-
- if (nIconIndex >= iconDirCount) {
- WARN(shell,"nIconIndex %d is larger than iconDirCount %d\n",
- nIconIndex,iconDirCount);
- UnmapViewOfFile(peimage);
- CloseHandle(fmapping);
- _lclose32( hFile);
- GlobalFree16(hRet);
- return 0;
- }
- cids = (CURSORICONDIR**)HeapAlloc(GetProcessHeap(),0,n*sizeof(CURSORICONDIR*));
-
- /* caller just wanted the number of entries */
-
- xresent = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(icongroupresdir+1);
- /* assure we don't get too much ... */
- if( n > iconDirCount - nIconIndex ) n = iconDirCount - nIconIndex;
-
- /* starting from specified index ... */
- xresent = xresent+nIconIndex;
-
- for (i=0;i<n;i++,xresent++) {
- CURSORICONDIR *cid;
- PIMAGE_RESOURCE_DIRECTORY resdir;
-
- /* go down this resource entry, name */
- resdir = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)rootresdir+(xresent->u2.s.OffsetToDirectory));
- /* default language (0) */
- resdir = GetResDirEntryW(resdir,(LPWSTR)0,(DWORD)rootresdir,TRUE);
- igdataent = (PIMAGE_RESOURCE_DATA_ENTRY)resdir;
-
- /* lookup address in mapped image for virtual address */
- igdata = NULL;
- for (j=0;j<pe_header->FileHeader.NumberOfSections;j++) {
- if (igdataent->OffsetToData < pe_sections[j].VirtualAddress)
- continue;
- if (igdataent->OffsetToData+igdataent->Size > pe_sections[j].VirtualAddress+pe_sections[j].SizeOfRawData)
- continue;
- igdata = peimage+(igdataent->OffsetToData-pe_sections[j].VirtualAddress+pe_sections[j].PointerToRawData);
- }
- if (!igdata) {
- WARN(shell,"no matching real address for icongroup!\n");
- UnmapViewOfFile(peimage);
- CloseHandle(fmapping);
- _lclose32( hFile);
- return 0;
- }
- /* found */
- cid = (CURSORICONDIR*)igdata;
- cids[i] = cid;
- RetPtr[i] = LookupIconIdFromDirectoryEx32(igdata,TRUE,SYSMETRICS_CXICON,SYSMETRICS_CYICON,0);
- }
- iconresdir=GetResDirEntryW(rootresdir,RT_ICON32W,
- (DWORD)rootresdir,FALSE);
- if (!iconresdir) {
- WARN(shell,"No Iconresourcedirectory!\n");
- UnmapViewOfFile(peimage);
- CloseHandle(fmapping);
- _lclose32( hFile);
- return 0;
- }
- for (i=0;i<n;i++) {
- PIMAGE_RESOURCE_DIRECTORY xresdir;
-
- xresdir = GetResDirEntryW(iconresdir,(LPWSTR)RetPtr[i],(DWORD)rootresdir,FALSE);
- xresdir = GetResDirEntryW(xresdir,(LPWSTR)0,(DWORD)rootresdir,TRUE);
-
- idataent = (PIMAGE_RESOURCE_DATA_ENTRY)xresdir;
-
- idata = NULL;
- /* map virtual to address in image */
- for (j=0;j<pe_header->FileHeader.NumberOfSections;j++) {
- if (idataent->OffsetToData < pe_sections[j].VirtualAddress)
- continue;
- if (idataent->OffsetToData+idataent->Size > pe_sections[j].VirtualAddress+pe_sections[j].SizeOfRawData)
- continue;
- idata = peimage+(idataent->OffsetToData-pe_sections[j].VirtualAddress+pe_sections[j].PointerToRawData);
+ if( pData == (BYTE*)-1 )
+ { hIcon = ICO_GetIconDirectory(hInstance, hFile, &lpiID); /* check for .ICO file */
+ if( hIcon )
+ { iconDirCount = 1; iconCount = lpiID->idCount;
}
- if (!idata) {
- WARN(shell,"no matching real address found for icondata!\n");
- RetPtr[i]=0;
+ }
+ else while( pTInfo->type_id && !(pIconStorage && pIconDir) )
+ { if( pTInfo->type_id == NE_RSCTYPE_GROUP_ICON ) /* find icon directory and icon repository */
+ { iconDirCount = pTInfo->count;
+ pIconDir = ((NE_NAMEINFO*)(pTInfo + 1));
+ TRACE(shell,"\tfound directory - %i icon families\n", iconDirCount);
+ }
+ if( pTInfo->type_id == NE_RSCTYPE_ICON )
+ { iconCount = pTInfo->count;
+ pIconStorage = ((NE_NAMEINFO*)(pTInfo + 1));
+ TRACE(shell,"\ttotal icons - %i\n", iconCount);
+ }
+ pTInfo = (NE_TYPEINFO *)((char*)(pTInfo+1)+pTInfo->count*sizeof(NE_NAMEINFO));
+ }
+
+ /* load resources and create icons */
+
+ if( (pIconStorage && pIconDir) || lpiID )
+ { if( nIconIndex == (UINT16)-1 )
+ { RetPtr[0] = iconDirCount;
+ }
+ else if( nIconIndex < iconDirCount )
+ { UINT16 i, icon;
+ if( n > iconDirCount - nIconIndex )
+ n = iconDirCount - nIconIndex;
+
+ for( i = nIconIndex; i < nIconIndex + n; i++ )
+ { /* .ICO files have only one icon directory */
+
+ if( lpiID == NULL )
+ hIcon = SHELL_LoadResource( hInstance, hFile, pIconDir + i, *(WORD*)pData );
+ RetPtr[i-nIconIndex] = GetIconID( hIcon, 3 );
+ GlobalFree16(hIcon);
+ }
+
+ for( icon = nIconIndex; icon < nIconIndex + n; icon++ )
+ { hIcon = 0;
+ if( lpiID )
+ { hIcon = ICO_LoadIcon( hInstance, hFile, lpiID->idEntries + RetPtr[icon-nIconIndex]);
+ }
+ else
+ { for( i = 0; i < iconCount; i++ )
+ { if( pIconStorage[i].id == (RetPtr[icon-nIconIndex] | 0x8000) )
+ { hIcon = SHELL_LoadResource( hInstance, hFile, pIconStorage + i,*(WORD*)pData );
+ }
+ }
+ }
+ if( hIcon )
+ { RetPtr[icon-nIconIndex] = LoadIconHandler( hIcon, TRUE );
+ FarSetOwner( RetPtr[icon-nIconIndex], GetExePtr(hInstance) );
+ }
+ else
+ { RetPtr[icon-nIconIndex] = 0;
+ }
+ }
+ }
+ }
+ if( lpiID )
+ HeapFree( GetProcessHeap(), 0, lpiID);
+ else
+ HeapFree( GetProcessHeap(), 0, pData);
+ }
+
+ if( sig == IMAGE_NT_SIGNATURE)
+ { LPBYTE idata,igdata;
+ PIMAGE_DOS_HEADER dheader;
+ PIMAGE_NT_HEADERS pe_header;
+ PIMAGE_SECTION_HEADER pe_sections;
+ PIMAGE_RESOURCE_DIRECTORY rootresdir,iconresdir,icongroupresdir;
+ PIMAGE_RESOURCE_DATA_ENTRY idataent,igdataent;
+ int i,j;
+ PIMAGE_RESOURCE_DIRECTORY_ENTRY xresent;
+ CURSORICONDIR **cids;
+
+ fmapping = CreateFileMapping32A(hFile,NULL,PAGE_READONLY|SEC_COMMIT,0,0,NULL);
+ if (fmapping == 0)
+ { /* FIXME, INVALID_HANDLE_VALUE? */
+ WARN(shell,"failed to create filemap.\n");
+ hRet = 0;
+ goto end_2; /* failure */
+ }
+ peimage = MapViewOfFile(fmapping,FILE_MAP_READ,0,0,0);
+ if (!peimage)
+ { WARN(shell,"failed to mmap filemap.\n");
+ hRet = 0;
+ goto end_2; /* failure */
+ }
+ dheader = (PIMAGE_DOS_HEADER)peimage;
+
+ /* it is a pe header, SHELL_GetResourceTable checked that */
+ pe_header = (PIMAGE_NT_HEADERS)(peimage+dheader->e_lfanew);
+
+ /* probably makes problems with short PE headers... but I haven't seen
+ * one yet...
+ */
+ pe_sections = (PIMAGE_SECTION_HEADER)(((char*)pe_header)+sizeof(*pe_header));
+ rootresdir = NULL;
+
+ for (i=0;i<pe_header->FileHeader.NumberOfSections;i++)
+ { if (pe_sections[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
+ continue;
+ /* FIXME: doesn't work when the resources are not in a seperate section */
+ if (pe_sections[i].VirtualAddress == pe_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress)
+ { rootresdir = (PIMAGE_RESOURCE_DIRECTORY)((char*)peimage+pe_sections[i].PointerToRawData);
+ break;
+ }
+ }
+
+ if (!rootresdir)
+ { WARN(shell,"haven't found section for resource directory.\n");
+ goto end_4; /* failure */
+ }
+
+ icongroupresdir = GetResDirEntryW(rootresdir,RT_GROUP_ICON32W, (DWORD)rootresdir,FALSE);
+
+ if (!icongroupresdir)
+ { WARN(shell,"No Icongroupresourcedirectory!\n");
+ goto end_4; /* failure */
+ }
+
+ iconDirCount = icongroupresdir->NumberOfNamedEntries+icongroupresdir->NumberOfIdEntries;
+
+ if( nIconIndex == (UINT16)-1 )
+ { RetPtr[0] = iconDirCount;
+ goto end_3; /* success */
+ }
+
+ if (nIconIndex >= iconDirCount)
+ { WARN(shell,"nIconIndex %d is larger than iconDirCount %d\n",nIconIndex,iconDirCount);
+ GlobalFree16(hRet);
+ goto end_4; /* failure */
+ }
+
+ cids = (CURSORICONDIR**)HeapAlloc(GetProcessHeap(),0,n*sizeof(CURSORICONDIR*));
+
+ /* caller just wanted the number of entries */
+ xresent = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(icongroupresdir+1);
+
+ /* assure we don't get too much ... */
+ if( n > iconDirCount - nIconIndex )
+ { n = iconDirCount - nIconIndex;
+ }
+
+ /* starting from specified index ... */
+ xresent = xresent+nIconIndex;
+
+ for (i=0;i<n;i++,xresent++)
+ { CURSORICONDIR *cid;
+ PIMAGE_RESOURCE_DIRECTORY resdir;
+
+ /* go down this resource entry, name */
+ resdir = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)rootresdir+(xresent->u2.s.OffsetToDirectory));
+
+ /* default language (0) */
+ resdir = GetResDirEntryW(resdir,(LPWSTR)0,(DWORD)rootresdir,TRUE);
+ igdataent = (PIMAGE_RESOURCE_DATA_ENTRY)resdir;
+
+ /* lookup address in mapped image for virtual address */
+ igdata = NULL;
+
+ for (j=0;j<pe_header->FileHeader.NumberOfSections;j++)
+ { if (igdataent->OffsetToData < pe_sections[j].VirtualAddress)
+ continue;
+ if (igdataent->OffsetToData+igdataent->Size > pe_sections[j].VirtualAddress+pe_sections[j].SizeOfRawData)
continue;
+ igdata = peimage+(igdataent->OffsetToData-pe_sections[j].VirtualAddress+pe_sections[j].PointerToRawData);
+ }
+
+ if (!igdata)
+ { WARN(shell,"no matching real address for icongroup!\n");
+ goto end_4; /* failure */
+ }
+ /* found */
+ cid = (CURSORICONDIR*)igdata;
+ cids[i] = cid;
+ RetPtr[i] = LookupIconIdFromDirectoryEx32(igdata,TRUE,SYSMETRICS_CXICON,SYSMETRICS_CYICON,0);
+ }
+
+ iconresdir=GetResDirEntryW(rootresdir,RT_ICON32W,(DWORD)rootresdir,FALSE);
+
+ if (!iconresdir)
+ { WARN(shell,"No Iconresourcedirectory!\n");
+ goto end_4; /* failure */
+ }
+
+ for (i=0;i<n;i++)
+ { PIMAGE_RESOURCE_DIRECTORY xresdir;
+ xresdir = GetResDirEntryW(iconresdir,(LPWSTR)(DWORD)RetPtr[i],(DWORD)rootresdir,FALSE);
+ xresdir = GetResDirEntryW(xresdir,(LPWSTR)0,(DWORD)rootresdir,TRUE);
+ idataent = (PIMAGE_RESOURCE_DATA_ENTRY)xresdir;
+ idata = NULL;
+
+ /* map virtual to address in image */
+ for (j=0;j<pe_header->FileHeader.NumberOfSections;j++)
+ { if (idataent->OffsetToData < pe_sections[j].VirtualAddress)
+ continue;
+ if (idataent->OffsetToData+idataent->Size > pe_sections[j].VirtualAddress+pe_sections[j].SizeOfRawData)
+ continue;
+ idata = peimage+(idataent->OffsetToData-pe_sections[j].VirtualAddress+pe_sections[j].PointerToRawData);
+ }
+ if (!idata)
+ { WARN(shell,"no matching real address found for icondata!\n");
+ RetPtr[i]=0;
+ continue;
}
RetPtr[i] = CreateIconFromResourceEx32(idata,idataent->Size,TRUE,0x00030000,SYSMETRICS_CXICON,SYSMETRICS_CYICON,0);
+ }
+ goto end_3; /* sucess */
}
- UnmapViewOfFile(peimage);
- CloseHandle(fmapping);
- _lclose32( hFile);
- return hRet;
- }
- _lclose32( hFile );
- /* return array with icon handles */
- return hRet;
+ goto end_1; /* return array with icon handles */
+/* cleaning up (try & catch would be nicer) */
+end_4: hRet = 0; /* failure */
+end_3: UnmapViewOfFile(peimage); /* success */
+end_2: CloseHandle(fmapping);
+end_1: _lclose32( hFile);
+ return hRet;
}
/*************************************************************************
@@ -892,43 +885,41 @@
* Return icon for given file (either from file itself or from associated
* executable) and patch parameters if needed.
*/
-HICON32 WINAPI ExtractAssociatedIcon32A(HINSTANCE32 hInst,LPSTR lpIconPath,
- LPWORD lpiIcon)
-{ TRACE(shell,"\n");
+HICON32 WINAPI ExtractAssociatedIcon32A(HINSTANCE32 hInst, LPSTR lpIconPath, LPWORD lpiIcon)
+{ TRACE(shell,"\n");
return ExtractAssociatedIcon16(hInst,lpIconPath,lpiIcon);
}
-HICON16 WINAPI ExtractAssociatedIcon16(HINSTANCE16 hInst,LPSTR lpIconPath,
- LPWORD lpiIcon)
-{ HICON16 hIcon;
+HICON16 WINAPI ExtractAssociatedIcon16(HINSTANCE16 hInst, LPSTR lpIconPath, LPWORD lpiIcon)
+{ HICON16 hIcon;
- TRACE(shell,"\n");
+ TRACE(shell,"\n");
- hIcon = ExtractIcon16(hInst, lpIconPath, *lpiIcon);
+ hIcon = ExtractIcon16(hInst, lpIconPath, *lpiIcon);
- if( hIcon < 2 )
- { if( hIcon == 1 ) /* no icons found in given file */
- { char tempPath[0x80];
+ if( hIcon < 2 )
+ { if( hIcon == 1 ) /* no icons found in given file */
+ { char tempPath[0x80];
UINT16 uRet = FindExecutable16(lpIconPath,NULL,tempPath);
if( uRet > 32 && tempPath[0] )
- { strcpy(lpIconPath,tempPath);
- hIcon = ExtractIcon16(hInst, lpIconPath, *lpiIcon);
- if( hIcon > 2 )
- return hIcon;
+ { strcpy(lpIconPath,tempPath);
+ hIcon = ExtractIcon16(hInst, lpIconPath, *lpiIcon);
+ if( hIcon > 2 )
+ return hIcon;
}
else hIcon = 0;
- }
+ }
- if( hIcon == 1 )
+ if( hIcon == 1 )
*lpiIcon = 2; /* MSDOS icon - we found .exe but no icons in it */
- else
+ else
*lpiIcon = 6; /* generic icon - found nothing */
- GetModuleFileName16(hInst, lpIconPath, 0x80);
- hIcon = LoadIcon16( hInst, MAKEINTRESOURCE16(*lpiIcon));
- }
- return hIcon;
+ GetModuleFileName16(hInst, lpIconPath, 0x80);
+ hIcon = LoadIcon16( hInst, MAKEINTRESOURCE16(*lpiIcon));
+ }
+ return hIcon;
}
/*************************************************************************