Andrew Eikum : shlwapi: Implement SHGetIniStringW.

Alexandre Julliard julliard at winehq.org
Thu Jul 22 12:09:18 CDT 2010


Module: wine
Branch: master
Commit: ef8cf0fdf2d6f892296f43616d1a5ef1ed2579b3
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=ef8cf0fdf2d6f892296f43616d1a5ef1ed2579b3

Author: Andrew Eikum <aeikum at codeweavers.com>
Date:   Wed Jul 21 11:23:55 2010 -0500

shlwapi: Implement SHGetIniStringW.

---

 dlls/shlwapi/ordinal.c       |   43 ++++++++++++++++++++--
 dlls/shlwapi/tests/ordinal.c |   83 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 122 insertions(+), 4 deletions(-)

diff --git a/dlls/shlwapi/ordinal.c b/dlls/shlwapi/ordinal.c
index 7c00669..2c9db24 100644
--- a/dlls/shlwapi/ordinal.c
+++ b/dlls/shlwapi/ordinal.c
@@ -3246,12 +3246,47 @@ BOOL WINAPI PlaySoundWrapW(LPCWSTR pszSound, HMODULE hmod, DWORD fdwSound)
 
 /*************************************************************************
  *      @	[SHLWAPI.294]
+ *
+ * Retrieve a key value from an INI file.  See GetPrivateProfileString for
+ * more information.
+ *
+ * PARAMS
+ *  appName   [I] The section in the INI file that contains the key
+ *  keyName   [I] The key to be retrieved
+ *  out       [O] The buffer into which the key's value will be copied
+ *  outLen    [I] The length of the `out' buffer
+ *  filename  [I] The location of the INI file
+ *
+ * RETURNS
+ *  Length of string copied into `out'.
  */
