示例#1
0
// this is workaround function for the Shell API Function SHBindToParent
// SHBindToParent is not available under Win95/98
HRESULT CShellContextMenu::SHBindToParentEx (LPCITEMIDLIST pidl, REFIID riid, VOID **ppv, LPCITEMIDLIST *ppidlLast)
{
	HRESULT hr = 0;
	if (!pidl || !ppv)
		return E_POINTER;
	
	int nCount = GetPIDLCount (pidl);
	if (nCount == 0)	// desktop pidl of invalid pidl
		return E_POINTER;

	IShellFolder * psfDesktop = NULL;
	SHGetDesktopFolder (&psfDesktop);
	if (nCount == 1)	// desktop pidl
	{
		if ((hr = psfDesktop->QueryInterface(riid, ppv)) == S_OK)
		{
			if (ppidlLast) 
				*ppidlLast = CopyPIDL (pidl);
		}
		psfDesktop->Release ();
		return hr;
	}

	LPBYTE pRel = GetPIDLPos (pidl, nCount - 1);
	LPITEMIDLIST pidlParent = NULL;
	pidlParent = CopyPIDL (pidl, pRel - (LPBYTE) pidl);
	IShellFolder * psfFolder = NULL;
	
	if ((hr = psfDesktop->BindToObject (pidlParent, NULL, __uuidof (psfFolder), (void **) &psfFolder)) != S_OK)
	{
		free (pidlParent);
		psfDesktop->Release ();
		return hr;
	}
	if ((hr = psfFolder->QueryInterface (riid, ppv)) == S_OK)
	{
		if (ppidlLast)
			*ppidlLast = CopyPIDL ((LPCITEMIDLIST) pRel);
	}
	free (pidlParent);
	psfFolder->Release ();
	psfDesktop->Release ();
	return hr;
}
示例#2
0
/*
 * Class:     sun_awt_shell_Win32ShellFolder2
 * Method:    doGetColumnValue
 * Signature: (JJI)Ljava/lang/Object;
 */
JNIEXPORT jobject JNICALL
    Java_sun_awt_shell_Win32ShellFolder2_doGetColumnValue
            (JNIEnv *env, jobject obj, jlong iShellFolder,
            jlong jpidl, jint columnIdx)
{

    HRESULT hr;
    IShellFolder *pIShellFolder = (IShellFolder*) iShellFolder;
    IUnknown *pIUnknown = NULL;


    LPITEMIDLIST pidl = (LPITEMIDLIST) jpidl;
    SHELLDETAILS sd;

    hr = pIShellFolder->QueryInterface(IID_IShellFolder2, (void**)&pIUnknown);
    if(SUCCEEDED (hr)) {
        // The folder exposes IShellFolder2 interface
        IShellFolder2 *pIShellFolder2 = (IShellFolder2*) pIUnknown;
        hr = pIShellFolder2->GetDetailsOf(pidl, (UINT)columnIdx, &sd);
        pIShellFolder2->Release();
        if (SUCCEEDED (hr)) {
            STRRET strRet = sd.str;
            return jstringFromSTRRET(env, pidl, &strRet);
        }
    }

    hr = pIShellFolder->CreateViewObject(NULL, IID_IShellDetails, (void**)&pIUnknown);
    if(SUCCEEDED (hr)) {
        // The folder exposes IShellDetails interface
        IShellDetails *pIShellDetails = (IShellDetails*) pIUnknown;
        hr = pIShellDetails->GetDetailsOf(pidl, (UINT)columnIdx, &sd);
        pIShellDetails->Release();
        if (SUCCEEDED (hr)) {
            STRRET strRet = sd.str;
            return jstringFromSTRRET(env, pidl, &strRet);
        }
    }

    // The folder exposes neither IShellFolder2 nor IShelDetails
    return NULL;
}
示例#3
0
/*
 * Class:     sun_awt_shell_Win32ShellFolder2
 * Method:    doGetColumnInfo
 * Signature: (J)[Lsun/awt/shell/ShellFolderColumnInfo;
 */
