shell32: Store simple full path for FolderItem.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
7c638b00c7
commit
0d87da46a9
|
@ -67,6 +67,7 @@ typedef struct {
|
||||||
IDispatch *application;
|
IDispatch *application;
|
||||||
IShellFolder2 *folder;
|
IShellFolder2 *folder;
|
||||||
PIDLIST_ABSOLUTE pidl;
|
PIDLIST_ABSOLUTE pidl;
|
||||||
|
WCHAR path[MAX_PATH];
|
||||||
} FolderImpl;
|
} FolderImpl;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -81,7 +82,7 @@ typedef struct {
|
||||||
FolderItem2 FolderItem2_iface;
|
FolderItem2 FolderItem2_iface;
|
||||||
LONG ref;
|
LONG ref;
|
||||||
FolderImpl *folder;
|
FolderImpl *folder;
|
||||||
VARIANT dir;
|
WCHAR *path; /* if NULL, folder path is used */
|
||||||
} FolderItemImpl;
|
} FolderItemImpl;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -657,8 +658,8 @@ static ULONG WINAPI FolderItemImpl_Release(FolderItem2 *iface)
|
||||||
|
|
||||||
if (!ref)
|
if (!ref)
|
||||||
{
|
{
|
||||||
VariantClear(&This->dir);
|
|
||||||
Folder3_Release(&This->folder->Folder3_iface);
|
Folder3_Release(&This->folder->Folder3_iface);
|
||||||
|
HeapFree(GetProcessHeap(), 0, This->path);
|
||||||
HeapFree(GetProcessHeap(), 0, This);
|
HeapFree(GetProcessHeap(), 0, This);
|
||||||
}
|
}
|
||||||
return ref;
|
return ref;
|
||||||
|
@ -759,40 +760,14 @@ static HRESULT WINAPI FolderItemImpl_put_Name(FolderItem2 *iface, BSTR bs)
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI FolderItemImpl_get_Path(FolderItem2 *iface, BSTR *pbs)
|
static HRESULT WINAPI FolderItemImpl_get_Path(FolderItem2 *iface, BSTR *path)
|
||||||
{
|
{
|
||||||
FolderItemImpl *This = impl_from_FolderItem(iface);
|
FolderItemImpl *This = impl_from_FolderItem(iface);
|
||||||
HRESULT ret = S_OK;
|
|
||||||
WCHAR *pathW;
|
|
||||||
int len;
|
|
||||||
|
|
||||||
TRACE("(%p,%p)\n", iface, pbs);
|
TRACE("(%p,%p)\n", iface, path);
|
||||||
|
|
||||||
*pbs = NULL;
|
*path = SysAllocString(This->path ? This->path : This->folder->path);
|
||||||
if (V_VT(&This->dir) == VT_I4)
|
return *path ? S_OK : E_OUTOFMEMORY;
|
||||||
{
|
|
||||||
pathW = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR));
|
|
||||||
if (!pathW) return E_OUTOFMEMORY;
|
|
||||||
ret = SHGetFolderPathW(NULL, V_I4(&This->dir), NULL, SHGFP_TYPE_CURRENT,
|
|
||||||
pathW);
|
|
||||||
if (ret == S_OK)
|
|
||||||
*pbs = SysAllocString(pathW);
|
|
||||||
else if (ret == E_INVALIDARG)
|
|
||||||
{
|
|
||||||
FIXME("not implemented for %#x\n", V_I4(&This->dir));
|
|
||||||
ret = E_NOTIMPL;
|
|
||||||
}
|
|
||||||
HeapFree(GetProcessHeap(), 0, pathW);
|
|
||||||
}
|
|
||||||
else /* VT_BSTR */
|
|
||||||
{
|
|
||||||
pathW = V_BSTR(&This->dir);
|
|
||||||
len = lstrlenW(pathW);
|
|
||||||
*pbs = SysAllocStringLen(pathW, pathW[len - 1] == '\\' ? len - 1 : len);
|
|
||||||
}
|
|
||||||
if (ret == S_OK && !*pbs)
|
|
||||||
ret = E_OUTOFMEMORY;
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI FolderItemImpl_get_GetLink(FolderItem2 *iface,
|
static HRESULT WINAPI FolderItemImpl_get_GetLink(FolderItem2 *iface,
|
||||||
|
@ -947,33 +922,28 @@ static const FolderItem2Vtbl FolderItemImpl_Vtbl = {
|
||||||
FolderItemImpl_ExtendedProperty
|
FolderItemImpl_ExtendedProperty
|
||||||
};
|
};
|
||||||
|
|
||||||
static HRESULT FolderItem_Constructor(FolderImpl *folder, VARIANT *dir, FolderItem **ppfi)
|
static HRESULT FolderItem_Constructor(FolderImpl *folder, const WCHAR *path, FolderItem **item)
|
||||||
{
|
{
|
||||||
FolderItemImpl *This;
|
FolderItemImpl *This;
|
||||||
HRESULT ret;
|
|
||||||
|
|
||||||
TRACE("%s\n", debugstr_variant(dir));
|
TRACE("%s\n", debugstr_w(path));
|
||||||
|
|
||||||
*ppfi = NULL;
|
*item = NULL;
|
||||||
|
|
||||||
|
This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*This));
|
||||||
|
if (!This)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
This = HeapAlloc(GetProcessHeap(), 0, sizeof(FolderItemImpl));
|
|
||||||
if (!This) return E_OUTOFMEMORY;
|
|
||||||
This->FolderItem2_iface.lpVtbl = &FolderItemImpl_Vtbl;
|
This->FolderItem2_iface.lpVtbl = &FolderItemImpl_Vtbl;
|
||||||
This->ref = 1;
|
This->ref = 1;
|
||||||
|
if (path)
|
||||||
VariantInit(&This->dir);
|
This->path = strdupW(path);
|
||||||
ret = VariantCopy(&This->dir, dir);
|
|
||||||
if (FAILED(ret))
|
|
||||||
{
|
|
||||||
HeapFree(GetProcessHeap(), 0, This);
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
This->folder = folder;
|
This->folder = folder;
|
||||||
Folder3_AddRef(&folder->Folder3_iface);
|
Folder3_AddRef(&folder->Folder3_iface);
|
||||||
|
|
||||||
*ppfi = (FolderItem *)&This->FolderItem2_iface;
|
*item = (FolderItem *)&This->FolderItem2_iface;
|
||||||
return ret;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI FolderItemsImpl_QueryInterface(FolderItems3 *iface,
|
static HRESULT WINAPI FolderItemsImpl_QueryInterface(FolderItems3 *iface,
|
||||||
|
@ -1116,7 +1086,6 @@ static HRESULT WINAPI FolderItemsImpl_Item(FolderItems3 *iface, VARIANT index, F
|
||||||
FolderItemsImpl *This = impl_from_FolderItems(iface);
|
FolderItemsImpl *This = impl_from_FolderItems(iface);
|
||||||
WCHAR buffW[MAX_PATH], *display_name;
|
WCHAR buffW[MAX_PATH], *display_name;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
VARIANT v;
|
|
||||||
|
|
||||||
TRACE("(%p,%s,%p)\n", iface, debugstr_variant(&index), item);
|
TRACE("(%p,%s,%p)\n", iface, debugstr_variant(&index), item);
|
||||||
|
|
||||||
|
@ -1158,18 +1127,14 @@ static HRESULT WINAPI FolderItemsImpl_Item(FolderItems3 *iface, VARIANT index, F
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case VT_ERROR:
|
case VT_ERROR:
|
||||||
return FolderItem_Constructor(This->folder, &This->folder->dir, item);
|
return FolderItem_Constructor(This->folder, NULL, item);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
FIXME("Index type %d not handled.\n", V_VT(&index));
|
FIXME("Index type %d not handled.\n", V_VT(&index));
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
V_VT(&v) = VT_BSTR;
|
return FolderItem_Constructor(This->folder, display_name, item);
|
||||||
V_BSTR(&v) = SysAllocString(display_name);
|
|
||||||
hr = FolderItem_Constructor(This->folder, &v, item);
|
|
||||||
VariantClear(&v);
|
|
||||||
return hr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI FolderItemsImpl__NewEnum(FolderItems3 *iface, IUnknown **ppunk)
|
static HRESULT WINAPI FolderItemsImpl__NewEnum(FolderItems3 *iface, IUnknown **ppunk)
|
||||||
|
@ -1521,7 +1486,6 @@ static HRESULT WINAPI FolderImpl_ParseName(Folder3 *iface, BSTR name, FolderItem
|
||||||
FolderItem *self;
|
FolderItem *self;
|
||||||
BSTR str;
|
BSTR str;
|
||||||
WCHAR pathW[MAX_PATH];
|
WCHAR pathW[MAX_PATH];
|
||||||
VARIANT v;
|
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
TRACE("(%p,%s,%p)\n", iface, debugstr_w(name), item);
|
TRACE("(%p,%s,%p)\n", iface, debugstr_w(name), item);
|
||||||
|
@ -1544,11 +1508,7 @@ static HRESULT WINAPI FolderImpl_ParseName(Folder3 *iface, BSTR name, FolderItem
|
||||||
if (!PathFileExistsW(pathW))
|
if (!PathFileExistsW(pathW))
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
|
|
||||||
V_VT(&v) = VT_BSTR;
|
return FolderItem_Constructor(This, pathW, item);
|
||||||
V_BSTR(&v) = SysAllocString(pathW);
|
|
||||||
hr = FolderItem_Constructor(This, &v, item);
|
|
||||||
VariantClear(&v);
|
|
||||||
return hr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI FolderImpl_NewFolder(Folder3 *iface, BSTR bName,
|
static HRESULT WINAPI FolderImpl_NewFolder(Folder3 *iface, BSTR bName,
|
||||||
|
@ -1584,13 +1544,13 @@ static HRESULT WINAPI FolderImpl_GetDetailsOf(Folder3 *iface, VARIANT vItem,
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI FolderImpl_get_Self(Folder3 *iface, FolderItem **ppfi)
|
static HRESULT WINAPI FolderImpl_get_Self(Folder3 *iface, FolderItem **item)
|
||||||
{
|
{
|
||||||
FolderImpl *This = impl_from_Folder(iface);
|
FolderImpl *This = impl_from_Folder(iface);
|
||||||
|
|
||||||
TRACE("(%p,%p)\n", iface, ppfi);
|
TRACE("(%p,%p)\n", iface, item);
|
||||||
|
|
||||||
return FolderItem_Constructor(This, &This->dir, ppfi);
|
return FolderItem_Constructor(This, NULL, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI FolderImpl_get_OfflineStatus(Folder3 *iface, LONG *pul)
|
static HRESULT WINAPI FolderImpl_get_OfflineStatus(Folder3 *iface, LONG *pul)
|
||||||
|
@ -1667,7 +1627,10 @@ static const Folder3Vtbl FolderImpl_Vtbl = {
|
||||||
|
|
||||||
static HRESULT Folder_Constructor(VARIANT *dir, IShellFolder2 *folder, LPITEMIDLIST pidl, Folder **ret)
|
static HRESULT Folder_Constructor(VARIANT *dir, IShellFolder2 *folder, LPITEMIDLIST pidl, Folder **ret)
|
||||||
{
|
{
|
||||||
|
PCUITEMID_CHILD last_part;
|
||||||
|
IShellFolder2 *parent;
|
||||||
FolderImpl *This;
|
FolderImpl *This;
|
||||||
|
STRRET strret;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
*ret = NULL;
|
*ret = NULL;
|
||||||
|
@ -1680,6 +1643,12 @@ static HRESULT Folder_Constructor(VARIANT *dir, IShellFolder2 *folder, LPITEMIDL
|
||||||
This->ref = 1;
|
This->ref = 1;
|
||||||
This->folder = folder;
|
This->folder = folder;
|
||||||
This->pidl = pidl;
|
This->pidl = pidl;
|
||||||
|
|
||||||
|
hr = SHBindToParent(pidl, &IID_IShellFolder2, (void **)&parent, &last_part);
|
||||||
|
IShellFolder2_GetDisplayNameOf(parent, last_part, SHGDN_FORPARSING, &strret);
|
||||||
|
StrRetToBufW(&strret, NULL, This->path, sizeof(This->path)/sizeof(*This->path));
|
||||||
|
IShellFolder2_Release(parent);
|
||||||
|
|
||||||
IShellDispatch_Constructor(NULL, &IID_IDispatch, (void **)&This->application);
|
IShellDispatch_Constructor(NULL, &IID_IDispatch, (void **)&This->application);
|
||||||
|
|
||||||
VariantInit(&This->dir);
|
VariantInit(&This->dir);
|
||||||
|
|
|
@ -244,10 +244,10 @@ static void test_namespace(void)
|
||||||
r = Folder2_get_Self(folder2, &item);
|
r = Folder2_get_Self(folder2, &item);
|
||||||
ok(r == S_OK, "Folder::get_Self failed: %08x\n", r);
|
ok(r == S_OK, "Folder::get_Self failed: %08x\n", r);
|
||||||
r = FolderItem_get_Path(item, &item_path);
|
r = FolderItem_get_Path(item, &item_path);
|
||||||
todo_wine {
|
|
||||||
ok(r == S_OK, "FolderItem::get_Path failed: %08x\n", r);
|
ok(r == S_OK, "FolderItem::get_Path failed: %08x\n", r);
|
||||||
ok(!lstrcmpW(item_path, clsidW), "expected %s, got %s\n", wine_dbgstr_w(clsidW), wine_dbgstr_w(item_path));
|
/* TODO: we return lowercase GUID here */
|
||||||
}
|
ok(!lstrcmpiW(item_path, clsidW), "expected %s, got %s\n", wine_dbgstr_w(clsidW), wine_dbgstr_w(item_path));
|
||||||
|
|
||||||
SysFreeString(item_path);
|
SysFreeString(item_path);
|
||||||
FolderItem_Release(item);
|
FolderItem_Release(item);
|
||||||
Folder2_Release(folder2);
|
Folder2_Release(folder2);
|
||||||
|
|
Loading…
Reference in New Issue