Странности WriteFile

Тема в разделе "WASM.WIN32", создана пользователем steelfactor, 1 дек 2011.

  1. steelfactor

    steelfactor New Member

    Публикаций:
    0
    Регистрация:
    26 апр 2007
    Сообщения:
    501
    Есть простейший код, который пишет в файл поксоренный буфер
    Код (Text):
    1. if ( handle != INVALID_HANDLE_VALUE )
    2.     {
    3.                 DWORD unused;
    4.         SIZE_T toWrite = strlen( Buffer );
    5.         VOID * tmp = (VOID *)memalloc(toWrite+1);
    6.         memcpy(tmp, Buffer, toWrite);
    7.         toWrite = encodeXor((LPSTR)tmp, toWrite);
    8.         if (toWrite != 0 )
    9.         {
    10.             WriteFile(handle, tmp, toWrite, &unused, 0);
    11.             memfree(tmp);
    12.         }
    13.         CloseHandle( handle );
    14.     }
    Сам файл создается без проблем, буфер нормально ксорится, но на записи буфера в файл начинаются непонятки.
    По непонятной для меня причине записи в файл не происходит, хотя если заменить переменную "DWORD unused" на "LPDWORD unused" буфер в файл успеет записаться, однако тут же вылетит kernel32!WriteFile с ошибкой Access Violation.
    Ради эксперимента попробовал использовать fopen/fputs - результат тот же самый, записи не нет
    Я себе весь моск уже сломал...
     
  2. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Проблема точно не с WriteFile. Возможно длину передаёте неверную. Также хороший тон это проверять возвращаемое значение WriteFile.
     
  3. steelfactor

    steelfactor New Member

    Публикаций:
    0
    Регистрация:
    26 апр 2007
    Сообщения:
    501
    Unused обнулял, заменял просто на 0 - толку нет.
    Контекст:
    Код вызывается на старте сервиса Windows - к svchost подгружается моя сервисная dll, в ServiceMain создается отдельный поток, где вызывается ряд функций. Все эти функции отрабатывают нормально, за исключением того кода, что я показал.
    Этот же самый код, вызванный просто для теста из _tmain какого-то постороннего проекта нормально работает.
     
  4. steelfactor

    steelfactor New Member

    Публикаций:
    0
    Регистрация:
    26 апр 2007
    Сообщения:
    501
    Сейчас проверил - WriteFile вызывается, возвращает TRUE, unused нулю не равна, но записи нет.
    Пойду застрелюсь нахрен...
     
  5. TSS

    TSS New Member

    Публикаций:
    0
    Регистрация:
    13 апр 2009
    Сообщения:
    494
    Нативный аналог данной ф-ции решит проблему скорее всего.
     
  6. steelfactor

    steelfactor New Member

    Публикаций:
    0
    Регистрация:
    26 апр 2007
    Сообщения:
    501
    Попробую..
     
  7. steelfactor

    steelfactor New Member

    Публикаций:
    0
    Регистрация:
    26 апр 2007
    Сообщения:
    501
    Использование Nt*-функции, а также обращение напрямую к int 0x2e шлюзу не помогло.
    Причина такого поведения так и осталась непонятой.
    Проблема была решена путем переноса функции в другую часть модуля, правильно это или нет, хз
    Было:
    Код (Text):
    1. __declspec(dllexport) void ServiceMain(void)
    2. {
    3.     ULONG unused = 0;
    4.     HANDLE mainThreadHandle = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&ServiceInit, NULL, 0, &unused);  
    5. }
    6. void ServiceInit(void)
    7. {
    8.         StartServiceCtrlDispatcher(DispatchTable);      // blocking call
    9.     InitMainModules();
    10. }
    11. VOID InitMainModules()
    12. {
    13.         Func1();
    14.         Func2();
    15.         SaveOptions();// <-------
    16. }
    Стало:
    Код (Text):
    1. __declspec(dllexport) void ServiceMain(void)
    2. {
    3.     ULONG unused = 0;
    4.         SaveOptions();// <-------
    5.     HANDLE mainThreadHandle = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&ServiceInit, NULL, 0, &unused);  
    6. }
    7. void ServiceInit(void)
    8. {
    9.         StartServiceCtrlDispatcher(DispatchTable);
    10. }
    11. VOID InitMainModules()
    12. {
    13.         Func1();
    14.         Func2();
    15. }
     
  8. AsmGuru62

    AsmGuru62 Member

    Публикаций:
    0
    Регистрация:
    12 сен 2002
    Сообщения:
    689
    Адрес:
    Toronto
    1. Вообще-то LPTHREAD_START_ROUTINE принимает один параметр и стек там может нарушаться.
    2. Если encodeXor использует какие-либо строковые функции - tmp не заканчивается нулём.
    3. Если toWrite=0, то память не освободится.
     
  9. steelfactor

    steelfactor New Member

    Публикаций:
    0
    Регистрация:
    26 апр 2007
    Сообщения:
    501
    А AsmGuru62 в первом пункте прав оказался, ServiceInit в моем случае должна выглядеть как static VOID ServiceInit(LPVOID param), тогда все работает нормально.
    Проглядел, каюсь :)
    AsmGuru62, спасибо!