diff --git a/dlls/shlwapi/ordinal.c b/dlls/shlwapi/ordinal.c
index d199742df2bf74e53e5c4e9828e611bd0aa4cde9..5ddcff4c792d6a85809d1d254bac38cd46247add 100644
--- a/dlls/shlwapi/ordinal.c
+++ b/dlls/shlwapi/ordinal.c
@@ -1,8 +1,9 @@
 /*
  * SHLWAPI ordinal functions
- * 
+ *
  * Copyright 1997 Marcus Meissner
  *           1998 Jürgen Schmied
+ *           2001 Jon Griffiths
  */
 
 #include <stdio.h>
@@ -11,6 +12,10 @@
 #include "windef.h"
 #include "winnls.h"
 #include "winbase.h"
+#include "ddeml.h"
+#include "shlobj.h"
+#include "shellapi.h"
+#include "commdlg.h"
 #include "wine/unicode.h"
 #include "wine/obj_base.h"
 #include "wingdi.h"
@@ -20,13 +25,27 @@
 DEFAULT_DEBUG_CHANNEL(shell);
 
 extern HINSTANCE shlwapi_hInstance;
+extern HMODULE SHLWAPI_hshell32;
+extern HMODULE SHLWAPI_hwinmm;
+extern HMODULE SHLWAPI_hcomdlg32;
+extern HMODULE SHLWAPI_hmpr;
+extern HMODULE SHLWAPI_hmlang;
+
+/* Macro to get function pointer for a module*/
+#define GET_FUNC(module, name, fail) \
+  if (!SHLWAPI_h##module) SHLWAPI_h##module = LoadLibraryA(#module ".dll"); \
+  if (!SHLWAPI_h##module) return fail; \
+  if (!pfnFunc) pfnFunc = (void*)GetProcAddress(SHLWAPI_h##module, name); \
+  if (!pfnFunc) return fail
 
 /*
- NOTES: The most functions exported by ordinal seem to be superflous.
+ NOTES: Most functions exported by ordinal seem to be superflous.
  The reason for these functions to be there is to provide a wraper
- for unicode functions to providing these functions on systems without
+ for unicode functions to provide these functions on systems without
  unicode functions eg. win95/win98. Since we have such functions we just
- call these.
+ call these. If running Wine with native DLL's, some late bound calls may
+ fail. However, its better to implement the functions in the forward DLL
+ and recommend the builtin rather than reimplementing the calls here!
 */
 
 /*************************************************************************
@@ -108,22 +127,63 @@ DWORD WINAPI SHLWAPI_24 (
 }
 
 /*************************************************************************
- *      SHLWAPI_38	[SHLWAPI.38]
+ *      SHLWAPI_30	[SHLWAPI.30]
  *
+ * Seems to be an isspaceW.
  */
-DWORD WINAPI SHLWAPI_38 ( DWORD x) {
-    FIXME("(%lx),stub!\n",x);
-    return 0;
+BOOL WINAPI SHLWAPI_30(LPWSTR lpcChar)
+{
+  switch (*lpcChar)
+  {
+  case (WCHAR)'\t':
+  case (WCHAR)' ':
+  case 160:
+  case 12288:
+  case 65279:
+    return TRUE;
+  }
+  return FALSE;
 }
+
 /*************************************************************************
- *	SHLWAPI_137
+ *      SHLWAPI_32	[SHLWAPI.32]
  */
-DWORD WINAPI SHLWAPI_137(
-	UINT  what)
+BOOL WINAPI SHLWAPI_32(LPCWSTR lpcChar)
 {
-  FIXME("(%#x)stub\n", what);
+ if (*lpcChar < (WCHAR)' ')
+   return TRUE;
+
+ /* This is probably a shlwapi bug, but we do it the same for compatability */
+ if (((DWORD)lpcChar & 0xffff) - 127 <= (WCHAR)' ')
+   return TRUE;
+ return FALSE;
+}
+
+/*************************************************************************
+ *      SHLWAPI_40	[SHLWAPI.40]
+ *
+ * Get pointer to next Unicode character.
+ */
+LPCWSTR WINAPI SHLWAPI_40(LPCWSTR str)
+{
+  return *str ? str + 1 : str;
+}
+
+/*************************************************************************
+ *      SHLWAPI_74	[SHLWAPI.74]
+ *
+ * Get the text from a given dialog item.
+ */
+INT WINAPI SHLWAPI_74(HWND hWnd, INT nItem, LPWSTR lpsDest,INT nDestLen)
+{
+  HWND hItem = GetDlgItem(hWnd, nItem);
+
+  if (hItem)
+    return GetWindowTextW(hItem, lpsDest, nDestLen);
+  if (nDestLen)
+    *lpsDest = (WCHAR)'\0';
   return 0;
-}  
+}
 
 /*************************************************************************
  *      SHLWAPI_151	[SHLWAPI.151]
@@ -134,6 +194,22 @@ DWORD WINAPI SHLWAPI_151(void)
   return 0;
 }
 
+/*************************************************************************
+ *      SHLWAPI_152	[SHLWAPI.152]
+ */
+DWORD WINAPI SHLWAPI_152(LPWSTR str1, LPWSTR str2, INT len)
+{
+  if (!len)
+    return 0;
+
+  while (--len && *str1 && *str1 == *str2)
+  {
+    str1++;
+    str2++;
+  }
+  return *str1 - *str2;
+}
+
 /*************************************************************************
  *      SHLWAPI_153	[SHLWAPI.153]
  */
@@ -146,14 +222,51 @@ DWORD WINAPI SHLWAPI_153(DWORD dw1, DWORD dw2, DWORD dw3)
 /*************************************************************************
  *      SHLWAPI_156	[SHLWAPI.156]
  *
- * FIXME: function guessed
+ *	Case sensitive string compare. Does not SetLastError().
+ */
+DWORD WINAPI SHLWAPI_156 ( LPWSTR str1, LPWSTR str2)
+{
+  while (*str1 && (*str1 == *str2)) { str1++; str2++; }
+  return (INT)(*str1 - *str2);
+}
+
+/*************************************************************************
+ *      SHLWAPI_162	[SHLWAPI.162]
+ *
+ * Ensure a multibyte character string doesn't end in a hanging lead byte.
  */
-DWORD WINAPI SHLWAPI_156 (
-	LPWSTR str1,	/* [???] NOTE: "shell32.dll" */
-	LPWSTR str2)	/* [???] NOTE: "shell32.dll" */
+DWORD WINAPI SHLWAPI_162(LPSTR lpStr, DWORD size)
 {
-	FIXME("(%s %s)stub\n",debugstr_w(str1),debugstr_w(str2));
-	return lstrcmpW(str1,str2);
+  if (lpStr && size)
+  {
+    LPSTR lastByte = lpStr + size - 1;
+
+    while(lpStr < lastByte)
+      lpStr += IsDBCSLeadByte(*lpStr) ? 2 : 1;
+
+    if(lpStr == lastByte && IsDBCSLeadByte(*lpStr))
+    {
+      *lpStr = '\0';
+      size--;
+    }
+    return size;
+  }
+  return 0;
+}
+
+/*************************************************************************
+ *      SHLWAPI_165	[SHLWAPI.165]
+ *
+ * SetWindowLongA with mask.
+ */
+LONG WINAPI SHLWAPI_165(HWND hwnd, INT offset, UINT wFlags, UINT wMask)
+{
+  LONG ret = GetWindowLongA(hwnd, offset);
+  UINT newFlags = (wFlags & wMask) | (ret & ~wFlags);
+
+  if (newFlags != ret)
+    ret = SetWindowLongA(hwnd, offset, newFlags);
+  return ret;
 }
 
 /*************************************************************************
@@ -169,6 +282,41 @@ DWORD WINAPI SHLWAPI_169 (IUnknown * lpUnknown)
 	return 0;
 }
 
+/*************************************************************************
+ *      SHLWAPI_170	[SHLWAPI.170]
+ *
+ * Skip URL '//' sequence.
+ */
+LPCSTR WINAPI SHLWAPI_170(LPCSTR lpszSrc)
+{
+  if (lpszSrc && lpszSrc[0] == '/' && lpszSrc[1] == '/')
+    lpszSrc += 2;
+  return lpszSrc;
+}
+
+/*************************************************************************
+ *      SHLWAPI_181	[SHLWAPI.181]
+ *
+ *	Enable or disable a menu item.
+ */
+UINT WINAPI SHLWAPI_181(HMENU hMenu, UINT wItemID, BOOL bEnable)
+{
+  return EnableMenuItem(hMenu, wItemID, bEnable ? MF_ENABLED : MF_GRAYED);
+}
+
+/*************************************************************************
+ *      SHLWAPI_183	[SHLWAPI.183]
+ *
+ * Register a window class if it isn't already.
+ */
+DWORD WINAPI SHLWAPI_183(WNDCLASSA *wndclass)
+{
+  WNDCLASSA wca;
+  if (GetClassInfoA(wndclass->hInstance, wndclass->lpszClassName, &wca))
+    return TRUE;
+  return (DWORD)RegisterClassA(wndclass);
+}
+
 /*************************************************************************
  *      SHLWAPI_193	[SHLWAPI.193]
  */
@@ -200,6 +348,105 @@ LPWSTR WINAPI SHLWAPI_215 (
 	return strncpyW(lpwStrDest, lpStrSrc, len);
 }
 
+/*************************************************************************
+ *      SHLWAPI_218	[SHLWAPI.218]
+ *
+ * WideCharToMultiByte with multi language support.
+ */
+INT WINAPI SHLWAPI_218(UINT CodePage, LPCWSTR lpSrcStr, LPSTR lpDstStr,
+                       LPINT lpnMultiCharCount)
+{
+  static HRESULT (WINAPI *pfnFunc)(LPDWORD,DWORD,LPCWSTR,LPINT,LPSTR,LPINT);
+  WCHAR emptyW[] = { '\0' };
+  int len , reqLen;
+  LPSTR mem;
+
+  if (!lpDstStr || !lpnMultiCharCount)
+    return 0;
+
+  if (!lpSrcStr)
+    lpSrcStr = emptyW;
+
+  *lpDstStr = '\0';
+
+  len = strlenW(lpSrcStr) + 1;
+
+  switch (CodePage)
+  {
+  case CP_WINUNICODE:
+    CodePage = CP_UTF8; /* Fall through... */
+  case 0x0000C350: /* FIXME: CP_ #define */
+  case CP_UTF7:
+  case CP_UTF8:
+    {
+      DWORD dwMode = 0;
+      INT nWideCharCount = len - 1;
+
+      GET_FUNC(mlang, "ConvertINetUnicodeToMultiByte", 0);
+      if (!pfnFunc(&dwMode, CodePage, lpSrcStr, &nWideCharCount, lpDstStr,
+                   lpnMultiCharCount))
+        return 0;
+
+      if (nWideCharCount < len - 1)
+      {
+        mem = (LPSTR)HeapAlloc(GetProcessHeap(), 0, *lpnMultiCharCount);
+        if (!mem)
+          return 0;
+
+        *lpnMultiCharCount = 0;
+
+        if (pfnFunc(&dwMode, CodePage, lpSrcStr, &len, mem, lpnMultiCharCount))
+        {
+          SHLWAPI_162 (mem, *lpnMultiCharCount);
+          lstrcpynA(lpDstStr, mem, *lpnMultiCharCount + 1);
+          return *lpnMultiCharCount + 1;
+        }
+        HeapFree(GetProcessHeap(), 0, mem);
+        return *lpnMultiCharCount;
+      }
+      lpDstStr[*lpnMultiCharCount] = '\0';
+      return *lpnMultiCharCount;
+    }
+    break;
+  default:
+    break;
+  }
+
+  reqLen = WideCharToMultiByte(CodePage, 0, lpSrcStr, len, lpDstStr,
+                               *lpnMultiCharCount, NULL, NULL);
+
+  if (!reqLen && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
+  {
+    reqLen = WideCharToMultiByte(CodePage, 0, lpSrcStr, len, NULL, 0, NULL, NULL);
+    if (reqLen)
+    {
+      mem = (LPSTR)HeapAlloc(GetProcessHeap(), 0, reqLen);
+      if (mem)
+      {
+        reqLen = WideCharToMultiByte(CodePage, 0, lpSrcStr, len, mem,
+                                     reqLen, NULL, NULL);
+
+        reqLen = SHLWAPI_162(mem, *lpnMultiCharCount);
+        reqLen++;
+
+        lstrcpynA(lpDstStr, mem, *lpnMultiCharCount);
+
+        HeapFree(GetProcessHeap(), 0, mem);
+      }
+    }
+  }
+  return reqLen;
+}
+
+/*************************************************************************
+ *      SHLWAPI_217	[SHLWAPI.217]
+ *
+ */
+INT WINAPI SHLWAPI_217(LPCWSTR lpSrcStr, LPSTR lpDstStr, LPINT lpnMultiCharCount)
+{
+  return SHLWAPI_218(CP_ACP, lpSrcStr, lpDstStr, lpnMultiCharCount);
+}
+
 /*************************************************************************
  *      SHLWAPI_219	[SHLWAPI.219]
  *
@@ -243,7 +490,7 @@ HANDLE WINAPI SHLWAPI_222 (LPCLSID guid)
 DWORD WINAPI SHLWAPI_223 (HANDLE handle)
 {
 	DWORD oldCount;
-	
+
 	FIXME("(0x%08x) stub\n",handle);
 
 	ReleaseSemaphore( handle, 1, &oldCount);	/* +1 */
@@ -254,20 +501,29 @@ DWORD WINAPI SHLWAPI_223 (HANDLE handle)
 /*************************************************************************
  *      SHLWAPI_237	[SHLWAPI.237]
  *
- * NOTES
- *  checks if a class is registered, if not it registers it
+ * Unicode version of SHLWAPI_183.
  */
 DWORD WINAPI SHLWAPI_237 (WNDCLASSW * lpWndClass)
 {
 	WNDCLASSW WndClass;
-	
+
 	TRACE("(0x%08x %s)\n",lpWndClass->hInstance, debugstr_w(lpWndClass->lpszClassName));
 
-	if (!GetClassInfoW(lpWndClass->hInstance, lpWndClass->lpszClassName, &WndClass))
-	{
-	  return RegisterClassW(lpWndClass);
-	}
-	return TRUE;
+	if (GetClassInfoW(lpWndClass->hInstance, lpWndClass->lpszClassName, &WndClass))
+		return TRUE;
+	return RegisterClassW(lpWndClass);
+}
+
+/*************************************************************************
+ *      SHLWAPI_240	[SHLWAPI.240]
+ *
+ *	Calls ASCII or Unicode WindowProc for the given window.
+ */
+LRESULT CALLBACK SHLWAPI_240(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
+{
+	if (IsWindowUnicode(hWnd))
+		return DefWindowProcW(hWnd, uMessage, wParam, lParam);
+	return DefWindowProcA(hWnd, uMessage, wParam, lParam);
 }
 
 /*************************************************************************
@@ -344,7 +600,7 @@ DWORD WINAPI SHLWAPI_278 (
 	HWND hwnd;
 	HCURSOR hCursor;
 	char * clsname = "WorkerA";
-	
+
 	FIXME("(0x%08lx 0x%08x 0x%08lx 0x%08lx 0x%08x 0x%08lx)stub\n",
 	  wndProc,hWndParent,dwExStyle,dwStyle,hMenu,z);
 
@@ -369,6 +625,112 @@ DWORD WINAPI SHLWAPI_278 (
 	return hwnd;
 }
 
+/*************************************************************************
+ *      SHLWAPI_289	[SHLWAPI.289]
+ *
+ * Late bound call to winmm.PlaySoundW
+ */
+BOOL WINAPI SHLWAPI_289(LPCWSTR pszSound, HMODULE hmod, DWORD fdwSound)
+{
+  static BOOL (WINAPI *pfnFunc)(LPCWSTR, HMODULE, DWORD) = NULL;
+
+  GET_FUNC(winmm, "PlaySoundW", FALSE);
+  return pfnFunc(pszSound, hmod, fdwSound);
+}
+
+/*************************************************************************
+ *      SHLWAPI_313	[SHLWAPI.313]
+ *
+ * Late bound call to shell32.SHGetFileInfoW
+ */
+DWORD WINAPI SHLWAPI_313(LPCWSTR path, DWORD dwFileAttributes,
+                         SHFILEINFOW *psfi, UINT sizeofpsfi, UINT flags)
+{
+  static DWORD (WINAPI *pfnFunc)(LPCWSTR,DWORD,SHFILEINFOW*,UINT,UINT) = NULL;
+
+  GET_FUNC(shell32, "SHGetFileInfoW", 0);
+  return pfnFunc(path, dwFileAttributes, psfi, sizeofpsfi, flags);
+}
+
+/*************************************************************************
+ *      SHLWAPI_318	[SHLWAPI.318]
+ *
+ * Late bound call to shell32.DragQueryFileW
+ */
+UINT WINAPI SHLWAPI_318(HDROP hDrop, UINT lFile, LPWSTR lpszFile, UINT lLength)
+{
+  static UINT (WINAPI *pfnFunc)(HDROP, UINT, LPWSTR, UINT) = NULL;
+
+  GET_FUNC(shell32, "DragQueryFileW", 0);
+  return pfnFunc(hDrop, lFile, lpszFile, lLength);
+}
+
+/*************************************************************************
+ *      SHLWAPI_333	[SHLWAPI.333]
+ *
+ * Late bound call to shell32.SHBrowseForFolderW
+ */
+LPITEMIDLIST WINAPI SHLWAPI_333(LPBROWSEINFOW lpBi)
+{
+  static LPITEMIDLIST (WINAPI *pfnFunc)(LPBROWSEINFOW) = NULL;
+
+  GET_FUNC(shell32, "SHBrowseForFolderW", NULL);
+  return pfnFunc(lpBi);
+}
+
+/*************************************************************************
+ *      SHLWAPI_334	[SHLWAPI.334]
+ *
+ * Late bound call to shell32.SHGetPathFromIDListW
+ */
+BOOL WINAPI SHLWAPI_334(LPCITEMIDLIST pidl,LPWSTR pszPath)
+{
+  static BOOL (WINAPI *pfnFunc)(LPCITEMIDLIST, LPWSTR) = NULL;
+
+  GET_FUNC(shell32, "SHGetPathFromIDListW", 0);
+  return pfnFunc(pidl, pszPath);
+}
+
+/*************************************************************************
+ *      SHLWAPI_335	[SHLWAPI.335]
+ *
+ * Late bound call to shell32.ShellExecuteExW
+ */
+BOOL WINAPI SHLWAPI_335(LPSHELLEXECUTEINFOW lpExecInfo)
+{
+  static BOOL (WINAPI *pfnFunc)(LPSHELLEXECUTEINFOW) = NULL;
+
+  GET_FUNC(shell32, "ShellExecuteExW", FALSE);
+  return pfnFunc(lpExecInfo);
+}
+
+/*************************************************************************
+ *      SHLWAPI_336	[SHLWAPI.336]
+ *
+ * Late bound call to shell32.SHFileOperationW.
+ */
+DWORD WINAPI SHLWAPI_336(LPSHFILEOPSTRUCTW lpFileOp)
+{
+  static HICON (WINAPI *pfnFunc)(LPSHFILEOPSTRUCTW) = NULL;
+
+  GET_FUNC(shell32, "SHFileOperationW", 0);
+  return pfnFunc(lpFileOp);
+}
+
+/*************************************************************************
+ *      SHLWAPI_337	[SHLWAPI.337]
+ *
+ * Late bound call to shell32.ExtractIconExW.
+ */
+HICON WINAPI SHLWAPI_337(LPCWSTR lpszFile, INT nIconIndex, HICON *phiconLarge,
+                         HICON *phiconSmall, UINT nIcons)
+{
+  static HICON (WINAPI *pfnFunc)(LPCWSTR, INT,HICON *,HICON *, UINT) = NULL;
+
+  GET_FUNC(shell32, "ExtractIconExW", (HICON)0);
+  return pfnFunc(lpszFile, nIconIndex, phiconLarge, phiconSmall, nIcons);
+}
+
 /*************************************************************************
  *      SHLWAPI_342	[SHLWAPI.342]
  *
@@ -397,12 +759,69 @@ DWORD WINAPI SHLWAPI_346 (
 }
 
 /*************************************************************************
- *      SHLWAPI_376	[SHLWAPI.377]
+ *      SHLWAPI_357	[SHLWAPI.357]
+ *
+ * Late bound call to shell32.SHGetNewLinkInfoW
+ */
+BOOL WINAPI SHLWAPI_357(LPCWSTR pszLinkTo, LPCWSTR pszDir, LPWSTR pszName,
+                        BOOL *pfMustCopy, UINT uFlags)
+{
+  static BOOL (WINAPI *pfnFunc)(LPCWSTR, LPCWSTR, LPCWSTR, BOOL*, UINT) = NULL;
+
+  GET_FUNC(shell32, "SHGetNewLinkInfoW", FALSE);
+  return pfnFunc(pszLinkTo, pszDir, pszName, pfMustCopy, uFlags);
+}
+
+/*************************************************************************
+ *      SHLWAPI_358	[SHLWAPI.358]
+ *
+ * Late bound call to shell32.SHDefExtractIconW
+ */
+DWORD WINAPI SHLWAPI_358(LPVOID arg1, LPVOID arg2, LPVOID arg3, LPVOID arg4,
+                         LPVOID arg5, LPVOID arg6)
+{
+  /* FIXME: Correct args */
+  static DWORD (WINAPI *pfnFunc)(LPVOID, LPVOID, LPVOID, LPVOID, LPVOID, LPVOID) = NULL;
+
+  GET_FUNC(shell32, "SHDefExtractIconW", 0);
+  return pfnFunc(arg1, arg2, arg3, arg4, arg5, arg6);
+}
+
+/*************************************************************************
+ *      SHLWAPI_364	[SHLWAPI.364]
+ *
+ * Wrapper for lstrcpynA with src and dst swapped.
+ */
+DWORD WINAPI SHLWAPI_364(LPCSTR src, LPSTR dst, INT n)
+{
+  lstrcpynA(dst, src, n);
+  return TRUE;
+}
+
+/*************************************************************************
+ *      SHLWAPI_370	[SHLWAPI.370]
+ *
+ * Late bound call to shell32.ExtractIconW
+ */
+HICON WINAPI SHLWAPI_370(HINSTANCE hInstance, LPCWSTR lpszExeFileName,
+                         UINT nIconIndex)
+{
+  static HICON (WINAPI *pfnFunc)(HINSTANCE, LPCWSTR, UINT) = NULL;
+
+  GET_FUNC(shell32, "ExtractIconW", (HICON)0);
+  return pfnFunc(hInstance, lpszExeFileName, nIconIndex);
+}
+
+/*************************************************************************
+ *      SHLWAPI_376	[SHLWAPI.376]
  */
 DWORD WINAPI SHLWAPI_376 (LONG x)
 {
 	FIXME("(0x%08lx)stub\n", x );
-	return 0xabba1245;
+  /* FIXME: This should be a forward in the .spec file to the win2k function
+   * kernel32.GetUserDefaultUILanguage, however that function isn't there yet.
+   */
+  return 0xabba1245;
 }
 
 /*************************************************************************
@@ -426,6 +845,139 @@ DWORD WINAPI SHLWAPI_378 (
 	return LoadLibraryA(x);
 }
 
+/*************************************************************************
+ *      SHLWAPI_389	[SHLWAPI.389]
+ *
+ * Late bound call to comdlg32.GetSaveFileNameW
+ */
+BOOL WINAPI SHLWAPI_389(LPOPENFILENAMEW ofn)
+{
+  static BOOL (WINAPI *pfnFunc)(LPOPENFILENAMEW) = NULL;
+
+  GET_FUNC(comdlg32, "GetSaveFileNameW", FALSE);
+  return pfnFunc(ofn);
+}
+
+/*************************************************************************
+ *      SHLWAPI_390	[SHLWAPI.390]
+ *
+ * Late bound call to mpr.WNetRestoreConnectionW
+ */
+DWORD WINAPI SHLWAPI_390(LPVOID arg1, LPVOID arg2)
+{
+  /* FIXME: Correct args */
+  static DWORD (WINAPI *pfnFunc)(LPVOID, LPVOID) = NULL;
+
+  GET_FUNC(mpr, "WNetRestoreConnectionW", 0);
+  return pfnFunc(arg1, arg2);
+}
+
+/*************************************************************************
+ *      SHLWAPI_391	[SHLWAPI.391]
+ *
+ * Late bound call to mpr.WNetGetLastErrorW
+ */
+DWORD WINAPI SHLWAPI_391(LPVOID arg1, LPVOID arg2, LPVOID arg3, LPVOID arg4,
+                         LPVOID arg5)
+{
+  /* FIXME: Correct args */
+  static DWORD (WINAPI *pfnFunc)(LPVOID, LPVOID, LPVOID, LPVOID, LPVOID) = NULL;
+
+  GET_FUNC(mpr, "WNetGetLastErrorW", 0);
+  return pfnFunc(arg1, arg2, arg3, arg4, arg5);
+}
+
+/*************************************************************************
+ *      SHLWAPI_401	[SHLWAPI.401]
+ *
+ * Late bound call to comdlg32.PageSetupDlgW
+ */
+BOOL WINAPI SHLWAPI_401(LPPAGESETUPDLGW pagedlg)
+{
+  static BOOL (WINAPI *pfnFunc)(LPPAGESETUPDLGW) = NULL;
+
+  GET_FUNC(comdlg32, "PageSetupDlgW", FALSE);
+  return pfnFunc(pagedlg);
+}
+
+/*************************************************************************
+ *      SHLWAPI_402	[SHLWAPI.402]
+ *
+ * Late bound call to comdlg32.PrintDlgW
+ */
+BOOL WINAPI SHLWAPI_402(LPPRINTDLGW printdlg)
+{
+  static BOOL (WINAPI *pfnFunc)(LPPRINTDLGW) = NULL;
+
+  GET_FUNC(comdlg32, "PrintDlgW", FALSE);
+  return pfnFunc(printdlg);
+}
+
+/*************************************************************************
+ *      SHLWAPI_403	[SHLWAPI.403]
+ *
+ * Late bound call to comdlg32.GetOpenFileNameW
+ */
+BOOL WINAPI SHLWAPI_403(LPOPENFILENAMEW ofn)
+{
+  static BOOL (WINAPI *pfnFunc)(LPOPENFILENAMEW) = NULL;
+
+  GET_FUNC(comdlg32, "GetOpenFileNameW", FALSE);
+  return pfnFunc(ofn);
+}
+
+/* INTERNAL: Map from HLS color space to RGB */
+static WORD ConvertHue(int wHue, WORD wMid1, WORD wMid2)
+{
+  wHue = wHue > 240 ? wHue - 240 : wHue < 0 ? wHue + 240 : wHue;
+
+  if (wHue > 160)
+    return wMid1;
+  else if (wHue > 120)
+    wHue = 160 - wHue;
+  else if (wHue > 40)
+    return wMid2;
+
+  return ((wHue * (wMid2 - wMid1) + 20) / 40) + wMid1;
+}
+
+/* Convert to RGB and scale into RGB range (0..255) */
+#define GET_RGB(h) (ConvertHue(h, wMid1, wMid2) * 255 + 120) / 240
+
+/*************************************************************************
+ *      ColorHLSToRGB	[SHLWAPI.404]
+ *
+ * Convert from HLS color space into an RGB COLORREF.
+ *
+ * NOTES
+ * Input HLS values are constrained to the range (0..240).
+ */
+COLORREF WINAPI ColorHLSToRGB(WORD wHue, WORD wLuminosity, WORD wSaturation)
+{
+  WORD wRed;
+
+  if (wSaturation)
+  {
+    WORD wGreen, wBlue, wMid1, wMid2;
+
+    if (wLuminosity > 120)
+      wMid2 = wSaturation + wLuminosity - (wSaturation * wLuminosity + 120) / 240;
+    else
+      wMid2 = ((wSaturation + 240) * wLuminosity + 120) / 240;
+
+    wMid1 = wLuminosity * 2 - wMid2;
+
+    wRed   = GET_RGB(wHue + 80);
+    wGreen = GET_RGB(wHue);
+    wBlue  = GET_RGB(wHue - 80);
+
+    return RGB(wRed, wGreen, wBlue);
+  }
+
+  wRed = wLuminosity * 255 / 240;
+  return RGB(wRed, wRed, wRed);
+}
+
 /*************************************************************************
  *      SHLWAPI_431	[SHLWAPI.431]
  */
@@ -439,20 +991,20 @@ DWORD WINAPI SHLWAPI_431 (DWORD x)
  *      SHLWAPI_437	[SHLWAPI.437]
  *
  * NOTES
- *  has to do something with switching the api between ascii and unicode
- *  observed values: 0 and 5
- *
- * accesses
- * HKLM\System\CurrentControlSet\Control\ProductOptions
- *
+ *  In the real shlwapi, One time initilisation calls GetVersionEx and reads
+ *  the registry to determine what O/S & Service Pack level is running, and
+ *  therefore which functions are available. Currently we always run as NT,
+ *  since this means that we don't need extra code to emulate Unicode calls,
+ *  they are forwarded directly to the appropriate API call instead.
+ *  Since the flags for whether to call or emulate Unicode are internal to
+ *  the dll, this function does not need a full implementation.
  */
-DWORD WINAPI SHLWAPI_437 (DWORD x)
+DWORD WINAPI SHLWAPI_437 (DWORD functionToCall)
 {
-	FIXME("(0x%08lx)stub\n", x);
+	FIXME("(0x%08lx)stub\n", functionToCall);
 	return 0xabba1247;
 }
 
-
 /*************************************************************************
  *      SHCreateShellPalette	[SHLWAPI.@]
  */
@@ -467,9 +1019,10 @@ HPALETTE WINAPI SHCreateShellPalette(HDC hdc)
  */
 DWORD WINAPI SHGetInverseCMAP (LPVOID x, DWORD why)
 {
-	FIXME("(%p, %#lx)stub\n", x, why); 
+	FIXME("(%p, %#lx)stub\n", x, why);
 	return 0;
-}	
+}
+
 /*************************************************************************
  *      SHIsLowMemoryMachine	[SHLWAPI.@]
  */
@@ -478,3 +1031,34 @@ DWORD WINAPI SHIsLowMemoryMachine (DWORD x)
 	FIXME("0x%08lx\n", x);
 	return 0;
 }
+
+/*************************************************************************
+ *      GetMenuPosFromID	[SHLWAPI.@]
+ */
+INT WINAPI GetMenuPosFromID(HMENU hMenu, UINT wID)
+{
+ MENUITEMINFOA mi;
+ INT nCount = GetMenuItemCount(hMenu), nIter = 0;
+
+ while (nIter < nCount)
+ {
+   mi.wID = 0;
+   if (!GetMenuItemInfoA(hMenu, nIter, TRUE, &mi) && mi.wID == wID)
+     return nIter;
+   nIter++;
+ }
+ return -1;
+}
+
+/*************************************************************************
+ *      _SHGetInstanceExplorer	[SHLWAPI.@]
+ *
+ * Late bound call to shell32.SHGetInstanceExplorer.
+ */
+HRESULT WINAPI _SHGetInstanceExplorer (LPUNKNOWN *lpUnknown)
+{
+  static HRESULT (WINAPI *pfnFunc)(LPUNKNOWN *) = NULL;
+
+  GET_FUNC(shell32, "SHGetInstanceExplorer", E_FAIL);
+  return pfnFunc(lpUnknown);
+}
diff --git a/dlls/shlwapi/reg.c b/dlls/shlwapi/reg.c
index f66bb3dc264eceaefbf613706aaf83243be368d7..fcf4a88b21c94027d8407d1bead4cdb027d10266 100644
--- a/dlls/shlwapi/reg.c
+++ b/dlls/shlwapi/reg.c
@@ -3,13 +3,20 @@
  */
 
 #include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
 #include "winerror.h"
 #include "winreg.h"
 #include "debugtools.h"
 #include "shlwapi.h"
+#include "wine/unicode.h"
 
 DEFAULT_DEBUG_CHANNEL(shell);
 
+static const char *lpszContentTypeA = "Content Type";
+static const WCHAR lpszContentTypeW[] = { 'C','o','n','t','e','n','t',' ','T','y','p','e','\0'};
+
 /*************************************************************************
  * SHRegGetUSValueA	[SHLWAPI.@]
  *
@@ -134,13 +141,13 @@ DWORD WINAPI SHGetValueA(
 {
 	HKEY hSubKey;
 	DWORD res;
-	
+
 	TRACE("(%s %s)\n", pSubKey, pValue);
-	
+
 	if((res = RegOpenKeyA(hkey, pSubKey, &hSubKey))) return res;
 	res = RegQueryValueExA(hSubKey, pValue, 0, pwType, pvData, pbData);
 	RegCloseKey( hSubKey );
-	
+
 	return res;
 }
 
@@ -159,13 +166,13 @@ DWORD WINAPI SHGetValueW(
 {
 	HKEY hSubKey;
 	DWORD res;
-	
+
 	TRACE("(%s %s)\n", debugstr_w(pSubKey), debugstr_w(pValue));
-	
+
 	if((res = RegOpenKeyW(hkey, pSubKey, &hSubKey))) return res;
 	res = RegQueryValueExW(hSubKey, pValue, 0, pwType, pvData, pbData);
 	RegCloseKey( hSubKey );
-	
+
 	return res;
 }
 
@@ -235,7 +242,7 @@ HRESULT WINAPI SHQueryValueExA(
  *
  * FIXME 
  *  if the datatype REG_EXPAND_SZ then expand the string and change
- *  *pdwType to REG_SZ. 
+ *  *pdwType to REG_SZ.
  */
 HRESULT WINAPI SHQueryValueExW (
 	HKEY hkey,
@@ -277,7 +284,7 @@ HRESULT WINAPI SHDeleteKeyA(
     /* find how many subkeys there are */
     dwKeyCount = 0;
     dwMaxSubkeyLen = 0;
-    r = RegQueryInfoKeyA(hSubKey, NULL, NULL, NULL, &dwKeyCount, 
+    r = RegQueryInfoKeyA(hSubKey, NULL, NULL, NULL, &dwKeyCount,
                     &dwMaxSubkeyLen, NULL, NULL, NULL, NULL, NULL, NULL);
     if(r != ERROR_SUCCESS)
     {
@@ -389,7 +396,7 @@ DWORD WINAPI SHDeleteEmptyKeyA(HKEY hKey, LPCSTR lpszSubKey)
         return r;
 
     dwKeyCount = 0;
-    r = RegQueryInfoKeyA(hSubKey, NULL, NULL, NULL, &dwKeyCount, 
+    r = RegQueryInfoKeyA(hSubKey, NULL, NULL, NULL, &dwKeyCount,
                     NULL, NULL, NULL, NULL, NULL, NULL, NULL);
     if(r != ERROR_SUCCESS)
         return r;
@@ -419,3 +426,75 @@ DWORD WINAPI SHDeleteEmptyKeyW(HKEY hKey, LPCWSTR lpszSubKey)
     return 0;
 }
 
+/*************************************************************************
+ * SHLWAPI_205   [SHLWAPI.205]
+ *
+ * Wrapper for SHGetValueA in case machine is in safe mode.
+ */
+DWORD WINAPI SHLWAPI_205(HKEY hkey, LPCSTR pSubKey, LPCSTR pValue,
+                         LPDWORD pwType, LPVOID pvData, LPDWORD pbData)
+{
+  if (GetSystemMetrics(SM_CLEANBOOT))
+    return ERROR_INVALID_FUNCTION;
+  return SHGetValueA(hkey, pSubKey, pValue, pwType, pvData, pbData);
+}
+
+/*************************************************************************
+ * SHLWAPI_206   [SHLWAPI.206]
+ *
+ * Unicode version of SHLWAPI_205.
+ */
+DWORD WINAPI SHLWAPI_206(HKEY hkey, LPCWSTR pSubKey, LPCWSTR pValue,
+                         LPDWORD pwType, LPVOID pvData, LPDWORD pbData)
+{
+  if (GetSystemMetrics(SM_CLEANBOOT))
+    return ERROR_INVALID_FUNCTION;
+  return SHGetValueW(hkey, pSubKey, pValue, pwType, pvData, pbData);
+}
+
+/*************************************************************************
+ * SHLWAPI_320   [SHLWAPI.320]
+ *
+ */
+BOOL WINAPI SHLWAPI_320(LPCSTR lpszSubKey, LPCSTR lpszValue)
+{
+  DWORD dwLen = strlen(lpszValue);
+  HRESULT ret = SHSetValueA(HKEY_CLASSES_ROOT, lpszSubKey, lpszContentTypeA,
+                            REG_SZ, lpszValue, dwLen);
+  return ret ? FALSE : TRUE;
+}
+
+/*************************************************************************
+ * SHLWAPI_321   [SHLWAPI.321]
+ *
+ * Unicode version of SHLWAPI_320.
+ */
+BOOL WINAPI SHLWAPI_321(LPCWSTR lpszSubKey, LPCWSTR lpszValue)
+{
+  DWORD dwLen = strlenW(lpszValue);
+  HRESULT ret = SHSetValueW(HKEY_CLASSES_ROOT, lpszSubKey, lpszContentTypeW,
+                            REG_SZ, lpszValue, dwLen);
+  return ret ? FALSE : TRUE;
+}
+
+/*************************************************************************
+ * SHLWAPI_322   [SHLWAPI.322]
+ *
+ */
+BOOL WINAPI SHLWAPI_322(LPCSTR lpszSubKey)
+{
+  HRESULT ret = SHDeleteValueA(HKEY_CLASSES_ROOT, lpszSubKey, lpszContentTypeA);
+  return ret ? FALSE : TRUE;
+}
+
+/*************************************************************************
+ * SHLWAPI_323   [SHLWAPI.323]
+ *
+ * Unicode version of SHLWAPI_322.
+ */
+BOOL WINAPI SHLWAPI_323(LPCWSTR lpszSubKey)
+{
+  HRESULT ret = SHDeleteValueW(HKEY_CLASSES_ROOT, lpszSubKey, lpszContentTypeW);
+  return ret ? FALSE : TRUE;
+}
+
diff --git a/dlls/shlwapi/shlwapi.spec b/dlls/shlwapi/shlwapi.spec
index b50f74993eba53b709b374218ffde1c12640cb8c..9dc75310de68f1f27454f4f76c0008854997d3d3 100644
--- a/dlls/shlwapi/shlwapi.spec
+++ b/dlls/shlwapi/shlwapi.spec
@@ -41,145 +41,145 @@ debug_channels (shell)
 29  stub @
 30  stub @
 31  stub @
-32  stub @
+32  stdcall @(ptr) SHLWAPI_32
 33  stub @
 34  stub @
 35  stub @
 36  stub @
 37  forward @ user32.CallWindowProcW
-38  stdcall @(long) SHLWAPI_38
-39  stub @
-40  stub @
+38  forward @ user32.CharLowerW
+39  forward @ user32.CharLowerBuffW
+40  stdcall @(wstr) SHLWAPI_40
 41  stub @
 42  stub @
-43  stub @
-44  stub @
-45  stub @
-46  stub @
-47  stub @
-48  stub @
+43  forward @ user32.CharUpperW
+44  forward @ user32.CharUpperBuffW
+45  forward @ kernel32.CompareStringW
+46  forward @ user32.CopyAcceleratorTableW
+47  forward @ user32.CreateAcceleratorTableW
+48  forward @ gdi32.CreateDCW
 49  stub @
-50  stub @
-51  stub @
-52  stub @
-53  stub @
+50  forward @ kernel32.CreateDirectoryW
+51  forward @ kernel32.CreateEventW
+52  forward @ kernel32.CreateFileW
+53  forward @ gdi32.CreateFontIndirectW
 54  forward @ gdi32.CreateICW
 55  forward @ user32.CreateWindowExW
 56  forward @ user32.DefWindowProcW
-57  stub @
+57  forward @ kernel32.DeleteFileW
 58  stub @
 59  stub @
-60  stub @
+60  forward @ user32.DispatchMessageW
 61  stub @
-62  stub @
-63  stub @
-64  stub @
-65  stub @
-66  stub @
-67 forward @ user32.FindWindowW
-68 forward @ kernel32.FormatMessageW
-69 forward @ user32.GetClassInfoW
-70  stub @
-71  stub @
-72  stub @
-73  stub @
-74  stub @
-75  stub @
-76  stub @
-77  stub @
-78  stub @
-79  stub @
+62  forward @ gdi32.EnumFontFamiliesW
+63  forward @ gdi32.EnumFontFamiliesExW
+64  forward @ kernel32.EnumResourceNamesW
+65  forward @ kernel32.FindFirstFileW
+66  forward @ kernel32.FindResourceW
+67  forward @ user32.FindWindowW
+68  forward @ kernel32.FormatMessageW
+69  forward @ user32.GetClassInfoW
+70  forward @ user32.GetClassLongW
+71  forward @ user32.GetClassNameW
+72  forward @ user32.GetClipboardFormatNameW
+73  forward @ kernel32.GetCurrentDirectoryW
+74  stdcall @(long long wstr long) SHLWAPI_74
+75  forward @ kernel32.GetFileAttributesW
+76  forward @ kernel32.GetFullPathNameW
+77  forward @ kernel32.GetLocaleInfoW
+78  forward @ user32.GetMenuStringW
+79  forward @ user32.GetMessageW
 80  forward @ kernel32.GetModuleFileNameW
 81  forward @ kernel32.GetSystemDirectoryW
 82  forward @ kernel32.SearchPathW
 83  forward @ kernel32.GetModuleHandleW
-84  stub @
-85  stub @
-86  stub @
-87  stub @
-88  stub @
-89  stub @
-90  stub @
-91  stub @
-92  stub @
-93  stub @
+84  forward @ gdi32.GetObjectW
+85  forward @ kernel32.GetPrivateProfileIntW
+86  forward @ kernel32.GetProfileStringW
+87  forward @ user32.GetPropW
+88  forward @ kernel32.GetStringTypeExW
+89  forward @ kernel32.GetTempFileNameW
+90  forward @ kernel32.GetTempPathW
+91  forward @ gdi32.GetTextExtentPoint32W
+92  forward @ gdi32.GetTextFaceW
+93  forward @ gdi32.GetTextMetricsW
 94  forward @ user32.GetWindowLongW
-95  stub @
-96  stub @
-97  stub @
-98  stub @
-99  stub @
-100 stub @
-101 stub @
+95  forward @ user32.GetWindowTextW
+96  forward @ user32.GetWindowTextLengthW
+97  forward @ kernel32.GetWindowsDirectoryW
+98  forward @ user32.InsertMenuW
+99  forward @ user32.IsDialogMessageW
+100 forward @ user32.LoadAcceleratorsW
+101 forward @ user32.LoadBitmapW
 102 forward @ user32.LoadCursorW
-103 stub @
-104 stub @
-105 stub @
-106 stub @
+103 forward @ user32.LoadIconW
+104 forward @ user32.LoadImageW
+105 forward @ user32.LoadLibraryExW
+106 forward @ user32.LoadMenuW
 107 forward @ user32.LoadStringW
-108 stub @
-109 stub @
-110 stub @
-111 stub @
-112 stub @
-113 stub @
-114 stub @
-115 stub @
-116 stub @
-117 stub @
-118 stub @
-119 stub @
+108 forward @ user32.MessageBoxIndirectW
+109 forward @ user32.ModifyMenuW
+110 forward @ gdi32.GetCharWidth32W
+111 forward @ gdi32.GetCharacterPlacementW
+112 forward @ kernel32.CopyFileW
+113 forward @ kernel32.MoveFileW
+114 forward @ user32.OemToCharW
+115 forward @ kernel32.OutputDebugStringW
+116 forward @ user32.PeekMessageW
+117 forward @ user32.PostMessageW
+118 forward @ user32.PostThreadMessageW
+119 forward @ advapi32.RegCreateKeyW
 120 forward @ advapi32.RegCreateKeyExW
-121 stub @
-122 stub @
-123 stub @
-124 stub @
+121 forward @ advapi32.RegDeleteKeyW
+122 forward @ advapi32.RegEnumKeyW
+123 forward @ advapi32.RegEnumKeyExW
+124 forward @ dvapi32.RegOpenKeyW
 125 forward @ advapi32.RegOpenKeyExW
-126 stub @
-127 stub @
+126 forward @ advapi32.RegQueryInfoKeyW
+127 forward @ advapi32.RegQueryValueW
 128 forward @ advapi32.RegQueryValueExW
-129 stub @
-130 stub @
+129 forward @ advapi32.RegSetValueW
+130 forward @ advapi32.RegSetValueExW
 131 forward @ user32.RegisterClassW
 132 forward @ user32.RegisterClipboardFormatW
-133 stub @
-134 stub @
-135 stub @
-136 stub @
-137 stdcall @(long) SHLWAPI_137
+133 forward @ user32.RegisterWindowMessageW
+134 forward @ user32.RemovePropW
+135 forward @ user32.SendDlgItemMessageW
+136 forward @ user32.SendMessageW
+137 forward @ kernel32.SetCurrentDirectoryW
 138 stub @
 139 stub @
-140 stub @
+140 forward @ user32.SetPropW
 141 forward @ user32.SetWindowLongW
-142 stub @
+142 forward @ user32.SetWindowsHookExW
 143 stub @
-144 stub @
-145 stub @
-146 stub @
+144 forward @ gdi32.StartDocW
+145 forward @ user32.SystemParametersInfoW
+146 forward @ user32.TranslateAcceleratorW
 147 forward @ user32.UnregisterClassW
-148 stub @
-149 stub @
-150 stub @
+148 forward @ user32.VkKeyScanW
+149 forward @ user32.WinHelpW
+150 forward @ user32.wvsprintfW
 151 stdcall @() SHLWAPI_151
-152 stub @
+152 stdcall @(wstr wstr long) SHLWAPI_152
 153 stdcall @(long long long) SHLWAPI_153
 154 stub @
 155 stub @
 156 stdcall @(wstr wstr) SHLWAPI_156
 157 stub @
-158 stub @
-159 stub @
+158 stub @ #(wstr wstr) SHLWAPI_158
+159 forward @ kernel32.CompareStringW
 160 stub @
 161 stub @
-162 stub @
+162 stdcall @(str long) SHLWAPI_162
 163 stub @
 164 stub @
-165 stub @
+165 stdcall @(long long long long) SHLWAPI_165
 166 stub @
 167 stub @
 168 stub @
 169 stdcall @(long) SHLWAPI_169
-170 stub @
+170 stdcall @(str) SHLWAPI_170
 171 stub @
 172 stub @
 173 stub @
@@ -190,9 +190,9 @@ debug_channels (shell)
 178 stub @
 179 stub @
 180 stub @
-181 stub @
+181 stdcall @(long long long) SHLWAPI_181
 182 stub @
-183 stub @
+183 stdcall @(ptr) SHLWAPI_183
 184 stub @
 185 stub @
 186 stub @
@@ -214,8 +214,8 @@ debug_channels (shell)
 202 stub @
 203 stub @
 204 stub @
-205 stub @
-206 stub @
+205 stdcall @(long str str ptr ptr ptr) SHLWAPI_205
+206 stdcall @(long wstr wstr ptr ptr ptr) SHLWAPI_206
 207 stub @
 208 stub @
 209 stub @
@@ -226,8 +226,8 @@ debug_channels (shell)
 214 stub @
 215 stdcall @(long long long) SHLWAPI_215
 216 stub @
-217 stub @
-218 stub @
+217 stdcall @(wstr str ptr) SHLWAPI_217
+218 stdcall @(long wstr str ptr) SHLWAPI_218
 219 stdcall @(long long long long) SHLWAPI_219
 220 stub @
 221 stub @
@@ -249,7 +249,7 @@ debug_channels (shell)
 237 stdcall @(ptr) SHLWAPI_237
 238 stub @
 239 stub @
-240 stub @
+240 stdcall @(long long long long) SHLWAPI_240
 241 stdcall @() SHLWAPI_241
 242 stub @
 243 stub @
@@ -298,7 +298,7 @@ debug_channels (shell)
 286 stub @
 287 stub @
 288 stub @
-289 stub @
+289 stdcall @(wstr long long) SHLWAPI_289
 290 stub @
 291 stub @
 292 stub @
@@ -307,32 +307,32 @@ debug_channels (shell)
 295 stub @
 296 stub @
 297 stub @
-298 stub @
+298 forward @ kernel32.WritePrivateProfileStringW
 299 stub @
 300 stub @
-301 stub @
-302 stub @
-303 stub @
-304 stub @
-305 stub @
-306 stub @
-307 stub @
-308 stub @
+301 forward @ gdi32.DrawTextExW # FIXME CreateFontW
+302 forward @ user32.GetMenuItemInfoW
+303 forward @ user32.InsertMenuItemW
+304 forward @ gdi32.CreateMetaFileW
+305 forward @ kernel32.CreateMutexW
+306 forward @ kernel32.ExpandEnvironmentStringsW
+307 forward @ kernel32.CreateSemaphoreW
+308 forward @ kernel32.IsBadStringPtrW
 309 forward @ kernel32.LoadLibraryW
-310 stub @
-311 stub @
-312 stub @
-313 stub @
-314 stub @
-315 stub @
+310 forward @ kernel32.GetTimeFormatW
+311 forward @ kernel32.GetDateFormatW
+312 forward @ kernel32.specGetPrivateProfileStringW
+313 stdcall @(ptr long ptr long long) SHLWAPI_313
+314 forward @ user32.RegisterClassExW
+315 forward @ user32.GetClassInfoExW
 316 stub SHCreateStreamOnFileAOld
 317 stub SHCreateStreamOnFileWOld
-318 stub @
-319 stub @
-320 stub @
-321 stub @
-322 stub @
-323 stub @
+318 stdcall @(long long wstr long) SHLWAPI_318
+319 forward @ user32.FindWindowExW
+320 stdcall @(str str) SHLWAPI_320
+321 stdcall @(wstr wstr) SHLWAPI_321
+322 stdcall @(str) SHLWAPI_322
+323 stdcall @(wstr) SHLWAPI_323
 324 stub @
 325 stub @
 326 stub @
@@ -341,22 +341,22 @@ debug_channels (shell)
 329 stub @
 330 stub @
 331 stub @
-332 stub @
-333 stub @
-334 stub @
-335 stub @
-336 stub @
-337 stub @
-338 stub @
-339 stub @
-340 stub @
-341 stub @
+332 forward @ user32.CallMsgFilterW
+333 stdcall @(ptr) SHLWAPI_333
+334 stdcall @(ptr wstr) SHLWAPI_334
+335 stdcall @(ptr) SHLWAPI_335
+336 stdcall @(ptr) SHLWAPI_336
+337 stdcall @(wstr long ptr ptr long) SHLWAPI_337
+338 forward @ kernel32.SetFileAttributesW
+339 forward @ kernel32.GetNumberFormatW
+340 forward @ user32.specMessageBoxW
+341 forward @ kernel32.FindNextFileW
 342 stdcall @(long long long long) SHLWAPI_342
 343 stub @
 344 stub @
 345 stub @
 346 stdcall @(wstr ptr long) SHLWAPI_346
-347 stub @
+347 forward @ advapi32.RegDeleteValueW
 348 stub @
 349 stub @
 350 stub @
@@ -366,26 +366,26 @@ debug_channels (shell)
 354 stub @
 355 stub @
 356 stub @
-357 stub @
-358 stub @
-359 stub @
-360 stub @
-361 stub @
+357 stdcall @(wstr wstr wstr long long) SHLWAPI_357
+358 stdcall @(ptr ptr ptr ptr ptr ptr) SHLWAPI_358
+359 forward @ kernel32.OpenEventW
+360 forward @ kernel32.specRemoveDirectoryW
+361 forward @ kernel32.GetShortPathNameW
 362 stub @
 363 stub @
-364 stub @
+364 stdcall @(str str long) SHLWAPI_364
 365 stub @
-366 stub @
-367 stub @
-368 stub @
-369 stub @
-370 stub @
+366 forward @ advapi32.RegEnumValueW
+367 forward @ kernel32.WritePrivateProfileStructW
+368 forward @ kernel32.GetPrivateProfileStructW
+369 forward @ kernel32.CreateProcessW
+370 stdcall @(long wstr long) SHLWAPI_370
 371 stub @
 372 stub @
 373 stub @
 374 stub @
 375 stub @
-376 stdcall @(long) SHLWAPI_376
+376 stdcall @(long) SHLWAPI_376  # kernel32.GetUserDefaultUILanguage
 377 stdcall @(long long long) SHLWAPI_377
 378 stdcall @(long long long) SHLWAPI_378
 379 stub @
@@ -398,9 +398,9 @@ debug_channels (shell)
 386 stub ChrCmpIW
 387 stub ColorAdjustLuma
 388 stub @
-389 stub @
-390 stub @
-391 stub @
+389 stdcall @(ptr) SHLWAPI_389
+390 stdcall @(ptr ptr) SHLWAPI_390
+391 stdcall @(ptr ptr ptr ptr ptr ) SHLWAPI_391
 392 stub @
 393 stub @
 394 stub @
@@ -410,10 +410,10 @@ debug_channels (shell)
 398 stub @
 399 stub @
 400 stub @
-401 stub @
-402 stub @
-403 stub @
-404 stub @
+401 stdcall @(ptr) SHLWAPI_401
+402 stdcall @(ptr) SHLWAPI_402
+403 stdcall @(ptr) SHLWAPI_403
+404 stdcall ColorHLSToRGB(long long long) ColorHLSToRGB
 405 stub @
 406 stub @
 407 stub @
@@ -443,7 +443,7 @@ debug_channels (shell)
 431 stdcall @(long) SHLWAPI_431
 432 stub @
 433 stub @
-434 stub @
+434 forward @ user32.SendMessageTimeoutW
 435 stub @
 436 stub @
 437 stdcall @(long) SHLWAPI_437
@@ -451,15 +451,15 @@ debug_channels (shell)
 439 stub @
 440 stub @
 441 stub @
-442 stub @
-443 stub @
-444 stub @
-445 stub @
+442 forward @ kernel32.GetEnvironmentVariableW
+443 forward @ kernel32.GetSystemWindowsDirectoryA
+444 forward @ kernel32.GetSystemWindowsDirectoryW
+445 stub ColorRGBToHLS
 446 stub @
 
 @ stdcall DllGetVersion (ptr) SHLWAPI_DllGetVersion
-@ stub    GetMenuPosFromID
-@ stub    HashData
+@ stdcall GetMenuPosFromID(ptr long) GetMenuPosFromID
+@ stdcall HashData (ptr long ptr long) HashData
 @ stub    IntlStrEqWorkerA
 @ stub    IntlStrEqWorkerW
 @ stdcall PathAddBackslashA (str) PathAddBackslashA
@@ -522,10 +522,10 @@ debug_channels (shell)
 @ stdcall PathIsUNCW(wstr) PathIsUNCW
 @ stdcall PathIsURLA(str) PathIsURLA
 @ stdcall PathIsURLW(wstr) PathIsURLW
-@ stdcall PathMakePrettyA(str)PathMakePrettyA
-@ stdcall PathMakePrettyW(wstr)PathMakePrettyW
-@ stdcall PathMakeSystemFolderA(str)PathMakeSystemFolderA
-@ stdcall PathMakeSystemFolderW(wstr)PathMakeSystemFolderW
+@ stdcall PathMakePrettyA(str) PathMakePrettyA
+@ stdcall PathMakePrettyW(wstr) PathMakePrettyW
+@ stdcall PathMakeSystemFolderA(str) PathMakeSystemFolderA
+@ stdcall PathMakeSystemFolderW(wstr) PathMakeSystemFolderW
 @ stdcall PathMatchSpecA  (str str) PathMatchSpecA
 @ stdcall PathMatchSpecW  (wstr wstr) PathMatchSpecW
 @ stdcall PathParseIconLocationA (str) PathParseIconLocationA
@@ -550,12 +550,12 @@ debug_channels (shell)
 @ stdcall PathSearchAndQualifyW(wstr ptr long)PathSearchAndQualifyW
 @ stdcall PathSetDlgItemPathA (long long ptr) PathSetDlgItemPathA
 @ stdcall PathSetDlgItemPathW (long long ptr) PathSetDlgItemPathW
-@ stdcall PathSkipRootA(str)PathSkipRootA
-@ stdcall PathSkipRootW(wstr)PathSkipRootW
-@ stdcall PathStripPathA(str)PathStripPathA
-@ stdcall PathStripPathW(wstr)PathStripPathW
-@ stdcall PathStripToRootA(str)PathStripToRootA
-@ stdcall PathStripToRootW(wstr)PathStripToRootW
+@ stdcall PathSkipRootA(str) PathSkipRootA
+@ stdcall PathSkipRootW(wstr) PathSkipRootW
+@ stdcall PathStripPathA(str) PathStripPathA
+@ stdcall PathStripPathW(wstr) PathStripPathW
+@ stdcall PathStripToRootA(str) PathStripToRootA
+@ stdcall PathStripToRootW(wstr) PathStripToRootW
 @ stdcall PathUnmakeSystemFolderA(str)PathUnmakeSystemFolderA
 @ stdcall PathUnmakeSystemFolderW(wstr)PathUnmakeSystemFolderW
 @ stdcall PathUnquoteSpacesA (str) PathUnquoteSpacesA
@@ -677,7 +677,7 @@ debug_channels (shell)
 @ stub    UrlGetLocationW
 @ stub    UrlGetPartA
 @ stub    UrlGetPartW
-@ stub    UrlHashA
+@ stdcall UrlHashA(str ptr long) UrlHashA
 @ stub    UrlHashW
 @ stub    UrlIsA
 @ stub    UrlIsNoHistoryA
@@ -691,12 +691,37 @@ debug_channels (shell)
 @ varargs wnsprintfW(ptr long wstr)wnsprintfW
 
 
-# exported in later versions 
+# exported in later versions
 @ stdcall StrRetToBufA (ptr ptr ptr long) StrRetToBufA
 @ stdcall StrRetToBufW (ptr ptr ptr long) StrRetToBufW
 #@ stdcall StrRetToStrA (ptr ptr ptr) StrRetToStrA
 #@ stdcall StrRetToStrW (ptr ptr ptr) StrRetToStrW
 @ stdcall SHRegGetPathA(long str str ptr long)SHRegGetPathA
 @ stdcall SHRegGetPathW(long wstr wstr ptr long)SHRegGetPathW
+@ stub    PathIsDirectoryEmptyA
+@ stub    PathIsDirectoryEmptyW
+@ stub    PathIsNetworkPathA
+@ stub    PathIsNetworkPathW
+@ stub    PathIsLFNFileSpecA
+@ stub    PathIsLFNFileSpecW
+@ stub    PathFindSuffixArrayA
+@ stub    PathFindSuffixArrayW
+@ stdcall _SHGetInstanceExplorer@4(ptr) _SHGetInstanceExplorer
+@ stub    PathUndecorateA
+@ stub    PathUndecorateW
+@ stub    SHCopyKeyA
 @ stub    SHCopyKeyW
 @ stub    SHAutoComplete
+@ stub    SHCreateStreamOnFileA
+@ stub    SHCreateStreamOnFileW
+@ stub    SHCreateStreamWrapper
+@ stub    SHCreateThread
+@ stub    SHGetThreadRef
+@ stub    SHRegDuplicateHKey
+@ stub    SHSetThreadRef
+@ stub    SHSkipJunction
+@ stub    SHStrDupA
+@ stub    SHStrDupW
+@ stub    StrFormatByteSize64A
+@ stub    StrFormatKBSizeA
+@ stub    StrFormatKBSizeW
diff --git a/dlls/shlwapi/shlwapi_main.c b/dlls/shlwapi/shlwapi_main.c
index 3ffea705382e0ea7513518f8e3d0a0db53fa073a..ff5a24101acbb05cdcbbb4693e4a218ba9377c76 100644
--- a/dlls/shlwapi/shlwapi_main.c
+++ b/dlls/shlwapi/shlwapi_main.c
@@ -13,6 +13,11 @@
 DEFAULT_DEBUG_CHANNEL(shell);
 
 HINSTANCE shlwapi_hInstance = 0; 
+HMODULE SHLWAPI_hshell32 = 0;
+HMODULE SHLWAPI_hwinmm = 0;
+HMODULE SHLWAPI_hcomdlg32 = 0;
+HMODULE SHLWAPI_hmpr = 0;
+HMODULE SHLWAPI_hmlang = 0;
 
 /*************************************************************************
  * SHLWAPI LibMain
@@ -28,6 +33,13 @@ BOOL WINAPI SHLWAPI_LibMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad
 	  case DLL_PROCESS_ATTACH:
 	    shlwapi_hInstance = hinstDLL;
 	    break;
+	  case DLL_PROCESS_DETACH:
+	    if (SHLWAPI_hshell32)  FreeLibrary(SHLWAPI_hshell32);
+	    if (SHLWAPI_hwinmm)    FreeLibrary(SHLWAPI_hwinmm);
+	    if (SHLWAPI_hcomdlg32) FreeLibrary(SHLWAPI_hcomdlg32);
+	    if (SHLWAPI_hmpr)      FreeLibrary(SHLWAPI_hmpr);
+	    if (SHLWAPI_hmlang)    FreeLibrary(SHLWAPI_hmlang);
+	    break;
 	}
 	return TRUE;
 }
diff --git a/dlls/shlwapi/url.c b/dlls/shlwapi/url.c
index 4b979d85fdcbf5daabc2dfaafdf53f8bf4fc6d77..96bf4428c0444745e1561e813702b017ee69b26b 100644
--- a/dlls/shlwapi/url.c
+++ b/dlls/shlwapi/url.c
@@ -13,6 +13,28 @@
 
 DEFAULT_DEBUG_CHANNEL(shell);
 
+static const unsigned char HashDataLookup[256] = {
+ 0x01, 0x0E, 0x6E, 0x19, 0x61, 0xAE, 0x84, 0x77, 0x8A, 0xAA, 0x7D, 0x76, 0x1B,
+ 0xE9, 0x8C, 0x33, 0x57, 0xC5, 0xB1, 0x6B, 0xEA, 0xA9, 0x38, 0x44, 0x1E, 0x07,
+ 0xAD, 0x49, 0xBC, 0x28, 0x24, 0x41, 0x31, 0xD5, 0x68, 0xBE, 0x39, 0xD3, 0x94,
+ 0xDF, 0x30, 0x73, 0x0F, 0x02, 0x43, 0xBA, 0xD2, 0x1C, 0x0C, 0xB5, 0x67, 0x46,
+ 0x16, 0x3A, 0x4B, 0x4E, 0xB7, 0xA7, 0xEE, 0x9D, 0x7C, 0x93, 0xAC, 0x90, 0xB0,
+ 0xA1, 0x8D, 0x56, 0x3C, 0x42, 0x80, 0x53, 0x9C, 0xF1, 0x4F, 0x2E, 0xA8, 0xC6,
+ 0x29, 0xFE, 0xB2, 0x55, 0xFD, 0xED, 0xFA, 0x9A, 0x85, 0x58, 0x23, 0xCE, 0x5F,
+ 0x74, 0xFC, 0xC0, 0x36, 0xDD, 0x66, 0xDA, 0xFF, 0xF0, 0x52, 0x6A, 0x9E, 0xC9,
+ 0x3D, 0x03, 0x59, 0x09, 0x2A, 0x9B, 0x9F, 0x5D, 0xA6, 0x50, 0x32, 0x22, 0xAF,
+ 0xC3, 0x64, 0x63, 0x1A, 0x96, 0x10, 0x91, 0x04, 0x21, 0x08, 0xBD, 0x79, 0x40,
+ 0x4D, 0x48, 0xD0, 0xF5, 0x82, 0x7A, 0x8F, 0x37, 0x69, 0x86, 0x1D, 0xA4, 0xB9,
+ 0xC2, 0xC1, 0xEF, 0x65, 0xF2, 0x05, 0xAB, 0x7E, 0x0B, 0x4A, 0x3B, 0x89, 0xE4,
+ 0x6C, 0xBF, 0xE8, 0x8B, 0x06, 0x18, 0x51, 0x14, 0x7F, 0x11, 0x5B, 0x5C, 0xFB,
+ 0x97, 0xE1, 0xCF, 0x15, 0x62, 0x71, 0x70, 0x54, 0xE2, 0x12, 0xD6, 0xC7, 0xBB,
+ 0x0D, 0x20, 0x5E, 0xDC, 0xE0, 0xD4, 0xF7, 0xCC, 0xC4, 0x2B, 0xF9, 0xEC, 0x2D,
+ 0xF4, 0x6F, 0xB6, 0x99, 0x88, 0x81, 0x5A, 0xD9, 0xCA, 0x13, 0xA5, 0xE7, 0x47,
+ 0xE6, 0x8E, 0x60, 0xE3, 0x3E, 0xB3, 0xF6, 0x72, 0xA2, 0x35, 0xA0, 0xD7, 0xCD,
+ 0xB4, 0x2F, 0x6D, 0x2C, 0x26, 0x1F, 0x95, 0x87, 0x00, 0xD8, 0x34, 0x3F, 0x17,
+ 0x25, 0x45, 0x27, 0x75, 0x92, 0xB8, 0xA3, 0xC8, 0xDE, 0xEB, 0xF8, 0xF3, 0xDB,
+ 0x0A, 0x98, 0x83, 0x7B, 0xE5, 0xCB, 0x4C, 0x78, 0xD1 };
+
 static BOOL URL_NeedEscape(CHAR ch, DWORD dwFlags)
 {
 
@@ -27,7 +49,7 @@ static BOOL URL_NeedEscape(CHAR ch, DWORD dwFlags)
     }
 
     if (ch <= 31 || ch >= 127)
-	return TRUE; 
+	return TRUE;
 
     else {
         switch (ch) {
@@ -55,7 +77,7 @@ static BOOL URL_NeedEscape(CHAR ch, DWORD dwFlags)
 /*************************************************************************
  *        UrlCanonicalizeA     [SHLWAPI]
  */
-HRESULT WINAPI UrlCanonicalizeA(LPCSTR pszUrl, LPSTR pszCanonicalized, 
+HRESULT WINAPI UrlCanonicalizeA(LPCSTR pszUrl, LPSTR pszCanonicalized,
 	LPDWORD pcchCanonicalized, DWORD dwFlags)
 {
     HRESULT hr = S_OK;
@@ -68,7 +90,7 @@ HRESULT WINAPI UrlCanonicalizeA(LPCSTR pszUrl, LPSTR pszCanonicalized,
 
     nLen = strlen(pszUrl);
     lpszUrlCpy = HeapAlloc(GetProcessHeap(), 0, nLen + 1);
-       
+
     if (dwFlags & URL_DONT_SIMPLIFY)
         memcpy(lpszUrlCpy, pszUrl, nLen + 1);
     else {
@@ -203,7 +225,7 @@ HRESULT WINAPI UrlEscapeW(
     FIXME("(%s %p %p 0x%08lx): stub\n",debugstr_w(pszUrl),
 	  pszEscaped, pcchEscaped, dwFlags);
     return E_NOTIMPL;
-}	
+}
 
 
 /*************************************************************************
@@ -290,3 +312,51 @@ HRESULT WINAPI UrlUnescapeW(
 	  pcchUnescaped, dwFlags);
     return E_NOTIMPL;
 }
+
+/*************************************************************************
+ *      HashData	[SHLWAPI]
+ *
+ * Hash an input block into a variable sized digest.
+ */
+BOOL WINAPI HashData(const unsigned char *lpSrc, INT nSrcLen,
+                     unsigned char *lpDest, INT nDestLen)
+{
+  INT srcCount = nSrcLen - 1, destCount = nDestLen - 1;
+
+  if (IsBadReadPtr(lpSrc, nSrcLen) ||
+      IsBadWritePtr(lpDest, nDestLen))
+    return FALSE;
+
+  while (destCount >= 0)
+  {
+    lpDest[destCount] = (destCount & 0xff);
+    destCount--;
+  }
+
+  while (srcCount >= 0)
+  {
+    destCount = nDestLen - 1;
+    while (destCount >= 0)
+    {
+      lpDest[destCount] = HashDataLookup[lpSrc[srcCount] ^ lpDest[destCount]];
+      destCount--;
+    }
+    srcCount--;
+  }
+  return TRUE;
+}
+
+/*************************************************************************
+ *      UrlHashA	[SHLWAPI]
+ *
+ * Hash an ASCII URL.
+ */
+HRESULT WINAPI UrlHashA(LPCSTR pszUrl, unsigned char *lpDest, INT nDestLen)
+{
+  if (IsBadStringPtrA(pszUrl, -1) || IsBadWritePtr(lpDest, nDestLen))
+    return E_INVALIDARG;
+
+  HashData(pszUrl, strlen(pszUrl), lpDest, nDestLen);
+  return NOERROR;
+}
+
diff --git a/tools/winapi_check/win32/shlwapi.api b/tools/winapi_check/win32/shlwapi.api
index c5b1ea1e333e7da58f9004b6d5495a10e109354e..3a7ede8a33196715b10dd7d1bc02f8ae67db8175 100644
--- a/tools/winapi_check/win32/shlwapi.api
+++ b/tools/winapi_check/win32/shlwapi.api
@@ -1,20 +1,28 @@
 %long
 
 BOOL
+COLORREF
 DWORD
 INT
 LONG
 HANDLE
 HDC
+HDROP
+HICON
+HINSTANCE
 HKEY
 HMENU
+HMODULE
 HPALETTE
 HRESULT
 HWND
+LPARAM
+LRESULT
 UCHAR
 UINT
 WCHAR
 WORD
+WPARAM
 
 %long # --forbidden
 
@@ -22,19 +30,34 @@ int
 
 %ptr
 
+BOOL *
 DLLVERSIONINFO *
+HICON *
 IStream *
 ITEMIDLIST *
 IUnknown *
+LPBROWSEINFOW
 LPBYTE
+LPCITEMIDLIST
 LPCLSID
 LPCVOID
 LPDWORD
+LPINT
+LPITEMIDLIST
+LPOPENFILENAMEW
+LPPAGESETUPDLGW
+LPPRINTDLGW
+LPSHELLEXECUTEINFOW
+LPSHFILEOPSTRUCTW
 LPSTRRET
+LPUNKNOWN *
 LPVOID
 REFIID
 REFGUID
+SHFILEINFOW *
+unsigned char *
 void *
+WNDCLASSA *
 
 %ptr --extension
 
@@ -53,4 +76,5 @@ void
 %wstr
 
 LPCWSTR
-LPWSTR
\ No newline at end of file
+LPWSTR
+