Release 971130

Sat Nov 29 12:35:26 1997  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [if1632/builtin.c]
	Build a complete PE header for builtin Win32 modules.

	* [loader/pe_image.c] [loader/module.c]
	HMODULE32 now points to the loading address of the module. There
	is no longer a separate PE_MODULE structure.

Fri Nov 28 11:21:47 1997  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>

	* [ole/*][configure.in][Makefile.in][include/interfaces.h]
	  [if1632/olesvr32.spec][if1632/olecli32.spec]
	New directory, moved OLE stuff there.
	new .spec files for olecli32,olesvr32, some stubs added.

	* [misc/shell.c]
	Added support for extracting icons from PE dlls.

	* [misc/shellord.c][if1632/shell32.spec]
	Added a huge heap of ordinal only exported shell functions
	(will work only in Win95).

	* [loader/task.c]
	Hack to make MakeProcInstance16 work in all cases (mplayer.exe).

	* [win32/string32.c][include/string32.h]
	Obsolete, removed.

	* [windows/keyboard.c]
	Added *RegisterHotkey.

	* [objects/font.c][objects/text.c]
	Added GetFontLanguageInfo, GetTextCharsetInfo.

Wed Nov 26 18:10:40 1997  Uwe Bonnes  <bon@elektron.ikp.physik.tu-darmstadt.de>

	* [misc/network.c]
	In WNetGetConnection16 return the Drive label and not the DOS-Cwd.
	Makes Wordview 6 start on a network connected machine.

	* [controls/status.c]
	Catch a Null pointer in SW_SetText.

	* [files/dos_fs.c]
 	Add NT5 functions GetLongPathName32.

	* [files/file.c]
	Make GetTempFileName16 accept drive 0 (Current Drive) too.
	Handle more errors and be more verbose in FILE_SetDosError, fix
	an error in DeleteFile32W

	* [memory/virtual.c]
	Implement FlushViewOfFile.

	* [misc/crtdll]
	Implement _rotl and splitpath and add a stub for 
	_abnormal_termination.

	* [misc/printdrv.c]
	Stub for EnumPrinters32A.

	* [win32/newfns]
	Add Stub for QueryPerformanceFrequency, change return value
	for QueryPerformanceCounter.
 	Add stub for DeviceIoControl.

Tue Nov 25 15:55:01 1997 Martin Boehme <boehme@informatik.mu-luebeck.de>

	* [controls/combo.c] [controls/edit.c] [windows/defwnd.c]
	  [windows/winpos.c] [windows/win.c]
	Removed WIN_NO_REDRAW flag.

Tue Nov 25 13:20:35 1997  Douglas Ridgway <ridgway@taiga.v-wave.com>

	* [graphics/x11drv/bitblt.c]
	Fixed memory leak in BITBLT_GetDstArea.

Sun Nov 23 14:05:23 1997  Andreas Mohr <100.30936@germany.net>

	* [files/directory.c]
	Export windows system directory to environment.

	* [if1632/Makefile.in] [if1632/builtin.c] [if1632/w32skrnl.spec]
	  [if1632/win32s16.spec] [misc/w32scomb.c] [misc/w32skrnl.c]
	Added Win32s DLLs W32SKRNL and WIN32S16.

	* [if1632/kernel32.spec] [loader/module.c]
	Added misc functions for Win32s.

	* [if1632/kernel.spec] [loader/task.c]
	Added DefineHandleTable().

	* [scheduler/process.c]
	Fixed SetEnvironmentVariable32A() to avoid heap corruption.

Sat Nov 22 14:11:42 1997  Kristian Nielsen  <kristian.nielsen@risoe.dk>

	* [windows/painting.c]
	Fix leak in BeginPaint16() for CS_PARENTDC windows where the
	update region was not properly released.

Thu Nov 20 03:55:29 1997  Gordon Chaffee <chaffee@CS.Berkeley.EDU>

	* [loader/pe_image.c]
	Implemented forwarded DLL functions.

	* [objects/dib.c]
	Added support for 16- and 32-bit mode DIBs.
	Support negative bitmap heights.

	* [win32/process.c]
	Added stub for CreateProcess32W.

	* [win32/security.c] [include/ntdll.h]
	Added stubs for LookupAccountSid32A/W.

	* [scheduler/process.c]
	Use the size specified in the PE header for the process heap.

Mon Nov 17 00:53:35 1997  Len White <phreak@cgocable.net>

	* [msdos/int3d.c]
	New file. Stubs for int3d.

Sun Nov 16 12:30:00 PST 1997  Jason Schonberg  <schon@mti.sgi.com>

	* [include/aspi.h]
	Changed comment style from C++ to C.
diff --git a/misc/shell.c b/misc/shell.c
index a824ab0..66a94ce 100644
--- a/misc/shell.c
+++ b/misc/shell.c
@@ -1,6 +1,7 @@
 /*
  * 				Shell Library Functions
  */
+#include <assert.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
@@ -17,8 +18,12 @@
 #include "win.h"
 #include "graphics.h"
 #include "cursoricon.h"
+#include "interfaces.h"
+#include "sysmetrics.h"
+#include "shlobj.h"
 #include "stddebug.h"
 #include "debug.h"
+#include "debugstr.h"
 #include "winreg.h"
 
 static const char * const SHELL_People[] =
@@ -29,6 +34,7 @@
     "Peter Bajusz",
     "Georg Beyerle",
     "Ross Biro",
+    "Martin Boehme",
     "Uwe Bonnes",
     "Erik Bos",
     "Fons Botman",
@@ -36,12 +42,14 @@
     "Andrew Bulhak",
     "John Burton",
     "Niels de Carpentier",
+    "Gordon Chaffee",
     "Jimen Ching",
     "David A. Cuthbert",
     "Huw D. M. Davies",
     "Roman Dolejsi",
     "Frans van Dorsselaer",
     "Chris Faherty",
+    "Carsten Fallesen",
     "Paul Falstad",
     "David Faure",
     "Claus Fischer",
@@ -89,6 +97,7 @@
     "Andreas Mohr",
     "Philippe De Muyter",
     "Itai Nahshon",
+    "Kristian Nielsen",
     "Henrik Olsen",
     "Michael Patra",
     "Dimitrie O. Paun",
@@ -132,12 +141,14 @@
     "Eric Warnke",
     "Manfred Weichel",
     "Morten Welinder",
+    "Len White",
     "Lawson Whitney",
     "Jan Willamowius",
     "Carl Williams",
     "Karl Guenter Wuensch",
     "Eric Youngdale",
     "James Youngman",
+    "Nikita V. Youshchenko",
     "Mikolaj Zalewski",
     "John Zero",
     NULL
@@ -746,48 +757,52 @@
 
 /*************************************************************************
  *				SHELL_GetResourceTable
- *
- * FIXME: Implement GetPEResourceTable in w32sys.c and call it here.
  */
-static BYTE* SHELL_GetResourceTable(HFILE32 hFile)
+static DWORD SHELL_GetResourceTable(HFILE32 hFile,LPBYTE *retptr)
 {
-  BYTE*              pTypeInfo = NULL;
   IMAGE_DOS_HEADER	mz_header;
-  IMAGE_OS2_HEADER	ne_header;
-  int		     size;
+  char			magic[4];
+  int			size;
   
+  *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)) return (BYTE*)-1;
+  if (	(_lread32(hFile,&mz_header,sizeof(mz_header)) != sizeof(mz_header)) ||
+  	(mz_header.e_magic != IMAGE_DOS_SIGNATURE)
+  )
+  	return 0;
 
   _llseek32( hFile, mz_header.e_lfanew, SEEK_SET );
