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

📄 filemoniker.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 3 页
字号:
    
            for(i=0;i<nb1;i++)
                CoTaskMemFree(stringTable1[i]);
    
            CoTaskMemFree(stringTable1);
    
            for(i=0;i<nb2;i++)
                CoTaskMemFree(stringTable2[i]);
    
            CoTaskMemFree(stringTable2);
    
            ret = CreateFileMoniker(commonPath,ppmkPrefix);
        }
        HeapFree(GetProcessHeap(),0,commonPath);
        return ret;
    }
    else
        return MonikerCommonPrefixWith(iface,pmkOther,ppmkPrefix);
}

/******************************************************************************
 *        DecomposePath (local function)
 */
int FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** stringTable)
{
    static const WCHAR bSlash[] = {'\\',0};
    WCHAR word[MAX_PATH];
    int i=0,j,tabIndex=0;
    LPOLESTR *strgtable ;

    int len=lstrlenW(str);

    TRACE("%s, %p\n", debugstr_w(str), *stringTable);

    strgtable =CoTaskMemAlloc(len*sizeof(LPOLESTR));

    if (strgtable==NULL)
	return E_OUTOFMEMORY;

    while(str[i]!=0){

        if(str[i]==bSlash[0]){

            strgtable[tabIndex]=CoTaskMemAlloc(2*sizeof(WCHAR));

            if (strgtable[tabIndex]==NULL)
	    	return E_OUTOFMEMORY;

            strcpyW(strgtable[tabIndex++],bSlash);

            i++;

        }
        else {

            for(j=0; str[i]!=0 && str[i]!=bSlash[0] ; i++,j++)
                word[j]=str[i];

            word[j]=0;

            strgtable[tabIndex]=CoTaskMemAlloc(sizeof(WCHAR)*(j+1));

            if (strgtable[tabIndex]==NULL)
                return E_OUTOFMEMORY;

            strcpyW(strgtable[tabIndex++],word);
        }
    }
    strgtable[tabIndex]=NULL;

    *stringTable=strgtable;

    return tabIndex;
}

/******************************************************************************
 *        FileMoniker_RelativePathTo
 */
static HRESULT WINAPI
FileMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath)
{
    IBindCtx *bind;
    HRESULT res;
    LPOLESTR str1=0,str2=0,*tabStr1=0,*tabStr2=0,relPath=0;
    DWORD len1=0,len2=0,sameIdx=0,j=0;
    static const WCHAR back[] ={'.','.','\\',0};

    TRACE("(%p,%p,%p)\n",iface,pmOther,ppmkRelPath);

    if (ppmkRelPath==NULL)
        return E_POINTER;

    if (pmOther==NULL)
        return E_INVALIDARG;

    res=CreateBindCtx(0,&bind);
    if (FAILED(res))
	return res;

    res=IMoniker_GetDisplayName(iface,bind,NULL,&str1);
    if (FAILED(res))
	return res;
    res=IMoniker_GetDisplayName(pmOther,bind,NULL,&str2);
    if (FAILED(res))
	return res;

    len1=FileMonikerImpl_DecomposePath(str1,&tabStr1);
    len2=FileMonikerImpl_DecomposePath(str2,&tabStr2);

    if (FAILED(len1) || FAILED(len2))
	return E_OUTOFMEMORY;

    /* count the number of similar items from the begin of the two paths */
    for(sameIdx=0; ( (tabStr1[sameIdx]!=NULL) &&
		   (tabStr2[sameIdx]!=NULL) &&
               (lstrcmpiW(tabStr1[sameIdx],tabStr2[sameIdx])==0)); sameIdx++);

    /* begin the construction of relativePath */
    /* if the two paths have a consecutive similar item from the begin ! the relativePath will be composed */
    /* by "..\\" in the begin */
    relPath=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(1+lstrlenW(str1)+lstrlenW(str2)));

    *relPath=0;

    if (len2>0 && !(len1==1 && len2==1 && sameIdx==0))
        for(j=sameIdx;(tabStr1[j] != NULL); j++)
            if (*tabStr1[j]!='\\')
                strcatW(relPath,back);

    /* add items of the second path (similar items with the first path are not included) to the relativePath */
    for(j=sameIdx;tabStr2[j]!=NULL;j++)
        strcatW(relPath,tabStr2[j]);

    res=CreateFileMoniker(relPath,ppmkRelPath);

    for(j=0; tabStr1[j]!=NULL;j++)
        CoTaskMemFree(tabStr1[j]);
    for(j=0; tabStr2[j]!=NULL;j++)
        CoTaskMemFree(tabStr2[j]);
    CoTaskMemFree(tabStr1);
    CoTaskMemFree(tabStr2);
    CoTaskMemFree(str1);
    CoTaskMemFree(str2);
    HeapFree(GetProcessHeap(),0,relPath);

    if (len1==0 || len2==0 || (len1==1 && len2==1 && sameIdx==0))
        return MK_S_HIM;

    return res;
}