-BOOL WINAPI SHGetIniStringW(LPCWSTR str1, LPCWSTR str2, LPWSTR pStr, DWORD some_len, LPCWSTR lpStr2)
+DWORD WINAPI SHGetIniStringW(LPCWSTR appName, LPCWSTR keyName, LPWSTR out,
+        DWORD outLen, LPCWSTR filename)
 {
-    FIXME("(%s,%s,%p,%08x,%s): stub!\n", debugstr_w(str1), debugstr_w(str2),
-        pStr, some_len, debugstr_w(lpStr2));
-    return TRUE;
+    INT ret;
+    WCHAR *buf;
+
+    TRACE("(%s,%s,%p,%08x,%s)\n", debugstr_w(appName), debugstr_w(keyName),
+        out, outLen, debugstr_w(filename));
+
+    if(outLen == 0)
+        return 0;
+
+    buf = HeapAlloc(GetProcessHeap(), 0, outLen * sizeof(WCHAR));
+    if(!buf){
+        *out = 0;
+        return 0;
+    }
+
+    ret = GetPrivateProfileStringW(appName, keyName, NULL, buf, outLen, filename);
+    if(ret)
+        strcpyW(out, buf);
+    else
+        *out = 0;
+
+    HeapFree(GetProcessHeap(), 0, buf);
+
+    return strlenW(out);
 }
 
 /*************************************************************************
diff --git a/dlls/shlwapi/tests/ordinal.c b/dlls/shlwapi/tests/ordinal.c
index 4b1690a..829819d 100644
--- a/dlls/shlwapi/tests/ordinal.c
+++ b/dlls/shlwapi/tests/ordinal.c
@@ -58,6 +58,7 @@ static HRESULT (WINAPI *pIUnknown_QueryServiceExec)(IUnknown*, REFIID, const GUI
 static HRESULT (WINAPI *pIUnknown_ProfferService)(IUnknown*, REFGUID, IServiceProvider*, DWORD*);
 static HWND    (WINAPI *pSHCreateWorkerWindowA)(LONG, HWND, DWORD, DWORD, HMENU, LONG_PTR);
 static HRESULT (WINAPI *pSHIShellFolder_EnumObjects)(LPSHELLFOLDER, HWND, SHCONTF, IEnumIDList**);
+static DWORD   (WINAPI *pSHGetIniStringW)(LPCWSTR, LPCWSTR, LPWSTR, DWORD, LPCWSTR);
 
 static HMODULE hmlang;
 static HRESULT (WINAPI *pLcidToRfc1766A)(LCID, LPSTR, INT);
@@ -70,6 +71,13 @@ static const CHAR ie_international[] = {
 static const CHAR acceptlanguage[] = {
     'A','c','c','e','p','t','L','a','n','g','u','a','g','e',0};
 
+static int strcmp_wa(LPCWSTR strw, const char *stra)
+{
+    CHAR buf[512];
+    WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), NULL, NULL);
+    return lstrcmpA(stra, buf);
+}
+
 typedef struct {
     int id;
     const void *args[5];
@@ -2518,6 +2526,79 @@ static void test_SHIShellFolder_EnumObjects(void)
     IShellFolder_Release(folder);
 }
 
+static void write_inifile(LPCWSTR filename)
+{
+    DWORD written;
+    HANDLE file;
+
+    static const char data[] =
+        "[TestApp]\r\n"
+        "AKey=1\r\n"
+        "AnotherKey=asdf\r\n";
+
+    file = CreateFileW(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
+    if(file == INVALID_HANDLE_VALUE)
+        return;
+
+    WriteFile(file, data, sizeof(data), &written, NULL);
+
+    CloseHandle(file);
+}
+
+static void test_SHGetIniString(void)
+{
+    DWORD ret;
+    WCHAR out[64] = {0};
+
+    static const WCHAR TestAppW[] = {'T','e','s','t','A','p','p',0};
+    static const WCHAR TestIniW[] = {'C',':','\\','t','e','s','t','.','i','n','i',0};
+    static const WCHAR AKeyW[] = {'A','K','e','y',0};
+    static const WCHAR AnotherKeyW[] = {'A','n','o','t','h','e','r','K','e','y',0};
+    static const WCHAR JunkKeyW[] = {'J','u','n','k','K','e','y',0};
+
+    if(!pSHGetIniStringW || is_win2k_and_lower){
+        win_skip("SHGetIniStringW is not available\n");
+        return;
+    }
+
+    write_inifile(TestIniW);
+
+    if(0){
+        /* these crash on Windows */
+        ret = pSHGetIniStringW(NULL, NULL, NULL, 0, NULL);
+        ret = pSHGetIniStringW(NULL, AKeyW, out, sizeof(out), TestIniW);
+        ret = pSHGetIniStringW(TestAppW, AKeyW, NULL, sizeof(out), TestIniW);
+    }
+
+    ret = pSHGetIniStringW(TestAppW, AKeyW, out, 0, TestIniW);
+    ok(ret == 0, "SHGetIniStringW should have given 0, instead: %d\n", ret);
+
+    /* valid arguments */
+    ret = pSHGetIniStringW(TestAppW, NULL, out, sizeof(out), TestIniW);
+    ok(broken(ret == 0) || /* win 98 */
+            ret == 4, "SHGetIniStringW should have given 4, instead: %d\n", ret);
+    ok(!lstrcmpW(out, AKeyW), "Expected %s, got: %s\n",
+                wine_dbgstr_w(AKeyW), wine_dbgstr_w(out));
+
+    ret = pSHGetIniStringW(TestAppW, AKeyW, out, sizeof(out), TestIniW);
+    ok(broken(ret == 0) || /* win 98 */
+                ret == 1, "SHGetIniStringW should have given 1, instead: %d\n", ret);
+    ok(broken(*out == 0) || /*win 98 */
+        !strcmp_wa(out, "1"), "Expected L\"1\", got: %s\n", wine_dbgstr_w(out));
+
+    ret = pSHGetIniStringW(TestAppW, AnotherKeyW, out, sizeof(out), TestIniW);
+    ok(broken(ret == 0) || /* win 98 */
+            ret == 4, "SHGetIniStringW should have given 4, instead: %d\n", ret);
+    ok(broken(*out == 0) || /* win 98 */
+            !strcmp_wa(out, "asdf"), "Expected L\"asdf\", got: %s\n", wine_dbgstr_w(out));
+
+    ret = pSHGetIniStringW(TestAppW, JunkKeyW, out, sizeof(out), TestIniW);
+    ok(ret == 0, "SHGetIniStringW should have given 0, instead: %d\n", ret);
+    ok(*out == 0, "Expected L\"\", got: %s\n", wine_dbgstr_w(out));
+
+    DeleteFileW(TestIniW);
+}
+
 static void init_pointers(void)
 {
 #define MAKEFUNC(f, ord) (p##f = (void*)GetProcAddress(hShlwapi, (LPSTR)(ord)))
@@ -2534,6 +2615,7 @@ static void init_pointers(void)
     MAKEFUNC(SHPackDispParams, 282);
     MAKEFUNC(IConnectionPoint_InvokeWithCancel, 283);
     MAKEFUNC(IConnectionPoint_SimpleInvoke, 284);
+    MAKEFUNC(SHGetIniStringW, 294);
     MAKEFUNC(SHFormatDateTimeA, 353);
     MAKEFUNC(SHFormatDateTimeW, 354);
     MAKEFUNC(SHIShellFolder_EnumObjects, 404);
@@ -2570,4 +2652,5 @@ START_TEST(ordinal)
     test_IUnknown_ProfferService();
     test_SHCreateWorkerWindowA();
     test_SHIShellFolder_EnumObjects();
+    test_SHGetIniString();
 }




More information about the wine-cvs mailing list