Reorganise/minor tidyup of ordinal functions.
Implement StrCmpLogicalW,StrFormatByteSizeA/W,StrFormatByteSize64A,
SHCreateStreamWrapper.
Fix some output .spec parameters from str to ptr.
Fix definition of StrFormatByteSize functions.

diff --git a/dlls/shlwapi/ordinal.c b/dlls/shlwapi/ordinal.c
index 3c9b148..3a2a7b3 100644
--- a/dlls/shlwapi/ordinal.c
+++ b/dlls/shlwapi/ordinal.c
@@ -46,12 +46,21 @@
 #include "winreg.h"
 #include "winuser.h"
 #include "wine/debug.h"
-#include "ordinal.h"
 #include "shlwapi.h"
 
 
 WINE_DEFAULT_DEBUG_CHANNEL(shell);
 
+/* Get a function pointer from a DLL handle */
+#define GET_FUNC(func, module, name, fail) \
+  do { \
+    if (!func) { \
+      if (!SHLWAPI_h##module && !(SHLWAPI_h##module = LoadLibraryA(#module ".dll"))) return fail; \
+      if (!(func = (void*)GetProcAddress(SHLWAPI_h##module, name))) return fail; \
+    } \
+  } while (0)
+
+/* DLL handles for late bound calls */
 extern HINSTANCE shlwapi_hInstance;
 extern HMODULE SHLWAPI_hshell32;
 extern HMODULE SHLWAPI_hwinmm;
@@ -70,61 +79,7 @@
 /* following is GUID for IPersistMoniker::GetClassID  -- see _174        */
 static DWORD id2[4] = {0x79eac9ee, 0x11cebaf9, 0xaa00828c, 0x0ba94b00};
 
-/* The following schemes were identified in the native version of
- * SHLWAPI.DLL version 5.50
- */
-typedef enum {
-    URL_SCHEME_INVALID     = -1,
-    URL_SCHEME_UNKNOWN     =  0,
-    URL_SCHEME_FTP,
-    URL_SCHEME_HTTP,
-    URL_SCHEME_GOPHER,
-    URL_SCHEME_MAILTO,
-    URL_SCHEME_NEWS,
-    URL_SCHEME_NNTP,
-    URL_SCHEME_TELNET,
-    URL_SCHEME_WAIS,
-    URL_SCHEME_FILE,
-    URL_SCHEME_MK,
-    URL_SCHEME_HTTPS,
-    URL_SCHEME_SHELL,
-    URL_SCHEME_SNEWS,
-    URL_SCHEME_LOCAL,
-    URL_SCHEME_JAVASCRIPT,
-    URL_SCHEME_VBSCRIPT,
-    URL_SCHEME_ABOUT,
-    URL_SCHEME_RES,
-    URL_SCHEME_MAXVALUE
-} URL_SCHEME;
-
-typedef struct {
-    URL_SCHEME  scheme_number;
-    LPCSTR scheme_name;
-} SHL_2_inet_scheme;
-
-static const SHL_2_inet_scheme shlwapi_schemes[] = {
-  {URL_SCHEME_FTP,        "ftp"},
-  {URL_SCHEME_HTTP,       "http"},
-  {URL_SCHEME_GOPHER,     "gopher"},
-  {URL_SCHEME_MAILTO,     "mailto"},
-  {URL_SCHEME_NEWS,       "news"},
-  {URL_SCHEME_NNTP,       "nntp"},
-  {URL_SCHEME_TELNET,     "telnet"},
-  {URL_SCHEME_WAIS,       "wais"},
-  {URL_SCHEME_FILE,       "file"},
-  {URL_SCHEME_MK,         "mk"},
-  {URL_SCHEME_HTTPS,      "https"},
-  {URL_SCHEME_SHELL,      "shell"},
-  {URL_SCHEME_SNEWS,      "snews"},
-  {URL_SCHEME_LOCAL,      "local"},
-  {URL_SCHEME_JAVASCRIPT, "javascript"},
-  {URL_SCHEME_VBSCRIPT,   "vbscript"},
-  {URL_SCHEME_ABOUT,      "about"},
-  {URL_SCHEME_RES,        "res"},
-  {0, 0}
-};
-
-/* function pointers for GET_FUNC macro; these need to be global because of gcc bug */
+/* Function pointers for GET_FUNC macro; these need to be global because of gcc bug */
 static LPITEMIDLIST (WINAPI *pSHBrowseForFolderW)(LPBROWSEINFOW);
 static HRESULT (WINAPI *pConvertINetUnicodeToMultiByte)(LPDWORD,DWORD,LPCWSTR,LPINT,LPSTR,LPINT);
 static BOOL    (WINAPI *pPlaySoundW)(LPCWSTR, HMODULE, DWORD);
@@ -160,189 +115,6 @@
 */
 
 /*************************************************************************
- *      @	[SHLWAPI.1]
- *
- * Identifies the Internet "scheme" in the passed string. ASCII based.
- * Also determines start and length of item after the ':'
- */
-DWORD WINAPI SHLWAPI_1 (LPCSTR x, UNKNOWN_SHLWAPI_1 *y)
-{
-    DWORD cnt;
-    const SHL_2_inet_scheme *inet_pro;
-
-    y->fcncde = URL_SCHEME_INVALID;
-    if (y->size != 0x18) return E_INVALIDARG;
-    /* FIXME: leading white space generates error of 0x80041001 which
-     *        is undefined
-     */
-    if (*x <= ' ') return 0x80041001;
-    cnt = 0;
-    y->sizep1 = 0;
-    y->ap1 = x;
-    while (*x) {
-	if (*x == ':') {
-	    y->sizep1 = cnt;
-	    cnt = -1;
-	    y->ap2 = x+1;
-	    break;
-	}
-	x++;
-	cnt++;
-    }
-
-    /* check for no scheme in string start */
-    /* (apparently schemes *must* be larger than a single character)  */
-    if ((*x == '\0') || (y->sizep1 <= 1)) {
-	y->ap1 = 0;
-	return 0x80041001;
-    }
-
-    /* found scheme, set length of remainder */
-    y->sizep2 = lstrlenA(y->ap2);
-
-    /* see if known scheme and return indicator number */
-    y->fcncde = URL_SCHEME_UNKNOWN;
-    inet_pro = shlwapi_schemes;
-    while (inet_pro->scheme_name) {
-	if (!strncasecmp(inet_pro->scheme_name, y->ap1,
-		    min(y->sizep1, lstrlenA(inet_pro->scheme_name)))) {
-	    y->fcncde = inet_pro->scheme_number;
-	    break;
-	}
-	inet_pro++;
-    }
-    return S_OK;
-}
-
-/*************************************************************************
- *      @	[SHLWAPI.2]
- *
- * Identifies the Internet "scheme" in the passed string. UNICODE based.
- * Also determines start and length of item after the ':'
- */
-DWORD WINAPI SHLWAPI_2 (LPCWSTR x, UNKNOWN_SHLWAPI_2 *y)
-{
-    DWORD cnt;
-    const SHL_2_inet_scheme *inet_pro;
-    LPSTR cmpstr;
-    INT len;
-
-    y->fcncde = URL_SCHEME_INVALID;
-    if (y->size != 0x18) return E_INVALIDARG;
-    /* FIXME: leading white space generates error of 0x80041001 which
-     *        is undefined
-     */
-    if (*x <= L' ') return 0x80041001;
-    cnt = 0;
-    y->sizep1 = 0;
-    y->ap1 = x;
-    while (*x) {
-	if (*x == L':') {
-	    y->sizep1 = cnt;
-	    cnt = -1;
-	    y->ap2 = x+1;
-	    break;
-	}
-	x++;
-	cnt++;
-    }
-
-    /* check for no scheme in string start */
-    /* (apparently schemes *must* be larger than a single character)  */
-    if ((*x == L'\0') || (y->sizep1 <= 1)) {
-	y->ap1 = 0;
-	return 0x80041001;
-    }
-
-    /* found scheme, set length of remainder */
-    y->sizep2 = lstrlenW(y->ap2);
-
-    /* see if known scheme and return indicator number */
-    len = WideCharToMultiByte(0, 0, y->ap1, y->sizep1, 0, 0, 0, 0);
-    cmpstr = (LPSTR)HeapAlloc(GetProcessHeap(), 0, len+1);
-    WideCharToMultiByte(0, 0, y->ap1, y->sizep1, cmpstr, len+1, 0, 0);
-    y->fcncde = URL_SCHEME_UNKNOWN;
-    inet_pro = shlwapi_schemes;
-    while (inet_pro->scheme_name) {
-	if (!strncasecmp(inet_pro->scheme_name, cmpstr,
-		    min(len, lstrlenA(inet_pro->scheme_name)))) {
-	    y->fcncde = inet_pro->scheme_number;
-	    break;
-	}
-	inet_pro++;
-    }
-    HeapFree(GetProcessHeap(), 0, cmpstr);
-    return S_OK;
-}
-
-/*************************************************************************
- * @	[SHLWAPI.3]
- *
- * Determine if a file exists locally and is of an executable type.
- *
- * PARAMS
- *  lpszFile       [O] File to search for
- *  dwWhich        [I] Type of executable to search for
- *
- * RETURNS
- *  TRUE  If the file was found. lpszFile contains the file name.
- *  FALSE Otherwise.
- *
- * NOTES
- *  lpszPath is modified in place and must be at least MAX_PATH in length.
- *  If the function returns FALSE, the path is modified to its orginal state.
- *  If the given path contains an extension or dwWhich is 0, executable
- *  extensions are not checked.
- *
- *  Ordinals 3-6 are a classic case of MS exposing limited functionality to
- *  users (here through PathFindOnPath) and keeping advanced functionality for
- *  their own developers exclusive use. Monopoly, anyone?
- */
-BOOL WINAPI SHLWAPI_3(LPSTR lpszFile,DWORD dwWhich)
-{
-  return SHLWAPI_PathFindLocalExeA(lpszFile,dwWhich);
-}
-
-/*************************************************************************
- * @	[SHLWAPI.4]
- *
- * Unicode version of SHLWAPI_3.
- */
-BOOL WINAPI SHLWAPI_4(LPWSTR lpszFile,DWORD dwWhich)
-{
-  return SHLWAPI_PathFindLocalExeW(lpszFile,dwWhich);
-}
-
-/*************************************************************************
- * @	[SHLWAPI.5]
- *
- * Search a range of paths for a specific type of executable.
- *
- * PARAMS
- *  lpszFile       [O] File to search for
- *  lppszOtherDirs [I] Other directories to look in
- *  dwWhich        [I] Type of executable to search for
- *
- * RETURNS
- *  Success: TRUE. The path to the executable is stored in sFile.
- *  Failure: FALSE. The path to the executable is unchanged.
- */
-BOOL WINAPI SHLWAPI_5(LPSTR lpszFile,LPCSTR *lppszOtherDirs,DWORD dwWhich)
-{
-  return SHLWAPI_PathFindOnPathExA(lpszFile,lppszOtherDirs,dwWhich);
-}
-
-/*************************************************************************
- * @	[SHLWAPI.6]
- *
- * Unicode version of SHLWAPI_5.
- */
-BOOL WINAPI SHLWAPI_6(LPWSTR lpszFile,LPCWSTR *lppszOtherDirs,DWORD dwWhich)
-{
-  return SHLWAPI_PathFindOnPathExW(lpszFile,lppszOtherDirs,dwWhich);
-}
-
-/*************************************************************************
  * SHLWAPI_DupSharedHandle
  *
  * Internal implemetation of SHLWAPI_11.
diff --git a/dlls/shlwapi/path.c b/dlls/shlwapi/path.c
index fe06174..1b2db26 100644
--- a/dlls/shlwapi/path.c
+++ b/dlls/shlwapi/path.c
@@ -35,11 +35,22 @@
 #define NO_SHLWAPI_STREAM
 #include "shlwapi.h"
 #include "wine/debug.h"
-#include "ordinal.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(shell);
 
-/* function pointers for GET_FUNC macro; these need to be global because of gcc bug */
+/* Get a function pointer from a DLL handle */
+#define GET_FUNC(func, module, name, fail) \
+  do { \
+    if (!func) { \
+      if (!SHLWAPI_h##module && !(SHLWAPI_h##module = LoadLibraryA(#module ".dll"))) return fail; \
+      if (!(func = (void*)GetProcAddress(SHLWAPI_h##module, name))) return fail; \
+    } \
+  } while (0)
+
+/* DLL handles for late bound calls */
+extern HMODULE SHLWAPI_hshell32;
+
+/* Function pointers for GET_FUNC macro; these need to be global because of gcc bug */
 static BOOL (WINAPI *pIsNetDrive)(DWORD);
 
 /*************************************************************************
@@ -1035,33 +1046,11 @@
 }
 
 /*************************************************************************
- * SHLWAPI_PathFindLocalExeA
+ * @	[SHLWAPI.4]
  *
- * Internal implementation of SHLWAPI_3.
+ * Unicode version of SHLWAPI_3.
  */
-BOOL WINAPI SHLWAPI_PathFindLocalExeA (LPSTR lpszPath, DWORD dwWhich)
-{
-  BOOL bRet = FALSE;
-
-  TRACE("(%s,%ld)\n", debugstr_a(lpszPath), dwWhich);
-
-  if (lpszPath)
-  {
-    WCHAR szPath[MAX_PATH];
-    MultiByteToWideChar(0,0,lpszPath,-1,szPath,MAX_PATH);
-    bRet = SHLWAPI_PathFindLocalExeW(szPath, dwWhich);
-    if (bRet)
-      WideCharToMultiByte(0,0,szPath,-1,lpszPath,MAX_PATH,0,0);
-  }
-  return bRet;
-}
-
-/*************************************************************************
- * SHLWAPI_PathFindLocalExeW
- *
- * Internal implementation of SHLWAPI_4.
- */
-BOOL WINAPI SHLWAPI_PathFindLocalExeW (LPWSTR lpszPath, DWORD dwWhich)
+BOOL WINAPI SHLWAPI_4(LPWSTR lpszPath,DWORD dwWhich)
 {
   static const WCHAR pszExts[7][5] = { { '.', 'p', 'i', 'f', '0'},
                                        { '.', 'c', 'o', 'm', '0'},
@@ -1101,6 +1090,46 @@
 }
 
 /*************************************************************************
+ * @	[SHLWAPI.3]
+ *
+ * Determine if a file exists locally and is of an executable type.
+ *
+ * PARAMS
+ *  lpszPath       [O] File to search for
+ *  dwWhich        [I] Type of executable to search for
+ *
+ * RETURNS
+ *  TRUE  If the file was found. lpszFile contains the file name.
+ *  FALSE Otherwise.
+ *
+ * NOTES
+ *  lpszPath is modified in place and must be at least MAX_PATH in length.
+ *  If the function returns FALSE, the path is modified to its orginal state.
+ *  If the given path contains an extension or dwWhich is 0, executable
+ *  extensions are not checked.
+ *
+ *  Ordinals 3-6 are a classic case of MS exposing limited functionality to
+ *  users (here through PathFindOnPath) and keeping advanced functionality for
+ *  their own developers exclusive use. Monopoly, anyone?
+ */
+BOOL WINAPI SHLWAPI_3(LPSTR lpszPath,DWORD dwWhich)
+{
+  BOOL bRet = FALSE;
+
+  TRACE("(%s,%ld)\n", debugstr_a(lpszPath), dwWhich);
+
+  if (lpszPath)
+  {
+    WCHAR szPath[MAX_PATH];
+    MultiByteToWideChar(0,0,lpszPath,-1,szPath,MAX_PATH);
+    bRet = SHLWAPI_4(szPath, dwWhich);
+    if (bRet)
+      WideCharToMultiByte(0,0,szPath,-1,lpszPath,MAX_PATH,0,0);
+  }
+  return bRet;
+}
+
+/*************************************************************************
  * SHLWAPI_PathFindInOtherDirs
  *
  * Internal helper for SHLWAPI_PathFindOnPathExA/W.
@@ -1120,7 +1149,7 @@
   GetSystemDirectoryW(buff, MAX_PATH);
   if (!PathAppendW(buff, lpszFile))
      return FALSE;
-  if (SHLWAPI_PathFindLocalExeW(buff, dwWhich))
+  if (SHLWAPI_4(buff, dwWhich))
   {
     strcpyW(lpszFile, buff);
     return TRUE;
@@ -1128,7 +1157,7 @@
   GetWindowsDirectoryW(buff, MAX_PATH);
   if (!PathAppendW(buff, szSystem ) || !PathAppendW(buff, lpszFile))
     return FALSE;
-  if (SHLWAPI_PathFindLocalExeW(buff, dwWhich))
+  if (SHLWAPI_4(buff, dwWhich))
   {
     strcpyW(lpszFile, buff);
     return TRUE;
@@ -1136,7 +1165,7 @@
   GetWindowsDirectoryW(buff, MAX_PATH);
   if (!PathAppendW(buff, lpszFile))
     return FALSE;
-  if (SHLWAPI_PathFindLocalExeW(buff, dwWhich))
+  if (SHLWAPI_4(buff, dwWhich))
   {
     strcpyW(lpszFile, buff);
     return TRUE;
@@ -1167,7 +1196,7 @@
 
     if (!PathAppendW(buff, lpszFile))
       return FALSE;
-    if (SHLWAPI_PathFindLocalExeW(buff, dwWhich))
+    if (SHLWAPI_4(buff, dwWhich))
     {
       strcpyW(lpszFile, buff);
       free(lpszPATH);
@@ -1178,13 +1207,21 @@
   return FALSE;
 }
 
-
 /*************************************************************************
- * SHLWAPI_PathFindOnPathExA
+ * @	[SHLWAPI.5]
  *
- * Internal implementation of SHLWAPI_5
+ * Search a range of paths for a specific type of executable.
+ *
+ * PARAMS
+ *  lpszFile       [O] File to search for
+ *  lppszOtherDirs [I] Other directories to look in
+ *  dwWhich        [I] Type of executable to search for
+ *
+ * RETURNS
+ *  Success: TRUE. The path to the executable is stored in sFile.
+ *  Failure: FALSE. The path to the executable is unchanged.
  */
-BOOL WINAPI SHLWAPI_PathFindOnPathExA(LPSTR lpszFile, LPCSTR *lppszOtherDirs, DWORD dwWhich)
+BOOL WINAPI SHLWAPI_5(LPSTR lpszFile,LPCSTR *lppszOtherDirs,DWORD dwWhich)
 {
   WCHAR szFile[MAX_PATH];
   WCHAR buff[MAX_PATH];
@@ -1206,7 +1243,7 @@
     {
       MultiByteToWideChar(0,0,*lpszOtherPath,-1,szOther,MAX_PATH);
       PathCombineW(buff, szOther, szFile);
-      if (SHLWAPI_PathFindLocalExeW(buff, dwWhich))
+      if (SHLWAPI_4(buff, dwWhich))
       {
         WideCharToMultiByte(0,0,buff,-1,lpszFile,MAX_PATH,0,0);
         return TRUE;
@@ -1224,11 +1261,11 @@
 }
 
 /*************************************************************************
- * SHLWAPI_PathFindOnPathExW
+ * @	[SHLWAPI.6]
  *
- * Internal implementation of SHLWAPI_6.
+ * Unicode version of SHLWAPI_5.
  */
-BOOL WINAPI SHLWAPI_PathFindOnPathExW(LPWSTR lpszFile, LPCWSTR *lppszOtherDirs, DWORD dwWhich)
+BOOL WINAPI SHLWAPI_6(LPWSTR lpszFile,LPCWSTR *lppszOtherDirs,DWORD dwWhich)
 {
   WCHAR buff[MAX_PATH];
 
@@ -1244,7 +1281,7 @@
     while (lpszOtherPath && *lpszOtherPath && (*lpszOtherPath)[0])
     {
       PathCombineW(buff, *lpszOtherPath, lpszFile);
-      if (SHLWAPI_PathFindLocalExeW(buff, dwWhich))
+      if (SHLWAPI_4(buff, dwWhich))
       {
         strcpyW(lpszFile, buff);
         return TRUE;
@@ -1272,7 +1309,7 @@
 BOOL WINAPI PathFindOnPathA(LPSTR lpszFile, LPCSTR *lppszOtherDirs)
 {
   TRACE("(%s,%p)\n", debugstr_a(lpszFile), lppszOtherDirs);
-  return SHLWAPI_PathFindOnPathExA(lpszFile, lppszOtherDirs, 0);
+  return SHLWAPI_5(lpszFile, lppszOtherDirs, 0);
  }
 
 /*************************************************************************
@@ -1280,10 +1317,10 @@
  *
  * See PathFindOnPathA.
  */
-BOOL WINAPI PathFindOnPathW (LPWSTR lpszFile, LPCWSTR *lppszOtherDirs)
+BOOL WINAPI PathFindOnPathW(LPWSTR lpszFile, LPCWSTR *lppszOtherDirs)
 {
   TRACE("(%s,%p)\n", debugstr_w(lpszFile), lppszOtherDirs);
-  return SHLWAPI_PathFindOnPathExW(lpszFile,lppszOtherDirs, 0);
+  return SHLWAPI_6(lpszFile,lppszOtherDirs, 0);
 }
 
 /*************************************************************************
@@ -1837,47 +1874,6 @@
 }
 
 /*************************************************************************
- * PathIsURLA	[SHLWAPI.@]
- *
- * Check if the given path is a URL.
- *
- * PARAMS
- *  lpszPath [I] Path to check.
- *
- * RETURNS
- *  TRUE  if lpszPath is a URL.
- *  FALSE if lpszPath is NULL or not a URL.
- */
-BOOL WINAPI PathIsURLA(LPCSTR lpstrPath)
-{
-    UNKNOWN_SHLWAPI_1 base;
-    DWORD res1;
-
-    if (!lpstrPath || !*lpstrPath) return FALSE;
-
-    /* get protocol        */
-    base.size = sizeof(base);
-    res1 = SHLWAPI_1(lpstrPath, &base);
-    return (base.fcncde > 0);
-}
-
-/*************************************************************************
- * PathIsURLW	[SHLWAPI.@]
- */
-BOOL WINAPI PathIsURLW(LPCWSTR lpstrPath)
-{
-    UNKNOWN_SHLWAPI_2 base;
-    DWORD res1;
-
-    if (!lpstrPath || !*lpstrPath) return FALSE;
-
-    /* get protocol        */
-    base.size = sizeof(base);
-    res1 = SHLWAPI_2(lpstrPath, &base);
-    return (base.fcncde > 0);
-}
-
-/*************************************************************************
  * PathIsContentTypeA   [SHLWAPI.@]
  *
  * Determine if a file is of a given registered content type.
diff --git a/dlls/shlwapi/regstream.c b/dlls/shlwapi/regstream.c
index 64400f8..49f3a3b 100644
--- a/dlls/shlwapi/regstream.c
+++ b/dlls/shlwapi/regstream.c
@@ -505,3 +505,43 @@
   }
   return iStrmRet;
 }
+
+/*************************************************************************
+ * SHCreateStreamWrapper   [SHLWAPI.@]
+ *
+ * Create a stream on a block of memory.
+ *
+ * PARAMS
+ * lpbData    [I] Memory block to create the stream on
+ * dwDataLen  [I] Length of data block
+ * dwReserved [I] Reserved, Must be 0.
+ * lppStream  [O] Destination for stream object
+ *
+ * RETURNS
+ * Success: S_OK. lppStream contains the new stream object.
+ * Failure: E_INVALIDARG, if any parameters are invalid,
+ *          E_OUTOFMEMORY if memory allocation fails.
+ *
+ * NOTES
+ *  The stream assumes ownership of the memory passed to it.
+ */
+HRESULT WINAPI SHCreateStreamWrapper(LPBYTE lpbData, DWORD dwDataLen,
+                                     DWORD dwReserved, IStream **lppStream)
+{
+  IStream* lpStream;
+
+  if (lppStream)
+    *lppStream = NULL;
+
+  if(dwReserved || !lppStream)
+    return E_INVALIDARG;
+
+  lpStream = IStream_Create((HKEY)0, lpbData, dwDataLen);
+
+  if(!lpStream)
+    return E_OUTOFMEMORY;
+
+  IStream_QueryInterface(lpStream, &IID_IStream, (void**)lppStream);
+  IStream_Release(lpStream);
+  return S_OK;
+}
diff --git a/dlls/shlwapi/shlwapi.spec b/dlls/shlwapi/shlwapi.spec
index 193bb9d..cbd02e0 100644
--- a/dlls/shlwapi/shlwapi.spec
+++ b/dlls/shlwapi/shlwapi.spec
@@ -623,10 +623,10 @@
 @ stdcall StrCpyW (ptr wstr) StrCpyW
 @ stdcall StrDupA (str) StrDupA
 @ stdcall StrDupW (wstr) StrDupW
-@ stdcall StrFormatByteSizeA(long str long) StrFormatByteSizeA
-@ stdcall StrFormatByteSizeW(long wstr long) StrFormatByteSizeW
-@ stdcall StrFromTimeIntervalA(str long long long) StrFromTimeIntervalA
-@ stdcall StrFromTimeIntervalW(wstr long long long) StrFromTimeIntervalW
+@ stdcall StrFormatByteSizeA(long ptr long) StrFormatByteSizeA
+@ stdcall StrFormatByteSizeW(long long ptr long) StrFormatByteSizeW
+@ stdcall StrFromTimeIntervalA(ptr long long long) StrFromTimeIntervalA
+@ stdcall StrFromTimeIntervalW(ptr long long long) StrFromTimeIntervalW
 @ stdcall StrIsIntlEqualA(long str str long) StrIsIntlEqualA
 @ stdcall StrIsIntlEqualW(long wstr wstr long) StrIsIntlEqualW
 @ stdcall StrNCatA(str str long) StrNCatA
@@ -711,7 +711,7 @@
 @ stdcall SHCreateStreamOnFileA(str long ptr) SHCreateStreamOnFileA
 @ stdcall SHCreateStreamOnFileW(wstr long ptr) SHCreateStreamOnFileW
 @ stdcall SHCreateStreamOnFileEx(wstr long long long ptr ptr) SHCreateStreamOnFileEx
-@ stub    SHCreateStreamWrapper
+@ stdcall SHCreateStreamWrapper(ptr ptr long ptr) SHCreateStreamWrapper
 @ stdcall SHGetThreadRef (ptr) SHGetThreadRef
 @ stdcall SHRegDuplicateHKey (long) SHRegDuplicateHKey
 @ stdcall SHRegSetPathA(long str str str long) SHRegSetPathA
@@ -722,6 +722,7 @@
 @ stdcall SHSkipJunction(ptr ptr) SHSkipJunction
 @ stdcall SHStrDupA (str ptr) SHStrDupA
 @ stdcall SHStrDupW (wstr ptr) SHStrDupW
-@ stub    StrFormatByteSize64A
+@ stdcall StrFormatByteSize64A(long long ptr long) StrFormatByteSize64A
 @ stdcall StrFormatKBSizeA(long long str long) StrFormatKBSizeA
 @ stdcall StrFormatKBSizeW(long long wstr long) StrFormatKBSizeW
+@ stdcall StrCmpLogicalW(wstr wstr) StrCmpLogicalW
diff --git a/dlls/shlwapi/string.c b/dlls/shlwapi/string.c
index 45db498..fe466eb 100644
--- a/dlls/shlwapi/string.c
+++ b/dlls/shlwapi/string.c
@@ -23,6 +23,7 @@
 #include "wine/port.h"
 
 #include <ctype.h>
+#include <math.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
@@ -1494,40 +1495,6 @@
 }
 
 /*************************************************************************
- * StrFormatByteSizeA				[SHLWAPI.@]
- */
-LPSTR WINAPI StrFormatByteSizeA ( DWORD dw, LPSTR pszBuf, UINT cchBuf )
-{	char buf[64];
-	TRACE("%lx %p %i\n", dw, pszBuf, cchBuf);
-	if ( dw<1024L )
-	{ sprintf (buf,"%ld bytes", dw);
-	}
-	else if ( dw<1048576L)
-	{ sprintf (buf,"%3.1f KB", (FLOAT)dw/1024);
-	}
-	else if ( dw < 1073741824L)
-	{ sprintf (buf,"%3.1f MB", (FLOAT)dw/1048576L);
-	}
-	else
-	{ sprintf (buf,"%3.1f GB", (FLOAT)dw/1073741824L);
-	}
-	lstrcpynA (pszBuf, buf, cchBuf);
-	return pszBuf;
-}
-
-/*************************************************************************
- * StrFormatByteSizeW				[SHLWAPI.@]
- */
-LPWSTR WINAPI StrFormatByteSizeW ( DWORD dw, LPWSTR pszBuf, UINT cchBuf )
-{
-        char buf[64];
-        StrFormatByteSizeA( dw, buf, sizeof(buf) );
-        if (!MultiByteToWideChar( CP_ACP, 0, buf, -1, pszBuf, cchBuf ) && cchBuf)
-            pszBuf[cchBuf-1] = 0;
-        return pszBuf;
-}
-
-/*************************************************************************
  * StrFormatKBSizeA	[SHLWAPI.@]
  *
  * Create a formatted string containing a byte count in Kilobytes.
@@ -2123,3 +2090,212 @@
   }
   return lpszDest;
 }
+
+/*************************************************************************
+ * StrCmpLogicalW	[SHLWAPI.@]
+ *
+ * Compare two strings, ignoring case and comparing digits as numbers.
+ *
+ * PARAMS
+ *  lpszStr  [I] First string to compare
+ *  lpszComp [I] Second string to compare
+ *  iLen     [I] Length to compare
+ *
+ * RETURNS
+ *  TRUE  If the strings are equal.
+ *  FALSE Otherwise.
+ */
+INT WINAPI StrCmpLogicalW(LPCWSTR lpszStr, LPCWSTR lpszComp)
+{
+  INT iDiff;
+
+  TRACE("(%s,%s)\n", debugstr_w(lpszStr), debugstr_w(lpszComp));
+
+  if (lpszStr && lpszComp)
+  {
+    while (*lpszStr)
+    {
+      if (!*lpszComp)
+        return 1;
+      else if (isdigitW(*lpszStr))
+      {
+        int iStr, iComp;
+
+        if (!isdigitW(*lpszComp))
+          return -1;
+
+        /* Compare the numbers */
+        StrToIntExW(lpszStr, 0, &iStr);
+        StrToIntExW(lpszComp, 0, &iComp);
+
+        if (iStr < iComp)
+          return -1;
+        else if (iStr > iComp)
+          return 1;
+
+        /* Skip */
+        while (isdigitW(*lpszStr))
+          lpszStr++;
+        while (isdigitW(*lpszComp))
+          lpszComp++;
+      }
+      else if (isdigitW(*lpszComp))
+        return 1;
+      else
+      {
+        iDiff = SHLWAPI_ChrCmpHelperA(*lpszStr,*lpszComp,NORM_IGNORECASE);
+        if (iDiff > 0)
+          return 1;
+        else if (iDiff < 0)
+          return -1;
+
+        lpszStr++;
+        lpszComp++;
+      }
+    }
+    if (*lpszComp)
+      return -1;
+  }
+  return 0;
+}
+
+/* Structure for formatting byte strings */
+typedef struct tagSHLWAPI_BYTEFORMATS
+{
+  LONGLONG dLimit;
+  double   dDivisor;
+  double   dNormaliser;
+  LPCSTR   lpszFormat;
+  CHAR     wPrefix;
+} SHLWAPI_BYTEFORMATS;
+
+/*************************************************************************
+ * StrFormatByteSize64A	[SHLWAPI.@]
+ *
+ * Create a string containing an abbreviated byte count of up to 2^63-1.
+ *
+ * PARAMS
+ *  llBytes  [I] Byte size to format
+ *  lpszDest [I] Destination for formatted string
+ *  cchMax   [I] Size of lpszDest
+ *
+ * RETURNS
+ *  lpszDest.
+ *
+ * NOTES
+ *  There is no StrFormatByteSize64W function, it is called StrFormatByteSizeW.
+ */
+LPSTR WINAPI StrFormatByteSize64A(LONGLONG llBytes, LPSTR lpszDest, UINT cchMax)
+{
+  static const char szBytes[] = "%ld bytes";
+  static const char sz3_0[] = "%3.0f";
+  static const char sz3_1[] = "%3.1f";
+  static const char sz3_2[] = "%3.2f";
+
+  static const SHLWAPI_BYTEFORMATS bfFormats[] =
+  {
+    { 10240, 10.24, 100.0, sz3_2, 'K' }, /* 10 KB */
+    { 102400, 102.4, 10.0, sz3_1, 'K' }, /* 100 KB */
+    { 1024000, 1024.0, 1.0, sz3_0, 'K' }, /* 1000 KB */
+    { 10485760, 10485.76, 100.0, sz3_2, 'M' }, /* 10 MB */
+    { 104857600, 104857.6, 10.0, sz3_1, 'M' }, /* 100 MB */
+    { 1048576000, 1048576.0, 1.0, sz3_0, 'M' }, /* 1000 MB */
+    { 10737418240, 10737418.24, 100.0, sz3_2, 'G' }, /* 10 GB */
+    { 107374182400, 107374182.4, 10.0, sz3_1, 'G' }, /* 100 GB */
+    { 1073741824000, 1073741824.0, 1.0, sz3_0, 'G' }, /* 1000 GB */
+    { 10995116277760, 10485.76, 100.0, sz3_2, 'T' }, /* 10 TB */
+    { 109951162777600, 104857.6, 10.0, sz3_1, 'T' }, /* 100 TB */
+    { 1099511627776000, 1048576.0, 1.0, sz3_0, 'T' }, /* 1000 TB */
+    { 11258999068426240, 10737418.24, 100.00, sz3_2, 'P' }, /* 10 PB */
+    { 112589990684262400, 107374182.4, 10.00, sz3_1, 'P' }, /* 100 PB */
+    { 1125899906842624000, 1073741824.0, 1.00, sz3_0, 'P' }, /* 1000 PB */
+    { 0, 10995116277.76, 100.00, sz3_2, 'E' } /* EB's, catch all */
+  };
+  char szBuff[32];
+  char szAdd[4];
+  double dBytes;
+  UINT i = 0;
+
+  TRACE("(%lld,%p,%d)\n", llBytes, lpszDest, cchMax);
+
+  if (!lpszDest || !cchMax)
+    return lpszDest;
+
+  if (llBytes < 1024)  /* 1K */
+  {
+    snprintf (lpszDest, cchMax, szBytes, (long)llBytes);
+    return lpszDest;
+  }
+
+  /* Note that if this loop completes without finding a match, i will be
+   * pointing at the last entry, which is a catch all for > 1000 PB
+   */
+  while (i < sizeof(bfFormats) / sizeof(SHLWAPI_BYTEFORMATS) - 1)
+  {
+    if (llBytes < bfFormats[i].dLimit)
+      break;
+    i++;
+  }
+  /* Above 1 TB we encounter problems with FP accuracy. So for amounts above
+   * this number we integer shift down by 1 MB first. The table above has
+   * the divisors scaled down from the '< 10 TB' entry onwards, to account
+   * for this. We also add a small fudge factor to get the correct result for
+   * counts that lie exactly on a 1024 byte boundary.
+   */
+  if (i > 8)
+    dBytes = (double)(llBytes >> 20) + 0.001; /* Scale down by I MB */
+  else
+    dBytes = (double)llBytes + 0.00001;
+
+  dBytes = floor(dBytes / bfFormats[i].dDivisor) / bfFormats[i].dNormaliser;
+
+  sprintf(szBuff, bfFormats[i].lpszFormat, dBytes);
+  szAdd[0] = ' ';
+  szAdd[1] = bfFormats[i].wPrefix;
+  szAdd[2] = 'B';
+  szAdd[3] = '\0';
+  strcat(szBuff, szAdd);
+  strncpy(lpszDest, szBuff, cchMax);
+  return lpszDest;
+}
+
+/*************************************************************************
+ * StrFormatByteSizeW	[SHLWAPI.@]
+ *
+ * See StrFormatByteSize64A.
+ */
+LPWSTR WINAPI StrFormatByteSizeW(LONGLONG llBytes, LPWSTR lpszDest,
+                                 UINT cchMax)
+{
+  char szBuff[32];
+
+  StrFormatByteSize64A(llBytes, szBuff, sizeof(szBuff));
+
+  if (lpszDest)
+    MultiByteToWideChar(CP_ACP, 0, szBuff, -1, lpszDest, cchMax);
+  return lpszDest;
+}
+
+/*************************************************************************
+ * StrFormatByteSizeA	[SHLWAPI.@]
+ *
+ * Create a string containing an abbreviated byte count of up to 2^31-1.
+ *
+ * PARAMS
+ *  dwBytes  [I] Byte size to format
+ *  lpszDest [I] Destination for formatted string
+ *  cchMax   [I] Size of lpszDest
+ *
+ * RETURNS
+ *  lpszDest.
+ *
+ * NOTES
+ *  The ASCII and Unicode versions of this function accept a different
+ *  integer size for dwBytes. See StrFormatByteSize64A.
+ */
+LPSTR WINAPI StrFormatByteSizeA(DWORD dwBytes, LPSTR lpszDest, UINT cchMax)
+{
+  TRACE("(%ld,%p,%d)\n", dwBytes, lpszDest, cchMax);
+
+  return StrFormatByteSize64A(dwBytes, lpszDest, cchMax);
+}
diff --git a/dlls/shlwapi/thread.c b/dlls/shlwapi/thread.c
index 0a3f187..4b97af2 100644
--- a/dlls/shlwapi/thread.c
+++ b/dlls/shlwapi/thread.c
@@ -30,14 +30,26 @@
 #define NO_SHLWAPI_STREAM
 #define NO_SHLWAPI_USER
 #include "shlwapi.h"
-#include "ordinal.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(shell);
 
-extern DWORD SHLWAPI_ThreadRef_index;  /* Initialised in shlwapi_main.c */
+/* Get a function pointer from a DLL handle */
+#define GET_FUNC(func, module, name, fail) \
+  do { \
+    if (!func) { \
+      if (!SHLWAPI_h##module && !(SHLWAPI_h##module = LoadLibraryA(#module ".dll"))) return fail; \
+      if (!(func = (void*)GetProcAddress(SHLWAPI_h##module, name))) return fail; \
+    } \
+  } while (0)
 
+/* DLL handles for late bound calls */
+extern HMODULE SHLWAPI_hshell32;
+
+/* Function pointers for GET_FUNC macro; these need to be global because of gcc bug */
 static HRESULT (WINAPI *pSHGetInstanceExplorer)(IUnknown**);
 
+extern DWORD SHLWAPI_ThreadRef_index;  /* Initialised in shlwapi_main.c */
+
 DWORD WINAPI SHLWAPI_23(REFGUID,LPSTR,INT);
 
 /**************************************************************************
diff --git a/dlls/shlwapi/url.c b/dlls/shlwapi/url.c
index 7a0048e..387ae9d 100644
--- a/dlls/shlwapi/url.c
+++ b/dlls/shlwapi/url.c
@@ -30,10 +30,63 @@
 #define NO_SHLWAPI_STREAM
 #include "shlwapi.h"
 #include "wine/debug.h"
-#include "ordinal.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(shell);
 
+/* The following schemes were identified in the native version of
+ * SHLWAPI.DLL version 5.50
+ */
+typedef enum {
+    URL_SCHEME_INVALID     = -1,
+    URL_SCHEME_UNKNOWN     =  0,
+    URL_SCHEME_FTP,
+    URL_SCHEME_HTTP,
+    URL_SCHEME_GOPHER,
+    URL_SCHEME_MAILTO,
+    URL_SCHEME_NEWS,
+    URL_SCHEME_NNTP,
+    URL_SCHEME_TELNET,
+    URL_SCHEME_WAIS,
+    URL_SCHEME_FILE,
+    URL_SCHEME_MK,
+    URL_SCHEME_HTTPS,
+    URL_SCHEME_SHELL,
+    URL_SCHEME_SNEWS,
+    URL_SCHEME_LOCAL,
+    URL_SCHEME_JAVASCRIPT,
+    URL_SCHEME_VBSCRIPT,
+    URL_SCHEME_ABOUT,
+    URL_SCHEME_RES,
+    URL_SCHEME_MAXVALUE
+} URL_SCHEME;
+
+typedef struct {
+    URL_SCHEME  scheme_number;
+    LPCSTR scheme_name;
+} SHL_2_inet_scheme;
+
+static const SHL_2_inet_scheme shlwapi_schemes[] = {
+  {URL_SCHEME_FTP,        "ftp"},
+  {URL_SCHEME_HTTP,       "http"},
+  {URL_SCHEME_GOPHER,     "gopher"},
+  {URL_SCHEME_MAILTO,     "mailto"},
+  {URL_SCHEME_NEWS,       "news"},
+  {URL_SCHEME_NNTP,       "nntp"},
+  {URL_SCHEME_TELNET,     "telnet"},
+  {URL_SCHEME_WAIS,       "wais"},
+  {URL_SCHEME_FILE,       "file"},
+  {URL_SCHEME_MK,         "mk"},
+  {URL_SCHEME_HTTPS,      "https"},
+  {URL_SCHEME_SHELL,      "shell"},
+  {URL_SCHEME_SNEWS,      "snews"},
+  {URL_SCHEME_LOCAL,      "local"},
+  {URL_SCHEME_JAVASCRIPT, "javascript"},
+  {URL_SCHEME_VBSCRIPT,   "vbscript"},
+  {URL_SCHEME_ABOUT,      "about"},
+  {URL_SCHEME_RES,        "res"},
+  {0, 0}
+};
+
 typedef struct {
     LPCWSTR pScheme;      /* [out] start of scheme                     */
     DWORD   szScheme;     /* [out] size of scheme (until colon)        */
@@ -56,6 +109,24 @@
     USERPASS,
 } WINE_URL_SCAN_TYPE;
 
+typedef struct {
+    INT     size;      /* [in]  (always 0x18)                       */
+    LPCSTR  ap1;       /* [out] start of scheme                     */
+    INT     sizep1;    /* [out] size of scheme (until colon)        */
+    LPCSTR  ap2;       /* [out] pointer following first colon       */
+    INT     sizep2;    /* [out] size of remainder                   */
+    INT     fcncde;    /* [out] function match of p1 (0 if unknown) */
+} UNKNOWN_SHLWAPI_1;
+
+typedef struct {
+    INT     size;      /* [in]  (always 0x18)                       */
+    LPCWSTR ap1;       /* [out] start of scheme                     */
+    INT     sizep1;    /* [out] size of scheme (until colon)        */
+    LPCWSTR ap2;       /* [out] pointer following first colon       */
+    INT     sizep2;    /* [out] size of remainder                   */
+    INT     fcncde;    /* [out] function match of p1 (0 if unknown) */
+} UNKNOWN_SHLWAPI_2;
+
 static const CHAR hexDigits[] = "0123456789ABCDEF";
 
 static const WCHAR fileW[] = {'f','i','l','e','\0'};
@@ -186,6 +257,122 @@
 
 
 /*************************************************************************
+ *      @	[SHLWAPI.1]
+ *
+ * Identifies the Internet "scheme" in the passed string. ASCII based.
+ * Also determines start and length of item after the ':'
+ */
+DWORD WINAPI SHLWAPI_1 (LPCSTR x, UNKNOWN_SHLWAPI_1 *y)
+{
+    DWORD cnt;
+    const SHL_2_inet_scheme *inet_pro;
+
+    y->fcncde = URL_SCHEME_INVALID;
+    if (y->size != 0x18) return E_INVALIDARG;
+    /* FIXME: leading white space generates error of 0x80041001 which
+     *        is undefined
+     */
+    if (*x <= ' ') return 0x80041001;
+    cnt = 0;
+    y->sizep1 = 0;
+    y->ap1 = x;
+    while (*x) {
+	if (*x == ':') {
+	    y->sizep1 = cnt;
+	    cnt = -1;
+	    y->ap2 = x+1;
+	    break;
+	}
+	x++;
+	cnt++;
+    }
+
+    /* check for no scheme in string start */
+    /* (apparently schemes *must* be larger than a single character)  */
+    if ((*x == '\0') || (y->sizep1 <= 1)) {
+	y->ap1 = 0;
+	return 0x80041001;
+    }
+
+    /* found scheme, set length of remainder */
+    y->sizep2 = lstrlenA(y->ap2);
+
+    /* see if known scheme and return indicator number */
+    y->fcncde = URL_SCHEME_UNKNOWN;
+    inet_pro = shlwapi_schemes;
+    while (inet_pro->scheme_name) {
+	if (!strncasecmp(inet_pro->scheme_name, y->ap1,
+		    min(y->sizep1, lstrlenA(inet_pro->scheme_name)))) {
+	    y->fcncde = inet_pro->scheme_number;
+	    break;
+	}
+	inet_pro++;
+    }
+    return S_OK;
+}
+
+/*************************************************************************
+ *      @	[SHLWAPI.2]
+ *
+ * Identifies the Internet "scheme" in the passed string. UNICODE based.
+ * Also determines start and length of item after the ':'
+ */
+DWORD WINAPI SHLWAPI_2 (LPCWSTR x, UNKNOWN_SHLWAPI_2 *y)
+{
+    DWORD cnt;
+    const SHL_2_inet_scheme *inet_pro;
+    LPSTR cmpstr;
+    INT len;
+
+    y->fcncde = URL_SCHEME_INVALID;
+    if (y->size != 0x18) return E_INVALIDARG;
+    /* FIXME: leading white space generates error of 0x80041001 which
+     *        is undefined
+     */
+    if (*x <= L' ') return 0x80041001;
+    cnt = 0;
+    y->sizep1 = 0;
+    y->ap1 = x;
+    while (*x) {
+	if (*x == L':') {
+	    y->sizep1 = cnt;
+	    cnt = -1;
+	    y->ap2 = x+1;
+	    break;
+	}
+	x++;
+	cnt++;
+    }
+
+    /* check for no scheme in string start */
+    /* (apparently schemes *must* be larger than a single character)  */
+    if ((*x == L'\0') || (y->sizep1 <= 1)) {
+	y->ap1 = 0;
+	return 0x80041001;
+    }
+
+    /* found scheme, set length of remainder */
+    y->sizep2 = lstrlenW(y->ap2);
+
+    /* see if known scheme and return indicator number */
+    len = WideCharToMultiByte(0, 0, y->ap1, y->sizep1, 0, 0, 0, 0);
+    cmpstr = (LPSTR)HeapAlloc(GetProcessHeap(), 0, len+1);
+    WideCharToMultiByte(0, 0, y->ap1, y->sizep1, cmpstr, len+1, 0, 0);
+    y->fcncde = URL_SCHEME_UNKNOWN;
+    inet_pro = shlwapi_schemes;
+    while (inet_pro->scheme_name) {
+	if (!strncasecmp(inet_pro->scheme_name, cmpstr,
+		    min(len, lstrlenA(inet_pro->scheme_name)))) {
+	    y->fcncde = inet_pro->scheme_number;
+	    break;
+	}
+	inet_pro++;
+    }
+    HeapFree(GetProcessHeap(), 0, cmpstr);
+    return S_OK;
+}
+
+/*************************************************************************
  *        UrlCanonicalizeA     [SHLWAPI.@]
  *
  * Uses the W version to do job.
@@ -1753,3 +1940,44 @@
     }
     return ret;
 }
+
+/*************************************************************************
+ * PathIsURLA	[SHLWAPI.@]
+ *
+ * Check if the given path is a URL.
+ *
+ * PARAMS
+ *  lpszPath [I] Path to check.
+ *
+ * RETURNS
+ *  TRUE  if lpszPath is a URL.
+ *  FALSE if lpszPath is NULL or not a URL.
+ */
+BOOL WINAPI PathIsURLA(LPCSTR lpstrPath)
+{
+    UNKNOWN_SHLWAPI_1 base;
+    DWORD res1;
+
+    if (!lpstrPath || !*lpstrPath) return FALSE;
+
+    /* get protocol        */
+    base.size = sizeof(base);
+    res1 = SHLWAPI_1(lpstrPath, &base);
+    return (base.fcncde > 0);
+}
+
+/*************************************************************************
+ * PathIsURLW	[SHLWAPI.@]
+ */
+BOOL WINAPI PathIsURLW(LPCWSTR lpstrPath)
+{
+    UNKNOWN_SHLWAPI_2 base;
+    DWORD res1;
+
+    if (!lpstrPath || !*lpstrPath) return FALSE;
+
+    /* get protocol        */
+    base.size = sizeof(base);
+    res1 = SHLWAPI_2(lpstrPath, &base);
+    return (base.fcncde > 0);
+}
diff --git a/include/shlwapi.h b/include/shlwapi.h
index 2201ac8..f7856dd 100644
--- a/include/shlwapi.h
+++ b/include/shlwapi.h
@@ -709,8 +709,17 @@
 #define SHStrDup WINELIB_NAME_AW(SHStrDup)
 
 LPSTR WINAPI StrFormatByteSizeA (DWORD,LPSTR,UINT);
-LPWSTR WINAPI StrFormatByteSizeW (DWORD,LPWSTR,UINT);
-#define StrFormatByteSize WINELIB_NAME_AW(StrFormatByteSize)
+
+/* A/W Pairing is broken for this function */
+LPSTR WINAPI StrFormatByteSize64A (LONGLONG,LPSTR,UINT);
+LPWSTR WINAPI StrFormatByteSizeW (LONGLONG,LPWSTR,UINT);
+#ifndef __WINE__
+#ifdef UNICODE
+#define StrFormatByteSize StrFormatByteSizeW
+#else
+#define StrFormatByteSize StrFormatByteSize64A
+#endif
+#endif
 
 int WINAPI StrFromTimeIntervalA(LPSTR,UINT,DWORD,int);
 int WINAPI StrFromTimeIntervalW(LPWSTR,UINT,DWORD,int);