-  if (_lread32( hFile, &ne_header, sizeof(ne_header) ) != sizeof(ne_header))
-      return NULL;
+  if (_lread32( hFile, magic, sizeof(magic) ) != sizeof(magic))
+	return 0;
+  _llseek32( hFile, mz_header.e_lfanew, SEEK_SET);
 
-  if (ne_header.ne_magic == IMAGE_NT_SIGNATURE) 
-     { fprintf(stdnimp,"Win32s FIXME: file %s line %i\n", __FILE__, __LINE__ );
-       return NULL; }
+  if (*(DWORD*)magic  == IMAGE_NT_SIGNATURE)
+	return IMAGE_NT_SIGNATURE;
+  if (*(WORD*)magic == IMAGE_OS2_SIGNATURE) {
+  	IMAGE_OS2_HEADER	ne_header;
+  	LPBYTE			pTypeInfo = NULL;
 
-  if (ne_header.ne_magic != IMAGE_OS2_SIGNATURE) return NULL;
+  	if (_lread32(hFile,&ne_header,sizeof(ne_header))!=sizeof(ne_header))
+		return 0;
 
-  size = ne_header.rname_tab_offset - ne_header.resource_tab_offset;
+	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;
+  } else
+  	*retptr = (LPBYTE)-1;
+  return IMAGE_OS2_SIGNATURE; /* handles .ICO too */
 
