Esempio n. 1
0
static void InternetCrackUrl_test(void)
{
  URL_COMPONENTSA urlSrc, urlComponents;
  char protocol[32], hostName[1024], userName[1024];
  char password[1024], extra[1024], path[1024];
  BOOL ret, firstret;
  DWORD GLE, firstGLE;

  ZeroMemory(&urlSrc, sizeof(urlSrc));
  urlSrc.dwStructSize = sizeof(urlSrc);
  urlSrc.lpszScheme = protocol;
  urlSrc.lpszHostName = hostName;
  urlSrc.lpszUserName = userName;
  urlSrc.lpszPassword = password;
  urlSrc.lpszUrlPath = path;
  urlSrc.lpszExtraInfo = extra;

  copy_compsA(&urlSrc, &urlComponents, 32, 1024, 1024, 1024, 2048, 1024);
  ret = InternetCrackUrl(TEST_URL, 0,0,&urlComponents);
  ok( ret, "InternetCrackUrl failed, error %d\n",GetLastError());
  ok((strcmp(TEST_URL_PATH,path) == 0),"path cracked wrong\n");

  /* Bug 1805: Confirm the returned lengths are correct:                     */
  /* 1. When extra info split out explicitly */
  zero_compsA(&urlComponents, 0, 1, 0, 0, 1, 1);
  ok(InternetCrackUrlA(TEST_URL2, 0, 0, &urlComponents),"InternetCrackUrl failed, error %d\n", GetLastError());
  ok(urlComponents.dwUrlPathLength == strlen(TEST_URL2_PATH),".dwUrlPathLength should be %d, but is %d\n", (DWORD)strlen(TEST_URL2_PATH), urlComponents.dwUrlPathLength);
  ok(!strncmp(urlComponents.lpszUrlPath,TEST_URL2_PATH,strlen(TEST_URL2_PATH)),"lpszUrlPath should be %s but is %s\n", TEST_URL2_PATH, urlComponents.lpszUrlPath);
  ok(urlComponents.dwHostNameLength == strlen(TEST_URL2_SERVER),".dwHostNameLength should be %d, but is %d\n", (DWORD)strlen(TEST_URL2_SERVER), urlComponents.dwHostNameLength);
  ok(!strncmp(urlComponents.lpszHostName,TEST_URL2_SERVER,strlen(TEST_URL2_SERVER)),"lpszHostName should be %s but is %s\n", TEST_URL2_SERVER, urlComponents.lpszHostName);
  ok(urlComponents.dwExtraInfoLength == strlen(TEST_URL2_EXTRA),".dwExtraInfoLength should be %d, but is %d\n", (DWORD)strlen(TEST_URL2_EXTRA), urlComponents.dwExtraInfoLength);
  ok(!strncmp(urlComponents.lpszExtraInfo,TEST_URL2_EXTRA,strlen(TEST_URL2_EXTRA)),"lpszExtraInfo should be %s but is %s\n", TEST_URL2_EXTRA, urlComponents.lpszHostName);

  /* 2. When extra info is not split out explicitly and is in url path */
  zero_compsA(&urlComponents, 0, 1, 0, 0, 1, 0);
  ok(InternetCrackUrlA(TEST_URL2, 0, 0, &urlComponents),"InternetCrackUrl failed with GLE %d\n",GetLastError());
  ok(urlComponents.dwUrlPathLength == strlen(TEST_URL2_PATHEXTRA),".dwUrlPathLength should be %d, but is %d\n", (DWORD)strlen(TEST_URL2_PATHEXTRA), urlComponents.dwUrlPathLength);
  ok(!strncmp(urlComponents.lpszUrlPath,TEST_URL2_PATHEXTRA,strlen(TEST_URL2_PATHEXTRA)),"lpszUrlPath should be %s but is %s\n", TEST_URL2_PATHEXTRA, urlComponents.lpszUrlPath);
  ok(urlComponents.dwHostNameLength == strlen(TEST_URL2_SERVER),".dwHostNameLength should be %d, but is %d\n", (DWORD)strlen(TEST_URL2_SERVER), urlComponents.dwHostNameLength);
  ok(!strncmp(urlComponents.lpszHostName,TEST_URL2_SERVER,strlen(TEST_URL2_SERVER)),"lpszHostName should be %s but is %s\n", TEST_URL2_SERVER, urlComponents.lpszHostName);
  ok(urlComponents.nPort == INTERNET_DEFAULT_HTTP_PORT,"urlComponents->nPort should have been 80 instead of %d\n", urlComponents.nPort);
  ok(urlComponents.nScheme == INTERNET_SCHEME_HTTP,"urlComponents->nScheme should have been INTERNET_SCHEME_HTTP instead of %d\n", urlComponents.nScheme);

  zero_compsA(&urlComponents, 1, 1, 1, 1, 1, 1);
  ok(InternetCrackUrlA(TEST_URL, strlen(TEST_URL), 0, &urlComponents),"InternetCrackUrl failed with GLE %d\n",GetLastError());
  ok(urlComponents.dwUrlPathLength == strlen(TEST_URL_PATH),".dwUrlPathLength should be %d, but is %d\n", lstrlenA(TEST_URL_PATH), urlComponents.dwUrlPathLength);
  ok(!strncmp(urlComponents.lpszUrlPath,TEST_URL_PATH,strlen(TEST_URL_PATH)),"lpszUrlPath should be %s but is %s\n", TEST_URL_PATH, urlComponents.lpszUrlPath);
  ok(urlComponents.dwHostNameLength == strlen(TEST_URL_HOST),".dwHostNameLength should be %d, but is %d\n", lstrlenA(TEST_URL_HOST), urlComponents.dwHostNameLength);
  ok(!strncmp(urlComponents.lpszHostName,TEST_URL_HOST,strlen(TEST_URL_HOST)),"lpszHostName should be %s but is %s\n", TEST_URL_HOST, urlComponents.lpszHostName);
  ok(urlComponents.nPort == INTERNET_DEFAULT_HTTP_PORT,"urlComponents->nPort should have been 80 instead of %d\n", urlComponents.nPort);
  ok(urlComponents.nScheme == INTERNET_SCHEME_HTTP,"urlComponents->nScheme should have been INTERNET_SCHEME_HTTP instead of %d\n", urlComponents.nScheme);
  ok(!urlComponents.lpszUserName, ".lpszUserName should have been set to NULL\n");
  ok(!urlComponents.lpszPassword, ".lpszPassword should have been set to NULL\n");
  ok(!urlComponents.lpszExtraInfo, ".lpszExtraInfo should have been set to NULL\n");
  ok(!urlComponents.dwUserNameLength,".dwUserNameLength should be 0, but is %d\n", urlComponents.dwUserNameLength);
  ok(!urlComponents.dwPasswordLength,".dwPasswordLength should be 0, but is %d\n", urlComponents.dwPasswordLength);
  ok(!urlComponents.dwExtraInfoLength,".dwExtraInfoLength should be 0, but is %d\n", urlComponents.dwExtraInfoLength);

  /*3. Check for %20 */
  copy_compsA(&urlSrc, &urlComponents, 32, 1024, 1024, 1024, 2048, 1024);
  ok(InternetCrackUrlA(TEST_URL3, 0, ICU_DECODE, &urlComponents),"InternetCrackUrl failed with GLE %d\n",GetLastError());

  /* Tests for lpsz* members pointing to real strings while 
   * some corresponding length members are set to zero.
   * As of IE7 (wininet 7.0*?) all members are checked. So we
   * run the first test and expect the outcome to be the same
   * for the first four (scheme, hostname, username and password).
   * The last two (path and extrainfo) are the same for all versions
   * of the wininet.dll.
   */
  copy_compsA(&urlSrc, &urlComponents, 0, 1024, 1024, 1024, 2048, 1024);
  SetLastError(0xdeadbeef);
  firstret = InternetCrackUrlA(TEST_URL3, 0, ICU_DECODE, &urlComponents);
  firstGLE = GetLastError();

  copy_compsA(&urlSrc, &urlComponents, 32, 0, 1024, 1024, 2048, 1024);
  SetLastError(0xdeadbeef);
  ret = InternetCrackUrlA(TEST_URL3, 0, ICU_DECODE, &urlComponents);
  GLE = GetLastError();
  ok(ret==firstret && (GLE==firstGLE), "InternetCrackUrl returned %d with GLE=%d (expected to return %d)\n",
    ret, GetLastError(), firstret);

  copy_compsA(&urlSrc, &urlComponents, 32, 1024, 0, 1024, 2048, 1024);
  SetLastError(0xdeadbeef);
  ret = InternetCrackUrlA(TEST_URL3, 0, ICU_DECODE, &urlComponents);
  GLE = GetLastError();
  ok(ret==firstret && (GLE==firstGLE), "InternetCrackUrl returned %d with GLE=%d (expected to return %d)\n",
    ret, GetLastError(), firstret);

  copy_compsA(&urlSrc, &urlComponents, 32, 1024, 1024, 0, 2048, 1024);
  SetLastError(0xdeadbeef);
  ret = InternetCrackUrlA(TEST_URL3, 0, ICU_DECODE, &urlComponents);
  GLE = GetLastError();
  ok(ret==firstret && (GLE==firstGLE), "InternetCrackUrl returned %d with GLE=%d (expected to return %d)\n",
    ret, GetLastError(), firstret);

  copy_compsA(&urlSrc, &urlComponents, 32, 1024, 1024, 1024, 0, 1024);
  SetLastError(0xdeadbeef);
  ret = InternetCrackUrlA(TEST_URL3, 0, ICU_DECODE, &urlComponents);
  GLE = GetLastError();
  todo_wine
  ok(ret==0 && (GLE==ERROR_INVALID_HANDLE || GLE==ERROR_INSUFFICIENT_BUFFER),
     "InternetCrackUrl returned %d with GLE=%d (expected to return 0 and ERROR_INVALID_HANDLE or ERROR_INSUFFICIENT_BUFFER)\n",
    ret, GLE);

  copy_compsA(&urlSrc, &urlComponents, 32, 1024, 1024, 1024, 2048, 0);
  SetLastError(0xdeadbeef);
  ret = InternetCrackUrlA(TEST_URL3, 0, ICU_DECODE, &urlComponents);
  GLE = GetLastError();
  todo_wine
  ok(ret==0 && (GLE==ERROR_INVALID_HANDLE || GLE==ERROR_INSUFFICIENT_BUFFER),
     "InternetCrackUrl returned %d with GLE=%d (expected to return 0 and ERROR_INVALID_HANDLE or ERROR_INSUFFICIENT_BUFFER)\n",
    ret, GLE);

  copy_compsA(&urlSrc, &urlComponents, 0, 0, 0, 0, 0, 0);
  ret = InternetCrackUrlA(TEST_URL3, 0, ICU_DECODE, &urlComponents);
  GLE = GetLastError();
  todo_wine
  ok(ret==0 && GLE==ERROR_INVALID_PARAMETER,
     "InternetCrackUrl returned %d with GLE=%d (expected to return 0 and ERROR_INVALID_PARAMETER)\n",
    ret, GLE);

  copy_compsA(&urlSrc, &urlComponents, 32, 1024, 1024, 1024, 2048, 1024);
  ret = InternetCrackUrl("about://host/blank", 0,0,&urlComponents);
  ok(ret, "InternetCrackUrl failed with %d\n", GetLastError());
  ok(!strcmp(urlComponents.lpszScheme, "about"), "lpszScheme was \"%s\" instead of \"about\"\n", urlComponents.lpszScheme);
  ok(!strcmp(urlComponents.lpszHostName, "host"), "lpszHostName was \"%s\" instead of \"host\"\n", urlComponents.lpszHostName);
  ok(!strcmp(urlComponents.lpszUrlPath, "/blank"), "lpszUrlPath was \"%s\" instead of \"/blank\"\n", urlComponents.lpszUrlPath);

  /* try a NULL lpszUrl */
  SetLastError(0xdeadbeef);
  copy_compsA(&urlSrc, &urlComponents, 32, 1024, 1024, 1024, 2048, 1024);
  ret = InternetCrackUrl(NULL, 0, 0, &urlComponents);
  GLE = GetLastError();
  ok(ret == FALSE, "Expected InternetCrackUrl to fail\n");
  ok(GLE == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GLE);

  /* try an empty lpszUrl, GetLastError returns 12006, whatever that means
   * we just need to fail and not return success
   */
  SetLastError(0xdeadbeef);
  copy_compsA(&urlSrc, &urlComponents, 32, 1024, 1024, 1024, 2048, 1024);
  ret = InternetCrackUrl("", 0, 0, &urlComponents);
  GLE = GetLastError();
  ok(ret == FALSE, "Expected InternetCrackUrl to fail\n");
  ok(GLE != 0xdeadbeef && GLE != ERROR_SUCCESS, "Expected GLE to represent a failure\n");

  /* Invalid Call: must set size of components structure (Windows only
   * enforces this on the InternetCrackUrlA version of the call) */
  copy_compsA(&urlSrc, &urlComponents, 0, 1024, 1024, 1024, 2048, 1024);
  SetLastError(0xdeadbeef);
  urlComponents.dwStructSize = 0;
  ret = InternetCrackUrlA(TEST_URL, 0, 0, &urlComponents);
  ok(ret == FALSE, "Expected InternetCrackUrl to fail\n");
  ok(GLE != 0xdeadbeef && GLE != ERROR_SUCCESS, "Expected GLE to represent a failure\n");

  /* Invalid Call: size of dwStructSize must be one of the "standard" sizes
   * of the URL_COMPONENTS structure (Windows only enforces this on the
   * InternetCrackUrlA version of the call) */
  copy_compsA(&urlSrc, &urlComponents, 0, 1024, 1024, 1024, 2048, 1024);
  SetLastError(0xdeadbeef);
  urlComponents.dwStructSize = sizeof(urlComponents) + 1;
  ret = InternetCrackUrlA(TEST_URL, 0, 0, &urlComponents);
  ok(ret == FALSE, "Expected InternetCrackUrl to fail\n");
  ok(GLE != 0xdeadbeef && GLE != ERROR_SUCCESS, "Expected GLE to represent a failure\n");
}
Esempio n. 2
0
static void test_crack_url(const crack_url_test_t *test)
{
    WCHAR buf[INTERNET_MAX_URL_LENGTH];
    URL_COMPONENTSW urlw;
    URL_COMPONENTSA url;
    BOOL b;

    zero_compsA(&url, 1, 1, 1, 1, 1, 1);

    b = InternetCrackUrlA(test->url, strlen(test->url), 0, &url);
    ok(b, "InternetCrackUrl failed with error %d\n", GetLastError());

    if(test->scheme_off == -1)
        ok(!url.lpszScheme, "[%s] url.lpszScheme = %p, expected NULL\n", test->url, url.lpszScheme);
    else
        ok(url.lpszScheme == test->url+test->scheme_off, "[%s] url.lpszScheme = %p, expected %p\n",
           test->url, url.lpszScheme, test->url+test->scheme_off);
    ok(url.dwSchemeLength == test->scheme_len, "[%s] url.lpszSchemeLength = %d, expected %d\n",
       test->url, url.dwSchemeLength, test->scheme_len);

    ok(url.nScheme == test->scheme, "[%s] url.nScheme = %d, expected %d\n", test->url, url.nScheme, test->scheme);

    if(test->host_off == -1)
        ok(!url.lpszHostName, "[%s] url.lpszHostName = %p, expected NULL\n", test->url, url.lpszHostName);
    else
        ok(url.lpszHostName == test->url+test->host_off, "[%s] url.lpszHostName = %p, expected %p\n",
           test->url, url.lpszHostName, test->url+test->host_off);
    if(test->host_skip_broken != -1 && url.dwHostNameLength == test->host_skip_broken) {
        win_skip("skipping broken dwHostNameLength result\n");
        return;
    }
    ok(url.dwHostNameLength == test->host_len, "[%s] url.lpszHostNameLength = %d, expected %d\n",
       test->url, url.dwHostNameLength, test->host_len);

    ok(url.nPort == test->port, "[%s] nPort = %d, expected %d\n", test->url, url.nPort, test->port);

    if(test->user_off == -1)
        ok(!url.lpszUserName, "[%s] url.lpszUserName = %p\n", test->url, url.lpszUserName);
    else
        ok(url.lpszUserName == test->url+test->user_off, "[%s] url.lpszUserName = %p, expected %p\n",
           test->url, url.lpszUserName, test->url+test->user_off);
    ok(url.dwUserNameLength == test->user_len, "[%s] url.lpszUserNameLength = %d, expected %d\n",
       test->url, url.dwUserNameLength, test->user_len);

    if(test->pass_off == -1)
        ok(!url.lpszPassword, "[%s] url.lpszPassword = %p\n", test->url, url.lpszPassword);
    else
        ok(url.lpszPassword == test->url+test->pass_off, "[%s] url.lpszPassword = %p, expected %p\n",
           test->url, url.lpszPassword, test->url+test->pass_off);
    ok(url.dwPasswordLength == test->pass_len, "[%s] url.lpszPasswordLength = %d, expected %d\n",
       test->url, url.dwPasswordLength, test->pass_len);

    if(test->path_off == -1)
        ok(!url.lpszUrlPath, "[%s] url.lpszPath = %p, expected NULL\n", test->url, url.lpszUrlPath);
    else
        ok(url.lpszUrlPath == test->url+test->path_off, "[%s] url.lpszPath = %p, expected %p\n",
           test->url, url.lpszUrlPath, test->url+test->path_off);
    ok(url.dwUrlPathLength == test->path_len, "[%s] url.lpszUrlPathLength = %d, expected %d\n",
       test->url, url.dwUrlPathLength, test->path_len);

    if(test->extra_off == -1)
        ok(!url.lpszExtraInfo, "[%s] url.lpszExtraInfo = %p, expected NULL\n", test->url, url.lpszExtraInfo);
    else
        ok(url.lpszExtraInfo == test->url+test->extra_off, "[%s] url.lpszExtraInfo = %p, expected %p\n",
           test->url, url.lpszExtraInfo, test->url+test->extra_off);
    ok(url.dwExtraInfoLength == test->extra_len, "[%s] url.lpszExtraInfoLength = %d, expected %d\n",
       test->url, url.dwExtraInfoLength, test->extra_len);

    memset(&urlw, 0, sizeof(URL_COMPONENTSW));
    urlw.dwStructSize = sizeof(URL_COMPONENTSW);
    urlw.dwSchemeLength = 1;
    urlw.dwHostNameLength = 1;
    urlw.dwUserNameLength = 1;
    urlw.dwPasswordLength = 1;
    urlw.dwUrlPathLength = 1;
    urlw.dwExtraInfoLength = 1;

    MultiByteToWideChar(CP_ACP, 0, test->url, -1, buf, sizeof(buf)/sizeof(buf[0]));
    b = InternetCrackUrlW(buf, lstrlenW(buf), 0, &urlw);
    if(!b && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) {
        win_skip("InternetCrackUrlW is not implemented\n");
        return;
    }
    ok(b, "InternetCrackUrl failed with error %d\n", GetLastError());

    if(test->scheme_off == -1)
        ok(!urlw.lpszScheme, "[%s] urlw.lpszScheme = %p, expected NULL\n", test->url, urlw.lpszScheme);
    else
        ok(urlw.lpszScheme == buf+test->scheme_off, "[%s] urlw.lpszScheme = %p, expected %p\n",
           test->url, urlw.lpszScheme, buf+test->scheme_off);
    ok(urlw.dwSchemeLength == test->scheme_len, "[%s] urlw.lpszSchemeLength = %d, expected %d\n",
       test->url, urlw.dwSchemeLength, test->scheme_len);

    ok(urlw.nScheme == test->scheme, "[%s] urlw.nScheme = %d, expected %d\n", test->url, urlw.nScheme, test->scheme);

    if(test->host_off == -1) {
        ok(!urlw.lpszHostName, "[%s] urlw.lpszHostName = %p, expected NULL\n", test->url, urlw.lpszHostName);
        ok(urlw.dwHostNameLength == 0 || broken(urlw.dwHostNameLength == 1), "[%s] urlw.lpszHostNameLength = %d, expected %d\n",
           test->url, urlw.dwHostNameLength, test->host_len);
    }else {
        ok(urlw.lpszHostName == buf+test->host_off, "[%s] urlw.lpszHostName = %p, expected %p\n",
           test->url, urlw.lpszHostName, test->url+test->host_off);
        ok(urlw.dwHostNameLength == test->host_len, "[%s] urlw.lpszHostNameLength = %d, expected %d\n",
           test->url, urlw.dwHostNameLength, test->host_len);
    }

    ok(urlw.nPort == test->port, "[%s] nPort = %d, expected %d\n", test->url, urlw.nPort, test->port);

    if(test->user_off == -1) {
        ok(!urlw.lpszUserName, "[%s] urlw.lpszUserName = %p\n", test->url, urlw.lpszUserName);
        ok(urlw.dwUserNameLength == 0 || broken(urlw.dwUserNameLength == 1), "[%s] urlw.lpszUserNameLength = %d, expected %d\n",
           test->url, urlw.dwUserNameLength, test->user_len);
    }else {
        ok(urlw.lpszUserName == buf+test->user_off, "[%s] urlw.lpszUserName = %p, expected %p\n",
           test->url, urlw.lpszUserName, buf+test->user_off);
        ok(urlw.dwUserNameLength == test->user_len, "[%s] urlw.lpszUserNameLength = %d, expected %d\n",
           test->url, urlw.dwUserNameLength, test->user_len);
    }

    if(test->pass_off == -1) {
        ok(!urlw.lpszPassword, "[%s] urlw.lpszPassword = %p\n", test->url, urlw.lpszPassword);
        ok(urlw.dwPasswordLength == 0 || broken(urlw.dwPasswordLength), "[%s] urlw.lpszPasswordLength = %d, expected %d\n",
           test->url, urlw.dwPasswordLength, test->pass_len);
    }else {
        ok(urlw.lpszPassword == buf+test->pass_off, "[%s] urlw.lpszPassword = %p, expected %p\n",
           test->url, urlw.lpszPassword, buf+test->pass_off);
        ok(urlw.dwPasswordLength == test->pass_len, "[%s] urlw.lpszPasswordLength = %d, expected %d\n",
           test->url, urlw.dwPasswordLength, test->pass_len);
    }

    if(test->path_off == -1)
        ok(!urlw.lpszUrlPath, "[%s] urlw.lpszPath = %p, expected NULL\n", test->url, urlw.lpszUrlPath);
    else
        ok(urlw.lpszUrlPath == buf+test->path_off, "[%s] urlw.lpszPath = %p, expected %p\n",
           test->url, urlw.lpszUrlPath, buf+test->path_off);
    ok(urlw.dwUrlPathLength == test->path_len, "[%s] urlw.lpszUrlPathLength = %d, expected %d\n",
       test->url, urlw.dwUrlPathLength, test->path_len);

    if(test->extra_off == -1) {
        ok(!urlw.lpszExtraInfo, "[%s] url.lpszExtraInfo = %p, expected NULL\n", test->url, urlw.lpszExtraInfo);
        ok(urlw.dwExtraInfoLength == 0 || broken(urlw.dwExtraInfoLength == 1), "[%s] urlw.lpszExtraInfoLength = %d, expected %d\n",
           test->url, urlw.dwExtraInfoLength, test->extra_len);
    }else {
        ok(urlw.lpszExtraInfo == buf+test->extra_off, "[%s] urlw.lpszExtraInfo = %p, expected %p\n",
           test->url, urlw.lpszExtraInfo, buf+test->extra_off);
        ok(urlw.dwExtraInfoLength == test->extra_len, "[%s] urlw.lpszExtraInfoLength = %d, expected %d\n",
           test->url, urlw.dwExtraInfoLength, test->extra_len);
    }
}
Esempio n. 3
0
static void test_crack_url(const crack_url_test_t *test)
{
    WCHAR buf[INTERNET_MAX_URL_LENGTH];
    URL_COMPONENTSW urlw;
    URL_COMPONENTSA url;
    char scheme[32], hostname[1024], username[1024];
    char password[1024], extrainfo[1024], urlpath[1024];
    BOOL b;

    /* test InternetCrackUrlA with NULL buffers */
    zero_compsA(&url, 1, 1, 1, 1, 1, 1);

    b = InternetCrackUrlA(test->url, strlen(test->url), 0, &url);
    ok(b, "InternetCrackUrl failed with error %d\n", GetLastError());

    if(test->scheme_off == -1)
        ok(!url.lpszScheme, "[%s] url.lpszScheme = %p, expected NULL\n", test->url, url.lpszScheme);
    else
        ok(url.lpszScheme == test->url+test->scheme_off, "[%s] url.lpszScheme = %p, expected %p\n",
           test->url, url.lpszScheme, test->url+test->scheme_off);
    ok(url.dwSchemeLength == test->scheme_len, "[%s] url.lpszSchemeLength = %d, expected %d\n",
       test->url, url.dwSchemeLength, test->scheme_len);

    ok(url.nScheme == test->scheme, "[%s] url.nScheme = %d, expected %d\n", test->url, url.nScheme, test->scheme);

    if(test->host_off == -1)
        ok(!url.lpszHostName, "[%s] url.lpszHostName = %p, expected NULL\n", test->url, url.lpszHostName);
    else
        ok(url.lpszHostName == test->url+test->host_off, "[%s] url.lpszHostName = %p, expected %p\n",
           test->url, url.lpszHostName, test->url+test->host_off);
    if(test->host_skip_broken != -1 && url.dwHostNameLength == test->host_skip_broken) {
        win_skip("skipping broken dwHostNameLength result\n");
        return;
    }
    ok(url.dwHostNameLength == test->host_len, "[%s] url.lpszHostNameLength = %d, expected %d\n",
       test->url, url.dwHostNameLength, test->host_len);

    ok(url.nPort == test->port, "[%s] nPort = %d, expected %d\n", test->url, url.nPort, test->port);

    if(test->user_off == -1)
        ok(!url.lpszUserName, "[%s] url.lpszUserName = %p\n", test->url, url.lpszUserName);
    else
        ok(url.lpszUserName == test->url+test->user_off, "[%s] url.lpszUserName = %p, expected %p\n",
           test->url, url.lpszUserName, test->url+test->user_off);
    ok(url.dwUserNameLength == test->user_len, "[%s] url.lpszUserNameLength = %d, expected %d\n",
       test->url, url.dwUserNameLength, test->user_len);

    if(test->pass_off == -1)
        ok(!url.lpszPassword, "[%s] url.lpszPassword = %p\n", test->url, url.lpszPassword);
    else
        ok(url.lpszPassword == test->url+test->pass_off, "[%s] url.lpszPassword = %p, expected %p\n",
           test->url, url.lpszPassword, test->url+test->pass_off);
    ok(url.dwPasswordLength == test->pass_len, "[%s] url.lpszPasswordLength = %d, expected %d\n",
       test->url, url.dwPasswordLength, test->pass_len);

    if(test->path_off == -1)
        ok(!url.lpszUrlPath, "[%s] url.lpszPath = %p, expected NULL\n", test->url, url.lpszUrlPath);
    else
        ok(url.lpszUrlPath == test->url+test->path_off, "[%s] url.lpszPath = %p, expected %p\n",
           test->url, url.lpszUrlPath, test->url+test->path_off);
    ok(url.dwUrlPathLength == test->path_len, "[%s] url.lpszUrlPathLength = %d, expected %d\n",
       test->url, url.dwUrlPathLength, test->path_len);

    if(test->extra_off == -1)
        ok(!url.lpszExtraInfo, "[%s] url.lpszExtraInfo = %p, expected NULL\n", test->url, url.lpszExtraInfo);
    else
        ok(url.lpszExtraInfo == test->url+test->extra_off, "[%s] url.lpszExtraInfo = %p, expected %p\n",
           test->url, url.lpszExtraInfo, test->url+test->extra_off);
    ok(url.dwExtraInfoLength == test->extra_len, "[%s] url.lpszExtraInfoLength = %d, expected %d\n",
       test->url, url.dwExtraInfoLength, test->extra_len);

    /* test InternetCrackUrlW with NULL buffers */
    memset(&urlw, 0, sizeof(URL_COMPONENTSW));
    urlw.dwStructSize = sizeof(URL_COMPONENTSW);
    urlw.dwSchemeLength = 1;
    urlw.dwHostNameLength = 1;
    urlw.dwUserNameLength = 1;
    urlw.dwPasswordLength = 1;
    urlw.dwUrlPathLength = 1;
    urlw.dwExtraInfoLength = 1;

    MultiByteToWideChar(CP_ACP, 0, test->url, -1, buf, sizeof(buf)/sizeof(buf[0]));
    b = InternetCrackUrlW(buf, lstrlenW(buf), 0, &urlw);
    if(!b && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) {
        win_skip("InternetCrackUrlW is not implemented\n");
        return;
    }
    ok(b, "InternetCrackUrl failed with error %d\n", GetLastError());

    if(test->scheme_off == -1)
        ok(!urlw.lpszScheme, "[%s] urlw.lpszScheme = %p, expected NULL\n", test->url, urlw.lpszScheme);
    else
        ok(urlw.lpszScheme == buf+test->scheme_off, "[%s] urlw.lpszScheme = %p, expected %p\n",
           test->url, urlw.lpszScheme, buf+test->scheme_off);
    ok(urlw.dwSchemeLength == test->scheme_len, "[%s] urlw.lpszSchemeLength = %d, expected %d\n",
       test->url, urlw.dwSchemeLength, test->scheme_len);

    ok(urlw.nScheme == test->scheme, "[%s] urlw.nScheme = %d, expected %d\n", test->url, urlw.nScheme, test->scheme);

    if(test->host_off == -1) {
        ok(!urlw.lpszHostName, "[%s] urlw.lpszHostName = %p, expected NULL\n", test->url, urlw.lpszHostName);
        ok(urlw.dwHostNameLength == 0 || broken(urlw.dwHostNameLength == 1), "[%s] urlw.lpszHostNameLength = %d, expected %d\n",
           test->url, urlw.dwHostNameLength, test->host_len);
    }else {
        ok(urlw.lpszHostName == buf+test->host_off, "[%s] urlw.lpszHostName = %p, expected %p\n",
           test->url, urlw.lpszHostName, test->url+test->host_off);
        ok(urlw.dwHostNameLength == test->host_len, "[%s] urlw.lpszHostNameLength = %d, expected %d\n",
           test->url, urlw.dwHostNameLength, test->host_len);
    }

    ok(urlw.nPort == test->port, "[%s] nPort = %d, expected %d\n", test->url, urlw.nPort, test->port);

    if(test->user_off == -1) {
        ok(!urlw.lpszUserName, "[%s] urlw.lpszUserName = %p\n", test->url, urlw.lpszUserName);
        ok(urlw.dwUserNameLength == 0 || broken(urlw.dwUserNameLength == 1), "[%s] urlw.lpszUserNameLength = %d, expected %d\n",
           test->url, urlw.dwUserNameLength, test->user_len);
    }else {
        ok(urlw.lpszUserName == buf+test->user_off, "[%s] urlw.lpszUserName = %p, expected %p\n",
           test->url, urlw.lpszUserName, buf+test->user_off);
        ok(urlw.dwUserNameLength == test->user_len, "[%s] urlw.lpszUserNameLength = %d, expected %d\n",
           test->url, urlw.dwUserNameLength, test->user_len);
    }

    if(test->pass_off == -1) {
        ok(!urlw.lpszPassword, "[%s] urlw.lpszPassword = %p\n", test->url, urlw.lpszPassword);
        ok(urlw.dwPasswordLength == 0 || broken(urlw.dwPasswordLength), "[%s] urlw.lpszPasswordLength = %d, expected %d\n",
           test->url, urlw.dwPasswordLength, test->pass_len);
    }else {
        ok(urlw.lpszPassword == buf+test->pass_off, "[%s] urlw.lpszPassword = %p, expected %p\n",
           test->url, urlw.lpszPassword, buf+test->pass_off);
        ok(urlw.dwPasswordLength == test->pass_len, "[%s] urlw.lpszPasswordLength = %d, expected %d\n",
           test->url, urlw.dwPasswordLength, test->pass_len);
    }

    if(test->path_off == -1)
        ok(!urlw.lpszUrlPath, "[%s] urlw.lpszPath = %p, expected NULL\n", test->url, urlw.lpszUrlPath);
    else
        ok(urlw.lpszUrlPath == buf+test->path_off, "[%s] urlw.lpszPath = %p, expected %p\n",
           test->url, urlw.lpszUrlPath, buf+test->path_off);
    ok(urlw.dwUrlPathLength == test->path_len, "[%s] urlw.lpszUrlPathLength = %d, expected %d\n",
       test->url, urlw.dwUrlPathLength, test->path_len);

    if(test->extra_off == -1) {
        ok(!urlw.lpszExtraInfo, "[%s] url.lpszExtraInfo = %p, expected NULL\n", test->url, urlw.lpszExtraInfo);
        ok(urlw.dwExtraInfoLength == 0 || broken(urlw.dwExtraInfoLength == 1), "[%s] urlw.lpszExtraInfoLength = %d, expected %d\n",
           test->url, urlw.dwExtraInfoLength, test->extra_len);
    }else {
        ok(urlw.lpszExtraInfo == buf+test->extra_off, "[%s] urlw.lpszExtraInfo = %p, expected %p\n",
           test->url, urlw.lpszExtraInfo, buf+test->extra_off);
        ok(urlw.dwExtraInfoLength == test->extra_len, "[%s] urlw.lpszExtraInfoLength = %d, expected %d\n",
           test->url, urlw.dwExtraInfoLength, test->extra_len);
    }

    /* test InternetCrackUrlA with valid buffers */
    memset(&url, 0, sizeof(URL_COMPONENTSA));
    url.dwStructSize = sizeof(URL_COMPONENTSA);
    url.lpszScheme = scheme;
    url.dwSchemeLength = sizeof(scheme);
    url.lpszHostName = hostname;
    url.dwHostNameLength = sizeof(hostname);
    url.lpszUserName = username;
    url.dwUserNameLength = sizeof(username);
    url.lpszPassword = password;
    url.dwPasswordLength = sizeof(password);
    url.lpszUrlPath = urlpath;
    url.dwUrlPathLength = sizeof(urlpath);
    url.lpszExtraInfo = extrainfo;
    url.dwExtraInfoLength = sizeof(extrainfo);

    b = InternetCrackUrlA(test->url, strlen(test->url), 0, &url);
    ok(b, "InternetCrackUrlA failed with error %d\n", GetLastError());

    ok(url.dwSchemeLength == strlen(test->exp_scheme), "[%s] Got wrong scheme length: %d\n",
            test->url, url.dwSchemeLength);
    ok(!strcmp(scheme, test->exp_scheme), "[%s] Got wrong scheme, expected: %s, got: %s\n",
            test->url, test->exp_scheme, scheme);

    ok(url.nScheme == test->scheme, "[%s] Got wrong nScheme, expected: %d, got: %d\n",
            test->url, test->scheme, url.nScheme);

    ok(url.dwHostNameLength == strlen(test->exp_hostname), "[%s] Got wrong hostname length: %d\n",
            test->url, url.dwHostNameLength);
    ok(!strcmp(hostname, test->exp_hostname), "[%s] Got wrong hostname, expected: %s, got: %s\n",
            test->url, test->exp_hostname, hostname);

    ok(url.nPort == test->port, "[%s] Got wrong port, expected: %d, got: %d\n",
            test->url, test->port, url.nPort);

    ok(url.dwUserNameLength == strlen(test->exp_username), "[%s] Got wrong username length: %d\n",
            test->url, url.dwUserNameLength);
    ok(!strcmp(username, test->exp_username), "[%s] Got wrong username, expected: %s, got: %s\n",
            test->url, test->exp_username, username);

    ok(url.dwPasswordLength == strlen(test->exp_password), "[%s] Got wrong password length: %d\n",
            test->url, url.dwPasswordLength);
    ok(!strcmp(password, test->exp_password), "[%s] Got wrong password, expected: %s, got: %s\n",
            test->url, test->exp_password, password);

    ok(url.dwUrlPathLength == strlen(test->exp_urlpath), "[%s] Got wrong urlpath length: %d\n",
            test->url, url.dwUrlPathLength);
    ok(!strcmp(urlpath, test->exp_urlpath), "[%s] Got wrong urlpath, expected: %s, got: %s\n",
            test->url, test->exp_urlpath, urlpath);

    ok(url.dwExtraInfoLength == strlen(test->exp_extrainfo), "[%s] Got wrong extrainfo length: %d\n",
            test->url, url.dwExtraInfoLength);
    ok(!strcmp(extrainfo, test->exp_extrainfo), "[%s] Got wrong extrainfo, expected: %s, got: %s\n",
            test->url, test->exp_extrainfo, extrainfo);

    /* test InternetCrackUrlW with valid buffers */
    memset(&urlw, 0, sizeof(URL_COMPONENTSW));
    urlw.dwStructSize = sizeof(URL_COMPONENTSW);
    urlw.lpszScheme = (WCHAR*)scheme;
    urlw.dwSchemeLength = sizeof(scheme) / sizeof(WCHAR);
    urlw.lpszHostName = (WCHAR*)hostname;
    urlw.dwHostNameLength = sizeof(hostname) / sizeof(WCHAR);
    urlw.lpszUserName = (WCHAR*)username;
    urlw.dwUserNameLength = sizeof(username) / sizeof(WCHAR);
    urlw.lpszPassword = (WCHAR*)password;
    urlw.dwPasswordLength = sizeof(password) / sizeof(WCHAR);
    urlw.lpszUrlPath = (WCHAR*)urlpath;
    urlw.dwUrlPathLength = sizeof(urlpath) / sizeof(WCHAR);
    urlw.lpszExtraInfo = (WCHAR*)extrainfo;
    urlw.dwExtraInfoLength = sizeof(extrainfo) / sizeof(WCHAR);

    b = InternetCrackUrlW(buf, lstrlenW(buf), 0, &urlw);
    ok(b, "InternetCrackUrlW failed with error %d\n", GetLastError());

    ok(urlw.dwSchemeLength == strlen(test->exp_scheme), "[%s] Got wrong scheme length: %d\n",
            test->url, urlw.dwSchemeLength);
    ok(!lstrcmpW((WCHAR*)scheme, w_str_of(test->exp_scheme)), "[%s] Got wrong scheme, expected: %s, got: %s\n",
            test->url, test->exp_scheme, wine_dbgstr_w((WCHAR*)scheme));

    ok(urlw.nScheme == test->scheme, "[%s] Got wrong nScheme, expected: %d, got: %d\n",
            test->url, test->scheme, urlw.nScheme);

    ok(urlw.dwHostNameLength == strlen(test->exp_hostname), "[%s] Got wrong hostname length: %d\n",
            test->url, urlw.dwHostNameLength);
    ok(!lstrcmpW((WCHAR*)hostname, w_str_of(test->exp_hostname)), "[%s] Got wrong hostname, expected: %s, got: %s\n",
            test->url, test->exp_hostname, wine_dbgstr_w((WCHAR*)hostname));

    ok(urlw.nPort == test->port, "[%s] Got wrong port, expected: %d, got: %d\n",
            test->url, test->port, urlw.nPort);

    ok(urlw.dwUserNameLength == strlen(test->exp_username), "[%s] Got wrong username length: %d\n",
            test->url, urlw.dwUserNameLength);
    ok(!lstrcmpW((WCHAR*)username, w_str_of(test->exp_username)), "[%s] Got wrong username, expected: %s, got: %s\n",
            test->url, test->exp_username, wine_dbgstr_w((WCHAR*)username));

    ok(urlw.dwPasswordLength == strlen(test->exp_password), "[%s] Got wrong password length: %d\n",
            test->url, urlw.dwPasswordLength);
    ok(!lstrcmpW((WCHAR*)password, w_str_of(test->exp_password)), "[%s] Got wrong password, expected: %s, got: %s\n",
            test->url, test->exp_password, wine_dbgstr_w((WCHAR*)password));

    ok(urlw.dwUrlPathLength == strlen(test->exp_urlpath), "[%s] Got wrong urlpath length: %d\n",
            test->url, urlw.dwUrlPathLength);
    ok(!lstrcmpW((WCHAR*)urlpath, w_str_of(test->exp_urlpath)), "[%s] Got wrong urlpath, expected: %s, got: %s\n",
            test->url, test->exp_urlpath, wine_dbgstr_w((WCHAR*)urlpath));

    ok(urlw.dwExtraInfoLength == strlen(test->exp_extrainfo), "[%s] Got wrong extrainfo length: %d\n",
            test->url, urlw.dwExtraInfoLength);
    ok(!lstrcmpW((WCHAR*)extrainfo, w_str_of(test->exp_extrainfo)), "[%s] Got wrong extrainfo, expected: %s, got: %s\n",
            test->url, test->exp_extrainfo, wine_dbgstr_w((WCHAR*)extrainfo));
}