Получение списка удаленных файлов в Корзине
Удалять файлы в Корзину мы уже научились, теперь давайте разберем, как можно получить список удаленных объектов, которые в этой Корзине находятся. С чего начнем? Ну конечно же с описания кучи структур, интерфейсов и констант, которые нам понадобятся.Code (Assembler) : Убрать нумерацию
- ; GUID {43826D1E-E718-42EE-BC55-A1E261C37BFE}
- IID_IShellItem dd 043826D1Eh
- dw 0E718h
- dw 042EEh
- db 0BCh, 055h, 0A1h, 0E2h, 061h, 0C3h, 07Bh, 0FEh
- ; GUID {93F2F68C-1D1B-11D3-A30E-00C04F79ABD1}
- IID_IShellFolder2 dd 093F2F68Ch
- dw 01D1Bh
- dw 011D3h
- db 0A3h, 00Eh, 000h, 0C0h, 04Fh, 079h, 0ABh, 0D1h
- ; IID_IShellFolder2 Interface
- struct IShellFolder2
- QueryInterface dd ?
- AddRef dd ?
- Release dd ?
- ; IShellFolder
- ParseDisplayName dd ?
- EnumObjects dd ?
- BindToObject dd ?
- BindToStorage dd ?
- CompareIDs dd ?
- CreateViewObject dd ?
- GetAttributesOf dd ?
- GetUIObjectOf dd ?
- GetDisplayNameOf dd ?
- SetNameOf dd ?
- ; IShellFolder2
- GetDefaultSearchGUID dd ?
- EnumSearches dd ?
- GetDefaultColumn dd ?
- GetDefaultColumnState dd ?
- GetDetailsEx dd ?
- GetDetailsOf dd ?
- MapColumnToSCID dd ?
- ends
- ; IID_IEnumIDList Interface
- struct IEnumIDList
- QueryInterface dd ?
- AddRef dd ?
- Release dd ?
- Next dd ?
- Skip dd ?
- Reset dd ?
- Clone dd ?
- ends
- struct STRRET
- uType dd ?
- union
- pOleStr dd ?
- uOffset dd ?
- cStr rb 260
- ends
- ends
- struct SHCOLUMNID
- fmtid rb 16
- pid dd ?
- ends
- S_OK = 0
- CSIDL_BITBUCKET = 0Ah
- SHCONTF_FOLDERS = 20h
- SHCONTF_NONFOLDERS = 40h
- SHGDN_NORMAL = 0
- SHGDN_INFOLDER = 1
- SHGDN_FOREDITING = 1000h
- SHGDN_FORPARSING = 8000h
- PID_DISPLACED_FROM = 2
- PID_DISPLACED_DATE = 3
- PKEY_SIZE = 12
- PSGUID_DISPLACED dd 09B174B33h
- dw 040FFh
- dw 011D2h
- db 0A2h, 07Eh, 000h, 0C0h, 04Fh, 0C3h, 008h, 071h
- PKEY_Size dd 0B725F130h
- dw 047EFh
- dw 0101Ah
- db 0A5h, 0F1h, 002h, 060h, 08Ch, 09Eh, 0EBh, 0ACh
Code (Assembler) : Убрать нумерацию
- ; Инициализировать COM-объект
- invoke CoInitialize,NULL
- invoke SHGetSpecialFolderLocation,NULL,CSIDL_BITBUCKET,pidl
- invoke SHGetDesktopFolder,psfDesktop
- ; Получить объект папки Корзины
- mov eax,[psfDesktop]
- mov eax,[eax]
- stdcall dword [eax+IShellFolder2.BindToObject],[psfDesktop],\
- [pidl],NULL,IID_IShellFolder2,psfRecycleBin
- ; Обработать содержимое Корзины
- mov eax,[psfRecycleBin]
- mov eax,[eax]
- stdcall dword [eax+IShellFolder2.EnumObjects],[psfRecycleBin],\
- NULL,SHCONTF_FOLDERS+SHCONTF_NONFOLDERS,peidl
- loc_next:
- ; Очередной элемент содержимого Корзины
- mov eax,[peidl]
- mov eax,[eax]
- stdcall dword [eax+IEnumIDList.Next],[peidl],1,pidlItem,NULL
- ; Больше ничего нет
- or eax,eax
- jnz loc_done
- ; Выполнить необходимые действия с объектом
- ...
- ...
- ...
- jmp loc_next
- loc_done:
- ; Прибраться за собой
- mov eax, [psfRecycleBin]
- mov eax, [eax]
- stdcall dword [eax+IShellFolder2.Release],[psfRecycleBin]
- mov eax, [psfDesktop]
- mov eax, [eax]
- stdcall dword [eax+IShellFolder2.Release],[psfDesktop]
- invoke CoTaskMemFree,[pidl]
- ; Удалить объект
- invoke CoUninitialize
Самое простое - определение имени файла и путь его нахождения. Делается это с помощью метода GetDisplayNameOf интерфейса IShellFolder. Полученную структуру надо будет преобразовать в привычный строковый вид при помощи функции StrRetToStr.
Code (Assembler) : Убрать нумерацию
- ; Обычный формат представления
- mov eax,[psfRecycleBin]
- mov eax,[eax]
- stdcall dword [eax+IShellFolder2.GetDisplayNameOf],[psfRecycleBin],\
- [pidlItem],SHGDN_NORMAL,strRet
- ; Преобразовать строку в привычный вид
- invoke StrRetToStr,strRet,[pidlItem],spszName
- ; [spszName] --> указатель на строку
- ...
- ...
- invoke CoTaskMemFree,[spszName]
- ; Формат представления относительно данной папки
- mov eax,[psfRecycleBin]
- mov eax,[eax]
- stdcall dword [eax+IShellFolder2.GetDisplayNameOf],[psfRecycleBin],\
- [pidlItem],SHGDN_INFOLDER,strRet
- invoke StrRetToStr,strRet,[pidlItem],spszName
- ; [spszName] --> указатель на строку
- ...
- ...
- invoke CoTaskMemFree,[spszName]
- ; Формат представления, используемый для дальнейшего разбора имени
- mov eax,[psfRecycleBin]
- mov eax,[eax]
- stdcall dword [eax+IShellFolder2.GetDisplayNameOf],[psfRecycleBin],\
- [pidlItem],SHGDN_FORPARSING,strRet
- invoke StrRetToStr,strRet,[pidlItem],spszName
- ; [spszName] --> указатель на строку
- ...
- ...
- invoke CoTaskMemFree,[spszName]
Code (Assembler) : Убрать нумерацию
- ; Заполнить GUID в структуре SHCOLUMNID
- mov edi,pscid.fmtid
- mov esi,PSGUID_DISPLACED
- movsd
- movsd
- movsd
- movsd
- ; Место удаления
- mov [pscid.pid],PID_DISPLACED_FROM
- mov eax,[psfRecycleBin]
- mov eax,[eax]
- stdcall dword [eax+IShellFolder2.GetDetailsEx],[psfRecycleBin],\
- [pidlItem],pscid,vt
- invoke VariantChangeType,vt,vt,0,VT_BSTR
- ; [vt.lVal] --> адрес строки
- ...
- ...
- invoke VariantClear,vt
- ; Дата удаления
- mov [pscid.pid],PID_DISPLACED_DATE
- mov eax,[psfRecycleBin]
- mov eax,[eax]
- stdcall dword [eax+IShellFolder2.GetDetailsEx],[psfRecycleBin],\
- [pidlItem],pscid,vt
- invoke VariantChangeType,vt,vt,0,VT_BSTR
- ; [vt.lVal] --> адрес строки
- ...
- ...
- invoke VariantClear,vt
Code (Assembler) : Убрать нумерацию
- ; Заполнить GUID в структуре SHCOLUMNID
- mov edi,pscid.fmtid
- mov esi,PKEY_Size
- movsd
- movsd
- movsd
- movsd
- ; Размер файла
- mov [pscid.pid],PKEY_SIZE
- mov eax,[psfRecycleBin]
- mov eax,[eax]
- stdcall dword [eax+IShellFolder2.GetDetailsEx],[psfRecycleBin],\
- [pidlItem],pscid,vt
- invoke VariantChangeType,vt,vt,0,VT_BSTR
- ; [vt.lVal] --> адрес строки с размером файла
- ...
- ...
- invoke VariantClear,vt
Для получения общей информации о количестве элементов в Корзине и занимаемом ими объеме можно воспользоваться стандартными функциями, а точнее функцией SHQueryRecycleBin:
Code (Assembler) : Убрать нумерацию
- struct SHQUERYRBINFO
- cbSize dd ?
- i64Size dq ?
- i64NumItems dq ?
- ends
- path db 'C:\',0
- rci SHQUERYRBINFO
- ; Получить размер и количество элементов в Корзине
- mov [rci.cbSize],sizeof.SHQUERYRBINFO
- invoke SHQueryRecycleBin,path,rci
Code (Assembler) : Убрать нумерацию
- ; Очистить Корзину без подтверждения
- SHERB_NOCONFIRMATION = 0x00000001
- invoke SHEmptyRecycleBin,HWND_DESKTOP,path,SHERB_NOCONFIRMATION
В приложении пример программы с исходным текстом, которая выводит список содержимого Корзины со всеми доступными свойствами каждого файла.
Просмотров: 1242 | Комментариев: 7
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
ManHunter
(22.11.2020 в 15:03):
Добавил пример получения общего содержимого Корзины и пример очистки Корзины. Архив тоже обновлен.
Сергей Озеров
(06.09.2020 в 00:07):
Огромное спасибо за пример! буду разбираться
ManHunter
(01.09.2020 в 12:50):
Запросто, как минимум по расширению
Petya
(01.09.2020 в 12:33):
А может ли в обычной папке NORMAL не совпадать с INFOLDER?
ManHunter
(27.08.2020 в 13:05):
Сергей Озеров, вот тут https://www.upload.ee/files/12...der.zip.html пример с исходником, получает содержимое папки C:\Windows
ManHunter
(27.08.2020 в 12:54):
Статью рисовать не буду, лениво :) Содержимое папки получаем примерно так:
; Инициализировать COM-объект
invoke CoInitialize,NULL
invoke SHGetDesktopFolder,psfDesktop
; Получить объект нужной папки
; ffname -> строка названия нужной папки в юникоде
mov eax,[psfDesktop]
mov eax,[eax]
stdcall dword [eax+IShellFolder2.ParseDisplayName],[psfDesktop],\
NULL,0,ffname,NULL,pidl,attr
; Получить объект папки
mov eax,[psfDesktop]
mov eax,[eax]
stdcall dword [eax+IShellFolder2.BindToObject],[psfDesktop],\
[pidl],NULL,IID_IShellFolder2,psfFolder
; Обработать содержимое папки
mov eax,[psfFolder]
mov eax,[eax]
stdcall dword [eax+IShellFolder2.EnumObjects],[psfFolder],\
NULL,SHCONTF_FOLDERS+SHCONTF_NONFOLDERS,peidl
loc_next:
; Очередной элемент содержимого папки
mov eax,[peidl]
mov eax,[eax]
stdcall dword [eax+IEnumIDList.Next],[peidl],1,pidlItem,NULL
; Больше ничего нет
or eax,eax
jnz loc_done
...
...
...
jmp loc_next
loc_done:
mov eax, [psfFolder]
mov eax, [eax]
stdcall dword [eax+IShellFolder2.Release],[psfFolder]
mov eax, [psfDesktop]
mov eax, [eax]
stdcall dword [eax+IShellFolder2.Release],[psfDesktop]
invoke CoTaskMemFree,[pidl]
; Удалить объект
invoke CoUninitialize
Внутри все свойства получаются точно так же, кроме даты удаления и исходного месторасположения. Пустой SIZE - значит это папка, непустой - файл, если определять по-быстрому без лишних движений.
; Инициализировать COM-объект
invoke CoInitialize,NULL
invoke SHGetDesktopFolder,psfDesktop
; Получить объект нужной папки
; ffname -> строка названия нужной папки в юникоде
mov eax,[psfDesktop]
mov eax,[eax]
stdcall dword [eax+IShellFolder2.ParseDisplayName],[psfDesktop],\
NULL,0,ffname,NULL,pidl,attr
; Получить объект папки
mov eax,[psfDesktop]
mov eax,[eax]
stdcall dword [eax+IShellFolder2.BindToObject],[psfDesktop],\
[pidl],NULL,IID_IShellFolder2,psfFolder
; Обработать содержимое папки
mov eax,[psfFolder]
mov eax,[eax]
stdcall dword [eax+IShellFolder2.EnumObjects],[psfFolder],\
NULL,SHCONTF_FOLDERS+SHCONTF_NONFOLDERS,peidl
loc_next:
; Очередной элемент содержимого папки
mov eax,[peidl]
mov eax,[eax]
stdcall dword [eax+IEnumIDList.Next],[peidl],1,pidlItem,NULL
; Больше ничего нет
or eax,eax
jnz loc_done
...
...
...
jmp loc_next
loc_done:
mov eax, [psfFolder]
mov eax, [eax]
stdcall dword [eax+IShellFolder2.Release],[psfFolder]
mov eax, [psfDesktop]
mov eax, [eax]
stdcall dword [eax+IShellFolder2.Release],[psfDesktop]
invoke CoTaskMemFree,[pidl]
; Удалить объект
invoke CoUninitialize
Внутри все свойства получаются точно так же, кроме даты удаления и исходного месторасположения. Пустой SIZE - значит это папка, непустой - файл, если определять по-быстрому без лишних движений.
Сергей Озеров
(27.08.2020 в 10:50):
А можно пример? Спасибо.
Добавить комментарий
Заполните форму для добавления комментария