Blog. Just Blog

Быстрый поиск

Введите фрагмент названия статьи для поиска

Получение списка удаленных файлов в Корзине

22.08.2020 | Категория: Образ мышления: Assembler | Автор: ManHunter
Удалять файлы в Корзину мы уже научились, теперь давайте разберем, как можно получить список удаленных объектов, которые в этой Корзине находятся. С чего начнем? Ну конечно же с описания кучи структур, интерфейсов и констант, которые нам понадобятся.
  1. ; GUID {43826D1E-E718-42EE-BC55-A1E261C37BFE}
  2. IID_IShellItem      dd 043826D1Eh
  3.                     dw 0E718h
  4.                     dw 042EEh
  5.                     db 0BCh, 055h, 0A1h, 0E2h, 061h, 0C3h, 07Bh, 0FEh
  6.  
  7. ; GUID {93F2F68C-1D1B-11D3-A30E-00C04F79ABD1}
  8. IID_IShellFolder2   dd 093F2F68Ch
  9.                     dw 01D1Bh
  10.                     dw 011D3h
  11.                     db 0A3h, 00Eh, 000h, 0C0h, 04Fh, 079h, 0ABh, 0D1h
  12.  
  13. ; IID_IShellFolder2 Interface
  14. struct IShellFolder2
  15.     QueryInterface      dd ?
  16.     AddRef              dd ?
  17.     Release             dd ?
  18.  
  19.     ; IShellFolder
  20.     ParseDisplayName    dd ?
  21.     EnumObjects         dd ?
  22.     BindToObject        dd ?
  23.     BindToStorage       dd ?
  24.     CompareIDs          dd ?
  25.     CreateViewObject    dd ?
  26.     GetAttributesOf     dd ?
  27.     GetUIObjectOf       dd ?
  28.     GetDisplayNameOf    dd ?
  29.     SetNameOf           dd ?
  30.  
  31.     ; IShellFolder2
  32.     GetDefaultSearchGUID  dd ?
  33.     EnumSearches          dd ?
  34.     GetDefaultColumn      dd ?
  35.     GetDefaultColumnState dd ?
  36.     GetDetailsEx          dd ?
  37.     GetDetailsOf          dd ?
  38.     MapColumnToSCID       dd ?
  39. ends
  40.  
  41. ; IID_IEnumIDList Interface
  42. struct IEnumIDList
  43.     QueryInterface      dd ?
  44.     AddRef              dd ?
  45.     Release             dd ?
  46.  
  47.     Next                dd ?
  48.     Skip                dd ?
  49.     Reset               dd ?
  50.     Clone               dd ?
  51. ends
  52.  
  53. struct STRRET
  54.     uType dd ?
  55.     union
  56.         pOleStr dd ?
  57.         uOffset dd ?
  58.         cStr    rb 260
  59.     ends
  60. ends
  61.  
  62. struct SHCOLUMNID
  63.      fmtid rb 16
  64.      pid   dd ?
  65. ends
  66.  
  67. S_OK               = 0
  68. CSIDL_BITBUCKET    = 0Ah
  69. SHCONTF_FOLDERS    = 20h
  70. SHCONTF_NONFOLDERS = 40h
  71. SHGDN_NORMAL       = 0
  72. SHGDN_INFOLDER     = 1
  73. SHGDN_FOREDITING   = 1000h
  74. SHGDN_FORPARSING   = 8000h
  75. PID_DISPLACED_FROM = 2
  76. PID_DISPLACED_DATE = 3
  77. PKEY_SIZE          = 12
  78.  
  79. PSGUID_DISPLACED   dd 09B174B33h
  80.                    dw 040FFh
  81.                    dw 011D2h
  82.                    db 0A2h, 07Eh, 000h, 0C0h, 04Fh, 0C3h, 008h, 071h
  83.  
  84. PKEY_Size dd 0B725F130h
  85.           dw 047EFh
  86.           dw 0101Ah
  87.           db 0A5h, 0F1h, 002h, 060h, 08Ch, 09Eh, 0EBh, 0ACh
