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;
 }
 
 /*************************************************************************