JNIEXPORT jobjectArray JNICALL
    Java_sun_awt_shell_Win32ShellFolder2_doGetColumnInfo
            (JNIEnv *env, jobject obj, jlong iShellFolder)
{

    HRESULT hr;
    IShellFolder *pIShellFolder = (IShellFolder*) iShellFolder;
    IUnknown *pIUnknown = NULL;

    jclass columnClass = env->FindClass("sun/awt/shell/ShellFolderColumnInfo");
    if(NULL == columnClass) {
        return NULL;
    }

    jmethodID columnConstructor =
        env->GetMethodID(columnClass, "<init>", "(Ljava/lang/String;IIZ)V");
    if(NULL == columnConstructor) {
        return NULL;
    }

    // We'are asking the object the list of available columns
    SHELLDETAILS sd;

    hr = pIShellFolder->QueryInterface(IID_IShellFolder2, (void**)&pIUnknown);
    if(SUCCEEDED (hr)) {

        // The folder exposes IShellFolder2 interface
        IShellFolder2 *pIShellFolder2 = (IShellFolder2*) pIUnknown;

        // Count columns
        int colNum = -1;
        hr = S_OK;
        do{
            hr = pIShellFolder2->GetDetailsOf(NULL, ++colNum, &sd);
        } while (SUCCEEDED (hr));

        jobjectArray columns =
            env->NewObjectArray((jsize) colNum, columnClass, NULL);
        if(NULL == columns) {
            pIShellFolder2->Release();
            return NULL;
        }

        // Fill column details list
        SHCOLSTATEF csFlags;
        colNum = 0;
        hr = S_OK;
        while (SUCCEEDED (hr)) {
            hr = pIShellFolder2->GetDetailsOf(NULL, colNum, &sd);

            if (SUCCEEDED (hr)) {
                hr = pIShellFolder2->GetDefaultColumnState(colNum, &csFlags);
                if (SUCCEEDED (hr)) {
                    if(!(csFlags & SHCOLSTATE_HIDDEN)) {
                        jobject column = CreateColumnInfo(env,
                                            &columnClass, &columnConstructor,
                                            &sd, csFlags & SHCOLSTATE_ONBYDEFAULT);
                        if(!column){
                            pIShellFolder2->Release();
                            return NULL;
                        }
                        env->SetObjectArrayElement(columns, (jsize) colNum, column);
                    }
                }
                colNum++;
            }
        }

        pIShellFolder2->Release();

        return columns;
    }

    hr = pIShellFolder->CreateViewObject(NULL, IID_IShellDetails, (void**)&pIUnknown);
    if(SUCCEEDED (hr)) {
        // The folder exposes IShellDetails interface
        IShellDetails *pIShellDetails = (IShellDetails*) pIUnknown;

        // Count columns
        int colNum = -1;
        hr = S_OK;
        do{
            hr = pIShellDetails->GetDetailsOf(NULL, ++colNum, &sd);
        } while (SUCCEEDED (hr));

        jobjectArray columns =
            env->NewObjectArray((jsize) colNum, columnClass, NULL);
        if(NULL == columns) {
            pIShellDetails->Release();
            return NULL;
        }

        // Fill column details list
        colNum = 0;
        hr = S_OK;
        while (SUCCEEDED (hr)) {
            hr = pIShellDetails->GetDetailsOf(NULL, colNum, &sd);
            if (SUCCEEDED (hr)) {
                jobject column = CreateColumnInfo(env,
                                    &columnClass, &columnConstructor,
                                    &sd, 1);
                if(!column){
                    pIShellDetails->Release();
                    return NULL;
                }
                env->SetObjectArrayElement(columns, (jsize) colNum++, column);
            }
        }

        pIShellDetails->Release();

        return columns;
    }

    // The folder exposes neither IShellFolder2 nor IShelDetails
    return NULL;

}
示例#4
0
static BOOL GetPidlAndShellFolder (char* pszPath, IShellFolder** ppsfOut, LPITEMIDLIST* ppidlOut)
{
	IShellFolder * pd = NULL;
	IMalloc* shMalloc = NULL;
	LPITEMIDLIST pidlFull = NULL;
	ULONG cch;
	ULONG attrs;
	BOOL success = FALSE;

	if (!SUCCEEDED (SHGetDesktopFolder (&pd)))
		goto BailOut;

	if (!SUCCEEDED (SHGetMalloc (&shMalloc)))
		goto BailOut;

	WCHAR wpath[MAX_PATH];
	mbstowcs (wpath, pszPath, 1+lstrlen(pszPath));

	//get fully-qualified pidl
	if (!SUCCEEDED (pd->ParseDisplayName (NULL, NULL, wpath, &cch, &pidlFull, &attrs)))
		goto BailOut;
	
	IShellFolder *psfCurr, *psfNext;
	if (!SUCCEEDED (pd->QueryInterface (IID_IShellFolder, (LPVOID*)&psfCurr)))
		goto BailOut;

	//for each pidl component, bind to folder
	LPITEMIDLIST pidlNext, pidlLast;
	pidlNext = PidlNext (pidlFull);
	pidlLast = pidlFull;
	
	while (pidlNext->mkid.cb != 0)
	{
		
		UINT uSave = pidlNext->mkid.cb;		//stop the chain temporarily
		pidlNext->mkid.cb = 0;				//so we can bind to the next folder 1 deeper
		if (!SUCCEEDED (psfCurr->BindToObject(pidlLast, NULL, IID_IShellFolder, (LPVOID*)&psfNext)))
			goto BailOut;
		pidlNext->mkid.cb = uSave;			//restore the chain

		psfCurr->Release();					//and set up to work with the next-level folder
		psfCurr = psfNext;
		pidlLast = pidlNext;

		pidlNext = PidlNext (pidlNext);		//advance to next pidl
	}

	success = TRUE;

	*ppidlOut = CopyPidl (pidlLast, shMalloc);
	*ppsfOut = psfCurr;

BailOut:
	//cleanup
	if (pidlFull != NULL && shMalloc != NULL)
		shMalloc->Free (pidlFull);		//other pidl's were only offsets into this, and don't need freeing
	if (pd != NULL)
		pd->Release();
	if (shMalloc != NULL)
		shMalloc->Release();

	return success;
}
示例#5
0
文件: Nav.cpp 项目: cdfmr/deebook
STDAPI _IEBindToObjectInternal(BOOL fStrictBind, LPCITEMIDLIST pidl, IBindCtx * pbc, REFIID riid, void **ppvOut)
{
    IShellFolder *psfTemp;
    HRESULT hr;

    *ppvOut = NULL;

        BOOL fIsUrlChild = IsURLChild(pidl, TRUE);

        if (fIsUrlChild || ILIsRooted(pidl))
        {
            hr = _GetRoot(pidl, fIsUrlChild, &psfTemp);
            if (SUCCEEDED(hr))
            {
                pidl = _ILNext(pidl);
                
                if (!ILIsEmpty(pidl))
                    hr = psfTemp->BindToObject(pidl, pbc, riid, ppvOut);
                else
                    hr = psfTemp->QueryInterface(riid, ppvOut);

                psfTemp->Release();
            }
        }
        else
        {
            // non integrated browser mode will succeed on 
            // BindToObject(IID_IShellFolder) even for things that should 
            // fail (files). to avoid the down stream problems caused by this we
            // filter out things that are not "browseable" up front, 
            //
            // NOTE: this does not work on simple PIDLs

            DWORD dwAttribs = SFGAO_FOLDER | SFGAO_BROWSABLE | SFGAO_FILESYSTEM;

            hr = _IEGetAttributesOf(pidl, &dwAttribs, fStrictBind);
            
            if (SUCCEEDED(hr)) 
            {
                switch (_ShouldDocObjBind(dwAttribs, fStrictBind))
                {
                case SHOULDBIND_DOCOBJ:
                    {
                        //
                        // shortcircuit and bind using our CDocObjectFolder for
                        // files which are BROWSABLE. Without this code, file:
                        // to non-Docobject files (such as multi-media files)
                        // won't do anything.
                        //
                        // is is needed for non integraded browser mode 
                        //
                        CDocObjectFolder *pdof = new CDocObjectFolder();

                        TraceMsg(TF_URLNAMESPACE, "IEBTO(%x) using DocObjectFolder", pidl);
                        if (pdof)
                        {
                            hr = pdof->Initialize(pidl);
                            if (SUCCEEDED(hr)) 
                                hr = pdof->QueryInterface(riid, ppvOut);
                            pdof->Release();
                        }
                        else
                            hr = E_OUTOFMEMORY;    
                    }
                    break;

                case SHOULDBIND_DESKTOP:
                    {
                        //
                        // This is the normal case. We just bind down through the desktop...
                        //
                        TraceMsg(TF_URLNAMESPACE, "IEBTO(%x) using Desktop", pidl);

                        hr = SHGetDesktopFolder(&psfTemp);
                        if (SUCCEEDED(hr))
                        {
                            // BRYANST: 7/22/97  -  NT Bug #188099
                            // shell32.dll in IE4 SI and only in that version had a bug if pbc was passed
                            // to IShellFolder::BindToObject() (fstreex.c!FSBindToFSFolder), it would fail
                            // to bind to Shell Extensions that extended file system folders, such as:
                            // the history folder, the occache, etc.  We work around this by passing a NULL pbc
                            // if the destination is an IE4 shell32.dll and it will go thru FSBindToFSFolder().
                            if (pbc && ShouldWorkAroundBCBug(pidl))
                            {
                                pbc = NULL;
                            }

                            hr = psfTemp->BindToObject(pidl, pbc, riid, ppvOut);
                            psfTemp->Release();
                        }
                    } 
                    break;

                default:
                    hr = E_FAIL;
                }
            } 
        }
}