Changelog:
Jon Griffiths <jon_p_griffiths@yahoo.com>
+dlls/shlwapi/shlwapi.spec dlls/shlwapi/ordinal.c
dlls/shlwapi/url.c
Add @405/406, document URL functions
Fix MLLoadLibraryW prototype
__________________________________
Do you Yahoo!?
Yahoo! SiteBuilder - Free, easy-to-use web site design software
http://sitebuilder.yahoo.com
diff -u wine/dlls/shlwapi/ordinal.c wine-develop-old/dlls/shlwapi/ordinal.c
--- wine/dlls/shlwapi/ordinal.c 2003-09-11 17:11:13.000000000 +0100
+++ wine-develop-old/dlls/shlwapi/ordinal.c 2003-09-21 05:36:42.000000000 +0100
@@ -3453,7 +3453,7 @@
*
* Unicode version of MLLoadLibraryA.
*/
-DWORD WINAPI MLLoadLibraryW(LPCWSTR new_mod, HMODULE inst_hwnd, DWORD dwFlags)
+HMODULE WINAPI MLLoadLibraryW(LPCWSTR new_mod, HMODULE inst_hwnd, DWORD dwFlags)
{
WCHAR mod_path[2*MAX_PATH];
LPWSTR ptr;
@@ -3464,9 +3464,9 @@
if (ptr) {
strcpyW(ptr+1, new_mod);
TRACE("loading %s\n", debugstr_w(mod_path));
- return (DWORD)LoadLibraryW(mod_path);
+ return LoadLibraryW(mod_path);
}
- return 0;
+ return NULL;
}
/*************************************************************************
@@ -3629,15 +3629,6 @@
}
/*************************************************************************
- * @ [SHLWAPI.406]
- */
-DWORD WINAPI MLBuildResURLW(LPVOID u, LPVOID v, LPVOID w, LPVOID x, LPVOID y, LPVOID z)
-{
- FIXME("%p %p %p %p %p %p\n", u, v, w, x, y, z);
- return 0;
-}
-
-/*************************************************************************
* @ [SHLWAPI.413]
*
* Get the current docking status of the system.
diff -u wine/dlls/shlwapi/shlwapi.spec wine-develop-old/dlls/shlwapi/shlwapi.spec
--- wine/dlls/shlwapi/shlwapi.spec 2003-09-12 13:33:09.000000000 +0100
+++ wine-develop-old/dlls/shlwapi/shlwapi.spec 2003-09-21 05:20:00.000000000 +0100
@@ -402,8 +402,8 @@
402 stdcall -noname PrintDlgWrapW(ptr)
403 stdcall -noname GetOpenFileNameWrapW(ptr)
404 stub -noname IShellFolder_EnumObjects
-405 stub -noname MLBuildResURLA
-406 stdcall -noname MLBuildResURLW(ptr ptr ptr ptr ptr ptr)
+405 stdcall -noname MLBuildResURLA(str ptr long str ptr long)
+406 stdcall -noname MLBuildResURLW(wstr ptr long wstr ptr long)
407 stub -noname AssocMakeProgid
408 stub -noname AssocMakeShell
409 stub -noname AssocMakeApplicationByKeyW
Common subdirectories: wine/dlls/shlwapi/tests and wine-develop-old/dlls/shlwapi/tests
diff -u wine/dlls/shlwapi/url.c wine-develop-old/dlls/shlwapi/url.c
--- wine/dlls/shlwapi/url.c 2003-09-11 17:11:13.000000000 +0100
+++ wine-develop-old/dlls/shlwapi/url.c 2003-09-21 05:35:55.000000000 +0100
@@ -18,6 +18,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include "config.h"
+#include "wine/port.h" /* strcasecmp */
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
@@ -32,6 +34,10 @@
#include "shlwapi.h"
#include "wine/debug.h"
+HMODULE WINAPI MLLoadLibraryW(LPCWSTR,HMODULE,DWORD);
+BOOL WINAPI MLFreeLibrary(HMODULE);
+HRESULT WINAPI MLBuildResURLW(LPCWSTR,HMODULE,DWORD,LPCWSTR,LPWSTR,DWORD);
+
WINE_DEFAULT_DEBUG_CHANNEL(shell);
/* The following schemes were identified in the native version of
@@ -154,7 +160,7 @@
0x25, 0x45, 0x27, 0x75, 0x92, 0xB8, 0xA3, 0xC8, 0xDE, 0xEB, 0xF8, 0xF3, 0xDB,
0x0A, 0x98, 0x83, 0x7B, 0xE5, 0xCB, 0x4C, 0x78, 0xD1 };
-static BOOL URL_NeedEscapeA(CHAR ch, DWORD dwFlags)
+static inline BOOL URL_NeedEscapeA(CHAR ch, DWORD dwFlags)
{
if (isalnum(ch))
@@ -199,7 +205,7 @@
}
}
-static BOOL URL_NeedEscapeW(WCHAR ch, DWORD dwFlags)
+static inline BOOL URL_NeedEscapeW(WCHAR ch, DWORD dwFlags)
{
if (isalnumW(ch))
@@ -244,7 +250,7 @@
}
}
-static BOOL URL_JustLocation(LPCWSTR str)
+static BOOL WINAPI URL_JustLocation(LPCWSTR str)
{
while(*str && (*str == L'/')) str++;
if (*str) {
@@ -394,8 +400,7 @@
* Success: S_OK. The pszCanonicalized contains the converted Url.
* Failure: E_POINTER, if *pcchCanonicalized is too small.
*
- * MSDN is wrong (at 10/30/01 - go figure). This should support the
- * following flags: GLA
+ * MSDN incorrectly describes the flags for this function. They should be:
*| URL_DONT_ESCAPE_EXTRA_INFO 0x02000000
*| URL_ESCAPE_SPACES_ONLY 0x04000000
*| URL_ESCAPE_PERCENT 0x00001000
@@ -601,7 +606,19 @@
/*************************************************************************
* UrlCombineA [SHLWAPI.@]
*
- * Uses the W version to do job.
+ * Combine two Urls.
+ *
+ * PARAMS
+ * pszBase [I] Base Url
+ * pszRelative [I] Url to combine with pszBase
+ * pszCombined [O] Destination for combined Url
+ * pcchCombined [O] Destination for length of pszCombined
+ * dwFlags [I] URL_ flags from "shlwapi.h"
+ *
+ * RETURNS
+ * Success: S_OK. pszCombined contains the combined Url, pcchCombined
+ * contains its length.
+ * Failure: An HRESULT error code indicating the error.
*/
HRESULT WINAPI UrlCombineA(LPCSTR pszBase, LPCSTR pszRelative,
LPSTR pszCombined, LPDWORD pcchCombined,
@@ -644,6 +661,8 @@
/*************************************************************************
* UrlCombineW [SHLWAPI.@]
+ *
+ * See UrlCombineA.
*/
HRESULT WINAPI UrlCombineW(LPCWSTR pszBase, LPCWSTR pszRelative,
LPWSTR pszCombined, LPDWORD pcchCombined,
@@ -698,7 +717,7 @@
* it ends at next '/' or end of string.
*/
while(*work && (*work != L'/')) work++;
- sizeloc = work - base.ap2;
+ sizeloc = (DWORD)(work - base.ap2);
}
}
@@ -707,7 +726,7 @@
*/
work = strrchrW((base.ap2+sizeloc), L'/');
if (work) {
- len = work - base.ap2 + 1;
+ len = (DWORD)(work - base.ap2 + 1);
base.sizep2 = len;
}
/*
@@ -902,31 +921,35 @@
/*************************************************************************
* UrlEscapeA [SHLWAPI.@]
*
+ * Converts unsafe characters in a Url into escape sequences.
+ *
+ * PARAMS
+ * pszUrl [I] Url to modify
+ * pszEscaped [O] Destination for modified Url
+ * pcchEscaped [I/O] Length of pszUrl, destination for length of pszEscaped
+ * dwFlags [I] URL_ flags from "shlwapi.h"
+ *
+ * RETURNS
+ * Success: S_OK. pszEscaped contains the escaped Url, pcchEscaped
+ * contains its length.
+ * Failure: E_POINTER, if pszEscaped is not large enough. In this case
+ * pcchEscaped is set to the required length.
+
* Converts unsafe characters into their escape sequences.
*
* NOTES
- * The converted string is returned in pszEscaped if the buffer size
- * (which should be supplied in pcchEscaped) is large enough, in this
- * case the function returns S_OK and pcchEscaped contains the length
- * of the escaped string. If the buffer is not large enough the
- * function returns E_POINTER and pcchEscaped contains the required
- * buffer size (including room for the '\0').
- *
- * By default the function stops converting at the first '?' or
- * '#'. [MSDN says differently]. If URL_ESCAPE_SPACES_ONLY flag is set
- * then only spaces are converted, but the conversion continues past a
- * '?' or '#'.
+ * - By default this function stops converting at the first '?' or
+ * '#' character (MSDN does not document this).
+ * - If dwFlags contains URL_ESCAPE_SPACES_ONLY then only spaces are
+ * converted, but the conversion continues past a '?' or '#'.
+ * - Note that this function did not work well (or at all) in shlwapi version 4.
*
- * BUGS:
- * Have now implemented the following flags:
+ * BUGS
+ * Only the following flags are implemented:
*| URL_ESCAPE_SPACES_ONLY
*| URL_DONT_ESCAPE_EXTRA_INFO
*| URL_ESCAPE_SEGMENT_ONLY
*| URL_ESCAPE_PERCENT
- * Initial testing seems to indicate that this is now working like
- * native shlwapi version 5. Note that these functions did not work
- * well (or at all) in shlwapi version 4.
- *
*/
HRESULT WINAPI UrlEscapeA(
LPCSTR pszUrl,
@@ -1089,7 +1112,7 @@
/*************************************************************************
* UrlUnescapeA [SHLWAPI.@]
*
- * Converts escape sequences back to ordinary characters.
+ * Converts Url escape sequences back to ordinary characters.
*
* PARAMS
* pszUrl [I/O] Url to convert
@@ -1104,7 +1127,7 @@
* this case pcchUnescaped is set to the size required.
* NOTES
* If dwFlags includes URL_DONT_ESCAPE_EXTRA_INFO, the conversion stops at
- * the first occurrence of either '?' or '#'.
+ * the first occurrence of either a '?' or '#' character.
*/
HRESULT WINAPI UrlUnescapeA(
LPCSTR pszUrl,
@@ -1242,17 +1265,14 @@
* no location.
*
* NOTES
- * MSDN (as of 2001-11-01) says that:
- * "The location is the segment of the URL starting with a ?
- * or # character."
- * Neither V4 nor V5 of shlwapi.dll implement the '?' and always return
- * a NULL.
- *
- * MSDN further states that:
- * "If a file URL has a query string, the returned string is
- * the query string."
- * In all test cases if the scheme starts with "fi" then a NULL is
- * returned. V5 gives the following results:
+ * - MSDN erroneously states that "The location is the segment of the Url
+ * starting with a '?' or '#' character". Neither V4 nor V5 of shlwapi.dll
+ * stop at '?' and always return a NULL in this case.
+ * - MSDN also erroneously states that "If a file URL has a query string,
+ * the returned string is the query string". In all tested cases, if the
+ * Url starts with "fi" then a NULL is returned. V5 gives the following results:
+ *| Result Url
+ *| ------ ---
*| NULL file://aa/b/cd#hohoh
*| #hohoh http://aa/b/cd#hohoh
*| NULL fi://aa/b/cd#hohoh
@@ -1299,6 +1319,17 @@
/*************************************************************************
* UrlCompareA [SHLWAPI.@]
+ *
+ * Compare two Urls.
+ *
+ * PARAMS
+ * pszUrl1 [I] First Url to compare
+ * pszUrl2 [I] Url to compare to pszUrl1
+ * fIgnoreSlash [I] TRUE = compare only up to a final slash
+ *
+ * RETURNS
+ * less than zero, zero, or greater than zero indicating pszUrl2 is greater
+ * than, equal to, or less than pszUrl1 respectively.
*/
INT WINAPI UrlCompareA(
LPCSTR pszUrl1,
@@ -1310,9 +1341,9 @@
if (!fIgnoreSlash)
return strcmp(pszUrl1, pszUrl2);
len1 = strlen(pszUrl1);
- if (pszUrl1[len1-1] == L'/') len1--;
+ if (pszUrl1[len1-1] == '/') len1--;
len2 = strlen(pszUrl2);
- if (pszUrl2[len2-1] == L'/') len2--;
+ if (pszUrl2[len2-1] == '/') len2--;
if (len1 == len2)
return strncmp(pszUrl1, pszUrl2, len1);
len = min(len1, len2);
@@ -1324,20 +1355,23 @@
/*************************************************************************
* UrlCompareW [SHLWAPI.@]
+ *
+ * See UrlCompareA.
*/
INT WINAPI UrlCompareW(
LPCWSTR pszUrl1,
LPCWSTR pszUrl2,
BOOL fIgnoreSlash)
{
- INT ret, len, len1, len2;
+ INT ret;
+ size_t len, len1, len2;
if (!fIgnoreSlash)
return strcmpW(pszUrl1, pszUrl2);
len1 = strlenW(pszUrl1);
- if (pszUrl1[len1-1] == L'/') len1--;
+ if (pszUrl1[len1-1] == '/') len1--;
len2 = strlenW(pszUrl2);
- if (pszUrl2[len2-1] == L'/') len2--;
+ if (pszUrl2[len2-1] == '/') len2--;
if (len1 == len2)
return strncmpW(pszUrl1, pszUrl2, len1);
len = min(len1, len2);
@@ -1351,7 +1385,7 @@
* HashData [SHLWAPI.@]
*
* Hash an input block into a variable sized digest.
- *
+ *
* PARAMS
* lpSrc [I] Input block
* nSrcLen [I] Length of lpSrc
@@ -1409,7 +1443,7 @@
if (IsBadStringPtrA(pszUrl, -1) || IsBadWritePtr(lpDest, nDestLen))
return E_INVALIDARG;
- HashData(pszUrl, strlen(pszUrl), lpDest, nDestLen);
+ HashData((PBYTE)pszUrl, (int)strlen(pszUrl), lpDest, nDestLen);
return S_OK;
}
@@ -1431,12 +1465,24 @@
* return the same digests for the same URL.
*/
WideCharToMultiByte(0, 0, pszUrl, -1, szUrl, MAX_PATH, 0, 0);
- HashData(szUrl, strlen(szUrl), lpDest, nDestLen);
+ HashData((PBYTE)szUrl, (int)strlen(szUrl), lpDest, nDestLen);
return S_OK;
}
/*************************************************************************
* UrlApplySchemeA [SHLWAPI.@]
+ *
+ * Apply a scheme to a Url.
+ *
+ * PARAMS
+ * pszIn [I] Url to apply scheme to
+ * pszOut [O] Destination for modified Url
+ * pcchOut [I/O] Length of pszOut/destination for length of pszOut
+ * dwFlags [I] URL_ flags from "shlwapi.h"
+ *
+ * RETURNS
+ * Success: S_OK: pszOut contains the modified Url, pcchOut contains its length.
+ * Failure: An HRESULT error code describing the error.
*/
HRESULT WINAPI UrlApplySchemeA(LPCSTR pszIn, LPSTR pszOut, LPDWORD pcchOut, DWORD dwFlags)
{
@@ -1471,12 +1517,12 @@
return ret;
}
-static HRESULT URL_GuessScheme(LPCWSTR pszIn, LPWSTR pszOut, LPDWORD pcchOut)
+static inline HRESULT URL_GuessScheme(LPCWSTR pszIn, LPWSTR pszOut, LPDWORD pcchOut)
{
HKEY newkey;
BOOL j;
- INT index, i;
- DWORD value_len, data_len, dwType;
+ INT index;
+ DWORD value_len, data_len, dwType, i;
WCHAR reg_path[MAX_PATH];
WCHAR value[MAX_PATH], data[MAX_PATH];
WCHAR Wxx, Wyy;
@@ -1519,7 +1565,7 @@
return -1;
}
-HRESULT URL_ApplyDefault(LPCWSTR pszIn, LPWSTR pszOut, LPDWORD pcchOut)
+static inline HRESULT URL_ApplyDefault(LPCWSTR pszIn, LPWSTR pszOut, LPDWORD pcchOut)
{
HKEY newkey;
DWORD data_len, dwType;
@@ -1549,6 +1595,8 @@
/*************************************************************************
* UrlApplySchemeW [SHLWAPI.@]
+ *
+ * See UrlApplySchemeA.
*/
HRESULT WINAPI UrlApplySchemeW(LPCWSTR pszIn, LPWSTR pszOut, LPDWORD pcchOut, DWORD dwFlags)
{
@@ -1689,6 +1737,15 @@
/*************************************************************************
* UrlIsNoHistoryA [SHLWAPI.@]
+ *
+ * Determine if a Url should not be stored in the users history list.
+ *
+ * PARAMS
+ * pszUrl [I] Url to check
+ *
+ * RETURNS
+ * TRUE, if pszUrl should be excluded from the history list,
+ * FALSE otherwise.
*/
BOOL WINAPI UrlIsNoHistoryA(LPCSTR pszUrl)
{
@@ -1697,6 +1754,8 @@
/*************************************************************************
* UrlIsNoHistoryW [SHLWAPI.@]
+ *
+ * See UrlIsNoHistoryA.
*/
BOOL WINAPI UrlIsNoHistoryW(LPCWSTR pszUrl)
{
@@ -1739,7 +1798,7 @@
*
* Characters tested based on RFC 1738
*/
-static LPCWSTR URL_ScanID(LPCWSTR start, LPDWORD size, WINE_URL_SCAN_TYPE type)
+static LPCWSTR WINAPI URL_ScanID(LPCWSTR start, LPDWORD size, WINE_URL_SCAN_TYPE type)
{
static DWORD alwayszero = 0;
BOOL cont = TRUE;
@@ -1834,7 +1893,7 @@
/*************************************************************************
* Attempt to parse URL into pieces.
*/
-static LONG URL_ParseUrl(LPCWSTR pszUrl, WINE_PARSE_URL *pl)
+static inline LONG URL_ParseUrl(LPCWSTR pszUrl, WINE_PARSE_URL *pl)
{
LPCWSTR work;
@@ -1899,6 +1958,19 @@
/*************************************************************************
* UrlGetPartA [SHLWAPI.@]
+ *
+ * Retrieve part of a Url.
+ *
+ * PARAMS
+ * pszIn [I] Url to parse
+ * pszOut [O] Destination for part of pszIn requested
+ * pcchOut [I/O] Length of pszOut/destination for length of pszOut
+ * dwPart [I] URL_PART_ enum from "shlwapi.h"
+ * dwFlags [I] URL_ flags from "shlwapi.h"
+ *
+ * RETURNS
+ * Success: S_OK. pszOut contains the part requested, pcchOut contains its length.
+ * Failure: An HRESULT error code describing the error.
*/
HRESULT WINAPI UrlGetPartA(LPCSTR pszIn, LPSTR pszOut, LPDWORD pcchOut,
DWORD dwPart, DWORD dwFlags)
@@ -1934,6 +2006,8 @@
/*************************************************************************
* UrlGetPartW [SHLWAPI.@]
+ *
+ * See UrlGetPartA.
*/
HRESULT WINAPI UrlGetPartW(LPCWSTR pszIn, LPWSTR pszOut, LPDWORD pcchOut,
DWORD dwPart, DWORD dwFlags)
@@ -2021,14 +2095,14 @@
/*************************************************************************
* PathIsURLA [SHLWAPI.@]
*
- * Check if the given path is a URL.
+ * 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.
+ * TRUE if lpszPath is a Url.
+ * FALSE if lpszPath is NULL or not a Url.
*/
BOOL WINAPI PathIsURLA(LPCSTR lpstrPath)
{
@@ -2277,9 +2351,116 @@
/*************************************************************************
* SHAutoComplete [SHLWAPI.@]
+ *
+ * Enable auto-completion for an edit control.
+ *
+ * PARAMS
+ * hwndEdit [I] Handle of control to enable auto-completion for
+ * dwFlags [I] SHACF_ flags from "shlwapi.h"
+ *
+ * RETURNS
+ * Success: S_OK. Auto-completion is enabled for the control.
+ * Failure: An HRESULT error code indicating the error.
*/
HRESULT WINAPI SHAutoComplete(HWND hwndEdit, DWORD dwFlags)
{
FIXME("SHAutoComplete stub\n");
return S_FALSE;
}
+
+/*************************************************************************
+ * MLBuildResURLA [SHLWAPI.405]
+ *
+ * Create a Url pointing to a resource in a module.
+ *
+ * PARAMS
+ * lpszLibName [I] Name of the module containing the resource
+ * hMod [I] Callers module handle
+ * dwFlags [I] Undocumented flags for loading the module
+ * lpszRes [I] Resource name
+ * lpszDest [O] Destination for resulting Url
+ * dwDestLen [I] Length of lpszDest
+ *
+ * RETURNS
+ * Success: S_OK. lpszDest constains the resource Url.
+ * Failure: E_INVALIDARG, if any argument is invalid, or
+ * E_FAIL if dwDestLen is too small.
+ */
+HRESULT WINAPI MLBuildResURLA(LPCSTR lpszLibName, HMODULE hMod, DWORD dwFlags,
+ LPCSTR lpszRes, LPSTR lpszDest, DWORD dwDestLen)
+{
+ WCHAR szLibName[MAX_PATH], szRes[MAX_PATH], szDest[MAX_PATH];
+ HRESULT hRet;
+
+ if (lpszLibName)
+ MultiByteToWideChar(CP_ACP, 0, lpszLibName, -1, szLibName, sizeof(szLibName)/sizeof(WCHAR));
+
+ if (lpszLibName)
+ MultiByteToWideChar(CP_ACP, 0, lpszLibName, -1, szLibName, sizeof(szLibName)/sizeof(WCHAR));
+
+ if (dwDestLen > sizeof(szLibName)/sizeof(WCHAR))
+ dwDestLen = sizeof(szLibName)/sizeof(WCHAR);
+
+ hRet = MLBuildResURLW(lpszLibName ? szLibName : NULL, hMod, dwFlags,
+ lpszRes ? szRes : NULL, szDest, dwDestLen);
+ if (SUCCEEDED(hRet))
+ WideCharToMultiByte(CP_ACP, 0, szDest, -1, lpszDest, dwDestLen, 0, 0);
+
+ return hRet;
+}
+
+/*************************************************************************
+ * MLBuildResURLA [SHLWAPI.406]
+ *
+ * See MLBuildResURLA.
+ */
+HRESULT WINAPI MLBuildResURLW(LPCWSTR lpszLibName, HMODULE hMod, DWORD dwFlags,
+ LPCWSTR lpszRes, LPWSTR lpszDest, DWORD dwDestLen)
+{
+ static const WCHAR szRes[] = { 'r','e','s',':','/','/','\0' };
+#define szResLen (sizeof(szRes)/sizeof(WCHAR) - sizeof(WCHAR))
+ HRESULT hRet = E_FAIL;
+
+ TRACE("(%s,%p,0x%08lx,%s,%p,%ld)\n", debugstr_w(lpszLibName), hMod, dwFlags,
+ debugstr_w(lpszRes), lpszDest, dwDestLen);
+
+ if (!lpszLibName || !hMod || hMod == INVALID_HANDLE_VALUE || !lpszRes ||
+ !lpszDest || (dwFlags && dwFlags != 2))
+ return E_INVALIDARG;
+
+ if (dwDestLen >= szResLen + 1)
+ {
+ dwDestLen -= (szResLen + 1);
+ memcpy(lpszDest, szRes, sizeof(lpszDest));
+
+ hMod = MLLoadLibraryW(lpszLibName, hMod, dwFlags);
+
+ if (hMod)
+ {
+ WCHAR szBuff[MAX_PATH];
+
+ if (GetModuleFileNameW(hMod, szBuff, sizeof(szBuff)/sizeof(WCHAR)))
+ {
+ DWORD dwPathLen = strlenW(szBuff) + 1;
+
+ if (dwDestLen >= dwPathLen)
+ {
+ DWORD dwResLen;
+
+ dwDestLen -= dwPathLen;
+ memcpy(lpszDest + szResLen, szBuff, dwPathLen * sizeof(WCHAR));
+
+ dwResLen = strlenW(lpszRes) + 1;
+ if (dwDestLen >= dwResLen + 1)
+ {
+ lpszDest[szResLen + dwPathLen + dwResLen] = '/';
+ memcpy(lpszDest + szResLen + dwPathLen, lpszRes, dwResLen * sizeof(WCHAR));
+ hRet = S_OK;
+ }
+ }
+ }
+ MLFreeLibrary(hMod);
+ }
+ }
+ return hRet;
+}