The attached patches fixes some functions of shlwapi I needed to run an application I wrote with BCB that was using MS XML Parser. I'm using it and works well AFAIK. -- Flameeyes <dgp85@xxxxxxxxxxxx> http://flameeyes.web.ctonet.it/
? dlls/kernel/comm.spec.c ? dlls/kernel/system.spec.c ? dlls/ntdll/ntdll.dll.glue.c ? dlls/ntdll/relay16.s ? dlls/user/display.spec.c ? dlls/user/keyboard.spec.c ? dlls/user/mouse.spec.c ? miscemu/Makefile ? miscemu/wine ? programs/osversioncheck/Makefile ? programs/osversioncheck/osversioncheck.exe.dbg.c ? programs/osversioncheck/osversioncheck.exe.spec.c ? programs/regapi/Makefile ? programs/regapi/regapi.exe.dbg.c ? programs/regapi/regapi.exe.spec.c ? programs/regtest/Makefile ? programs/regtest/regtest.exe.dbg.c ? programs/regtest/regtest.exe.spec.c ? tools/winewrap Index: dlls/shlwapi/path.c =================================================================== RCS file: /home/wine/wine/dlls/shlwapi/path.c,v retrieving revision 1.38 diff -u -3 -r1.38 path.c --- dlls/shlwapi/path.c 22 Sep 2003 19:46:32 -0000 1.38 +++ dlls/shlwapi/path.c 18 Dec 2003 18:52:54 -0000 @@ -3058,8 +3058,77 @@ */ BOOL WINAPI PathSearchAndQualifyA(LPCSTR lpszPath, LPSTR lpszBuf, UINT cchBuf) { - FIXME("(%s,%p,0x%08x)-stub\n", debugstr_a(lpszPath), lpszBuf, cchBuf); - return FALSE; + TRACE("(%s %p %d)\n", debugstr_a(lpszPath), lpszBuf, cchBuf); + + if (!lpszPath || !*lpszPath) + return FALSE; + + LPSTR temp_in = malloc(sizeof(*lpszPath) * cchBuf); + StrCpyA(temp_in, lpszPath); + lpszPath = temp_in; + LPSTR temp_out = lpszBuf; + LPSTR temp_out2 = temp_out; + BOOL ret = TRUE; + + if (*temp_in == '\\' && temp_in[1] == '\\') + { + /* Network share: skip share server and mount point */ + temp_in += 2; + if ((temp_in = StrChrA(temp_in, '\\')) && + (temp_in = StrChrA(temp_in + 1, '\\'))) + temp_in++; + } + + /* Check x:\ */ + if (temp_in[0] && temp_in[1] == ':' && temp_in[2] == '\\') + temp_in += 3; + + if ( temp_in != lpszPath ) + { + StrCpyNA(temp_out, lpszPath, (temp_in - lpszPath) +1); + temp_out += (temp_in - lpszPath); + temp_out2 = temp_out; + *temp_out = '\0'; + lpszPath = temp_in; + } else { + FIXME("must prepend current path"); + } + + while(*temp_in) + { + if ( *temp_in == '.' ) + { + if ( ! temp_in[1] ) + { ret = TRUE; break; } + + if ( temp_in[1] == '\\' ) { temp_in += 2; continue; } + + if ( temp_in[1] == '.' && temp_in[2] == '\\' ) + { + if ( temp_out == temp_out2 ) { temp_in += 3; continue; } + + temp_out = StrRChrA(temp_out, temp_out2, '\\'); + *temp_out = '\0'; continue; + } + } //if ( *temp_in == '.' ) + + if ( StrChrA(temp_in, '\\') ) + { + size_t len = (StrChrA(temp_in, '\\') - temp_in )+1; + StrCpyNA(temp_out, temp_in, len+1); + temp_out += len; + temp_in += len; + *temp_out = '\0'; continue; + } else { + StrCpyA(temp_out, temp_in); + break; + } + } // while + + TRACE("(%s)\n", debugstr_a(lpszBuf)); + + free(temp_in); + return ret; } /************************************************************************* @@ -3069,8 +3138,77 @@ */ BOOL WINAPI PathSearchAndQualifyW(LPCWSTR lpszPath, LPWSTR lpszBuf, UINT cchBuf) { - FIXME("(%s,%p,0x%08x)-stub\n", debugstr_w(lpszPath), lpszBuf, cchBuf); - return FALSE; + TRACE("(%s %p %d)\n", debugstr_w(lpszPath), lpszBuf, cchBuf); + + if (!lpszPath || !*lpszPath) + return FALSE; + + LPWSTR temp_in = malloc(sizeof(*lpszPath) * cchBuf); + StrCpyW(temp_in, lpszPath); + lpszPath = temp_in; + LPWSTR temp_out = lpszBuf; + LPWSTR temp_out2 = temp_out; + BOOL ret = TRUE; + + if (*temp_in == '\\' && temp_in[1] == '\\') + { + /* Network share: skip share server and mount point */ + temp_in += 2; + if ((temp_in = StrChrW(temp_in, '\\')) && + (temp_in = StrChrW(temp_in + 1, '\\'))) + temp_in++; + } + + /* Check x:\ */ + if (temp_in[0] && temp_in[1] == ':' && temp_in[2] == '\\') + temp_in += 3; + + if ( temp_in != lpszPath ) + { + StrCpyNW(temp_out, lpszPath, (temp_in - lpszPath) +1); + temp_out += (temp_in - lpszPath); + temp_out2 = temp_out; + *temp_out = '\0'; + lpszPath = temp_in; + } else { + FIXME("must prepend current path"); + } + + while(*temp_in) + { + if ( *temp_in == '.' ) + { + if ( ! temp_in[1] ) + { ret = TRUE; break; } + + if ( temp_in[1] == '\\' ) { temp_in += 2; continue; } + + if ( temp_in[1] == '.' && temp_in[2] == '\\' ) + { + if ( temp_out == temp_out2 ) { temp_in += 3; continue; } + + temp_out = StrRChrW(temp_out, temp_out2, '\\'); + *temp_out = '\0'; continue; + } + } //if ( *temp_in == '.' ) + + if ( StrChrW(temp_in, '\\') ) + { + size_t len = (StrChrW(temp_in, '\\') - temp_in )+1; + StrCpyNW(temp_out, temp_in, len+1); + temp_out += len; + temp_in += len; + *temp_out = '\0'; continue; + } else { + StrCpyW(temp_out, temp_in); + break; + } + } // while + + TRACE("(%s)\n", debugstr_w(lpszBuf)); + + free(temp_in); + return ret; } /************************************************************************* @@ -3187,7 +3325,7 @@ HRESULT WINAPI PathCreateFromUrlW(LPCWSTR lpszUrl, LPWSTR lpszPath, LPDWORD pcchPath, DWORD dwFlags) { - static const WCHAR stemp[] = { 'f','i','l','e',':','/','/',0 }; + static const WCHAR stemp[] = { 'f','i','l','e',':','/','/', '/', 0 }; LPWSTR pwszPathPart; HRESULT hr; @@ -3196,6 +3334,11 @@ if (!lpszUrl || !lpszPath || !pcchPath || !*pcchPath) return E_INVALIDARG; + /* Path of the form file:///... */ + if (!strncmpW(lpszUrl, stemp, 8)) + { + lpszUrl += 8; + } /* Path of the form file://... */ if (!strncmpW(lpszUrl, stemp, 7)) { Index: dlls/shlwapi/url.c =================================================================== RCS file: /home/wine/wine/dlls/shlwapi/url.c,v retrieving revision 1.26 diff -u -3 -r1.26 url.c --- dlls/shlwapi/url.c 1 Oct 2003 03:10:42 -0000 1.26 +++ dlls/shlwapi/url.c 18 Dec 2003 18:53:00 -0000 @@ -464,7 +464,19 @@ nByteLen = (lstrlenW(pszUrl) + 1) * sizeof(WCHAR); /* length in bytes */ lpszUrlCpy = HeapAlloc(GetProcessHeap(), 0, nByteLen); - if (dwFlags & URL_DONT_SIMPLIFY) + if (dwFlags & URL_FILE_USE_PATHURL && ( *pszUrl && pszUrl[1] == ':' && pszUrl[2] == '\\' ) ) + { + pszCanonicalized[0] = 'f'; + pszCanonicalized[1] = 'i'; + pszCanonicalized[2] = 'l'; + pszCanonicalized[3] = 'e'; + pszCanonicalized[4] = ':'; + pszCanonicalized[5] = '/'; + pszCanonicalized[6] = '/'; + StrCpyW(pszCanonicalized+7, pszUrl); + TRACE("result %s\n", debugstr_w(pszCanonicalized)); + return S_OK; + } else if (dwFlags & URL_DONT_SIMPLIFY) memcpy(lpszUrlCpy, pszUrl, nByteLen); else { @@ -1693,8 +1705,12 @@ case URLIS_URL: case URLIS_NOHISTORY: case URLIS_FILEURL: + return !StrCmpNA("file://", pszUrl, 7); case URLIS_APPLIABLE: - case URLIS_DIRECTORY: + case URLIS_DIRECTORY: { + LPCWSTR last = StrChrW(pszUrl, '\0') -1; + return ( *last == '/' || *last == '\\' ); + } case URLIS_HASQUERY: default: FIXME("(%s %d): stub\n", debugstr_a(pszUrl), Urlis); @@ -1712,6 +1728,7 @@ UNKNOWN_SHLWAPI_2 base; DWORD res1; + TRACE("(%s %d)\n", debugstr_w(pszUrl), Urlis); switch (Urlis) { case URLIS_OPAQUE: @@ -1726,8 +1743,13 @@ case URLIS_URL: case URLIS_NOHISTORY: case URLIS_FILEURL: + return pszUrl[0] == 'f' && pszUrl[1] == 'i' && pszUrl[2] == 'l' + && pszUrl[3] == 'e' && pszUrl[4] == ':' && pszUrl[5] == '/' && pszUrl[6] == '/'; case URLIS_APPLIABLE: - case URLIS_DIRECTORY: + case URLIS_DIRECTORY: { + LPCWSTR last = StrChrW(pszUrl, '\0') -1; + return ( *last == '/' || *last == '\\' ); + } case URLIS_HASQUERY: default: FIXME("(%s %d): stub\n", debugstr_w(pszUrl), Urlis); @@ -2175,26 +2197,29 @@ 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 */ + if ( ! (pszPath[0] && pszPath[1] == ':' && pszPath[2] == '\\') ) { - dwChRequired = lstrlenA(pszPath); - if (dwChRequired > *pcchUrl) + for (pszConstPointer = pszPath; *pszConstPointer; pszConstPointer++) { - *pcchUrl = dwChRequired; - return E_POINTER; + if (isalpha(*pszConstPointer) || isdigit(*pszConstPointer) || + *pszConstPointer == '.' || *pszConstPointer == '-') + nCharBeforeColon++; + else break; } - else + if (*pszConstPointer == ':') /* then already in URL format, so copy */ { - *pcchUrl = dwChRequired; - StrCpyA(pszUrl, pszPath); - return S_FALSE; + 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 */ @@ -2248,6 +2273,8 @@ pszPointer++; } StrCpyA(pszPointer, pszNewUrl); + LPWSTR slash; + while((slash = StrChrW(pszUrl, '\\'))) *slash = '/'; TRACE("<- %s\n", debugstr_a(pszUrl)); return S_OK; } @@ -2276,23 +2303,26 @@ 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 */ + if ( ! (pszPath[0] && pszPath[1] == ':' && pszPath[2] == '\\') ) { - dwChRequired = lstrlenW(pszPath); - *pcchUrl = dwChRequired; - if (dwChRequired > *pcchUrl) - return E_POINTER; - else + for (pszConstPointer = pszPath; *pszConstPointer; pszConstPointer++) + { + if (isalphaW(*pszConstPointer) || isdigitW(*pszConstPointer) || + *pszConstPointer == '.' || *pszConstPointer == '-') + nCharBeforeColon++; + else break; + } + if (*pszConstPointer == ':') /* then already in URL format, so copy */ { - StrCpyW(pszUrl, pszPath); - return S_FALSE; + 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 */ @@ -2346,6 +2376,9 @@ } StrCpyW(pszPointer, pszPath); StrCpyW(pszUrl, pszNewUrl); + + LPWSTR slash; + while((slash = StrChrW(pszUrl, '\\'))) *slash = '/'; return S_OK; }