/******************************************************************************
 *        FileMoniker_GetDisplayName
 */
static HRESULT WINAPI
FileMonikerImpl_GetDisplayName(IMoniker* iface, IBindCtx* pbc,
                               IMoniker* pmkToLeft, LPOLESTR *ppszDisplayName)
{
    FileMonikerImpl *This = (FileMonikerImpl *)iface;

    int len=lstrlenW(This->filePathName);

    TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,ppszDisplayName);

    if (ppszDisplayName==NULL)
        return E_POINTER;

    if (pmkToLeft!=NULL)
        return E_INVALIDARG;

    *ppszDisplayName=CoTaskMemAlloc(sizeof(WCHAR)*(len+1));
    if (*ppszDisplayName==NULL)
        return E_OUTOFMEMORY;

    strcpyW(*ppszDisplayName,This->filePathName);

    TRACE("-- %s\n", debugstr_w(*ppszDisplayName));
    
    return S_OK;
}

/******************************************************************************
 *        FileMoniker_ParseDisplayName
 */
static HRESULT WINAPI
FileMonikerImpl_ParseDisplayName(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
                     LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut)
{
    FIXME("(%p,%p,%p,%p,%p,%p),stub!\n",iface,pbc,pmkToLeft,pszDisplayName,pchEaten,ppmkOut);
    return E_NOTIMPL;
}

/******************************************************************************
 *        FileMoniker_IsSystemMoniker
 */
static HRESULT WINAPI
FileMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdMksys)
{
    TRACE("(%p,%p)\n",iface,pwdMksys);

    if (!pwdMksys)
        return E_POINTER;

    (*pwdMksys)=MKSYS_FILEMONIKER;

    return S_OK;
}

/*******************************************************************************
 *        FileMonikerIROTData_QueryInterface
 */
static HRESULT WINAPI
FileMonikerROTDataImpl_QueryInterface(IROTData *iface,REFIID riid,VOID** ppvObject)
{

    IMoniker *This = impl_from_IROTData(iface);

    TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppvObject);

    return FileMonikerImpl_QueryInterface(This, riid, ppvObject);
}

/***********************************************************************
 *        FileMonikerIROTData_AddRef
 */
static ULONG WINAPI
FileMonikerROTDataImpl_AddRef(IROTData *iface)
{
    IMoniker *This = impl_from_IROTData(iface);

    TRACE("(%p)\n",This);

    return IMoniker_AddRef(This);
}

/***********************************************************************
 *        FileMonikerIROTData_Release
 */
static ULONG WINAPI
FileMonikerROTDataImpl_Release(IROTData* iface)
{
    IMoniker *This = impl_from_IROTData(iface);

    TRACE("(%p)\n",This);

    return FileMonikerImpl_Release(This);
}

/******************************************************************************
 *        FileMonikerIROTData_GetComparaisonData
 */
static HRESULT WINAPI
FileMonikerROTDataImpl_GetComparisonData(IROTData* iface, BYTE* pbData,
                                          ULONG cbMax, ULONG* pcbData)
{
    IMoniker *This = impl_from_IROTData(iface);
    FileMonikerImpl *This1 = (FileMonikerImpl *)This;
    int len = (strlenW(This1->filePathName)+1);
    int i;
    LPWSTR pszFileName;

    TRACE("(%p, %lu, %p)\n", pbData, cbMax, pcbData);

    *pcbData = sizeof(CLSID) + len * sizeof(WCHAR);
    if (cbMax < *pcbData)
        return E_OUTOFMEMORY;

    memcpy(pbData, &CLSID_FileMoniker, sizeof(CLSID));
    pszFileName = (LPWSTR)(pbData+sizeof(CLSID));
    for (i = 0; i < len; i++)
        pszFileName[i] = toupperW(This1->filePathName[i]);

    return S_OK;
}

/*
 * Virtual function table for the FileMonikerImpl class which include IPersist,
 * IPersistStream and IMoniker functions.
 */
static const IMonikerVtbl VT_FileMonikerImpl =
{
    FileMonikerImpl_QueryInterface,
    FileMonikerImpl_AddRef,
    FileMonikerImpl_Release,
    FileMonikerImpl_GetClassID,
    FileMonikerImpl_IsDirty,
    FileMonikerImpl_Load,
    FileMonikerImpl_Save,
    FileMonikerImpl_GetSizeMax,
    FileMonikerImpl_BindToObject,
    FileMonikerImpl_BindToStorage,
    FileMonikerImpl_Reduce,
    FileMonikerImpl_ComposeWith,
    FileMonikerImpl_Enum,
    FileMonikerImpl_IsEqual,
    FileMonikerImpl_Hash,
    FileMonikerImpl_IsRunning,
    FileMonikerImpl_GetTimeOfLastChange,
    FileMonikerImpl_Inverse,
    FileMonikerImpl_CommonPrefixWith,
    FileMonikerImpl_RelativePathTo,
    FileMonikerImpl_GetDisplayName,
    FileMonikerImpl_ParseDisplayName,
    FileMonikerImpl_IsSystemMoniker
};

/* Virtual function table for the IROTData class. */
static const IROTDataVtbl VT_ROTDataImpl =
{
    FileMonikerROTDataImpl_QueryInterface,
    FileMonikerROTDataImpl_AddRef,
    FileMonikerROTDataImpl_Release,
    FileMonikerROTDataImpl_GetComparisonData
};

/******************************************************************************
 *         FileMoniker_Construct (local function)
 */
static HRESULT WINAPI
FileMonikerImpl_Construct(FileMonikerImpl* This, LPCOLESTR lpszPathName)
{
    int nb=0,i;
    int sizeStr=lstrlenW(lpszPathName);
    LPOLESTR *tabStr=0;
    static const WCHAR twoPoint[]={'.','.',0};
    static const WCHAR bkSlash[]={'\\',0};
    BYTE addBkSlash;

    TRACE("(%p,%s)\n",This,debugstr_w(lpszPathName));

    /* Initialize the virtual fgunction table. */
    This->lpvtbl1      = &VT_FileMonikerImpl;
    This->lpvtbl2      = &VT_ROTDataImpl;
    This->ref          = 0;
    This->pMarshal     = NULL;

    This->filePathName=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr+1));

    if (This->filePathName==NULL)
        return E_OUTOFMEMORY;

    strcpyW(This->filePathName,lpszPathName);

    nb=FileMonikerImpl_DecomposePath(This->filePathName,&tabStr);

    if (nb > 0 ){

        addBkSlash=1;
        if (lstrcmpW(tabStr[0],twoPoint)!=0)
            addBkSlash=0;
        else
            for(i=0;i<nb;i++){

                if ( (lstrcmpW(tabStr[i],twoPoint)!=0) && (lstrcmpW(tabStr[i],bkSlash)!=0) ){
                    addBkSlash=0;
                    break;
                }
                else

                    if (lstrcmpW(tabStr[i],bkSlash)==0 && i<nb-1 && lstrcmpW(tabStr[i+1],bkSlash)==0){
                        *tabStr[i]=0;
                        sizeStr--;
                        addBkSlash=0;
                        break;
                    }
            }

        if (lstrcmpW(tabStr[nb-1],bkSlash)==0)
            addBkSlash=0;

        This->filePathName=HeapReAlloc(GetProcessHeap(),0,This->filePathName,(sizeStr+1)*sizeof(WCHAR));

        *This->filePathName=0;

        for(i=0;tabStr[i]!=NULL;i++)
            strcatW(This->filePathName,tabStr[i]);

        if (addBkSlash)
            strcatW(This->filePathName,bkSlash);
    }

    for(i=0; tabStr[i]!=NULL;i++)
        CoTaskMemFree(tabStr[i]);
    CoTaskMemFree(tabStr);

    return S_OK;
}

/******************************************************************************
 *        CreateFileMoniker (OLE32.@)
 ******************************************************************************/
HRESULT WINAPI CreateFileMoniker(LPCOLESTR lpszPathName, LPMONIKER * ppmk)
{
    FileMonikerImpl* newFileMoniker;
    HRESULT  hr;

    TRACE("(%s,%p)\n",debugstr_w(lpszPathName),ppmk);

    if (!ppmk)
        return E_POINTER;

    if(!lpszPathName)
        return MK_E_SYNTAX;

    *ppmk=NULL;

    newFileMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(FileMonikerImpl));

    if (!newFileMoniker)
        return E_OUTOFMEMORY;

    hr = FileMonikerImpl_Construct(newFileMoniker,lpszPathName);

    if (SUCCEEDED(hr))
	hr = FileMonikerImpl_QueryInterface((IMoniker*)newFileMoniker,&IID_IMoniker,(void**)ppmk);
    else
        HeapFree(GetProcessHeap(),0,newFileMoniker);

    return hr;
}

static HRESULT WINAPI FileMonikerCF_QueryInterface(LPCLASSFACTORY iface,
                                                  REFIID riid, LPVOID *ppv)
{
    *ppv = NULL;
    if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory))
    {
        *ppv = iface;
        IUnknown_AddRef(iface);
        return S_OK;
    }
    return E_NOINTERFACE;
}

static ULONG WINAPI FileMonikerCF_AddRef(LPCLASSFACTORY iface)
{
    return 2; /* non-heap based object */
}

static ULONG WINAPI FileMonikerCF_Release(LPCLASSFACTORY iface)
{
    return 1; /* non-heap based object */
}

static HRESULT WINAPI FileMonikerCF_CreateInstance(LPCLASSFACTORY iface,
    LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv)
{
    FileMonikerImpl* newFileMoniker;
    HRESULT  hr;
    static const WCHAR wszEmpty[] = { 0 };

    TRACE("(%p, %s, %p)\n", pUnk, debugstr_guid(riid), ppv);

    *ppv = NULL;

    if (pUnk)
        return CLASS_E_NOAGGREGATION;

    newFileMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(FileMonikerImpl));
    if (!newFileMoniker)
        return E_OUTOFMEMORY;

    hr = FileMonikerImpl_Construct(newFileMoniker, wszEmpty);

    if (SUCCEEDED(hr))
	hr = FileMonikerImpl_QueryInterface((IMoniker*)newFileMoniker, riid, ppv);
    if (FAILED(hr))
        HeapFree(GetProcessHeap(),0,newFileMoniker);

    return hr;
}

static HRESULT WINAPI FileMonikerCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
{
    FIXME("(%d), stub!\n",fLock);
    return S_OK;
}

static const IClassFactoryVtbl FileMonikerCFVtbl =
{
    FileMonikerCF_QueryInterface,
    FileMonikerCF_AddRef,
    FileMonikerCF_Release,
    FileMonikerCF_CreateInstance,
    FileMonikerCF_LockServer
};
static const IClassFactoryVtbl *FileMonikerCF = &FileMonikerCFVtbl;

HRESULT FileMonikerCF_Create(REFIID riid, LPVOID *ppv)
{
    return IClassFactory_QueryInterface((IClassFactory *)&FileMonikerCF, riid, ppv);
}

⌨️ 快捷键说明

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