📄 filemoniker.c
字号:
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 + -