예제 #1
0
파일: shlfolder.c 프로젝트: DeltaYang/wine
/***********************************************************************
 *	SHELL32_CoCreateInitSF
 *
 * Creates a shell folder and initializes it with a pidl and a root folder
 * via IPersistFolder3 or IPersistFolder.
 *
 * NOTES
 *   pathRoot can be NULL for Folders being a drive.
 *   In this case the absolute path is built from pidlChild (eg. C:)
 */
static HRESULT SHELL32_CoCreateInitSF (LPCITEMIDLIST pidlRoot, LPCWSTR pathRoot,
                LPCITEMIDLIST pidlChild, REFCLSID clsid, LPVOID * ppvOut)
{
    HRESULT hr;

    TRACE ("(%p %s %p %s %p)\n", pidlRoot, debugstr_w(pathRoot), pidlChild, debugstr_guid(clsid), ppvOut);

    hr = SHCoCreateInstance(NULL, clsid, NULL, &IID_IShellFolder, ppvOut);
    if (SUCCEEDED (hr))
    {
	LPITEMIDLIST pidlAbsolute = ILCombine (pidlRoot, pidlChild);
	IPersistFolder *pPF;
	IPersistFolder3 *ppf;

        if (_ILIsFolder(pidlChild) &&
            SUCCEEDED (IUnknown_QueryInterface ((IUnknown *) * ppvOut, &IID_IPersistFolder3, (LPVOID *) & ppf))) 
        {
	    PERSIST_FOLDER_TARGET_INFO ppfti;

	    ZeroMemory (&ppfti, sizeof (ppfti));

	    /* fill the PERSIST_FOLDER_TARGET_INFO */
	    ppfti.dwAttributes = -1;
	    ppfti.csidl = -1;

	    /* build path */
	    if (pathRoot) {
		lstrcpynW (ppfti.szTargetParsingName, pathRoot, MAX_PATH - 1);
		PathAddBackslashW(ppfti.szTargetParsingName); /* FIXME: why have drives a backslash here ? */
	    }

	    if (pidlChild) {
                int len = lstrlenW(ppfti.szTargetParsingName);

		if (!_ILSimpleGetTextW(pidlChild, ppfti.szTargetParsingName + len, MAX_PATH - len))
			hr = E_INVALIDARG;
	    }

	    IPersistFolder3_InitializeEx (ppf, NULL, pidlAbsolute, &ppfti);
	    IPersistFolder3_Release (ppf);
	}
	else if (SUCCEEDED ((hr = IUnknown_QueryInterface ((IUnknown *) * ppvOut, &IID_IPersistFolder, (LPVOID *) & pPF)))) {
	    IPersistFolder_Initialize (pPF, pidlAbsolute);
	    IPersistFolder_Release (pPF);
	}
	ILFree (pidlAbsolute);
    }
    TRACE ("-- (%p) ret=0x%08x\n", *ppvOut, hr);
    return hr;
}
예제 #2
0
static void test_ShortcutFolder(void) {
    LPSHELLFOLDER pDesktopFolder, pWineTestFolder;
    IPersistFolder3 *pWineTestPersistFolder;
    LPITEMIDLIST pidlWineTestFolder, pidlCurFolder;
    HRESULT hr;
    CLSID clsid;
    const CLSID CLSID_WineTest = 
        { 0x9b352ebf, 0x2765, 0x45c1, { 0xb4, 0xc6, 0x85, 0xcc, 0x7f, 0x7a, 0xbc, 0x64 } };
    WCHAR wszWineTestFolder[] = {
        ':',':','{','9','B','3','5','2','E','B','F','-','2','7','6','5','-','4','5','C','1','-',
        'B','4','C','6','-','8','5','C','C','7','F','7','A','B','C','6','4','}',0 };

    /* First, we register all the necessary registry keys/values for our 'WineTest'
     * shell object. */
    register_keys(HKEY_CLASSES_ROOT, HKEY_CLASSES_ROOT_keys, 1);

    hr = SHGetDesktopFolder(&pDesktopFolder);
    ok (SUCCEEDED(hr), "SHGetDesktopFolder failed! hr = %08x\n", hr);
    if (FAILED(hr)) goto cleanup;

    /* Convert the wszWineTestFolder string to an ITEMIDLIST. */
    hr = IShellFolder_ParseDisplayName(pDesktopFolder, NULL, NULL, wszWineTestFolder, NULL, 
                                       &pidlWineTestFolder, NULL);
    todo_wine
    {
        ok (hr == HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER),
            "Expected %08x, got %08x\n", HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER), hr);
    }
    if (FAILED(hr)) {
        IShellFolder_Release(pDesktopFolder);
        goto cleanup;
    }

    /* FIXME: these tests are never run */

    /* Bind to a WineTest folder object. There has to be some support for this in shdocvw.dll.
     * This isn't implemented in wine yet.*/
    hr = IShellFolder_BindToObject(pDesktopFolder, pidlWineTestFolder, NULL, &IID_IShellFolder, 
                                   (LPVOID*)&pWineTestFolder);
    IShellFolder_Release(pDesktopFolder);
    ILFree(pidlWineTestFolder);
    ok (SUCCEEDED(hr), "IShellFolder::BindToObject(WineTestFolder) failed! hr = %08x\n", hr);
    if (FAILED(hr)) goto cleanup;

    hr = IShellFolder_QueryInterface(pWineTestFolder, &IID_IPersistFolder3, (LPVOID*)&pWineTestPersistFolder);
    ok (SUCCEEDED(hr), "IShellFolder::QueryInterface(IPersistFolder3) failed! hr = %08x\n", hr);
    IShellFolder_Release(pWineTestFolder);
    if (FAILED(hr)) goto cleanup;

    /* The resulting folder object has the FolderShortcut CLSID, instead of it's own. */
    hr = IPersistFolder3_GetClassID(pWineTestPersistFolder, &clsid);
    ok (SUCCEEDED(hr), "IPersist::GetClassID failed! hr = %08x\n", hr);
    ok (IsEqualCLSID(&CLSID_FolderShortcut, &clsid), "GetClassId returned wrong CLSID!\n"); 
  
    pidlCurFolder = (LPITEMIDLIST)0xdeadbeef;
    hr = IPersistFolder3_GetCurFolder(pWineTestPersistFolder, &pidlCurFolder);
    ok (SUCCEEDED(hr), "IPersistFolder3::GetCurFolder failed! hr = %08x\n", hr);
    ok (pidlCurFolder->mkid.cb == 20 && ((LPSHITEMID)((BYTE*)pidlCurFolder+20))->cb == 0 && 
        IsEqualCLSID(&CLSID_WineTest, (REFCLSID)((LPBYTE)pidlCurFolder+4)), 
        "GetCurFolder returned unexpected pidl!\n");

    ILFree(pidlCurFolder);
    IPersistFolder3_Release(pWineTestPersistFolder);

cleanup:
    unregister_keys(HKEY_CLASSES_ROOT, HKEY_CLASSES_ROOT_keys, 1);
}