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