📄 filemoniker.c
字号:
/******************************************************************************
* 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, %u, %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;
}
/* find a character from a set in reverse without the string having to be null-terminated */
static inline WCHAR *memrpbrkW(const WCHAR *ptr, size_t n, const WCHAR *accept)
{
const WCHAR *end, *ret = NULL;
for (end = ptr + n; ptr < end; ptr++) if (strchrW(accept, *ptr)) ret = ptr;
return (WCHAR *)ret;
}
HRESULT FileMoniker_CreateFromDisplayName(LPBC pbc, LPCOLESTR szDisplayName,
LPDWORD pchEaten, LPMONIKER *ppmk)
{
LPCWSTR end;
static const WCHAR wszSeparators[] = {':','\\','/','!',0};
for (end = szDisplayName + strlenW(szDisplayName);
end && (end != szDisplayName);
end = memrpbrkW(szDisplayName, end - szDisplayName, wszSeparators))
{
HRESULT hr;
IRunningObjectTable *rot;
IMoniker *file_moniker;
LPWSTR file_display_name;
LPWSTR full_path_name;
DWORD full_path_name_len;
int len = end - szDisplayName;
file_display_name = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
if (!file_display_name) return E_OUTOFMEMORY;
memcpy(file_display_name, szDisplayName, len * sizeof(WCHAR));
file_display_name[len] = '\0';
hr = CreateFileMoniker(file_display_name, &file_moniker);
if (FAILED(hr))
{
HeapFree(GetProcessHeap(), 0, file_display_name);
return hr;
}
hr = IBindCtx_GetRunningObjectTable(pbc, &rot);
if (FAILED(hr))
{
HeapFree(GetProcessHeap(), 0, file_display_name);
IMoniker_Release(file_moniker);
return hr;
}
hr = IRunningObjectTable_IsRunning(rot, file_moniker);
IRunningObjectTable_Release(rot);
if (FAILED(hr))
{
HeapFree(GetProcessHeap(), 0, file_display_name);
IMoniker_Release(file_moniker);
return hr;
}
if (hr == S_OK)
{
TRACE("found running file moniker for %s\n", debugstr_w(file_display_name));
*pchEaten = len;
*ppmk = file_moniker;
HeapFree(GetProcessHeap(), 0, file_display_name);
return S_OK;
}
full_path_name_len = GetFullPathNameW(file_display_name, 0, NULL, NULL);
if (!full_path_name_len)
{
HeapFree(GetProcessHeap(), 0, file_display_name);
IMoniker_Release(file_moniker);
return MK_E_SYNTAX;
}
full_path_name = HeapAlloc(GetProcessHeap(), 0, full_path_name_len * sizeof(WCHAR));
if (!full_path_name)
{
HeapFree(GetProcessHeap(), 0, file_display_name);
IMoniker_Release(file_moniker);
return E_OUTOFMEMORY;
}
GetFullPathNameW(file_display_name, full_path_name_len, full_path_name, NULL);
if (GetFileAttributesW(full_path_name) == INVALID_FILE_ATTRIBUTES)
TRACE("couldn't open file %s\n", debugstr_w(full_path_name));
else
{
TRACE("got file moniker for %s\n", debugstr_w(szDisplayName));
*pchEaten = len;
*ppmk = file_moniker;
HeapFree(GetProcessHeap(), 0, file_display_name);
HeapFree(GetProcessHeap(), 0, full_path_name);
return S_OK;
}
HeapFree(GetProcessHeap(), 0, file_display_name);
HeapFree(GetProcessHeap(), 0, full_path_name);
IMoniker_Release(file_moniker);
}
return MK_E_CANTOPENFILE;
}
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 + -