shlwapi.UrlCreateFromPath[AW] & shlwapi.PathCreateFromFileA

Robert Shearman R.J.Shearman at warwick.ac.uk
Wed Dec 11 16:13:15 CST 2002


These are used in certain circumstances in HtmlHelp viewer

ChangeLog:
- Implement UrlCreateFromPath[AW]
- Implement slightly related PathCreateFromFileA
-------------- next part --------------
Index: wine/dlls/shlwapi/path.c
===================================================================
RCS file: /home/wine/wine/dlls/shlwapi/path.c,v
retrieving revision 1.26
diff -u -r1.26 path.c
--- wine/dlls/shlwapi/path.c	13 Nov 2002 19:43:53 -0000	1.26
+++ wine/dlls/shlwapi/path.c	11 Dec 2002 20:28:48 -0000
@@ -3124,11 +3124,18 @@
 HRESULT WINAPI PathCreateFromUrlA(LPCSTR lpszUrl, LPSTR lpszPath,
                                   LPDWORD pcchPath, DWORD dwFlags)
 {
-  FIXME("(%s,%p,%p,0x%08lx)-stub\n", debugstr_a(lpszUrl), lpszPath, pcchPath, dwFlags);
+  LPSTR pszPathPart;
+  TRACE("(%s,%p,%p,0x%08lx)\n", debugstr_a(lpszUrl), lpszPath, pcchPath, dwFlags);

   if (!lpszUrl || !lpszPath || !pcchPath || !*pcchPath)
     return E_INVALIDARG;

+  pszPathPart = StrChrA(lpszUrl, ':');
+  if ((((pszPathPart - lpszUrl) == 1) && isalpha(*lpszUrl)) ||
+         !lstrcmpA(lpszUrl, "file:"))
+  {
+    return UrlUnescapeA(pszPathPart, lpszPath, pcchPath, dwFlags);
+  }
     /* extracts thing prior to : in pszURL and checks against:
      *   https
      *   shell
@@ -3136,7 +3143,7 @@
      *   about  - if match returns E_INVALIDARG
      */

-  return S_OK;
+  return E_INVALIDARG;
 }

 /*************************************************************************
Index: wine/dlls/shlwapi/shlwapi.spec
===================================================================
RCS file: /home/wine/wine/dlls/shlwapi/shlwapi.spec,v
retrieving revision 1.63
diff -u -r1.63 shlwapi.spec
--- wine/dlls/shlwapi/shlwapi.spec	7 Dec 2002 23:48:10 -0000	1.63
+++ wine/dlls/shlwapi/shlwapi.spec	11 Dec 2002 20:28:51 -0000
@@ -657,8 +657,8 @@
 @ stdcall UrlCombineW(wstr wstr wstr ptr long) UrlCombineW
 @ stdcall UrlCompareA(str str long) UrlCompareA
 @ stdcall UrlCompareW(wstr wstr long) UrlCompareW
-@ stub    UrlCreateFromPathA
-@ stub    UrlCreateFromPathW
+@ stdcall UrlCreateFromPathA(str ptr ptr long) UrlCreateFromPathA
+@ stdcall UrlCreateFromPathW(wstr ptr ptr long) UrlCreateFromPathW
 @ stdcall UrlEscapeA(str ptr ptr long)UrlEscapeA
 @ stdcall UrlEscapeW(wstr ptr ptr long)UrlEscapeW
 @ stdcall UrlGetLocationA(str) UrlGetLocationA
Index: wine/dlls/shlwapi/url.c
===================================================================
RCS file: /home/wine/wine/dlls/shlwapi/url.c,v
retrieving revision 1.19
diff -u -r1.19 url.c
--- wine/dlls/shlwapi/url.c	20 Sep 2002 19:41:08 -0000	1.19
+++ wine/dlls/shlwapi/url.c	11 Dec 2002 20:28:56 -0000
@@ -181,7 +181,7 @@
 	case '{':
 	case '}':
 	case '|':
-	case '\\':
+//	case '\\':
 	case '^':
 	case ']':
 	case '[':
@@ -921,8 +921,8 @@
     char next[3], *dst = pszEscaped;
     INT len;

-    TRACE("(%s %p %p 0x%08lx)\n", debugstr_a(pszUrl), pszEscaped,
-	  pcchEscaped, dwFlags);
+    TRACE("(%s %p %lx 0x%08lx)\n", debugstr_a(pszUrl), pszEscaped,
+	  *pcchEscaped, dwFlags);

     if(dwFlags & ~(URL_ESCAPE_SPACES_ONLY |
 		   URL_ESCAPE_SEGMENT_ONLY |
@@ -1981,3 +1981,210 @@
     res1 = SHLWAPI_2(lpstrPath, &base);
     return (base.fcncde > 0);
 }
+
+/*************************************************************************
+ *      UrlCreateFromPathA  	[SHLWAPI.@]
+ */
+HRESULT WINAPI UrlCreateFromPathA(LPCSTR pszPath, LPSTR pszUrl, LPDWORD pcchUrl, DWORD dwReserved)
+{
+	// Variables used
+	DWORD nCharBeforeColon = 0;
+	DWORD nSlashes = 0;
+	DWORD dwChRequired = 0;
+	LPSTR pszNewUrl = NULL;
+	LPCSTR pszConstPointer = NULL;
+	LPSTR pszPointer = NULL;
+	DWORD i;
+	HRESULT ret;
+
+    TRACE("(%s, %p, %p, 0x%08lx)\n", debugstr_a(pszPath), pszUrl,
+	  pcchUrl, dwReserved);
+
+	// Validate arguments
+	if (dwReserved != 0)
+	{
+		FIXME("dwReserved should be 0: 0x%08lx\n", dwReserved);
+		return E_INVALIDARG;
+	}
+	if (IsBadStringPtrA(pszUrl, -1) || IsBadReadPtr(pcchUrl, sizeof(DWORD)) || IsBadWritePtr(pszUrl, *pcchUrl))
+	{
+		ERR("Invalid argument\n");
+		return E_INVALIDARG;
+	}
+
+	for (pszConstPointer = pszPath; *pszConstPointer; pszConstPointer++)
+	{
+		if (isalpha(*pszConstPointer) || isdigit(*pszConstPointer) ||
+			*pszConstPointer == '.' || *pszConstPointer == '-')
+			nCharBeforeColon++; continue;
+		break;
+	}
+	if (*pszConstPointer == ':') // then already in URL format, so copy
+	{
+		dwChRequired = lstrlenA(pszPath);
+		if (dwChRequired > *pcchUrl)
+		{
+			*pcchUrl = dwChRequired;
+			return E_POINTER;
+		}
+		else
+		{
+			*pcchUrl = dwChRequired;
+			StrCpyA(pszUrl, pszPath);
+			return S_FALSE;
+		}
+	}
+	// then must need converting to file: format
+
+	// Strip off leading slashes
+	while (*pszPath == '\\' || *pszPath == '/')
+	{
+		pszPath++;
+		nSlashes++;
+	}
+
+	dwChRequired = *pcchUrl; /* UrlEscape will fill this in with the correct amount */
+	TRACE("pszUrl: %s\n", debugstr_a(pszPath));
+	pszNewUrl = HeapAlloc(GetProcessHeap(), 0, dwChRequired + 1);
+	ret = UrlEscapeA(pszPath, pszNewUrl, &dwChRequired, URL_ESCAPE_PERCENT);
+	TRACE("ret: 0x%08lx, pszUrl: %s\n", ret, debugstr_a(pszNewUrl));
+	TRACE("%d\n", dwChRequired);
+	if (ret != E_POINTER && FAILED(ret))
+		return ret;
+	dwChRequired += 5; // "file:"
+	if ((lstrlenA(pszUrl) > 1) && isalpha(pszUrl[0]) && (pszUrl[1] == ':'))
+	{
+		dwChRequired += 3; // "///"
+		nSlashes = 3;
+	}
+	else
+		switch (nSlashes)
+		{
+		case 0: // no slashes
+			break;
+		case 2: // two slashes
+		case 4:
+		case 5:
+		case 6:
+			dwChRequired += 2;
+			nSlashes = 2;
+			break;
+		default: // three slashes
+			dwChRequired += 3;
+			nSlashes = 3;
+		}
+
+	if (dwChRequired > *pcchUrl)
+		return E_POINTER;
+	*pcchUrl = dwChRequired; // Return number of chars required (not including termination)
+	StrCpyA(pszUrl, "file:");
+	pszPointer = pszUrl + lstrlenA(pszUrl);
+	for (i=0; i < nSlashes; i++)
+	{
+		*pszPointer = '/';
+		pszPointer++;
+	}
+	StrCpyA(pszPointer, pszNewUrl);
+	TRACE("<- %s\n", debugstr_a(pszUrl));
+	return S_OK;
+}
+
+/*************************************************************************
+ *      UrlCreateFromPathA  	[SHLWAPI.@]
+ */
+HRESULT WINAPI UrlCreateFromPathW(LPCWSTR pszPath, LPWSTR pszUrl, LPDWORD pcchUrl, DWORD dwReserved)
+{
+	// Variables used
+	DWORD nCharBeforeColon = 0;
+	DWORD nSlashes = 0;
+	DWORD dwChRequired = 0;
+	LPWSTR pszNewUrl = NULL;
+	LPCWSTR pszConstPointer = NULL;
+	LPWSTR pszPointer = NULL;
+	DWORD i;
+	HRESULT ret;
+
+    TRACE("(%s, %p, %p, 0x%08lx)\n", debugstr_w(pszPath), pszUrl,
+	  pcchUrl, dwReserved);
+
+	// Validate arguments
+	if (dwReserved != 0)
+		return E_INVALIDARG;
+	if (IsBadStringPtrW(pszUrl, -1) || IsBadReadPtr(pcchUrl, sizeof(DWORD)) || IsBadWritePtr(pszUrl, *pcchUrl * sizeof(WCHAR)))
+		return E_INVALIDARG;
+
+	for (pszConstPointer = pszPath; *pszConstPointer; pszConstPointer++)
+	{
+		if (isalphaW(*pszConstPointer) || isdigitW(*pszConstPointer) ||
+			*pszConstPointer == '.' || *pszConstPointer == '-')
+			nCharBeforeColon++; continue;
+		break;
+	}
+	if (*pszConstPointer == ':') // then already in URL format, so copy
+	{
+		dwChRequired = lstrlenW(pszPath);
+		*pcchUrl = dwChRequired;
+		if (dwChRequired > *pcchUrl)
+			return E_POINTER;
+		else
+		{
+			StrCpyW(pszUrl, pszPath);
+			return S_FALSE;
+		}
+	}
+	// then must need converting to file: format
+
+	// Strip off leading slashes
+	while (*pszPath == '\\' || *pszPath == '/')
+	{
+		pszPath++;
+		nSlashes++;
+	}
+
+	dwChRequired = *pcchUrl; /* UrlEscape will fill this in with the correct amount */
+	ret = UrlEscapeW(pszPath, pszUrl, &dwChRequired, URL_ESCAPE_PERCENT);
+	if (ret != E_POINTER && FAILED(ret))
+		return ret;
+	dwChRequired += 5; // "file:"
+	if ((lstrlenW(pszUrl) > 1) && isalphaW(pszUrl[0]) && (pszUrl[1] == ':'))
+	{
+		dwChRequired += 3; // "///"
+		nSlashes = 3;
+	}
+	else
+		switch (nSlashes)
+		{
+		case 0: // no slashes
+			break;
+		case 2: // two slashes
+		case 4:
+		case 5:
+		case 6:
+			dwChRequired += 2;
+			nSlashes = 2;
+			break;
+		default: // three slashes
+			dwChRequired += 3;
+			nSlashes = 3;
+		}
+
+	*pcchUrl = dwChRequired; // Return number of chars required (not including termination)
+	if (dwChRequired > *pcchUrl)
+		return E_POINTER;
+	pszNewUrl = HeapAlloc(GetProcessHeap(), 0, (dwChRequired + 1) * sizeof(WCHAR));
+	StrCpyW(pszNewUrl, fileW);
+	pszPointer = pszNewUrl + 4;
+	*pszPointer = ':';
+	pszPointer++;
+	for (i=0; i < nSlashes; i++)
+	{
+		*pszPointer = '/';
+		pszPointer++;
+	}
+	StrCpyW(pszPointer, pszPath);
+	StrCpyW(pszUrl, pszNewUrl);
+	return S_OK;
+}


More information about the wine-patches mailing list