Перевод секунд из FileHeader->DateTimeStamp в

Тема в разделе "WASM.BEGINNERS", создана пользователем Denis__, 22 дек 2006.

  1. Denis__

    Denis__ New Member

    Публикаций:
    0
    Регистрация:
    5 янв 2006
    Сообщения:
    56
    Открываю файл PETools,смотрю в FileHeader->DateTimeStamp - 422C240Ch,что PETools переводит как
    9:51:08 7 марта 2005г, а Windows показывает дату создания файла 1:51:06 7 марта 2005
    Написал свою програмку меня получается 13:51:08 5 марта 2005г.
    Посмотрите кто прав,интуитивно понимаю что не я :),посмотрите код что неправильно,может у кого нибудь есть другие идеи.
     
  2. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Если DateTimeStamp это число секунд с 0 часов 1 янв.1970-го, то правильный рез-т - первый
    На код взглянул, но ошибки искать как-то лень ;) Посему предлагаю свой вариантик
    Код (Text):
    1. proc DateTimeStampToSysTime dwTimeStamp, lpSystemTime
    2. smin  = 60;
    3. shour = smin*60;
    4. sday  = shour*24;
    5. syear = sday*365;
    6.     push ebx
    7.     push edi
    8.     push esi
    9.     mov  eax,[dwTimeStamp]
    10.     mov  esi,[lpSystemTime]
    11.     mov  ecx,syear
    12.     xor edx,edx
    13.     mov [esi+SYSTEMTIME.wDayOfWeek],dx
    14.     mov [esi+SYSTEMTIME.wMilliseconds],dx
    15.     div ecx      ;eax - полных лет по 365 дней, edx - остаток секунд
    16.     mov ebx,eax
    17.     mov edi,eax
    18.  
    19.     sub ebx,3
    20.     shr ebx,2
    21.     inc ebx      ;число добавляемых високосных дней
    22.  
    23.     mov eax,edx
    24.     xor edx,edx
    25.     mov ecx,sday
    26.     div ecx      ;eax - число дней сверх лет по 365 дней
    27.                  ;edx - остаток секунд
    28.     sub eax,ebx  ;вычитаем число високосных дней
    29.     sbb ebx,ebx  ;коррекция года в сл. перескока
    30.     add edi,ebx
    31.     lea ecx,[edi+1970]
    32.     mov [esi+SYSTEMTIME.wYear],cx
    33.     and ebx,365    ;коррекция дней в сл.перескока
    34.     add eax,ebx    ;число полных дней с начала года
    35.  
    36.     xor ebx,ebx
    37.     add edi,2
    38.     test edi,3
    39.     setz bl         ;год - високосный
    40.     shl ebx,2
    41.     add ebx,0EEFBB3h ;двухбитовые добавки к числу дней по месяцам отн.28
    42.     xor ecx,ecx     ;счетчик месяцев
    43. @@:
    44.     inc ecx
    45.     mov edi,ebx
    46.     and edi,3
    47.     shr ebx,2
    48.     add edi,28
    49.     sub eax,edi
    50.     jge @B
    51.     lea eax,[eax+edi+1]
    52.     mov [esi+SYSTEMTIME.wMonth],cx
    53.     mov [esi+SYSTEMTIME.wDay],ax
    54.  
    55.     mov eax,edx
    56.     xor edx,edx
    57.     mov ecx,shour
    58.     div ecx
    59.     mov [esi+SYSTEMTIME.wHour],ax
    60.  
    61.     mov eax,edx
    62.     xor edx,edx
    63.     mov ecx,smin
    64.     div ecx
    65.     mov [esi+SYSTEMTIME.wMinute],ax
    66.     mov [esi+SYSTEMTIME.wSecond],dx
    67.  
    68.     pop esi
    69.     pop edi
    70.     pop ebx
    71.     ret
    72. endp
    А еще проще конвертнуть время в FileTime и вызвать FileTimeToSystemTime ;))
    Код (Text):
    1. proc DateTimeStampToSysTime dwTimeStamp, lpSystemTime
    2.   sub esp,8
    3.   mov eax,[dwTimeStamp]
    4.   mov ecx,10000000
    5.   mul ecx
    6.   add eax,0D53E8000h
    7.   adc edx,019DB1DEh
    8.   mov [esp],eax
    9.   mov [esp+4],edx
    10.   mov eax,esp
    11.   invoke FileTimeToSystemTime, eax, [lpSystemTime]
    12.   add esp,8
    13.   ret
    14. endp
     
  3. Denis__

    Denis__ New Member

    Публикаций:
    0
    Регистрация:
    5 янв 2006
    Сообщения:
    56
    Leo tnx.

    С первым алгоритмом разобрался, а вот со вторым объясни, что обозначают константы: 10000000,0D53E8000h,019DB1DEh,0EEFBB3h

    И еще один интересный момент, компилю программу МОСКОВСКОЕ ВРЕМЯ 24 декабря 2006 г., 0:06:16
    FileHeader->DateTimeStamp = 458D9A48 = 1166907976
    Windows корректно отображает время, секунда в секунду.
    ReTools и lordpe 23 декабря 2006 г 21:06:16.
    Так что врут они на 3 часа. А на файлах созданных в 2004 разница еще больше.
    Кстати ReTools переводит секунды по твоему второму варианту, но я там с этими константами запутался.
    А lordpe вызывает функцию gmtime из библиотеки MSVCRT. :)
     
  4. khv_test

    khv_test New Member

    Публикаций:
    0
    Регистрация:
    30 июн 2004
    Сообщения:
    135
    0x19DB1DE 0xD53E8000 это 116444736000000000
    а это число 100 наносекундных интервалов между 1 Января , 1601 и первым явваря 1, 1970.

    т.к. The FILETIME structure is a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601.

    для того чтоб перевести в SYSTEMTIME надо
    long long ft=uTime*10000000.0+116444736000000000.0;

    остальное в аттаче в примере где показывается дата инсталяции винды..
     
  5. Denis__

    Denis__ New Member

    Публикаций:
    0
    Регистрация:
    5 янв 2006
    Сообщения:
    56
    Есть одна идея :).Плз. люди с Востока или с другого часового пояса кроме МОСКВЫ, приатачьте файл с компиленый вами.
    Не важно HelloWorld или еще что, напишите время создания файла и разницу времени с МОСКВОЙ.
     
  6. khv_test

    khv_test New Member

    Публикаций:
    0
    Регистрация:
    30 июн 2004
    Сообщения:
    135
    в моем архиве
    WindowsInstallDate.exe

    раельная дата как в зипе показывает а LordPE и PE Tools кажет 458E10DF в GMT 5:32:15
    разница у мня GMT+10 в москве GMT+3 на 7 часов разница..
    так что все ок :)
     
  7. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Denis__
    Чтобы не привязываться к часовым поясам и летнему\зимнему времени все даты записываются в GMT\UTC и GetSystemTime тоже выдает GMT. Для перевода GMT в местное время можно использовать ф-и FileTimeToLocalFileTime или GetTimeZoneInformation + SystemTimeToTzSpecificLocalTime. Подробности см. в msdn - многие вопросы отпадут сами собой ;)

    PS: насчет констант khv_test уже объяснил - множитель 10^7 это перевод из секунд в 0.1 мкс = 100 нс, а прибавляемая константа это смещение начала отсчета дат, получить ее легко - заполни структуру SystemTime для 00:00:00 1.01.1970 и вызови SystemTimeToFileTime
    Что касается 0EEFBB3h из первого варианта, то в двоичном виде это 111011101111101110110011b, где каждые два бита это разница между числом дней в месяце и 28, т.е. янв 31-28=3=11b, фев 28-28=0=00b, март 31-28=3=11b и т.д.
     
  8. Denis__

    Denis__ New Member

    Публикаций:
    0
    Регистрация:
    5 янв 2006
    Сообщения:
    56
    Всем спосибо за помощь.