Удаление файла по маске и по полному пути (проблема с DeleteFile)

Тема в разделе "WASM.BEGINNERS", создана пользователем Adrax, 31 янв 2007.

  1. Adrax

    Adrax Алексей

    Публикаций:
    0
    Регистрация:
    14 окт 2006
    Сообщения:
    135
    Адрес:
    г. Курск
    Уважаемые программисты! Прошу помощи: пытаюсь написать консольную утилиту, удаляющую файлы по их полному пути и по маске. Получилось вот что:
    Код (Text):
    1. format PE console
    2. include 'win32axp.inc'
    3.  
    4. section '.data' data readable writeable
    5. ns dd ?
    6. hout dd ?
    7. buffer db 261 dup (?)
    8. help db 'Using: mydel.exe path_to_file',0
    9. Retry db 'Program fails. Please, retry',0
    10. seek dd ?
    11.  
    12. fd FINDDATA NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
    13.  
    14. section '.code' code readable executable
    15. fuck:
    16. invoke GetStdHandle,STD_OUTPUT_HANDLE
    17. mov [hout],eax
    18. invoke GetCommandLine
    19. mov esi,eax
    20. cycle1:
    21.  cmp byte [esi],20h
    22.  je parameter
    23.  cmp byte [esi],0Dh
    24.  je najobka
    25.  inc esi
    26.  jmp cycle1
    27. parameter:
    28.  mov edi,buffer
    29.  mov ecx,261
    30.    cycle2:
    31.      inc esi
    32.      mov al,byte [esi]
    33.      cmp al,0Dh
    34.      je konets
    35.      mov byte [edi],al
    36.      inc edi
    37.      loop cycle2
    38.  
    39. konets:
    40.   mov byte [edi],0
    41.   invoke lstrlen,buffer
    42.   test eax,eax
    43.   jz najobka
    44.   invoke FindFirstFile,buffer,fd
    45.   cmp eax,-1
    46.   ;сравнение с INVALID_HANDLE_VALUE
    47.   je retry
    48.   mov [seek],eax
    49.   invoke DeleteFile,fd.cFileName
    50.   test eax,eax
    51.   jz retry
    52.  
    53. deleting:
    54.   invoke FindNextFile,[seek],fd
    55.   test eax,eax
    56.   jz errr
    57.   invoke DeleteFile,fd.cFileName
    58.   jmp deleting
    59.  
    60.  
    61. errr:
    62.  invoke GetLastError
    63.  cmp eax,18
    64.  je exit
    65.  
    66. retry:
    67.  invoke WriteConsole,[hout],Retry,28,ns,NULL
    68.  
    69. exit:
    70.  invoke FindClose,[seek]
    71.  invoke ExitProcess,0
    72.  
    73. najobka:
    74.  invoke WriteConsole,[hout],help,29,ns,NULL
    75.  jmp exit
    76.  
    77. .end fuck
    Удаление по имени и маске файла в текущей директории идёт прекрасно, однако при указании полного пути, программа выдаёт "Program fails. Please, retry". Когда пихнул int3 перед DeleteFile, в Оле увидел, что вместо пути и имени файла функции передаётся какая-то строка псевдографических символов.
    Прошу вас пояснить мне мою ошибку
    Попутно ещё вопрос: как реализовать удаление файлов с помощью SHFileOperation? Я пытался вызывать её из FASM (пришлось инклуду свою варганить, фасм про _SHFILEOPSTRUCT не знает ничего), указал все необходимые параметры, пытался удалять и по маске, и по полному пути, функция возвращает, что всё ОК, но файл не удаляется. Быть может, на NT есть свои тонкости?
    Заранее благодарен
     
  2. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    fd.cFileName - это имя файла без пути, поэтому чтобы удаление работало не только в текущей директории, нужно к этому имени "приклеить" путь к файлу
     
  3. ksu_ant

    ksu_ant New Member

    Публикаций:
    0
    Регистрация:
    28 сен 2005
    Сообщения:
    273
    Код на Delphi.
    Код (Text):
    1. gettemppath(Sizeof(frombuf),frombuf);
    2. temp:=strpas(frombuf);temp:=temp+'Test';//Получение пути к папке TEMP\Test
    3. FillChar( frombuf, Sizeof(frombuf), 0 );
    4. StrPCopy(frombuf,temp);
    5. GetCurrentDirectory(sizeof(tobuf),tobuf);
    6. CurDir:=strpas(tobuf);
    7. if SetCurrentDirectory(frombuf) then begin  //если такая папка есть - удаляем.
    8. with OpStruc do begin
    9.     Wnd := Handle;
    10.     wFunc := FO_DELETE;
    11.     pFrom := @frombuf;
    12.     pTo := nil;
    13.     fFlags := FOF_NOCONFIRMATION or FOF_RENAMEONCOLLISION or FOF_SILENT;
    14.     fAnyOperationsAborted := False;
    15.     hNameMappings := Nil;
    16.     lpszProgressTitle := Nil;
    17. end;
    18. ShFileOperation( OpStruc );
    19. end;
    Копирование *.jpg по маске из каталога TEMP\files. tobuf - куда скопировать.
    Код (Text):
    1. s:=temp+'files'+'\'+'*.jpg';
    2. StrPCopy( frombuf, s);
    3. StrPCopy( tobuf,st);
    4.   with OpStruc do begin
    5.     Wnd := Handle;
    6.     wFunc := FO_COPY;
    7.     pFrom := @frombuf;
    8.     pTo := @tobuf;
    9.     fFlags := FOF_NOCONFIRMATION or FOF_SILENT OR FOF_FILESONLY;
    10.     fAnyOperationsAborted := False;
    11.     hNameMappings := Nil;
    12.     lpszProgressTitle := Nil;
    13.   end;
    14. ShFileOperation( OpStruc );
    Думаю, поможет.
    Удачи!
     
  4. Adrax

    Adrax Алексей

    Публикаций:
    0
    Регистрация:
    14 окт 2006
    Сообщения:
    135
    Адрес:
    г. Курск
    Так и знал, что cFileName не содержит пути!!
    Просто в одной статье сказанули, что там и полный путь хранится, а я и поверил...
    СПАСИБО!!
     
  5. Adrax

    Adrax Алексей

    Публикаций:
    0
    Регистрация:
    14 окт 2006
    Сообщения:
    135
    Адрес:
    г. Курск
    Встречный вопрос про SHFileOperation: можно ли её вызвать из консольного приложения, заюзав хэндл стандартного вывода или просто NULL? Или под неё необходимо создавать окошко?
     
  6. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Лучше 0, чем STDOUT - это разные вещи.
     
  7. Adrax

    Adrax Алексей

    Публикаций:
    0
    Регистрация:
    14 окт 2006
    Сообщения:
    135
    Адрес:
    г. Курск
    2 Ice Student
    Знаю... Только ни с нулём, ни с stdout не работает... Неужели эту ф-цию нельзя вызвать из консоли?
     
  8. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    Adrax
    Ни что не мешает использовать SHFileOperation в консольном приложении.

    с stdout не работает
    Уж не в качестве ли SHFILEOPSTRUCT.hwnd ты указал хэндл стандартного вывода?
     
  9. Adrax

    Adrax Алексей

    Публикаций:
    0
    Регистрация:
    14 окт 2006
    Сообщения:
    135
    Адрес:
    г. Курск
    2 q_q
    И туда указывал...
    Что можно подсунуть в _SHFILEOPSTRUCT.hwnd для консольного приложения?
     
  10. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    Adrax
    И туда указывал...
    Зачем? Описание элементов структуры SHFILEOPSTRUCT в msdn/psdk читал?
    "hwnd - Window handle to the dialog box ...", или для тебя "window handle" и "handle to the specified device, or a redirected handle" не отличаются?

    Что можно подсунуть
    Либо дескриптор окна, либо NULL (0). Я делал так (синтаксис masm):
    Код (Text):
    1. ...
    2.     local fo:SHFILEOPSTRUCT
    3.  
    4.     invoke RtlZeroMemory, addr fo, sizeof fo
    5.     mov fo.wFunc, FO_DELETE
    6.     mov fo.pFrom, offset buff
    7.     mov fo.fFlags, FOF_ALLOWUNDO or FOF_FILESONLY or FOF_NOCONFIRMATION or FOF_SILENT
    8.     invoke SHFileOperation, addr fo
    9. ...
     
  11. Adrax

    Adrax Алексей

    Публикаций:
    0
    Регистрация:
    14 окт 2006
    Сообщения:
    135
    Адрес:
    г. Курск
    2 q_q
    Хэндл окна от хэндла устройства я ещё отличаю... Просто пытался с NULL'ом - не заработало, возможно, где-то ещё косяк...
    Раз у тебя пашет, значит, надо поискать ошибки в моей реализации