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/shellord.c b/misc/shellord.c
new file mode 100644
index 0000000..f3a1191
--- /dev/null
+++ b/misc/shellord.c
@@ -0,0 +1,525 @@
+/*
+ * 				Shell Ordinal Functions
+ *
+ * These are completely undocumented. The meaning of the functions changes
+ * between different OS versions (NT uses Unicode strings, 95 uses ASCII
+ * strings, etc. etc.)
+ * 
+ * They are just here so that explorer.exe and iexplore.exe can be tested.
+ *
+ * Copyright 1997 Marcus Meissner
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <ctype.h>
+#include "windows.h"
+#include "file.h"
+#include "shell.h"
+#include "heap.h"
+#include "module.h"
+#include "neexe.h"
+#include "resource.h"
+#include "dlgs.h"
+#include "win.h"
+#include "graphics.h"
+#include "cursoricon.h"
+#include "interfaces.h"
+#include "shlobj.h"
+#include "stddebug.h"
+#include "debug.h"
+#include "winreg.h"
+
+/*************************************************************************
+ *				SHELL32_32	[SHELL32.32]
+ * append \ if there is none
+ */
+LPSTR WINAPI SHELL32_32(LPSTR path) {
+    int len;
+
+    len = lstrlen32A(path);
+    if (len && path[len-1]!='\\') {
+    	path[len+0]='\\';
+	path[len+1]='\0';
+	return path+len+1;
+    } else
+    	return path+len;
+}
+
+/*************************************************************************
+ *				SHELL32_34	[SHELL32.34]
+ * basename(char *fn);
+ */
+LPSTR WINAPI SHELL32_34(LPSTR fn) {
+    LPSTR basefn;
+
+    basefn = fn;
+    while (fn[0]) {
+    	if (((fn[0]=='\\') || (fn[0]==':')) && fn[1] && fn[1]!='\\')
+	    basefn = fn+1;
+	fn++;
+    }
+    return basefn;
+}
+
+/*************************************************************************
+ *	 		 SHELL32_35   			[SHELL32.35]
+ * bool getpath(char *pathname); truncates passed argument to a valid path
+ * returns if the string was modified or not.
+ * "\foo\xx\foo"-> "\foo\xx"
+ * "\"		-> "\"
+ * "a:\foo"	-> "a:\"
+ */
+DWORD WINAPI SHELL32_35(LPSTR fn) {
+	LPSTR	x,cutplace;
+
+	if (!fn[0])
+		return 0;
+	x=fn;
+	cutplace = fn;
+	while (*x) {
+		if (*x=='\\') {
+			cutplace=x++;
+			continue;
+		}
+		if (*x==':') {
+			x++;
+			if (*x=='\\')
+				cutplace=++x;
+			continue; /* already x++ed */
+		}
+		x++;
+	}
+	if (!*cutplace)
+		return 0;
+	if (cutplace==fn) {
+		if (fn[0]=='\\') {
+			if (!fn[1])
+				return 0;
+			fn[0]='\0';
+			return 1;
+		}
+	}
+	*cutplace='\0';
+	return 1;
+}
+
+/*************************************************************************
+ *				SHELL32_37	[SHELL32.37]
+ * concat_paths(char*target,const char*add);
+ * concats "target\\add" and writes them to target
+ */
+LPSTR WINAPI SHELL32_37(LPSTR target,LPSTR x1,LPSTR x2) {
+	char	buf[260];
+
+	if (!x2 || !x2[0]) {
+		lstrcpy32A(target,x1);
+		return target;
+	}
+	lstrcpy32A(buf,x1);
+	SHELL32_32(buf); /* append \ if not there */
+	lstrcat32A(buf,x2);
+	lstrcpy32A(target,buf);
+	return target;
+}
+
+/*************************************************************************
+ *				SHELL32_36	[SHELL32.36]
+ * concat_paths(char*target,const char*add);
+ * concats "target\\add" and writes them to target
+ */
+LPSTR WINAPI SHELL32_36(LPSTR x1,LPSTR x2) {
+	while (x2[0]=='\\') x2++;
+	return SHELL32_37(x1,x1,x2);
+}
+
+/*************************************************************************
+ *				SHELL32_52	[SHELL32.52]
+ * look for next arg in string. handle "quoted" strings
+ * returns pointer to argument *AFTER* the space. Or to the \0.
+ */
+LPSTR WINAPI SHELL32_52(LPSTR cmdline) {
+    BOOL32	qflag = FALSE;
+
+    while (*cmdline) {
+    	if ((*cmdline==' ') && !qflag)
+		return cmdline+1;
+	if (*cmdline=='"')
+		qflag=!qflag;
+	cmdline++;
+    }
+    return cmdline;
+}
+
+/*************************************************************************
+ *				SHELL32_45	[SHELL32.45]
+ * file_exists(char *fn);
+ */
+BOOL32 WINAPI SHELL32_45(LPSTR fn) {
+    if (GetFileAttributes32A(fn)==-1)
+    	return FALSE;
+    else
+    	return TRUE;
+}
+
+/*************************************************************************
+ *				SHELL32_175	[SHELL32.175]
+ * unknown
+ */
+void WINAPI SHELL32_175(DWORD x1,DWORD x2,DWORD x3,DWORD x4) {
+    fprintf(stdnimp,"SHELL32_175(0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub\n",
+    	x1,x2,x3,x4
+    );
+}
+
+/*************************************************************************
+ *				SHELL32_181	[SHELL32.181]
+ * unknown
+ */
+void WINAPI SHELL32_181(DWORD x,DWORD y) {
+    fprintf(stderr,"SHELL32_181(0x%08lx,0x%08lx)\n",x,y);
+}
+
+/*************************************************************************
+ *				SHELL32_119	[SHELL32.119]
+ * unknown
+ */
+void WINAPI SHELL32_119(LPVOID x) {
+    fprintf(stderr,"SHELL32_119(%p),stub\n",x);
+}
+
+/*************************************************************************
+ *				SHELL32_75	[SHELL32.75]
+ * unknown
+ */
+BOOL32 WINAPI SHELL32_75(LPDWORD x,LPDWORD y) {
+    fprintf(stderr,"SHELL32_75(%p,%p),stub\n",x,y);
+    return TRUE;
+}
+
+DWORD WINAPI
+SHELL32_DllGetClassObject(REFCLSID *clsid,REFIID *iid,LPVOID *x) {
+	char	xclsid[50],xiid[50];
+
+	StringFromCLSID((LPCLSID)clsid,xclsid);
+	StringFromCLSID((LPCLSID)iid,xiid);
+	fprintf(stderr,"SHELL32_DllGetClassObject(%s,%s,%p), STUB\n",xclsid,xiid,x);
+	return 0;
+}
+
+static FARPROC32 _find_moduleproc(LPSTR dllname,HMODULE32 *xhmod,LPSTR name) {
+	HMODULE32	hmod;
+	FARPROC32	dllunload,nameproc;
+
+	if (xhmod) *xhmod = 0;
+	if (!lstrcmpi32A(SHELL32_34(dllname),"shell32.dll"))
+		return (FARPROC32)SHELL32_DllGetClassObject;
+
+	hmod = LoadLibraryEx32A(dllname,0,LOAD_WITH_ALTERED_SEARCH_PATH);
+	if (!hmod)
+		return NULL;
+	dllunload = GetProcAddress32(hmod,"DllCanUnloadNow");
+	if (!dllunload)
+		if (xhmod) *xhmod = hmod;
+	nameproc = GetProcAddress32(hmod,name);
+	if (!nameproc) {
+		FreeLibrary32(hmod);
+		return NULL;
+	}
+	/* register unloadable dll with unloadproc ... */
+	return nameproc;
+}
+
+static DWORD _get_instance(REFCLSID clsid,LPSTR dllname,
+	LPVOID	unknownouter,REFIID refiid,LPVOID inst
+) {
+	DWORD	WINAPI	(*dllgetclassob)(REFCLSID,REFIID,LPVOID);
+	DWORD		hres;
+	LPCLASSFACTORY	classfac;
+
+	dllgetclassob = (DWORD(*)(REFCLSID,REFIID,LPVOID))_find_moduleproc(dllname,NULL,"DllGetClassObject");
+	if (!dllgetclassob)
+		return 0x80070000|GetLastError();
+
+	hres = (*dllgetclassob)(clsid,(REFIID)&IID_IClassFactory,&classfac);
+	if (hres<0)
+		return hres;
+
+	classfac->lpvtbl->fnCreateInstance(classfac,unknownouter,refiid,inst);
+	classfac->lpvtbl->fnRelease(classfac);
+	return 0;
+}
+/*************************************************************************
+ *				SHELL32_102	[SHELL32.102]
+ * unknown
+ */
+LRESULT WINAPI SHELL32_102(
+	LPSTR aclsid,CLSID *clsid,LPUNKNOWN unknownouter,REFIID refiid,LPVOID inst
+) {
+	char	buffer[256],xclsid[48],xiid[48],path[260],tmodel[100];
+	HKEY	inprockey;
+	DWORD	pathlen,type,tmodellen;
+	DWORD	hres;
+	
+	StringFromCLSID(refiid,xiid);
+
+	if (clsid)
+		StringFromCLSID(clsid,xclsid);
+	else {
+		if (!aclsid)
+		    return 0x80040154;
+		strcpy(xclsid,aclsid);
+	}
+	fprintf(stderr,"SHELL32_102(%p,%s,%p,%s,%p)\n",
+		aclsid,xclsid,unknownouter,xiid,inst
+	);
+
+	sprintf(buffer,"CLSID\\%s\\InProcServer32",xclsid);
+	if (RegOpenKeyEx32A(HKEY_CLASSES_ROOT,buffer,0,0x02000000,&inprockey))
+		return _get_instance(clsid,"shell32.dll",unknownouter,refiid,inst);
+	pathlen=sizeof(path);
+	if (RegQueryValue32A(inprockey,NULL,path,&pathlen)) {
+		RegCloseKey(inprockey);
+		return _get_instance(clsid,"shell32.dll",unknownouter,refiid,inst);
+	}
+	fprintf(stderr,"	-> server dll is %s\n",path);
+	tmodellen=sizeof(tmodel);
+	type=REG_SZ;
+	if (RegQueryValueEx32A(inprockey,"ThreadingModel",NULL,&type,tmodel,&tmodellen)) {
+		RegCloseKey(inprockey);
+		return _get_instance(clsid,"shell32.dll",unknownouter,refiid,inst);
+	}
+	fprintf(stderr,"	-> threading model is %s\n",tmodel);
+	hres=_get_instance(clsid,path,unknownouter,refiid,inst);
+	if (hres<0)
+		hres=_get_instance(clsid,"shell32.dll",unknownouter,refiid,inst);
+	RegCloseKey(inprockey);
+	return hres;
+}
+
+
+/*************************************************************************
+ *			 SHELL32_183   			[SHELL32.183]
+ * Format and output errormessage.
+ */
+void __cdecl SHELL32_183(HMODULE32 hmod,HWND32 hwnd,DWORD id,DWORD x,DWORD type,LPVOID arglist) {
+	char	buf[100],buf2[100],*buf3;
+	LPVOID	args = &arglist;
+
+	if (!LoadString32A(hmod,x,buf,100))
+		strcpy(buf,"Desktop");
+	LoadString32A(hmod,id,buf2,100);
+	/* FIXME: the varargs handling doesn't. */
+	FormatMessage32A(0x500,buf2,0,0,&buf3,256,&args);
+
+	fprintf(stderr,"SHELL32_183(%08lx,%08lx,%08lx(%s),%08lx(%s),%08lx,%p),stub!\n",
+		(DWORD)hmod,(DWORD)hwnd,id,buf2,x,buf,type,arglist
+	);
+	MessageBox32A(hwnd,buf3,buf,id|0x10000);
+}
+
+
+/*************************************************************************
+ *			 SHELL32_71   			[SHELL32.71]
+ * returns internal shell values in the passed pointers
+ */
+BOOL32 WINAPI SHELL32_71(LPDWORD x,LPDWORD y) {
+
+	fprintf(stderr,"SHELL32_71(%p,%p),stub!\n",x,y);
+	return TRUE;
+}
+
+/*************************************************************************
+ *			 SHELL32_72   			[SHELL32.72]
+ * dunno. something with icons
+ */
+void WINAPI SHELL32_72(LPSTR x,DWORD y,DWORD z) {
+	fprintf(stderr,"SHELL32_72(%s,%08lx,%08lx),stub!\n",x,y,z);
+}
+
+/*************************************************************************
+ *			 SHELL32_100   			[SHELL32.100]
+ * walks through policy table, queries <app> key, <type> value, returns 
+ * queried (DWORD) value.
+ * {0x00001,Explorer,NoRun}
+ * {0x00002,Explorer,NoClose}
+ * {0x00004,Explorer,NoSaveSettings}
+ * {0x00008,Explorer,NoFileMenu}
+ * {0x00010,Explorer,NoSetFolders}
+ * {0x00020,Explorer,NoSetTaskbar}
+ * {0x00040,Explorer,NoDesktop}
+ * {0x00080,Explorer,NoFind}
+ * {0x00100,Explorer,NoDrives}
+ * {0x00200,Explorer,NoDriveAutoRun}
+ * {0x00400,Explorer,NoDriveTypeAutoRun}
+ * {0x00800,Explorer,NoNetHood}
+ * {0x01000,Explorer,NoStartBanner}
+ * {0x02000,Explorer,RestrictRun}
+ * {0x04000,Explorer,NoPrinterTabs}
+ * {0x08000,Explorer,NoDeletePrinter}
+ * {0x10000,Explorer,NoAddPrinter}
+ * {0x20000,Explorer,NoStartMenuSubFolders}
+ * {0x40000,Explorer,MyDocsOnNet}
+ * {0x80000,WinOldApp,NoRealMode}
+ */
+DWORD WINAPI SHELL32_100(DWORD pol) {
+	HKEY	xhkey;
+
+	fprintf(stderr,"SHELL32_100(%08lx),stub!\n",pol);
+	if (RegOpenKey32A(HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Policies",&xhkey))
+		return 0;
+	/* FIXME: do nothing for now, just return 0 (== "allowed") */
+	RegCloseKey(xhkey);
+	return 0;
+	
+}
+
+DWORD WINAPI SHELL32_77(DWORD x,DWORD y,DWORD z) {
+	fprintf(stderr,"SHELL32_77(%08lx,%08lx,%08lx),stub!\n",x,y,z);
+	return 0;
+}
+
+/*************************************************************************
+ *	 		 SHELL32_79   			[SHELL32.79]
+ * create_directory_and_notify(...)
+ */
+DWORD WINAPI SHELL32_79(LPCSTR dir,LPVOID xvoid) {
+	fprintf(stderr,"mkdir %s,%p\n",dir,xvoid);
+	if (!CreateDirectory32A(dir,xvoid))
+		return FALSE;
+	/* SHChangeNotify(8,1,dir,0); */
+	return TRUE;
+}
+
+/*************************************************************************
+ *	 		 SHELL32_165   			[SHELL32.165]
+ * create_path_and_notify(...)
+ */
+DWORD WINAPI SHELL32_165(DWORD x,LPCSTR path) {
+	if (SHELL32_79(path,(LPVOID)x))
+		return 0;
+	fprintf(stderr,"SHELL32_165(%08lx,%s),stub!\n",x,path);
+	return 0;
+}
+
+/*************************************************************************
+ *	 		 SHELL32_29   			[SHELL32.29]
+ * is_rootdir(const char*path)
+ */
+BOOL32 WINAPI SHELL32_29(LPCSTR x) {
+	if (!lstrcmp32A(x+1,":\\"))		/* "X:\" */
+		return 1;
+	if (!lstrcmp32A(x,"\\"))		/* "\" */
+		return 1;
+	if (x[0]=='\\' && x[1]=='\\') {		/* UNC "\\<xx>\" */
+		int	foundbackslash = 0;
+		x=x+2;
+		while (*x) {
+			if (*x++=='\\')
+				foundbackslash++;
+		}
+		if (foundbackslash<=1)	/* max 1 \ more ... */
+			return 1;
+	}
+	return 0;
+}
+
+/*************************************************************************
+ *	 		 SHELL32_152   			[SHELL32.152]
+ * itemlist_length
+ */
+DWORD WINAPI SHELL32_152(LPITEMIDLIST iil) {
+	LPSHITEMID	si;
+	DWORD		len;
+
+	si = &(iil->mkid);
+	len = 2;
+	while (si->cb) {
+		len	+= si->cb;
+		si	 = (LPSHITEMID)(((char*)si)+si->cb);
+	}
+	return len;
+}
+
+/*************************************************************************
+ *	 		 SHELL32_196   			[SHELL32.196]
+ * void *task_alloc(DWORD len), uses SHMalloc allocator
+ */
+LPVOID WINAPI SHELL32_196(DWORD len) {
+	return (LPVOID)LocalAlloc32(len,LMEM_ZEROINIT); /* FIXME */
+}
+
+/*************************************************************************
+ *	 		 SHELL32_18   			[SHELL32.18]
+ * copy_itemidlist()
+ */
+LPITEMIDLIST WINAPI SHELL32_18(LPITEMIDLIST iil) {
+	DWORD		len;
+	LPITEMIDLIST	newiil;
+
+	len = SHELL32_152(iil);
+	newiil = (LPITEMIDLIST)SHELL32_196(len);
+	memcpy(newiil,iil,len);
+	return newiil;
+}
+
+/*************************************************************************
+ *	 		 SHELL32_25   			[SHELL32.25]
+ * merge_itemidlist()
+ */
+LPITEMIDLIST WINAPI SHELL32_25(LPITEMIDLIST iil1,LPITEMIDLIST iil2) {
+	DWORD		len1,len2;
+	LPITEMIDLIST	newiil;
+
+	len1 	= SHELL32_152(iil1)-2;
+	len2	= SHELL32_152(iil2);
+	newiil	= SHELL32_196(len1+len2);
+	memcpy(newiil,iil1,len1);
+	memcpy(((char*)newiil)+len1,iil2,len2);
+	return newiil;
+}
+
+/*************************************************************************
+ *	 		 SHELL32_16   			[SHELL32.16]
+ * find_lastitem_in_itemidlist()
+ */
+LPSHITEMID WINAPI SHELL32_16(LPITEMIDLIST iil) {
+	LPSHITEMID	lastsii,sii;
+
+	if (!iil)
+		return NULL;
+	sii = &(iil->mkid);
+	lastsii = sii;
+	while (sii->cb) {
+		lastsii = sii;
+		sii = (LPSHITEMID)(((char*)sii)+sii->cb);
+	}
+	return lastsii;
+}
+
+/*************************************************************************
+ *	 		 SHELL32_195   			[SHELL32.195]
+ * free_ptr() - frees memory using IMalloc
+ */
+DWORD WINAPI SHELL32_195(LPVOID x) {
+	return LocalFree32((HANDLE32)x);
+}
+
+/*************************************************************************
+ *	 		 SHELL32_155   			[SHELL32.155]
+ * free_check_ptr - frees memory (if not NULL) allocated by SHMalloc allocator
+ */
+DWORD WINAPI SHELL32_155(LPVOID x) {
+	if (!x)
+		return 0;
+	return SHELL32_195(x);
+}
+
+/*************************************************************************
+ *	 		 SHELL32_62   			[SHELL32.62]
+ */
+DWORD WINAPI SHELL32_62(DWORD x,DWORD y,DWORD z,DWORD a) {
+	fprintf(stderr,"SHELL32_62(%08lx,%08lx,%08lx,%08lx),stub!\n",x,y,z,a);
+	return 0xffffffff;
+}