⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shellpath.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 3 页
字号:
    testDesktop();
    testPersonal();
    testShellValues(requiredShellValues, ARRAY_SIZE(requiredShellValues),
     FALSE);
    testShellValues(optionalShellValues, ARRAY_SIZE(optionalShellValues),
     TRUE);
}

/* Verifies various shell virtual folders have the correct well-known GUIDs. */
static void testGUIDs(void)
{
    matchGUID(CSIDL_BITBUCKET, &CLSID_RecycleBin);
    matchGUID(CSIDL_CONTROLS, &CLSID_ControlPanel);
    matchGUID(CSIDL_DRIVES, &CLSID_MyComputer);
    matchGUID(CSIDL_INTERNET, &CLSID_Internet);
    matchGUID(CSIDL_NETWORK, &CLSID_NetworkPlaces);
    matchGUID(CSIDL_PERSONAL, &CLSID_MyDocuments);
    matchGUID(CSIDL_COMMON_DOCUMENTS, &CLSID_CommonDocuments);
}

/* Verifies various shell paths match the environment variables to which they
 * correspond.
 */
static void testEnvVars(void)
{
    matchSpecialFolderPathToEnv(CSIDL_PROGRAM_FILES, "ProgramFiles");
    matchSpecialFolderPathToEnv(CSIDL_APPDATA, "APPDATA");
    matchSpecialFolderPathToEnv(CSIDL_PROFILE, "USERPROFILE");
    matchSpecialFolderPathToEnv(CSIDL_WINDOWS, "SystemRoot");
    matchSpecialFolderPathToEnv(CSIDL_WINDOWS, "windir");
    matchSpecialFolderPathToEnv(CSIDL_PROGRAM_FILES_COMMON,
     "CommonProgramFiles");
    /* this is only set on Wine, but can't hurt to verify it: */
    matchSpecialFolderPathToEnv(CSIDL_SYSTEM, "winsysdir");
}

/* Verifies the shell path for CSIDL_WINDOWS matches the return from
 * GetWindowsDirectory.  If SHGetSpecialFolderPath fails, no harm, no foul--not
 * every shell32 version supports CSIDL_WINDOWS.
 */
static void testWinDir(void)
{
    char windowsShellPath[MAX_PATH], windowsDir[MAX_PATH] = { 0 };

    if (!pSHGetSpecialFolderPathA) return;

    if (pSHGetSpecialFolderPathA(NULL, windowsShellPath, CSIDL_WINDOWS, FALSE))
    {
        PathRemoveBackslashA(windowsShellPath);
        GetWindowsDirectoryA(windowsDir, sizeof(windowsDir));
        PathRemoveBackslashA(windowsDir);
        ok(!lstrcmpiA(windowsDir, windowsShellPath),
         "GetWindowsDirectory does not match SHGetSpecialFolderPath:\n"
         "GetWindowsDirectory returns %s\nSHGetSpecialFolderPath returns %s\n",
         windowsDir, windowsShellPath);
    }
}

/* Verifies the shell path for CSIDL_SYSTEM and CSIDL_SYSTEMX86 matches the
 * return from GetSystemDirectory.  If SHGetSpecialFolderPath fails, no harm,
 * no foul--not every shell32 version supports CSIDL_SYSTEM.
 */
static void testSystemDir(void)
{
    char systemShellPath[MAX_PATH], systemDir[MAX_PATH] = { 0 };

    if (!pSHGetSpecialFolderPathA) return;

    GetSystemDirectoryA(systemDir, sizeof(systemDir));
    PathRemoveBackslashA(systemDir);
    if (pSHGetSpecialFolderPathA(NULL, systemShellPath, CSIDL_SYSTEM, FALSE))
    {
        PathRemoveBackslashA(systemShellPath);
        ok(!lstrcmpiA(systemDir, systemShellPath),
         "GetSystemDirectory does not match SHGetSpecialFolderPath:\n"
         "GetSystemDirectory returns %s\nSHGetSpecialFolderPath returns %s\n",
         systemDir, systemShellPath);
    }
    /* check CSIDL_SYSTEMX86; note that this isn't always present, so don't
     * worry if it fails
     */
    if (pSHGetSpecialFolderPathA(NULL, systemShellPath, CSIDL_SYSTEMX86, FALSE))
    {
        PathRemoveBackslashA(systemShellPath);
        ok(!lstrcmpiA(systemDir, systemShellPath),
         "GetSystemDirectory does not match SHGetSpecialFolderPath:\n"
         "GetSystemDirectory returns %s\nSHGetSpecialFolderPath returns %s\n",
         systemDir, systemShellPath);
    }
}