Для доступа к Корзине сперва надо получить объект рабочего стола, а уже через него определить объект Корзины. После этого поочередно получаем объекты ее содержимого и выполняем с ними нужные действия.
  1.         ; Инициализировать COM-объект
  2.         invoke  CoInitialize,NULL
  3.         invoke  SHGetSpecialFolderLocation,NULL,CSIDL_BITBUCKET,pidl
  4.         invoke  SHGetDesktopFolder,psfDesktop
  5.  
  6.         ; Получить объект папки Корзины
  7.         mov     eax,[psfDesktop]
  8.         mov     eax,[eax]
  9.         stdcall dword [eax+IShellFolder2.BindToObject],[psfDesktop],\
  10.                 [pidl],NULL,IID_IShellFolder2,psfRecycleBin
  11.  
  12.         ; Обработать содержимое Корзины
  13.         mov     eax,[psfRecycleBin]
  14.         mov     eax,[eax]
  15.         stdcall dword [eax+IShellFolder2.EnumObjects],[psfRecycleBin],\
  16.                 NULL,SHCONTF_FOLDERS+SHCONTF_NONFOLDERS,peidl
  17.  
  18. loc_next:
  19.         ; Очередной элемент содержимого Корзины
  20.         mov     eax,[peidl]
  21.         mov     eax,[eax]
  22.         stdcall dword [eax+IEnumIDList.Next],[peidl],1,pidlItem,NULL
  23.         ; Больше ничего нет
  24.         or      eax,eax
  25.         jnz     loc_done
  26.  
  27.         ; Выполнить необходимые действия с объектом
  28.         ...
  29.         ...
  30.         ...
  31.  
  32.         jmp     loc_next
  33.  
  34. loc_done:
  35.         ; Прибраться за собой
  36.         mov     eax, [psfRecycleBin]
  37.         mov     eax, [eax]
  38.         stdcall dword [eax+IShellFolder2.Release],[psfRecycleBin]
  39.  
  40.         mov     eax, [psfDesktop]
  41.         mov     eax, [eax]
  42.         stdcall dword [eax+IShellFolder2.Release],[psfDesktop]
  43.  
  44.         invoke  CoTaskMemFree,[pidl]
  45.  
  46.         ; Удалить объект
  47.         invoke  CoUninitialize
Получив очередной объект, можно узнать его свойства. Это может быть имя файла, его исходное месторасположение, нынешнее имя в Корзине, дата удаления, размер файла.

Читать статью целиком »
Просмотров: 1349 | Комментариев: 7

Delayed Start 1.6

20.08.2020 | Категория: Мои программы | Автор: ManHunter

Скриншот программы Delayed Start

Программа для запуска других приложений с заданной задержкой. Кроме собственно запуска может автоматически прятать окно запущенного приложения, что особенно полезно для консольных программ. Дополнительно программа Delayed Start может быть использована, когда требуется выдержать нужную паузу в командных файлах. Для этого достаточно указать только время задержки без имени запускаемого приложения. Я использую Delayed Start в автозагрузке, чтобы "тяжелые" программы запускались не все одновременно, сильно нагружая систему, а по очереди и в нужной мне последовательности.

Для использования в командных файлах предусмотрены следующие коды возврата:
errorlevel = 1 - запуск произведен успешно или запуск вообще не выполнялся (пауза)
errorlevel = 0 - при запуске произошла ошибка

Для отладки запуска программ с разными параметрами в архиве прилагается файлик test.exe. Он просто выводит окно со своей командной строкой.

Читать статью целиком »
Просмотров: 17242 | Комментариев: 58

Программное удаление файла в Корзину

18.08.2020 | Категория: Образ мышления: Assembler | Автор: ManHunter
Небольшой сниппет - удаление файла или группы файлов в Корзину. Делается это при помощи функции SHFileOperation, но сперва нам надо будет определить необходимую структуру SHFILEOPSTRUCT и несколько констант.
  1. struct SHFILEOPSTRUCT
  2.         hwnd                  dd ?
  3.         wFunc                 dd ?
  4.         pFrom                 dd ?
  5.         pTo                   dd ?
  6.         fFlags                dw ?
  7.         fAnyOperationsAborted dd ?
  8.         hNameMappings         dd ?
  9.         lpszProgressTitle     dd ?
  10. ends
  11.  
  12. FO_DELETE = 3h
  13.  
  14. FOF_ALLOWUNDO      = 40h
  15. FOF_NOCONFIRMATION = 10h
  16. FOF_SILENT         = 4h
Сам код очень простой. Указываем тип операции FO_DELETE, то есть удаление, в параметре pFrom передаем список объектов на удаление, флагами настраиваем поведение - удалять с возможностью отката (то есть в Корзину), не показывать никаких подтверждений и диалогов.
  1.         mov     [fos.hwnd],HWND_DESKTOP
  2.         mov     [fos.wFunc],FO_DELETE
  3.         mov     [fos.pFrom],fname
  4.         mov     [fos.fFlags],FOF_ALLOWUNDO+FOF_NOCONFIRMATION+FOF_SILENT
  5.         invoke  SHFileOperation,fos
Обратите внимание, что список объектов должен заканчиваться двойным нулевым символом, даже если удаляется один файл. Также при удалении файлов со съемных носителей они могут удаляться без попадания в Корзину, но это как и при удалении через Проводник Windows.

Читать статью целиком »
Просмотров: 1275 | Комментариев: 6

Использование мультимедийного таймера

16.08.2020 | Категория: Образ мышления: Assembler | Автор: ManHunter
Интересная разновидность системных событий - высокоточный мультимедийный таймер. Гарантированный интервал срабатывания мультимедийных таймеров - около 10 миллисекунд против 50 миллисекунд обычных таймеров, устанавливаемых при помощи функции SetTimer. Кроме того, мультимедийные таймеры позволяют использовать обработчики, которые будут срабатывать в нужные интервалы, тогда как сообщения WM_TIMER от обычных таймеров идут через общую очередь. Если главный поток подвис, заснул или продолжительное время реагирует на какое-нибудь тяжелое сообщение, то таймеру придется ожидать, пока обработчик дойдет до него. Таким образом, добиться предсказуемой периодичности таймера будет очень сложно. Мультимедийные таймеры выполняются в собственном потоке, поэтому лишены перечисленных недостатков.

Слова словами, но давайте проверим это на практике. Для этого в простом оконном приложении установим обычный таймер на интервал 1 миллисекунду, вместе с этим создадим мультимедийный таймер с таким же интервалом срабатывания. При каждом срабатывании каждого из этих таймеров будет увеличен соответствующий счетчик. По истечении определенного времени, например, 5 секунд, сравним результаты.

Обработчик окна будет выглядеть примерно так. Для удобства я оставил только минимально необходимый код.
  1.         cmp     [msg],WM_INITDIALOG
  2.         je      wminitdialog
  3.         cmp     [msg],WM_TIMER
  4.         je      wmtimer
  5.         ...
  6.         ...
  7. wminitdialog:
  8.         ; Обнулить счетчики
  9.         mov     [dCntTim],0
  10.         mov     [dCntMM],0
  11.  
  12.         ; Получить начальное время
  13.         invoke  GetTickCount
  14.         mov     [dTime],eax
  15.  
  16.         ; Установить обычный таймер на интервал 1 мс
  17.         invoke  SetTimer,[hwnddlg],1,1,NULL
  18.  
  19.         ; Установить мультимедийный таймер на интервал 1 мс
  20.         TIME_PERIODIC = 0x0001
  21.         invoke  timeSetEvent,1,1,TimeProc,777,TIME_PERIODIC
  22.  
  23.         ...
  24.         ...
  25. wmtimer:
  26.         ; Увеличить счетчик по событию WM_TIMER
  27.         inc     [dCntTim]
  28.  
  29.         ; Прошло 5 секунд?
  30.         invoke  GetTickCount
  31.         sub     eax,[dTime]
  32.         cmp     eax,5000
  33.         jb      processed
  34.         jmp     wmclose
  35.  
  36. wmclose:
  37.         ; Удалить оба счетчика
  38.         invoke  KillTimer,[hwnddlg],1
  39.         invoke  timeKillEvent,[hTimer]
При инициализации окна устанавливается обычный и мультимедийный таймеры, при получении сообщения WM_TIMER увеличиваем обычный счетчик, а в функции-обработчике высокоточного таймера увеличиваем мультимедийный счетчик.
  1. ;-----------------------------------------------------------
  2. ; Обработчик высокоточного таймера
  3. ;-----------------------------------------------------------
  4. proc TimeProc uTimerID:DWORD,uMsg:DWORD,dwUser:DWORD,dw1:DWORD,dw2:DWORD
  5.         ; Увеличить счетчик по системному событию
  6.         inc     [dCntMM]
  7.         ret
  8. endp
Ну и момент истины. По результатам тестирования выяснилось, что за 5 секунд обычный таймер вызывается всего около 320 раз, тогда как обработчик мультимедийного таймера вызывается четко не менее 5000 раз. Что и требовалось доказать.

Читать статью целиком »
Просмотров: 1312 | Комментариев: 4

Передача данных приложению с помощью WM_DROPFILES

09.07.2020 | Категория: Образ мышления: Assembler | Автор: ManHunter
Обрабатывать перетаскивание файлов в окно программы мы уже умеем, а сегодня узнаем, как сэмулировать это действие, то есть передать стороннему приложению список файлов через отправку сообщения WM_DROPFILES.

Начинаем с описания структуры DROPFILES, потому что FASM про нее ничего не знает. Так часто приходится писать подобное, что впору уже вводить какую-нибудь аббревиатуру, типа "Самостоятельно Описываем Структуры, Недостающие Интерфейсы, Константы Ассемблера" - "С.О.С.Н.И.К.А". Шутка.
  1. struct DROPFILES
  2.         pFiles dd ?
  3.         pt     POINT
  4.         fNC    dd ?
  5.         fWide  dd ?
  6. ends
Перед отправкой сообщения окну надо заполнить структуру DROPFILES. Значимыми полями являются pFiles - указатель на список файлов относительно начала структуры, и fWide - в каком формате передаются имена файлов, ASCII или юникод. Хотя на расположение списка файлов в памяти нет явных ограничений, обычно этот список размещается прямо за структурой и завершается нулевым байтом. Соответственно, указатель на этот список будет равен размеру структуры DROPFILES. Память под все это дело надо выделять с учетом нулевых разделителей между именами файлов и завершающим нулем.

Ну и сам код. Определяем размер и выделяем память, заполняем структуру и имена файлов, отправляем сообщение целевому окну.
  1.         ; Размер структуры DROPFILES
  2.         mov     ebx,sizeof.DROPFILES
  3.         inc     ebx
  4.  
  5.         ; Длина имени первого файла
  6.         invoke  lstrlen,file1
  7.         add     ebx,eax
  8.         inc     ebx
  9.  
  10.         ; Длина имени второго файла
  11.         invoke  lstrlen,file2
  12.         add     ebx,eax
  13.         inc     ebx
  14.  
  15.         ; Выделить память
  16.         invoke  GlobalAlloc,GMEM_SHARE+GMEM_MOVEABLE+GMEM_ZEROINIT,ebx
  17.         mov     [mem],eax
  18.         invoke  GlobalLock,eax
  19.         mov     [dfiles],eax
  20.  
  21.         ; Заполнить структуру DROPFILES
  22.         mov     edi,[dfiles]
  23.         mov     [edi+DROPFILES.pFiles],sizeof.DROPFILES
  24.         mov     [edi+DROPFILES.pt.x],0
  25.         mov     [edi+DROPFILES.pt.y],0
  26.         mov     [edi+DROPFILES.fNC],FALSE
  27.         mov     [edi+DROPFILES.fWide],FALSE
  28.         add     edi,sizeof.DROPFILES
  29.  
  30.         ; Дописать к ней передаваемые файлы
  31.         mov     esi,file1
  32. @@:
  33.         lodsb
  34.         stosb
  35.         or      al,al
  36.         jnz     @b
  37.  
  38.         mov     esi,file2
  39. @@:
  40.         lodsb
  41.         stosb
  42.         or      al,al
  43.         jnz     @b
  44.  
  45.         ; Завершающий нулевой байт
  46.         xor     eax,eax
  47.         stosb
  48.  
  49.         ; Отправить сообщение WM_DROPFILES
  50.         invoke  GlobalUnlock,[mem]
  51.         invoke  PostMessage,[destination_window],WM_DROPFILES,[mem],0
  52.         invoke  GlobalFree,[mem]
Обратите внимание, что отправка сообщения выполняется через PostMessage, иначе целевое приложение по какой-то причине может подвиснуть.

Читать статью целиком »
Просмотров: 1197 | Комментариев: 1

01 ... 07 08 09 10 11 12 13 ... 36
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2025
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.07 сек. / MySQL: 3 (0.0077 сек.) / Память: 4.5 Mb
Наверх