+static void test_StrStrA(void)
+{
+ static const char *deadbeefA = "DeAdBeEf";
+
+ const struct
+ {
+ const char *search;
+ const char *expect;
+ } StrStrA_cases[] =
+ {
+ {"", NULL},
+ {"DeAd", deadbeefA},
+ {"dead", NULL},
+ {"AdBe", deadbeefA + 2},
+ {"adbe", NULL},
+ {"BeEf", deadbeefA + 4},
+ {"beef", NULL},
+ };
+
+ LPSTR ret;
+ int i;
+
+ /* Tests crash on Win2k */
+ if (0)
+ {
+ ret = StrStrA(NULL, NULL);
+ ok(!ret, "Expected StrStrA to return NULL, got %p\n", ret);
+
+ ret = StrStrA(NULL, "");
+ ok(!ret, "Expected StrStrA to return NULL, got %p\n", ret);
+
+ ret = StrStrA("", NULL);
+ ok(!ret, "Expected StrStrA to return NULL, got %p\n", ret);
+ }
+
+ ret = StrStrA("", "");
+ ok(!ret, "Expected StrStrA to return NULL, got %p\n", ret);
+
+ for (i = 0; i < sizeof(StrStrA_cases)/sizeof(StrStrA_cases[0]); i++)
+ {
+ ret = StrStrA(deadbeefA, StrStrA_cases[i].search);
+ ok(ret == StrStrA_cases[i].expect,
+ "[%d] Expected StrStrA to return %p, got %p\n",
+ i, StrStrA_cases[i].expect, ret);
+ }
+}
+
+static void test_StrStrW(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};
+
+ const struct
+ {
+ const WCHAR *search;
+ const WCHAR *expect;
+ } StrStrW_cases[] =
+ {
+ {emptyW, NULL},
+ {deadW, deadbeefW},
+ {dead_lowerW, NULL},
+ {adbeW, deadbeefW + 2},
+ {adbe_lowerW, NULL},
+ {beefW, deadbeefW + 4},
+ {beef_lowerW, NULL},
+ };
+
+ LPWSTR ret;
+ int i;
+
+ /* Tests crash on Win2k */
+ if (0)
+ {
+ ret = StrStrW(NULL, NULL);
+ ok(!ret, "Expected StrStrW to return NULL, got %p\n", ret);
+
+ ret = StrStrW(NULL, emptyW);
+ ok(!ret, "Expected StrStrW to return NULL, got %p\n", ret);
+
+ ret = StrStrW(emptyW, NULL);
+ ok(!ret, "Expected StrStrW to return NULL, got %p\n", ret);
+ }
+
+ ret = StrStrW(emptyW, emptyW);
+ ok(!ret, "Expected StrStrW to return NULL, got %p\n", ret);
+
+ for (i = 0; i < sizeof(StrStrW_cases)/sizeof(StrStrW_cases[0]); i++)
+ {
+ ret = StrStrW(deadbeefW, StrStrW_cases[i].search);
+ ok(ret == StrStrW_cases[i].expect,
+ "[%d] Expected StrStrW to return %p, got %p\n",
+ i, StrStrW_cases[i].expect, ret);
+ }
+}
+
+static void test_StrStrIA(void)
+{
+ static const char *deadbeefA = "DeAdBeEf";
+
+ const struct
+ {
+ const char *search;
+ const char *expect;
+ } StrStrIA_cases[] =
+ {
+ {"", NULL},
+ {"DeAd", deadbeefA},
+ {"dead", deadbeefA},
+ {"AdBe", deadbeefA + 2},
+ {"adbe", deadbeefA + 2},
+ {"BeEf", deadbeefA + 4},
+ {"beef", deadbeefA + 4},
+ {"cafe", NULL},
+ };
+
+ LPSTR ret;
+ int i;
+
+ /* Tests crash on Win2k */
+ if (0)
+ {
+ ret = StrStrIA(NULL, NULL);
+ ok(!ret, "Expected StrStrIA to return NULL, got %p\n", ret);
+
+ ret = StrStrIA(NULL, "");
+ ok(!ret, "Expected StrStrIA to return NULL, got %p\n", ret);
+
+ ret = StrStrIA("", NULL);
+ ok(!ret, "Expected StrStrIA to return NULL, got %p\n", ret);
+ }
+
+ ret = StrStrIA("", "");
+ ok(!ret, "Expected StrStrIA to return NULL, got %p\n", ret);
+
+ for (i = 0; i < sizeof(StrStrIA_cases)/sizeof(StrStrIA_cases[0]); i++)
+ {
+ ret = StrStrIA(deadbeefA, StrStrIA_cases[i].search);
+ ok(ret == StrStrIA_cases[i].expect,
+ "[%d] Expected StrStrIA to return %p, got %p\n",
+ i, StrStrIA_cases[i].expect, ret);
+ }
+}
+
+static void test_StrStrIW(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 WCHAR *expect;
+ } StrStrIW_cases[] =
+ {
+ {emptyW, NULL},
+ {deadW, deadbeefW},
+ {dead_lowerW, deadbeefW},
+ {adbeW, deadbeefW + 2},
+ {adbe_lowerW, deadbeefW + 2},
+ {beefW, deadbeefW + 4},
+ {beef_lowerW, deadbeefW + 4},
+ {cafeW, NULL},
+ };
+
+ LPWSTR ret;
+ int i;
+
+ /* Tests crash on Win2k */
+ if (0)
+ {
+ ret = StrStrIW(NULL, NULL);
+ ok(!ret, "Expected StrStrIW to return NULL, got %p\n", ret);
+
+ ret = StrStrIW(NULL, emptyW);
+ ok(!ret, "Expected StrStrIW to return NULL, got %p\n", ret);
+
+ ret = StrStrIW(emptyW, NULL);
+ ok(!ret, "Expected StrStrIW to return NULL, got %p\n", ret);
+ }
+
+ ret = StrStrIW(emptyW, emptyW);
+ ok(!ret, "Expected StrStrIW to return NULL, got %p\n", ret);
+
+ for (i = 0; i < sizeof(StrStrIW_cases)/sizeof(StrStrIW_cases[0]); i++)
+ {
+ ret = StrStrIW(deadbeefW, StrStrIW_cases[i].search);
+ ok(ret == StrStrIW_cases[i].expect,
+ "[%d] Expected StrStrIW to return %p, got %p\n",
+ i, StrStrIW_cases[i].expect, ret);
+ }
+}
+
+static void test_StrStrNW(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};
+
+ const struct
+ {
+ const WCHAR *search;
+ const UINT count;
+ const WCHAR *expect;
+ } StrStrNW_cases[] =
+ {
+ {emptyW, sizeof(deadbeefW)/sizeof(WCHAR), NULL},
+ {deadW, sizeof(deadbeefW)/sizeof(WCHAR), deadbeefW},
+ {dead_lowerW, sizeof(deadbeefW)/sizeof(WCHAR), NULL},
+ {adbeW, sizeof(deadbeefW)/sizeof(WCHAR), deadbeefW + 2},
+ {adbe_lowerW, sizeof(deadbeefW)/sizeof(WCHAR), NULL},
+ {beefW, sizeof(deadbeefW)/sizeof(WCHAR), deadbeefW + 4},
+ {beef_lowerW, 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},
+ };
+
+ LPWSTR ret;
+ UINT i;
+
+ if (!pStrStrNW)
+ {
+ win_skip("StrStrNW() is not available\n");
+ return;
+ }
+
+ ret = pStrStrNW(NULL, NULL, 0);
+ ok(!ret, "Expected StrStrNW to return NULL, got %p\n", ret);
+
+ ret = pStrStrNW(NULL, NULL, 10);
+ ok(!ret, "Expected StrStrNW to return NULL, got %p\n", ret);
+
+ ret = pStrStrNW(NULL, emptyW, 10);
+ ok(!ret, "Expected StrStrNW to return NULL, got %p\n", ret);
+
+ ret = pStrStrNW(emptyW, NULL, 10);
+ ok(!ret, "Expected StrStrNW to return NULL, got %p\n", ret);
+
+ ret = pStrStrNW(emptyW, emptyW, 10);
+ ok(!ret, "Expected StrStrNW to return NULL, got %p\n", ret);
+
+ for (i = 0; i < sizeof(StrStrNW_cases)/sizeof(StrStrNW_cases[0]); i++)
+ {
+ ret = pStrStrNW(deadbeefW, StrStrNW_cases[i].search, StrStrNW_cases[i].count);
+ ok(ret == StrStrNW_cases[i].expect,
+ "[%d] Expected StrStrNW to return %p, got %p\n",
+ i, StrStrNW_cases[i].expect, ret);
+ }
+
+ /* StrStrNW 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 = pStrStrNW(deadbeefW, beefW, 100);
+ ok(ret == deadbeefW + 4, "Expected StrStrNW to return deadbeefW + 4, got %p\n", ret);
+
+ if (0)
+ {
+ ret = pStrStrNW(deadbeefW, beefW, ~0U);
+ ok(!ret, "Expected StrStrNW to return NULL, got %p\n", ret);
+ }
+}
+
+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);
+ }
+}
+