shlwapi: UrlCreateFromPath

Huw D M Davies h.davies1 at physics.ox.ac.uk
Tue Oct 5 05:25:47 CDT 2004


Test to follow.

        Huw Davies <huw at codeweavers.com>
        Rewrite UrlCreateFromPath        
-- 
Huw Davies
huw at codeweavers.com
Index: dlls/shlwapi/url.c
===================================================================
RCS file: /home/wine/wine/dlls/shlwapi/url.c,v
retrieving revision 1.42
diff -u -r1.42 url.c
--- dlls/shlwapi/url.c	5 Oct 2004 04:11:49 -0000	1.42
+++ dlls/shlwapi/url.c	5 Oct 2004 09:52:21 -0000
@@ -2102,6 +2102,41 @@
 /*************************************************************************
  *      UrlCreateFromPathA  	[SHLWAPI.@]
  * 
+ * See UrlCreateFromPathW
+ */
+HRESULT WINAPI UrlCreateFromPathA(LPCSTR pszPath, LPSTR pszUrl, LPDWORD pcchUrl, DWORD dwReserved)
+{
+    WCHAR bufW[INTERNET_MAX_URL_LENGTH];
+    WCHAR *urlW = bufW;
+    UNICODE_STRING pathW;
+    HRESULT ret;
+    DWORD lenW = sizeof(bufW)/sizeof(WCHAR), lenA;
+
+    if(!RtlCreateUnicodeStringFromAsciiz(&pathW, pszPath))
+        return E_INVALIDARG;
+    if((ret = UrlCreateFromPathW(pathW.Buffer, urlW, &lenW, dwReserved)) == E_POINTER) {
+        urlW = HeapAlloc(GetProcessHeap(), 0, lenW * sizeof(WCHAR));
+        ret = UrlCreateFromPathW(pathW.Buffer, urlW, &lenW, dwReserved);
+    }
+    if(ret == S_OK || ret == S_FALSE) {
+        RtlUnicodeToMultiByteSize(&lenA, urlW, lenW * sizeof(WCHAR));
+        if(*pcchUrl > lenA) {
+            RtlUnicodeToMultiByteN(pszUrl, *pcchUrl - 1, &lenA, urlW, lenW * sizeof(WCHAR));
+            pszUrl[lenA] = 0;
+            *pcchUrl = lenA;
+        } else {
+            *pcchUrl = lenA + 1;
+            ret = E_POINTER;
+        }
+    }
+    if(urlW != bufW) HeapFree(GetProcessHeap(), 0, urlW);
+    RtlFreeUnicodeString(&pathW);
+    return ret;
+}
+
+/*************************************************************************
+ *      UrlCreateFromPathW  	[SHLWAPI.@]
+ *
  * Create a Url from a file path.
  *
  * PARAMS
@@ -2111,206 +2146,51 @@
  *  dwReserved [I] Reserved, must be 0
  *
  * RETURNS
- *  Success: S_OK. pszUrl contains the converted path.
+ *  Success: S_OK pszUrl contains the converted path, S_FALSE if the path is already a Url
  *  Failure: An HRESULT error code.
  */
-HRESULT WINAPI UrlCreateFromPathA(LPCSTR pszPath, LPSTR pszUrl, LPDWORD pcchUrl, DWORD dwReserved)
-{
-	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 (!pszUrl || !pcchUrl || !pszUrl)
-	{
-		ERR("Invalid argument\n");
-		return E_INVALIDARG;
-	}
-
-	for (pszConstPointer = pszPath; *pszConstPointer; pszConstPointer++)
-	{
-		if (isalpha(*pszConstPointer) || isdigit(*pszConstPointer) ||
-			*pszConstPointer == '.' || *pszConstPointer == '-')
-			nCharBeforeColon++;
-		else 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("%ld\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;
-}
-
-/*************************************************************************
- *      UrlCreateFromPathW  	[SHLWAPI.@]
- *
- * See UrlCreateFromPathA.
- */
 HRESULT WINAPI UrlCreateFromPathW(LPCWSTR pszPath, LPWSTR pszUrl, LPDWORD pcchUrl, DWORD dwReserved)
 {
-	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 (!pszUrl || !pcchUrl || !pszUrl)
-		return E_INVALIDARG;
-
-	for (pszConstPointer = pszPath; *pszConstPointer; pszConstPointer++)
-	{
-		if (isalphaW(*pszConstPointer) || isdigitW(*pszConstPointer) ||
-			*pszConstPointer == '.' || *pszConstPointer == '-')
-			nCharBeforeColon++;
-		else 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 */
+    DWORD needed;
+    HRESULT ret;
+    WCHAR *pszNewUrl;
+    WCHAR file_colonW[] = {'f','i','l','e',':',0};
+    WCHAR three_slashesW[] = {'/','/','/',0};
+    PARSEDURLW parsed_url;
+
+    TRACE("(%s, %p, %p, 0x%08lx)\n", debugstr_w(pszPath), pszUrl, pcchUrl, dwReserved);
+
+    /* Validate arguments */
+    if (dwReserved != 0)
+        return E_INVALIDARG;
+    if (!pszUrl || !pcchUrl)
+        return E_INVALIDARG;
+
+
+    parsed_url.cbSize = sizeof(parsed_url);
+    if(ParseURLW(pszPath, &parsed_url) == S_OK) {
+        if(parsed_url.nScheme != URL_SCHEME_INVALID && parsed_url.cchProtocol > 1) {
+            needed = strlenW(pszPath);
+            if (needed >= *pcchUrl) {
+                *pcchUrl = needed + 1;
+                return E_POINTER;
+            } else {
+                *pcchUrl = needed;
+                strcpyW(pszUrl, pszPath);
+                return S_FALSE;
+            }
+	}
+    }
+
+    pszNewUrl = HeapAlloc(GetProcessHeap(), 0, (strlenW(pszPath) + 9) * sizeof(WCHAR)); /* "file:///" + pszPath_len + 1 */
+    strcpyW(pszNewUrl, file_colonW);
+    if(isalphaW(pszPath[0]) && pszPath[1] == ':')
+        strcatW(pszNewUrl, three_slashesW);
+    strcatW(pszNewUrl, pszPath);
+    ret = UrlEscapeW(pszNewUrl, pszUrl, pcchUrl, URL_ESCAPE_PERCENT);
 
-	/* 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;
+    HeapFree(GetProcessHeap(), 0, pszNewUrl);
+    return ret;
 }
 
 /*************************************************************************



More information about the wine-patches mailing list