/* Globals used by subprocesses */
static int    myARGC;
static char **myARGV;
static char   base[MAX_PATH];
static char   selfname[MAX_PATH];

static int init(void)
{
    myARGC = winetest_get_mainargs(&myARGV);
    if (!GetCurrentDirectoryA(sizeof(base), base)) return 0;
    strcpy(selfname, myARGV[0]);
    return 1;
}

/* Subprocess helper 1: test what happens when CSIDL_FAVORITES is set to a
 * nonexistent directory.
 */
static void testNonExistentPath1(void)
{
    HRESULT hr;
    LPITEMIDLIST pidl;
    char path[MAX_PATH];

    /* test some failure cases first: */
    hr = pSHGetFolderPathA(NULL, CSIDL_FAVORITES, NULL,
     SHGFP_TYPE_CURRENT, NULL);
    ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND),
     "SHGetFolderPath returned 0x%08lx, expected 0x80070002\n", hr);
    pidl = NULL;
    hr = pSHGetFolderLocation(NULL, CSIDL_FAVORITES, NULL, 0,
     &pidl);
    ok(hr == E_FAIL,
     "SHGetFolderLocation returned 0x%08lx, expected E_FAIL\n", hr);
    if (SUCCEEDED(hr) && pidl)
        IMalloc_Free(pMalloc, pidl);
    ok(!pSHGetSpecialFolderPathA(NULL, path, CSIDL_FAVORITES, FALSE),
     "SHGetSpecialFolderPath succeeded, expected failure\n");
    pidl = NULL;
    hr = pSHGetSpecialFolderLocation(NULL, CSIDL_FAVORITES, &pidl);
    ok(hr == E_FAIL, "SHGetFolderLocation returned 0x%08lx, expected E_FAIL\n",
     hr);
    if (SUCCEEDED(hr) && pidl)
        IMalloc_Free(pMalloc, pidl);
    /* now test success: */
    hr = pSHGetFolderPathA(NULL, CSIDL_FAVORITES | CSIDL_FLAG_CREATE, NULL,
     SHGFP_TYPE_CURRENT, path);
    if (SUCCEEDED(hr))
    {
        BOOL ret;

        if (winetest_interactive)
            printf("CSIDL_FAVORITES was changed to %s\n", path);
        ret = CreateDirectoryA(path, NULL);
        ok(!ret,
         "CreateDirectoryA succeeded but should have failed "
         "with ERROR_ALREADY_EXISTS\n");
        if (!ret)
            ok(GetLastError() == ERROR_ALREADY_EXISTS,
             "CreateDirectoryA failed with %ld, "
             "expected ERROR_ALREADY_EXISTS\n",
             GetLastError());
    }
    ok(SUCCEEDED(hr),
     "SHGetFolderPath(NULL, CSIDL_FAVORITES | CSIDL_FLAG_CREATE, "
     "NULL, SHGFP_TYPE_CURRENT, path)\nfailed: 0x%08lx\n", hr);
}

/* Subprocess helper 2: make sure SHGetFolderPath still succeeds when the
 * original value of CSIDL_FAVORITES is restored.
 */
static void testNonExistentPath2(void)
{
    HRESULT hr;

    hr = pSHGetFolderPathA(NULL, CSIDL_FAVORITES | CSIDL_FLAG_CREATE, NULL,
     SHGFP_TYPE_CURRENT, NULL);
    ok(SUCCEEDED(hr), "SHGetFolderPath failed: 0x%08lx\n", hr);
}

static void doChild(const char *arg)
{
    if (arg[0] == '1')
        testNonExistentPath1();
    else if (arg[0] == '2')
        testNonExistentPath2();
}

/* Tests the return values from the various shell functions both with and
 * without the use of the CSIDL_FLAG_CREATE flag.  This flag only appeared in
 * version 5 of the shell, so don't test unless it's at least version 5.
 * The test reads a value from the registry, modifies it, calls
 * SHGetFolderPath once with the CSIDL_FLAG_CREATE flag, and immediately
 * afterward without it.  Then it restores the registry and deletes the folder
 * that was created.
 * One oddity with respect to restoration: shell32 caches somehow, so it needs
 * to be reloaded in order to see the correct (restored) value.
 * Some APIs unrelated to the ones under test may fail, but I expect they're
 * covered by other unit tests; I just print out something about failure to
 * help trace what's going on.
 */
static void testNonExistentPath(void)
{
    static const char userShellFolders[] = 
     "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders";
    char originalPath[MAX_PATH], modifiedPath[MAX_PATH];
    HKEY key;

    if (!pSHGetFolderPathA) return;
    if (!pSHGetFolderLocation) return;
    if (!pSHGetSpecialFolderPathA) return;
    if (!pSHGetSpecialFolderLocation) return;
    if (!pSHFileOperationA) return;
    if (shellVersion.dwMajorVersion < 5) return;

    if (!RegOpenKeyExA(HKEY_CURRENT_USER, userShellFolders, 0, KEY_ALL_ACCESS,
     &key))
    {
        DWORD len, type;

        len = sizeof(originalPath);
        if (!RegQueryValueExA(key, "Favorites", NULL, &type,
         (LPBYTE)&originalPath, &len))
        {
            size_t len = strlen(originalPath);

            memcpy(modifiedPath, originalPath, len);
            modifiedPath[len++] = '2';
            modifiedPath[len++] = '\0';
            if (winetest_interactive)
                printf("Changing CSIDL_FAVORITES to %s\n", modifiedPath);
            if (!RegSetValueExA(key, "Favorites", 0, type, (LPBYTE) modifiedPath, len))
            {
                char buffer[MAX_PATH];
                STARTUPINFOA startup;
                PROCESS_INFORMATION info;
                HRESULT hr;
                BOOL ret;

                wnsprintfA(buffer, sizeof(buffer), "%s tests/shellpath.c 1",
                 selfname);
                memset(&startup, 0, sizeof(startup));
                startup.cb = sizeof(startup);
                startup.dwFlags = STARTF_USESHOWWINDOW;
                startup.dwFlags = SW_SHOWNORMAL;
                CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL,
                 &startup, &info);
                ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0,
                 "child process termination\n");

                /* Query the path to be able to delete it below */
                hr = pSHGetFolderPathA(NULL, CSIDL_FAVORITES, NULL,
                 SHGFP_TYPE_CURRENT, modifiedPath);
                ok(SUCCEEDED(hr), "SHGetFolderPathA failed: 0x%08lx\n", hr);

                /* restore original values: */
                if (winetest_interactive)
                    printf("Restoring CSIDL_FAVORITES to %s\n", originalPath);
                RegSetValueExA(key, "Favorites", 0, type, (LPBYTE) originalPath,
                 strlen(originalPath) + 1);
                RegFlushKey(key);

                wnsprintfA(buffer, sizeof(buffer), "%s tests/shellpath.c 2",
                 selfname);
                memset(&startup, 0, sizeof(startup));
                startup.cb = sizeof(startup);
                startup.dwFlags = STARTF_USESHOWWINDOW;
                startup.dwFlags = SW_SHOWNORMAL;
                CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL,
                 &startup, &info);
                ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0,
                 "child process termination\n");

                ret = RemoveDirectoryA(modifiedPath);
                ok( ret, "RemoveDirectoryA failed: %ld\n", GetLastError());
            }
        }
        else if (winetest_interactive)
            printf("RegQueryValueExA(key, Favorites, ...) failed\n");
        if (key)
            RegCloseKey(key);
    }
    else if (winetest_interactive)
        printf("RegOpenKeyExA(HKEY_CURRENT_USER, %s, ...) failed\n",
         userShellFolders);
}

START_TEST(shellpath)
{
    if (!init()) return;

    loadShell32();
    if (!hShell32) return;

    if (myARGC >= 3)
        doChild(myARGV[2]);
    else
    {
        /* first test various combinations of parameters: */
        testApiParameters();

        /* check known values: */
        testPidlTypes();
        testGUIDs();
        testEnvVars();
        testWinDir();
        testSystemDir();
        testNonExistentPath();
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -