📄 filemoniker.c
字号:
res=IBindCtx_GetRunningObjectTable(pbc,&prot);
if (SUCCEEDED(res)){
/* if the requested class was loaded before ! we don't need to reload it */
res = IRunningObjectTable_GetObject(prot,iface,&pObj);
if (res==S_FALSE){
/* first activation of this class */
res=GetClassFile(This->filePathName,&clsID);
if (SUCCEEDED(res)){
res=CoCreateInstance(&clsID,NULL,CLSCTX_ALL,&IID_IPersistFile,(void**)&ppf);
if (SUCCEEDED(res)){
res=IPersistFile_Load(ppf,This->filePathName,STGM_READ);
if (SUCCEEDED(res)){
pObj=(IUnknown*)ppf;
IUnknown_AddRef(pObj);
}
}
}
}
}
}
else{
res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IClassFactory,(void**)&pcf);
if (res==E_NOINTERFACE){
res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IClassActivator,(void**)&pca);
if (res==E_NOINTERFACE)
return MK_E_INTERMEDIATEINTERFACENOTSUPPORTED;
}
if (pcf!=NULL){
IClassFactory_CreateInstance(pcf,NULL,&IID_IPersistFile,(void**)ppf);
res=IPersistFile_Load(ppf,This->filePathName,STGM_READ);
if (SUCCEEDED(res)){
pObj=(IUnknown*)ppf;
IUnknown_AddRef(pObj);
}
}
if (pca!=NULL){
FIXME("()\n");
/*res=GetClassFile(This->filePathName,&clsID);
if (SUCCEEDED(res)){
res=IClassActivator_GetClassObject(pca,&clsID,CLSCTX_ALL,0,&IID_IPersistFile,(void**)&ppf);
if (SUCCEEDED(res)){
pObj=(IUnknown*)ppf;
IUnknown_AddRef(pObj);
}
}*/
}
}
if (pObj!=NULL){
/* get the requested interface from the loaded class */
res= IUnknown_QueryInterface(pObj,riid,ppvResult);
IBindCtx_RegisterObjectBound(pbc,(IUnknown*)*ppvResult);
IUnknown_Release(pObj);
}
if (prot!=NULL)
IRunningObjectTable_Release(prot);
if (ppf!=NULL)
IPersistFile_Release(ppf);
if (pca!=NULL)
IClassActivator_Release(pca);
if (pcf!=NULL)
IClassFactory_Release(pcf);
return res;
}
/******************************************************************************
* FileMoniker_BindToStorage
*/
static HRESULT WINAPI
FileMonikerImpl_BindToStorage(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
REFIID riid, VOID** ppvObject)
{
LPOLESTR filePath=0;
IStorage *pstg=0;
HRESULT res;
TRACE("(%p,%p,%p,%s,%p)\n",iface,pbc,pmkToLeft,debugstr_guid(riid),ppvObject);
if (pmkToLeft==NULL){
if (IsEqualIID(&IID_IStorage, riid)){
/* get the file name */
IMoniker_GetDisplayName(iface,pbc,pmkToLeft,&filePath);
/* verifie if the file contains a storage object */
res=StgIsStorageFile(filePath);
if(res==S_OK){
res=StgOpenStorage(filePath,NULL,STGM_READWRITE|STGM_SHARE_DENY_WRITE,NULL,0,&pstg);
if (SUCCEEDED(res)){
*ppvObject=pstg;
IStorage_AddRef(pstg);
return res;
}
}
CoTaskMemFree(filePath);
}
else
if ( (IsEqualIID(&IID_IStream, riid)) || (IsEqualIID(&IID_ILockBytes, riid)) )
return E_FAIL;
else
return E_NOINTERFACE;
}
else {
FIXME("(%p,%p,%p,%s,%p)\n",iface,pbc,pmkToLeft,debugstr_guid(riid),ppvObject);
return E_NOTIMPL;
}
return res;
}
/******************************************************************************
* FileMoniker_Reduce
******************************************************************************/
static HRESULT WINAPI
FileMonikerImpl_Reduce(IMoniker* iface, IBindCtx* pbc, DWORD dwReduceHowFar,
IMoniker** ppmkToLeft, IMoniker** ppmkReduced)
{
TRACE("(%p,%p,%ld,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
if (ppmkReduced==NULL)
return E_POINTER;
IMoniker_AddRef(iface);
*ppmkReduced=iface;
return MK_S_REDUCED_TO_SELF;
}
/******************************************************************************
* FileMoniker_ComposeWith
*/
static HRESULT WINAPI
FileMonikerImpl_ComposeWith(IMoniker* iface, IMoniker* pmkRight,
BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite)
{
HRESULT res;
LPOLESTR str1=0,str2=0,*strDec1=0,*strDec2=0,newStr=0;
static const WCHAR twoPoint[]={'.','.',0};
static const WCHAR bkSlash[]={'\\',0};
IBindCtx *bind=0;
int i=0,j=0,lastIdx1=0,lastIdx2=0;
DWORD mkSys;
TRACE("(%p,%p,%d,%p)\n",iface,pmkRight,fOnlyIfNotGeneric,ppmkComposite);
if (ppmkComposite==NULL)
return E_POINTER;
if (pmkRight==NULL)
return E_INVALIDARG;
*ppmkComposite=0;
IMoniker_IsSystemMoniker(pmkRight,&mkSys);
/* check if we have two filemonikers to compose or not */
if(mkSys==MKSYS_FILEMONIKER){
CreateBindCtx(0,&bind);
IMoniker_GetDisplayName(iface,bind,NULL,&str1);
IMoniker_GetDisplayName(pmkRight,bind,NULL,&str2);
/* decompose pathnames of the two monikers : (to prepare the path merge operation ) */
lastIdx1=FileMonikerImpl_DecomposePath(str1,&strDec1)-1;
lastIdx2=FileMonikerImpl_DecomposePath(str2,&strDec2)-1;
if ((lastIdx1==-1 && lastIdx2>-1)||(lastIdx1==1 && lstrcmpW(strDec1[0],twoPoint)==0))
return MK_E_SYNTAX;
if(lstrcmpW(strDec1[lastIdx1],bkSlash)==0)
lastIdx1--;
/* for etch "..\" in the left of str2 remove the right element from str1 */
for(i=0; ( (lastIdx1>=0) && (strDec2[i]!=NULL) && (lstrcmpW(strDec2[i],twoPoint)==0) ) ;i+=2){
lastIdx1-=2;
}
/* the length of the composed path string is raised by the sum of the two paths lengths */
newStr=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(lstrlenW(str1)+lstrlenW(str2)+1));
if (newStr==NULL)
return E_OUTOFMEMORY;
/* new path is the concatenation of the rest of str1 and str2 */
for(*newStr=0,j=0;j<=lastIdx1;j++)
strcatW(newStr,strDec1[j]);
if ((strDec2[i]==NULL && lastIdx1>-1 && lastIdx2>-1) || lstrcmpW(strDec2[i],bkSlash)!=0)
strcatW(newStr,bkSlash);
for(j=i;j<=lastIdx2;j++)
strcatW(newStr,strDec2[j]);
/* create a new moniker with the new string */
res=CreateFileMoniker(newStr,ppmkComposite);
/* free all strings space memory used by this function */
HeapFree(GetProcessHeap(),0,newStr);
for(i=0; strDec1[i]!=NULL;i++)
CoTaskMemFree(strDec1[i]);
for(i=0; strDec2[i]!=NULL;i++)
CoTaskMemFree(strDec2[i]);
CoTaskMemFree(strDec1);
CoTaskMemFree(strDec2);
CoTaskMemFree(str1);
CoTaskMemFree(str2);
return res;
}
else if(mkSys==MKSYS_ANTIMONIKER){
*ppmkComposite=NULL;
return S_OK;
}
else if (fOnlyIfNotGeneric){
*ppmkComposite=NULL;
return MK_E_NEEDGENERIC;
}
else
return CreateGenericComposite(iface,pmkRight,ppmkComposite);
}
/******************************************************************************
* FileMoniker_Enum
*/
static HRESULT WINAPI
FileMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker)
{
TRACE("(%p,%d,%p)\n",iface,fForward,ppenumMoniker);
if (ppenumMoniker == NULL)
return E_POINTER;
*ppenumMoniker = NULL;
return S_OK;
}
/******************************************************************************
* FileMoniker_IsEqual
*/
static HRESULT WINAPI
FileMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
{
FileMonikerImpl *This = (FileMonikerImpl *)iface;
CLSID clsid;
LPOLESTR filePath;
IBindCtx* bind;
HRESULT res;
TRACE("(%p,%p)\n",iface,pmkOtherMoniker);
if (pmkOtherMoniker==NULL)
return S_FALSE;
IMoniker_GetClassID(pmkOtherMoniker,&clsid);
if (!IsEqualCLSID(&clsid,&CLSID_FileMoniker))
return S_FALSE;
res = CreateBindCtx(0,&bind);
if (FAILED(res)) return res;
if (SUCCEEDED(IMoniker_GetDisplayName(pmkOtherMoniker,bind,NULL,&filePath))) {
int result = lstrcmpiW(filePath, This->filePathName);
CoTaskMemFree(filePath);
if ( result == 0 ) return S_OK;
}
return S_FALSE;
}
/******************************************************************************
* FileMoniker_Hash
*/
static HRESULT WINAPI
FileMonikerImpl_Hash(IMoniker* iface,DWORD* pdwHash)
{
FileMonikerImpl *This = (FileMonikerImpl *)iface;
int h = 0,i,skip,len;
int off = 0;
LPOLESTR val;
if (pdwHash==NULL)
return E_POINTER;
val = This->filePathName;
len = lstrlenW(val);
if (len < 16) {
for (i = len ; i > 0; i--) {
h = (h * 37) + val[off++];
}
} else {
/* only sample some characters */
skip = len / 8;
for (i = len ; i > 0; i -= skip, off += skip) {
h = (h * 39) + val[off];
}
}
*pdwHash=h;
return S_OK;
}
/******************************************************************************
* FileMoniker_IsRunning
*/
static HRESULT WINAPI
FileMonikerImpl_IsRunning(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
IMoniker* pmkNewlyRunning)
{
IRunningObjectTable* rot;
HRESULT res;
TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pmkNewlyRunning);
if ( (pmkNewlyRunning!=NULL) && (IMoniker_IsEqual(pmkNewlyRunning,iface)==S_OK) )
return S_OK;
if (pbc==NULL)
return E_POINTER;
res=IBindCtx_GetRunningObjectTable(pbc,&rot);
if (FAILED(res))
return res;
res = IRunningObjectTable_IsRunning(rot,iface);
IRunningObjectTable_Release(rot);
return res;
}
/******************************************************************************
* FileMoniker_GetTimeOfLastChange
******************************************************************************/
static HRESULT WINAPI
FileMonikerImpl_GetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc,
IMoniker* pmkToLeft, FILETIME* pFileTime)
{
FileMonikerImpl *This = (FileMonikerImpl *)iface;
IRunningObjectTable* rot;
HRESULT res;
WIN32_FILE_ATTRIBUTE_DATA info;
TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pFileTime);
if (pFileTime==NULL)
return E_POINTER;
if (pmkToLeft!=NULL)
return E_INVALIDARG;
res=IBindCtx_GetRunningObjectTable(pbc,&rot);
if (FAILED(res))
return res;
res= IRunningObjectTable_GetTimeOfLastChange(rot,iface,pFileTime);
if (FAILED(res)){ /* the moniker is not registered */
if (!GetFileAttributesExW(This->filePathName,GetFileExInfoStandard,&info))
return MK_E_NOOBJECT;
*pFileTime=info.ftLastWriteTime;
}
return S_OK;
}
/******************************************************************************
* FileMoniker_Inverse
*/
static HRESULT WINAPI
FileMonikerImpl_Inverse(IMoniker* iface,IMoniker** ppmk)
{
TRACE("(%p,%p)\n",iface,ppmk);
return CreateAntiMoniker(ppmk);
}
/******************************************************************************
* FileMoniker_CommonPrefixWith
*/
static HRESULT WINAPI
FileMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix)
{
LPOLESTR pathThis,pathOther,*stringTable1,*stringTable2,commonPath;
IBindCtx *pbind;
DWORD mkSys;
ULONG nb1,nb2,i,sameIdx;
BOOL machimeNameCase=FALSE;
if (ppmkPrefix==NULL)
return E_POINTER;
if (pmkOther==NULL)
return E_INVALIDARG;
*ppmkPrefix=0;
/* check if we have the same type of moniker */
IMoniker_IsSystemMoniker(pmkOther,&mkSys);
if(mkSys==MKSYS_FILEMONIKER){
HRESULT ret;
CreateBindCtx(0,&pbind);
/* create a string based on common part of the two paths */
IMoniker_GetDisplayName(iface,pbind,NULL,&pathThis);
IMoniker_GetDisplayName(pmkOther,pbind,NULL,&pathOther);
nb1=FileMonikerImpl_DecomposePath(pathThis,&stringTable1);
nb2=FileMonikerImpl_DecomposePath(pathOther,&stringTable2);
if (nb1==0 || nb2==0)
return MK_E_NOPREFIX;
commonPath=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(min(lstrlenW(pathThis),lstrlenW(pathOther))+1));
*commonPath=0;
for(sameIdx=0; ( (stringTable1[sameIdx]!=NULL) &&
(stringTable2[sameIdx]!=NULL) &&
(lstrcmpiW(stringTable1[sameIdx],stringTable2[sameIdx])==0)); sameIdx++);
if (sameIdx > 1 && *stringTable1[0]=='\\' && *stringTable2[1]=='\\'){
machimeNameCase=TRUE;
for(i=2;i<sameIdx;i++)
if( (*stringTable1[i]=='\\') && (i+1 < sameIdx) && (*stringTable1[i+1]=='\\') ){
machimeNameCase=FALSE;
break;
}
}
if (machimeNameCase && *stringTable1[sameIdx-1]=='\\')
sameIdx--;
if (machimeNameCase && (sameIdx<=3) && (nb1 > 3 || nb2 > 3) )
ret = MK_E_NOPREFIX;
else
{
for(i=0;i<sameIdx;i++)
strcatW(commonPath,stringTable1[i]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -