📄 filemoniker.c
字号:
/******************************************************************************
* 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]);
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};
LPOLESTR word;
int i=0,j,tabIndex=0, ret=0;
LPOLESTR *strgtable ;
int len=lstrlenW(str);
TRACE("%s, %p\n", debugstr_w(str), *stringTable);
strgtable = CoTaskMemAlloc(len*sizeof(WCHAR));
if (strgtable==NULL)
return E_OUTOFMEMORY;
word = CoTaskMemAlloc((len + 1)*sizeof(WCHAR));
if (word==NULL)
{
ret = E_OUTOFMEMORY;
goto lend;
}
while(str[i]!=0){
if(str[i]==bSlash[0]){
strgtable[tabIndex]=CoTaskMemAlloc(2*sizeof(WCHAR));
if (strgtable[tabIndex]==NULL)
{
ret = E_OUTOFMEMORY;
goto lend;
}
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)
{
ret = E_OUTOFMEMORY;
goto lend;
}
strcpyW(strgtable[tabIndex++],word);
}
}
strgtable[tabIndex]=NULL;
*stringTable=strgtable;
ret = tabIndex;
lend:
if (ret < 0)
{
for (i = 0; i < tabIndex; i++)
CoTaskMemFree(strgtable[i]);
CoTaskMemFree(strgtable);
}
if (word)
CoTaskMemFree(word);
return ret;
}
/******************************************************************************
* 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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -