Andrew Nguyen : shlwapi: Implement StrStrNIW.

Alexandre Julliard julliard at winehq.org
Mon Jul 19 11:05:44 CDT 2010


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

Author: Andrew Nguyen <anguyen at codeweavers.com>
Date:   Sun Jul 18 19:35:43 2010 -0500

shlwapi: Implement StrStrNIW.

---

 dlls/shlwapi/shlwapi.spec   |    1 +
 dlls/shlwapi/string.c       |   35 +++++++++++++++
 dlls/shlwapi/tests/string.c |   97 +++++++++++++++++++++++++++++++++++++++++++
 include/shlwapi.h           |    1 +
 4 files changed, 134 insertions(+), 0 deletions(-)

diff --git a/dlls/shlwapi/shlwapi.spec b/dlls/shlwapi/shlwapi.spec
index b0e3e0e..8ad4373 100644
--- a/dlls/shlwapi/shlwapi.spec
+++ b/dlls/shlwapi/shlwapi.spec
@@ -802,6 +802,7 @@
 @ stdcall StrStrIA(str str)
 @ stdcall StrStrIW(wstr wstr)
 @ stdcall StrStrNW(wstr wstr long)
+@ stdcall StrStrNIW(wstr wstr long)
 @ stdcall StrStrW(wstr wstr)
 @ stdcall StrToIntA(str)
 @ stdcall StrToIntExA(str long ptr)
diff --git a/dlls/shlwapi/string.c b/dlls/shlwapi/string.c
index 96a7843..6102f3c 100644
--- a/dlls/shlwapi/string.c
+++ b/dlls/shlwapi/string.c
@@ -744,6 +744,41 @@ LPWSTR WINAPI StrStrNW(LPCWSTR lpFirst, LPCWSTR lpSrch, UINT cchMax)
 }
 
 /*************************************************************************
+ * StrStrNIW	[SHLWAPI.@]
+ *
+ * Find a substring within a string up to a given number of initial characters,
+ * ignoring case.
+ *
+ * PARAMS
+ *  lpFirst    [I] String to search in
+ *  lpSrch     [I] String to look for
+ *  cchMax     [I] Maximum number of initial search characters
+ *
+ * RETURNS
+ *  The start of lpFirst within lpSrch, or NULL if not found.
+ */
+LPWSTR WINAPI StrStrNIW(LPCWSTR lpFirst, LPCWSTR lpSrch, UINT cchMax)
+{
+    UINT i;
+    int len;
+
+    TRACE("(%s, %s, %u)\n", debugstr_w(lpFirst), debugstr_w(lpSrch), cchMax);
+
+    if (!lpFirst || !lpSrch || !*lpSrch || !cchMax)
+        return NULL;
+
+    len = strlenW(lpSrch);
+
+    for (i = cchMax; *lpFirst && (i > 0); i--, lpFirst++)
+    {
+        if (!strncmpiW(lpFirst, lpSrch, len))
+            return (LPWSTR)lpFirst;
+    }
+
+    return NULL;
+}
+
+/*************************************************************************
  * StrToIntA	[SHLWAPI.@]
  *
  * Read a signed integer from a string.
diff --git a/dlls/shlwapi/tests/string.c b/dlls/shlwapi/tests/string.c
index 71e1d4b..3d6d4a2 100644
--- a/dlls/shlwapi/tests/string.c
+++ b/dlls/shlwapi/tests/string.c
@@ -59,6 +59,7 @@ static HRESULT (WINAPI *pStrRetToBSTR)(STRRET*,void*,BSTR*);
 static HRESULT (WINAPI *pStrRetToBufA)(STRRET*,LPCITEMIDLIST,LPSTR,UINT);
 static HRESULT (WINAPI *pStrRetToBufW)(STRRET*,LPCITEMIDLIST,LPWSTR,UINT);
 static LPWSTR  (WINAPI *pStrStrNW)(LPCWSTR,LPCWSTR,UINT);
+static LPWSTR  (WINAPI *pStrStrNIW)(LPCWSTR,LPCWSTR,UINT);
 static INT     (WINAPIV *pwnsprintfA)(LPSTR,INT,LPCSTR, ...);
 static INT     (WINAPIV *pwnsprintfW)(LPWSTR,INT,LPCWSTR, ...);
 static LPWSTR  (WINAPI *pStrChrNW)(LPWSTR,WCHAR,UINT);
@@ -1248,6 +1249,100 @@ static void test_StrStrNW(void)
     }
 }
 
+static void test_StrStrNIW(void)
+{
+    static const WCHAR emptyW[] = {0};
+    static const WCHAR deadbeefW[] = {'D','e','A','d','B','e','E','f',0};
+    static const WCHAR deadW[] = {'D','e','A','d',0};
+    static const WCHAR dead_lowerW[] = {'d','e','a','d',0};
+    static const WCHAR adbeW[] = {'A','d','B','e',0};
+    static const WCHAR adbe_lowerW[] = {'a','d','b','e',0};
+    static const WCHAR beefW[] = {'B','e','E','f',0};
+    static const WCHAR beef_lowerW[] = {'b','e','e','f',0};
+    static const WCHAR cafeW[] = {'c','a','f','e',0};
+
+    const struct
+    {
+        const WCHAR *search;
+        const UINT count;
+        const WCHAR *expect;
+    } StrStrNIW_cases[] =
+    {
+        {emptyW, sizeof(deadbeefW)/sizeof(WCHAR), NULL},
+        {deadW, sizeof(deadbeefW)/sizeof(WCHAR), deadbeefW},
+        {dead_lowerW, sizeof(deadbeefW)/sizeof(WCHAR), deadbeefW},
+        {adbeW, sizeof(deadbeefW)/sizeof(WCHAR), deadbeefW + 2},
+        {adbe_lowerW, sizeof(deadbeefW)/sizeof(WCHAR), deadbeefW + 2},
+        {beefW, sizeof(deadbeefW)/sizeof(WCHAR), deadbeefW + 4},
+        {beef_lowerW, sizeof(deadbeefW)/sizeof(WCHAR), deadbeefW + 4},
+        {cafeW, sizeof(deadbeefW)/sizeof(WCHAR), NULL},
+        {beefW, 0, NULL},
+        {beefW, 1, NULL},
+        {beefW, 2, NULL},
+        {beefW, 3, NULL},
+        {beefW, 4, NULL},
+        {beefW, 5, deadbeefW + 4},
+        {beefW, 6, deadbeefW + 4},
+        {beefW, 7, deadbeefW + 4},
+        {beefW, 8, deadbeefW + 4},
+        {beefW, 9, deadbeefW + 4},
+        {beef_lowerW, 0, NULL},
+        {beef_lowerW, 1, NULL},
+        {beef_lowerW, 2, NULL},
+        {beef_lowerW, 3, NULL},
+        {beef_lowerW, 4, NULL},
+        {beef_lowerW, 5, deadbeefW + 4},
+        {beef_lowerW, 6, deadbeefW + 4},
+        {beef_lowerW, 7, deadbeefW + 4},
+        {beef_lowerW, 8, deadbeefW + 4},
+        {beef_lowerW, 9, deadbeefW + 4},
+    };
+
+    LPWSTR ret;
+    UINT i;
+
+    if (!pStrStrNIW)
+    {
+        win_skip("StrStrNIW() is not available\n");
+        return;
+    }
+
+    ret = pStrStrNIW(NULL, NULL, 0);
+    ok(!ret, "Expected StrStrNIW to return NULL, got %p\n", ret);
+
+    ret = pStrStrNIW(NULL, NULL, 10);
+    ok(!ret, "Expected StrStrNIW to return NULL, got %p\n", ret);
+
+    ret = pStrStrNIW(NULL, emptyW, 10);
+    ok(!ret, "Expected StrStrNIW to return NULL, got %p\n", ret);
+
+    ret = pStrStrNIW(emptyW, NULL, 10);
+    ok(!ret, "Expected StrStrNIW to return NULL, got %p\n", ret);
+
+    ret = pStrStrNIW(emptyW, emptyW, 10);
+    ok(!ret, "Expected StrStrNIW to return NULL, got %p\n", ret);
+
+    for (i = 0; i < sizeof(StrStrNIW_cases)/sizeof(StrStrNIW_cases[0]); i++)
+    {
+        ret = pStrStrNIW(deadbeefW, StrStrNIW_cases[i].search, StrStrNIW_cases[i].count);
+        ok(ret == StrStrNIW_cases[i].expect,
+           "[%d] Expected StrStrNIW to return %p, got %p\n",
+           i, StrStrNIW_cases[i].expect, ret);
+    }
+
+    /* StrStrNIW accepts counts larger than the search string length but rejects
+     * counts larger than around 2G. The limit seems to change based on the
+     * caller executable itself. */
+    ret = pStrStrNIW(deadbeefW, beefW, 100);
+    ok(ret == deadbeefW + 4, "Expected StrStrNIW to return deadbeefW + 4, got %p\n", ret);
+
+    if (0)
+    {
+        ret = pStrStrNIW(deadbeefW, beefW, ~0U);
+        ok(!ret, "Expected StrStrNIW to return NULL, got %p\n", ret);
+    }
+}
+
 START_TEST(string)
 {
   HMODULE hShlwapi;
@@ -1279,6 +1374,7 @@ START_TEST(string)
   pStrRetToBufA = (void *)GetProcAddress(hShlwapi, "StrRetToBufA");
   pStrRetToBufW = (void *)GetProcAddress(hShlwapi, "StrRetToBufW");
   pStrStrNW = (void *)GetProcAddress(hShlwapi, "StrStrNW");
+  pStrStrNIW = (void *)GetProcAddress(hShlwapi, "StrStrNIW");
   pwnsprintfA = (void *)GetProcAddress(hShlwapi, "wnsprintfA");
   pwnsprintfW = (void *)GetProcAddress(hShlwapi, "wnsprintfW");
 
@@ -1323,6 +1419,7 @@ START_TEST(string)
   test_StrStrIA();
   test_StrStrIW();
   test_StrStrNW();
+  test_StrStrNIW();
 
   CoUninitialize();
 }
diff --git a/include/shlwapi.h b/include/shlwapi.h
index fe58bb5..dd2da4f 100644
--- a/include/shlwapi.h
+++ b/include/shlwapi.h
@@ -877,6 +877,7 @@ LPWSTR WINAPI StrStrIW(LPCWSTR,LPCWSTR);
 #define StrStrI WINELIB_NAME_AW(StrStrI)
 
 LPWSTR WINAPI StrStrNW(LPCWSTR,LPCWSTR,UINT);
+LPWSTR WINAPI StrStrNIW(LPCWSTR,LPCWSTR,UINT);
 
 int WINAPI StrToIntA(LPCSTR);
 int WINAPI StrToIntW(LPCWSTR);




More information about the wine-cvs mailing list