@Retr0Hacker

Как узнать возраст файла в Ассемблере?

Приветствую всех гениев цифровой эпохи

На повестке дня все все ещё вчерашняя задачка: "Используйте функцию GetOpenFileName для выбора файла. Проверить, если возраст файла не превышает 3 дней, выполните его. В противном случае вывести диалоговое окно с вопросом о удалении файла. Если пользователь пригодится, вытереть." (Внимание. Если в задании сказано использовать структуру, то она должна быть размещена в динамически выделенной памяти)"

С открытием файла я разобрался, и теперь все работает как Швейцарские часы. Но возникла другая неурядица.
Как определить возраст файла?

Вообще я изначально думал с помощью GetFileTime вытащить все данные про файловое время, затем с помощью FileTimeToLocalFileTime преобразовать его в локальное время, а с помощью FileTimeToSystemTime - в системное. Затем сделать вычитание одного от другого с помощь sub, и дальше как в условии задачи.

Вот для функции FileTimeToLocalFileTime нужна структура FILETIME в которой вот такие параметры:
DWORD dwLowDateTime; 
    DWORD dwHighDateTime;


А для функции FileTimeToSystemTime нужна структура SYSTEMTIME в которой вот такие параметры:
WORD wYear; 
    WORD wMonth; 
    WORD wDayOfWeek; 
    WORD wDay; 
    WORD wHour; 
    WORD wMinute; 
    WORD wSecond; 
    WORD wMilliseconds;


И вот как тогда быть? Как мне найти возраст файла? Есть ли какой-то альтернативный способ? А если и мой способ сойдет, то что именно и от чего нужно отнимать?

File.inc
include WINDOWS.inc

include user32.inc
include kernel32.inc
include comdlg32.inc

includelib user32.lib
includelib kernel32.lib
includelib comdlg32.lib

.data
	
	Time_title	db ' Лабораторная '№3,0
	format db 'Файлу больше 3 дней. Удалить его?', 0
	buf db 255 dup(0)	
	hFile dd 0
	readed dd 0
	hmem dd 0


File.asm
.386
.model flat,STDCALL
option casemap :none  ;case sensitive
include Third.inc
include RADbg.inc

Mem_Alloc PROC Buf_Size:DWORD
	add Buf_Size,4	
	invoke GlobalAlloc,GMEM_MOVEABLE or GMEM_ZEROINIT,Buf_Size
	push eax 
	invoke GlobalLock,eax 
	pop [eax]
	add eax,4
Mem_Alloc endp


Mem_Free PROC DATA:DWORD
	mov eax,DATA
	sub eax,4	
	mov eax,[eax] 	
	push eax		
	push eax
	call GlobalUnlock	
	call GlobalFree	
Mem_Free endp


.code
Begin:
	call main
	invoke ExitProcess,NULL
	
main proc
	LOCAL ftCreate, ftLocale: FILETIME;
	LOCAL stUTC, stLocal: SYSTEMTIME;
	
	invoke Mem_Alloc, 1000h
	mov hmem, eax
	invoke Mem_Alloc, sizeof OPENFILENAME
	mov edi, eax
	assume edi: ptr OPENFILENAME
	xor eax, eax
	mov [edi].lStructSize, sizeof OPENFILENAME
	mov [edi].lpstrFile, offset buf
	mov [edi].nMaxFile, 255
	invoke GetOpenFileName, edi
	invoke CreateFile, [edi].lpstrFile, GENERIC_READ,\
		FILE_SHARE_READ, NULL, OPEN_EXISTING,\
		FILE_ATTRIBUTE_NORMAL, NULL
	mov hFile,eax			;
	invoke GetFileTime, hFile, addr ftCreate, NULL, NULL
	invoke FileTimeToLocalFileTime, addr ftCreate, addr ftLocale
	invoke FileTimeToSystemTime, addr ftCreate, addr stUTC
	
	cmp eax, 1
	jz l1
	invoke ReadFile, hFile, hmem, 1000h, addr readed, 0
	invoke MessageBox, 0, hmem, addr Time_title, MB_OKCANCEL
	
	jmp l2

l1:
	invoke MessageBox, 0, addr format, addr Time_title, MB_OKCANCEL
	cmp eax, IDOK
	jne l2
	invoke DeleteFile, addr [edi].lpstrFile
	
l2:
	
	assume edi: dword
	invoke CloseHandle, hFile
	invoke Mem_Free, hmem
	invoke Mem_Free, edi
	
	ret

main endp	
end Begin
  • Вопрос задан
  • 191 просмотр
Пригласить эксперта
Ответы на вопрос 1
jcmvbkbc
@jcmvbkbc
http://dilbert.com/strip/1998-08-24
Как мне найти возраст файла?

Сравнить creationTime который возвращает GetFileTime с текущим временем которое возвращает GetSystemTimeAsFileTime. 3 дня -- это 3 * 24 * 60 * 60 * 10000000 100-наносекундных интервала (в таких единицах измеряется FILETIME).
Чтобы упростить себе задачу можно сравнивать только старшие части (dwHighDateTime) структур FILETIME, вес младшей части -- 429 секунд, меньше 10 минут.
Типа того:

invoke GetFileTime, hFile, addr ftCreate, NULL, NULL
  invoke GetSystemTimeAsFileTime, addr ftNow
  mov eax, ftNow.dwHighDateTime
  sub eax, ftCreate.dwHighDateTime
  cmp eax, (3 * 24 * 60 * 60 * 10000000 / 0x100000000)
  jg <файл старше 3 дней>
  /* иначе файл младше 3 дней */

Если упрощать не хочется и нужно отмерить в точности 3 дня, то хвост можно переписать так:
mov eax, ftNow.dwHighDateTime
  sub eax, ftCreate.dwHighDateTime
  cmp eax, (3 * 24 * 60 * 60 * 10000000 / 0x100000000)
  jg <файл старше 3 дней>
  jl <файл младще 3 дней>
  mov eax, ftNow.dwLowDateTime
  sub eax, ftCreate.dwLowDateTime
  cmp eax, (3 * 24 * 60 * 60 * 10000000 % 0x100000000)
  jg <файл старше 3 дней>  
  /* иначе файл младше 3 дней */
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы