PDA

Просмотр полной версии : Работа с виртуальными папками и файлами



Kolinus
16.05.2005, 11:59
Доброго времени суток.
Имею:
Мобильное утройство, подключенное к компьютеру с Виндовс ХР.
Это устройство отображается в виде объекта в "моем компьютере".
Через проводник виндовый могу зайти в это устройство, увидеть его ФС и так далее.
Могу залезть программно в это устройство, увидеть папки в его ФС.
Задача:
вытащить файлы из определенных папок этого устройства.
Проблема:
программно не вижу файлов и не представляю как их оттуда выдернуть.
Замечание:
для навигации по папкам использую SHGetDesktopFolder и итеративно перебираю все папки входящие в нее, спускаясь ниже.

Romeo
16.05.2005, 12:44
Ты хочешь сказать, что IShellFolder::EnumObjects соотвествующего ShellFolder объекта возвращает пустой EnumIDList объект?

Kolinus
16.05.2005, 12:49
Очень на то похоже, хотя я и включаю флаг ..._NONFOLDER
То есть енамобжектс возвращает нормальный ответ, а когда делаю Next, то получаю ошибку

Romeo
16.05.2005, 12:58
1. Попробуй перечислить, все виртуальные айтемы: как файлы, так и папки.
2. Проверяй результат, который возвращает IShellFolder::EnumObjects.
3. Перед тем, как вызывать IEnumIDList::Next, вызови на всякий случай IEnumIDList::Reset.

Результаты исследований приведи в ответе.

Kolinus
16.05.2005, 15:15
Все я их вижу - по ходу проблема была в том что они скрытые а я не указывал флаг.
Теперь вопрос- как их все-таки оттуда скопировать на локальный диск ??

Romeo
16.05.2005, 17:53
Нужно спросить у ShellFolder объекта интерфейс IPersistFolder2 и вызвать IPersistFolder2::GetCurFolder. После этого конкатенировать полученный pidl папки с pidl'ом, который вернёт EnumIDList::Next. Полученный full pidl нужно загнать в SHGetPathFromIDList и получить реальный путь к файлу. После этого можно воспользоваться один из миллиона способов скопировать файл, от элементаного CopyFile до навороченного шеловского SHFileOperation.

Kolinus
17.05.2005, 15:25
А как сконкатинировать данные пидлы ?

Romeo
17.05.2005, 15:34
Читай MSDN (напиши в поиске "pidl copy" и открой первую же ссылку). Там даны прямо готовые функции для работы с pidl'ами. Стоит только скопировать и вставить в совй код :).

Kolinus
17.05.2005, 16:20
LPSHELLFOLDER folder - папка, содержащая файлы

IPersistFolder2 *pf;

folder->QueryInterface(IID_IPersistFolder2,(void**)&pf);
LPITEMIDLIST pidlFolder;
hr=pf->GetCurFolder(&pidlFolder);
if(SUCCEEDED(hr))
{
LPITEMIDLIST pidlNew;
UINT cb1 = GetSize(pidlFolder) - sizeof(pidlFolder->mkid.cb);
UINT cb2 = GetSize(pidlChild);
IMalloc *g_pMalloc;
SHGetMalloc(&g_pMalloc);
pidlNew = (LPITEMIDLIST)g_pMalloc->Alloc(cb1 + cb2);
if (pidlNew)
{
CopyMemory(pidlNew, pidlChild, cb1);
CopyMemory(((LPSTR)pidlNew) + cb1, pidlFolder, cb2);
}
char path[MAX_PATH];
BOOL ret;
ret=SHGetPathFromIDList(pidlNew,path);

ret - ложь то есть не возвращает имя.
в чем бага может быть ?

Romeo
17.05.2005, 17:56
Возможно пути к файлу нет, он существует только в виртуально. Нужно подумать.

Romeo
17.05.2005, 18:13
Да, кстати, нашёл ошибку у тебя в коде. Плохо копировал из MDSN :) Завершающий ноль тоже нужно копировать:

...
pidlNew = (LPITEMIDLIST)g_pMalloc->Alloc(cb1 + cb2 + sizeof(SHORT));
...
CopyMemory(((LPSTR)pidlNew) + cb1, pidlFolder, cb2 + sizeof(SHORT));

Kolinus
17.05.2005, 18:38
Изначально идет путь фолдера, а потом ребенок.
Так ?
Все равно что-то не пашет.
А через винду каким-то образом можно скопировать :(.

Eugie
18.05.2005, 01:57
Romeo, нет GetSize() из примера MSDN учитывает концевые нули.

Kolinus, поменяй порядок:


CopyMemory(pidlNew, pidlFolder, cb1);
CopyMemory(((LPSTR)pidlNew) + cb1, pidlChild, cb2);

Romeo
18.05.2005, 11:16
Точно, просмотрел, времени было мало. Действительно в неправильном порядке копируется. Если будет возвращаться неправильный результат и после этого фикса, то напиши код ошибки. Это многое прояснит.

Kolinus
18.05.2005, 15:46
Поменял и так и этак.
Делал и с нулями и без.
Возвращает всегда ложь.
GetLastError() ничего не дает :(.
Что еще посоветуете ? :)

Eugie
18.05.2005, 16:49
SHGetPathFromIDList очень простая функция, чтобы ошибка лежала слишком глубоко. ИМХО, всего 2 варианта: 1) буфер мал; 2) путь не существует. А уж что там на самом деле - тебе виднее;)

Kolinus
18.05.2005, 17:27
Размер буфера 2560 - вряд ли мало.
а насчет не существует - через виндовый эксплорер я их могу скопировать.
Или может такое быть что через эксплорер копируются, а программно - нет??

Romeo
18.05.2005, 17:38
Есть ещё вариант: такого файла на диске не существует - он виртуальный.

Kolinus
18.05.2005, 17:39
Возможно.
Но ведь виндой-то я его могу вытянуть. Вот что меня ставит в тупик. :(

Kolinus
19.05.2005, 12:48
Такой вопрос: а код
hr=folder->QueryInterface(IID_IPersistFolder2,(void**)&pf);
LPITEMIDLIST pidlFolder;
hr=pf->GetCurFolder(&pidlFolder);
возвращает полный или относительный пидл в фолдер?
че-то я в МСДНе этого не углядель :(

Romeo
19.05.2005, 12:55
Конечно полный. Относительно чего ему быть, если он относительный? :)

Kolinus
19.05.2005, 13:16
Я спросил потому как не могу вытянуть имя даже у фолдера :(