-  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;
-          }
-      }
-  }
-  /* no resources */
-
-  return pTypeInfo;
 }
 
 /*************************************************************************
@@ -886,11 +901,13 @@
 {
   HGLOBAL16 	hRet = 0;
   HGLOBAL16*	RetPtr = NULL;
-  BYTE*  	pData;
+  LPBYTE  	pData;
   OFSTRUCT 	ofs;
+  DWORD		sig;
   HFILE32 	hFile = OpenFile32( lpszExeFileName, &ofs, OF_READ );
+  UINT16	iconDirCount = 0,iconCount = 0;
   
-  dprintf_reg(stddeb, "InternalExtractIcon(%04x, file '%s', start from %d, extract %d\n", 
+  dprintf_reg(stddeb,"InternalExtractIcon(%04x,file %s,start %d,extract %d\n", 
 		       hInstance, lpszExeFileName, nIconIndex, n);
 
   if( hFile == HFILE_ERROR32 || !n ) return 0;
@@ -898,13 +915,13 @@
   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 */
 
-  if( (pData = SHELL_GetResourceTable(hFile)) )
+  sig = SHELL_GetResourceTable(hFile,&pData);
+
+  if(sig == IMAGE_OS2_SIGNATURE)
   {
     HICON16	 hIcon = 0;
-    UINT16       iconDirCount = 0;
-    UINT16       iconCount = 0;
     NE_TYPEINFO* pTInfo = (NE_TYPEINFO*)(pData + 2);
     NE_NAMEINFO* pIconStorage = NULL;
     NE_NAMEINFO* pIconDir = NULL;
@@ -980,30 +997,181 @@
     if( lpiID ) HeapFree( GetProcessHeap(), 0, lpiID);
     else HeapFree( GetProcessHeap(), 0, pData);
   } 
- _lclose32( hFile );
- 
-  /* return array with icon handles */
+  if( sig == IMAGE_NT_SIGNATURE)
+  {
+  	LPBYTE			peimage,idata,igdata;
+	LPIMAGE_DOS_HEADER	dheader;
+	LPIMAGE_NT_HEADERS	pe_header;
+	LPIMAGE_SECTION_HEADER	pe_sections;
+	LPIMAGE_RESOURCE_DIRECTORY	rootresdir,iconresdir,icongroupresdir;
+	LPIMAGE_RESOURCE_DATA_ENTRY	idataent,igdataent;
+	HANDLE32		fmapping;
+	int			i,j;
+	LPIMAGE_RESOURCE_DIRECTORY_ENTRY	xresent;
+	CURSORICONDIR		**cids;
+	
+	fmapping = CreateFileMapping32A(hFile,NULL,PAGE_READONLY|SEC_COMMIT,0,0,NULL);
+	if (fmapping == 0) { /* FIXME, INVALID_HANDLE_VALUE? */
+		fprintf(stderr,"InternalExtractIcon:failed to create filemap.\n");
+		_lclose32( hFile);
+		return 0;
+	}
+	peimage = MapViewOfFile(fmapping,FILE_MAP_READ,0,0,0);
+	if (!peimage) {
+		fprintf(stderr,"InternalExtractIcon:failed to mmap filemap.\n");
+		CloseHandle(fmapping);
+		_lclose32( hFile);
+		return 0;
+	}
+	dheader = (LPIMAGE_DOS_HEADER)peimage;
+	/* it is a pe header, SHELL_GetResourceTable checked that */
+	pe_header = (LPIMAGE_NT_HEADERS)(peimage+dheader->e_lfanew);
+	/* probably makes problems with short PE headers... but I haven't seen 
+	 * one yet... 
+	 */
+	pe_sections = (LPIMAGE_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 = (LPIMAGE_RESOURCE_DIRECTORY)((char*)peimage+pe_sections[i].PointerToRawData);
+			break;
+		}
+	}
 
+	if (!rootresdir) {
+		fprintf(stderr,"InternalExtractIcon: haven't found section for resource directory.\n");
+		UnmapViewOfFile(peimage);
+		CloseHandle(fmapping);
+		_lclose32( hFile);
+		return 0;
+	}
+	icongroupresdir = GetResDirEntryW(rootresdir,(LPWSTR)RT_GROUP_ICON,(DWORD)rootresdir);
+	if (!icongroupresdir) {
+		fprintf(stderr,"InternalExtractIcon: 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) {
+		fprintf(stderr,"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 = (LPIMAGE_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;
+		LPIMAGE_RESOURCE_DIRECTORY	resdir;
+
+		/* go down this resource entry, name */
+		resdir = (LPIMAGE_RESOURCE_DIRECTORY)((DWORD)rootresdir+(xresent->u2.s.OffsetToDirectory));
+		/* default language (0) */
+		resdir = GetResDirEntryW(resdir,(LPWSTR)0,(DWORD)rootresdir);
+		igdataent = (LPIMAGE_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) {
+			fprintf(stderr,"InternalExtractIcon: no matching real address found for icongroup!\n");
+			UnmapViewOfFile(peimage);
+			CloseHandle(fmapping);
+			_lclose32( hFile);
+			return 0;
+		}
+		/* found */
+		cid = (CURSORICONDIR*)igdata;
+		cids[i] = cid;
+		fprintf(stderr,"cursoricondir %d: idType %d, idCount %d\n",
+			i,cid->idType,cid->idCount
+		);
+		RetPtr[i] = LookupIconIdFromDirectoryEx32(igdata,TRUE,SYSMETRICS_CXICON,SYSMETRICS_CYICON,0);
+		fprintf(stderr,"-> best match is %08x\n",RetPtr[i]);
+	}
+	iconresdir=GetResDirEntryW(rootresdir,(LPWSTR)RT_ICON,(DWORD)rootresdir);
+	if (!iconresdir) {
+	    fprintf(stderr,"InternalExtractIcon: No Iconresourcedirectory!\n");
+	    UnmapViewOfFile(peimage);
+	    CloseHandle(fmapping);
+	    _lclose32( hFile);
+	    return 0;
+	}
+	for (i=0;i<n;i++) {
+	    LPIMAGE_RESOURCE_DIRECTORY	xresdir;
+
+	    xresdir = GetResDirEntryW(iconresdir,(LPWSTR)RetPtr[i],(DWORD)rootresdir);
+	    xresdir = GetResDirEntryW(xresdir,(LPWSTR)0,(DWORD)rootresdir);
+
+	    idataent = (LPIMAGE_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) {
+		fprintf(stderr,"InternalExtractIcon: 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);
+	}
+	UnmapViewOfFile(peimage);
+	CloseHandle(fmapping);
+	_lclose32( hFile);
+	return hRet;
+  }
+  _lclose32( hFile );
+  /* return array with icon handles */
   return hRet;
+
 }
 
 /*************************************************************************
  *             ExtractIcon16   (SHELL.34)
  */
 HICON16 WINAPI ExtractIcon16( HINSTANCE16 hInstance, LPCSTR lpszExeFileName,
-                              UINT16 nIconIndex )
+	UINT16 nIconIndex )
 {
-  HGLOBAL16 handle = InternalExtractIcon(hInstance,lpszExeFileName,nIconIndex, 1);
-
-  if( handle )
-    {
-      HICON16* ptr = (HICON16*)GlobalLock16(handle);
-      HICON16  hIcon = *ptr;
-
-      GlobalFree16(handle);
-      return hIcon;
-    }
-  return 0;
+    return ExtractIcon32A( hInstance, lpszExeFileName, nIconIndex );
 }
 
 
@@ -1011,10 +1179,32 @@
  *             ExtractIcon32A   (SHELL32.133)
  */
 HICON32 WINAPI ExtractIcon32A( HINSTANCE32 hInstance, LPCSTR lpszExeFileName,
-                               UINT32 nIconIndex )
+	UINT32 nIconIndex )
 {
-    /* FIXME */
-    return ExtractIcon16( hInstance, lpszExeFileName, nIconIndex );
+    HGLOBAL16 handle = InternalExtractIcon(hInstance,lpszExeFileName,nIconIndex, 1);
+
+    if( handle )
+    {
+	HICON16* ptr = (HICON16*)GlobalLock16(handle);
+	HICON16  hIcon = *ptr;
+
+	GlobalFree16(handle);
+	return hIcon;
+    }
+    return 0;
+}
+
+/*************************************************************************
+ *             ExtractIcon32W   (SHELL32.180)
+ */
+HICON32 WINAPI ExtractIcon32W( HINSTANCE32 hInstance, LPCWSTR lpszExeFileName,
+	UINT32 nIconIndex )
+{
+	LPSTR	exefn = HEAP_strdupWtoA(GetProcessHeap(),0,lpszExeFileName);
+	HICON32	ret = ExtractIcon32A(hInstance,exefn,nIconIndex);
+
+	HeapFree(GetProcessHeap(),0,exefn);
+	return ret;
 }
 
 
@@ -1024,37 +1214,37 @@
  * Return icon for given file (either from file itself or from associated
  * executable) and patch parameters if needed.
  */
-HICON16 WINAPI ExtractAssociatedIcon(HINSTANCE16 hInst,LPSTR lpIconPath,
-                                     LPWORD lpiIcon)
+HICON16 WINAPI ExtractAssociatedIcon16(HINSTANCE16 hInst,LPSTR lpIconPath,
+	LPWORD lpiIcon)
 {
     HICON16 hIcon = ExtractIcon16(hInst, lpIconPath, *lpiIcon);
 
     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);
+		hIcon = ExtractIcon16(hInst, lpIconPath, *lpiIcon);
 
 		if( hIcon > 2 ) return hIcon;
-	      }
+	    }
 	    else hIcon = 0;
-	  }
-	
-	if( hIcon == 1 ) 
-	  *lpiIcon = 2;   /* MSDOS icon - we found .exe but no icons in it */
-	else
-	  *lpiIcon = 6;   /* generic icon - found nothing */
+	}
 
-        GetModuleFileName16(hInst, lpIconPath, 0x80);
+	if( hIcon == 1 ) 
+	    *lpiIcon = 2;   /* MSDOS icon - we found .exe but no icons in it */
+	else
+	    *lpiIcon = 6;   /* generic icon - found nothing */
+
+	GetModuleFileName16(hInst, lpIconPath, 0x80);
 	hIcon = LoadIcon16( hInst, MAKEINTRESOURCE(*lpiIcon));
-      }
+    }
 
     return hIcon;
 }
@@ -1066,30 +1256,30 @@
  */
 LPSTR SHELL_FindString(LPSTR lpEnv, LPCSTR entry)
 {
-  UINT16 	l = strlen(entry); 
-  for( ; *lpEnv ; lpEnv+=strlen(lpEnv)+1 )
-     {
-       if( lstrncmpi32A(lpEnv, entry, l) ) continue;
-       
-       if( !*(lpEnv+l) )
-         return (lpEnv + l); 		/* empty entry */
-       else if ( *(lpEnv+l)== '=' )
-	 return (lpEnv + l + 1);
-     }
-  return NULL;
+    UINT16 	l = strlen(entry); 
+    for( ; *lpEnv ; lpEnv+=strlen(lpEnv)+1 )
+    {
+	if( lstrncmpi32A(lpEnv, entry, l) ) continue;
+
+	if( !*(lpEnv+l) )
+	    return (lpEnv + l); 		/* empty entry */
+	else if ( *(lpEnv+l)== '=' )
+	    return (lpEnv + l + 1);
+    }
+    return NULL;
 }
 
 SEGPTR WINAPI FindEnvironmentString(LPSTR str)
 {
- SEGPTR  spEnv = GetDOSEnvironment();
- LPSTR  lpEnv = (LPSTR)PTR_SEG_TO_LIN(spEnv);
- 
- LPSTR  lpString = (spEnv)?SHELL_FindString(lpEnv, str):NULL; 
+    SEGPTR  spEnv = GetDOSEnvironment();
+    LPSTR  lpEnv = (LPSTR)PTR_SEG_TO_LIN(spEnv);
 
- if( lpString )		/*  offset should be small enough */
-     return spEnv + (lpString - lpEnv);
+    LPSTR  lpString = (spEnv)?SHELL_FindString(lpEnv, str):NULL; 
 
- return (SEGPTR)NULL;
+    if( lpString )		/*  offset should be small enough */
+	return spEnv + (lpString - lpEnv);
+
+    return (SEGPTR)NULL;
 }
 
 /*************************************************************************
@@ -1250,6 +1440,30 @@
 }
 
 /*************************************************************************
+ *				SHAppBarMessage32	[SHELL32.207]
+ */
+UINT32 WINAPI SHAppBarMessage32(DWORD msg, PAPPBARDATA data)
+{
+    fprintf(stdnimp,"SHAppBarMessage32(0x%08lx,%p)\n", msg, data);
+#if 0
+    switch (msg) {
+        case ABM_ACTIVATE:
+        case ABM_GETAUTOHIDEBAR:
+        case ABM_GETSTATE:
+        case ABM_GETTASKBARPOS:
+        case ABM_NEW:
+        case ABM_QUERYPOS:
+        case ABM_REMOVE:
+        case ABM_SETAUTOHIDEBAR:
+        case ABM_SETPOS:
+        case ABM_WINDOWPOSCHANGED:
+	    ;
+    }
+#endif
+    return 0;
+}
+
+/*************************************************************************
  *				CommandLineToArgvW	[SHELL32.7]
  */
 LPWSTR* WINAPI CommandLineToArgvW(LPWSTR cmdline,LPDWORD numargs)
@@ -1329,9 +1543,7 @@
  */
 
 /* This is the wrong place, but where is the right one?  */
-typedef UINT32 REFCLSID32;
-typedef UINT32 REFIID32;
-typedef UINT32 HRESULT32;
+#if 0
 #define E_OUTOFMEMORY 0x8007000EL
 
 HRESULT32 WINAPI SHELL32_DllGetClassObject (REFCLSID32 clsid,
@@ -1346,3 +1558,9 @@
 
   return hres;
 }
+#endif
+
+DWORD WINAPI SHGetDesktopFolder(LPSHELLFOLDER *shellfolder) {
+	*shellfolder = NULL;
+	return 0;
+}