Конференция "WinAPI" » kernel-mode и потоко-безопасный лог.
 
  • Riply © (22.09.08 09:53) [0]
    Здравствуйте !
    Т.к. мое IMHO, что любое серьезное дело надо начинать с организации ведения лога, :)
    приступила к изучению сабжевой темы.

    Пожелания к нашему логу:
    1. Потоко-безопасен.
    2. При IRQL = PASSIVE_LEVEL ведет запись в файл ( ZwWriteFile )
      и отправляет Dbg-сообщение ( DbgPrint )
    3. При PASSIVE_LEVEL < IRQL <= DISPATCH_LEVEL только отправляет Dbg-сообщение.
    4. В обоих случаях (DbgPrint и ZwWriteFile) , для формирования сообщения
      используется заранее выделенная (при загрузке драйвера) память.
     
    Подскажите, пожалуйста, какие объекты синхронизации лучше использовать
    при данных требованиях и (главное) почему ?

    Посмотрела различные варианты, но так и не смогла выбрать нужный :(
    А может не смогла понять из их описания, как с ними надо работать.
    (Offtop: и когда же у нас появиться раздел "WinApi для начинающих" ?
    ибо у меня ощущение, что я запуталась в основах )

    Вот что меня смущает:

    KEVENT:
    Для его ожидания надо использовать KeWaitForXxx.
    А в MSDN сказано:
    "Callers of KeWaitForSingleObject must be running at IRQL <= DISPATCH_LEVEL.
    However, if Timeout <> 0, the caller must be running at IRQL <= APC_LEVEL and in a nonarbitrary thread context."
    Соответсвенно, он не очень нам подходит.

    KMUTEX:
    аналогичные возражения, кроме того MSDN рекомендует вместо них использовать FAST_MUTEX

    FAST_MUTEX:
    С ним, я совсем запуталась.
    Функции типа ExAcquireFastMutexUnsafe требуют строгого(?) равенства IRQL = APC_LEVEL
    А, если использовать ExAcquireFastMutex, то они нас автоматически
    переведут из PASSIVE_LEVEL в APC_LEVEL.
    Получается, что при их использовании, нам в принципе невозможно вызывать ZwWriteFile
    т.к. она работает только в PASSIVE_LEVEL ?

    KSPIN_LOSK:
    Вообще страшная штука :)
    Мало того, что нас перебрасывают в DISPATCH_LEVEL,
    да еще Солдатов пишет, что "не рекомендуется удерживать объект спин-блокировки более 25 микросекунд"
    Шарахаемся от них как от огня :)

    ERESOURCE:
    Вот, вроде то, что мы так долго искали.
    Как я поняла:
    1. они никуда нас не перебрасывают
    2. имеют богатый набор функций для управления, из которых только функции типа
      ExAcquireResourceExclusiveLite требуют IRQL <= APC_LEVEL, остальные же IRQL <= DISPATCH_LEVEL.
    3. Да и вообще MSDN на все лады распевает, какие они прекрасные и производительные :)

    Но, как всегда впрочем, мне кажется что "что-то здесь не то".
    Например, Солдатов про них пишет:
    "что исключительный доступ к данным, охраняемым объектом типа ERESOURCE,
    реализуется через механизм спин-блокировок."

    Т.е. они (такие вкусные) работают на том, от чего мы бежали как черт от ладана ?
    Почему же их использование не несет тех же ограничений, что и KSPIN_LOSK ?
  • Городской Шаман (22.09.08 14:10) [1]
    А разве NtCreateFile не будет работать при уровне IRQL APC или DPC?
  • Riply © (22.09.08 14:39) [2]
    > [1] Городской Шаман   (22.09.08 14:10)
    > А разве NtCreateFile не будет работать при уровне IRQL APC или DPC?

    Вообще-то CreateFile меня не очень интересует (создали и забыли :), мне нужна ZwWriteFile.
    А про нее в MSDN написано:
    "Callers of ZwWriteFile must be running at IRQL = PASSIVE_LEVEL and with APCs enabled."
  • Городской Шаман (22.09.08 16:22) [3]
    Ну есть NTWriteFile. Вот её заголовки(те же самые как у ZwWriteFile)

    function  NtWriteFile(
       FileHandle : HANDLE;
       Event : HANDLE;
       ApcRoutine : PIO_APC_ROUTINE;
       ApcContext : PVOID;
       IoStatusBlock : PIO_STATUS_BLOCK;
       Buffer : PVOID;
       Length : ULONG;
       ByteOffset : PLARGE_INTEGER;
       Key : PULONG
     ): NTSTATUS; stdcall;

    NTWriteFile вообще-то должна работать при иных IRQL от Passive Level. Хотя не проверял.
  • Игорь Шевченко © (22.09.08 16:28) [4]

    > NTWriteFile вообще-то должна работать при иных IRQL от Passive
    > Level. Хотя не проверял.


    Не должна. Результатом будет любимая надпись IRQL IS NOT LESS OR EQUAL

    Автору: От всех ошибок спасает Driver Verifier, а вообще методика таких логов очень хорошо описана в исходниках filemon, regmon и иных изделиях Руссиновича и Когсуэлла.
  • Городской Шаман (22.09.08 16:32) [5]
    Ну драйвер filemon вообще никаких логов не ведет, он просто запоминает лог в буфере и приложение два раза в секунду опрашивает драйвер на предмет наличия данных в буффере.
  • Thomas Anders (26.09.08 00:34) [6]

    > kernel-mode и потоко-безопасный лог

    Как альтернативный вариант ведению логов записью в файл, можно воспользоваться записью в системный журнал ошибок. Позднее созданную запись можно просмотреть в Event Viewer. Ваша задача как разработчика драйвера - создать подходящие пакеты регистрации ошибок при возникновении события, заслуживающего внимания. См. в DDK функции IoWriteErrorLogEntry, IoAllocateErrorLogEntry.
  • Riply © (26.09.08 06:53) [7]
    >[6] Thomas Anders   (26.09.08 00:34)
    >Как альтернативный вариант ведению логов записью в файл, можно воспользоваться записью в системный журнал ошибок.

    Спасибо.
  • Игорь Шевченко © (26.09.08 10:48) [8]

    > Как альтернативный вариант ведению логов записью в файл,
    >  можно воспользоваться записью в системный журнал ошибок


    Давить таких писателей. Давить всех, кто пишет в eventlog всякий неинтересный мусор
  • Rouse_ © (26.09.08 11:01) [9]

    > Давить всех, кто пишет в eventlog всякий неинтересный мусор

    Перечислите параметры "интересного мусора" плз, аж интересно стало :)
    Да и кстати. в чем проблема то? Заводим собственный журнал, чтоб Application или System не замусоривать и резвимся там вовсю :)
  • Riply © (26.09.08 11:16) [10]
    > [9] Rouse_ ©   (26.09.08 11:01)
    > Перечислите параметры "интересного мусора" плз, аж интересно стало :)

    Саш, ты не читал лога моего драйвера :)
    Он выглядит примерно так:
    .......
    "тут я пытаюсь создать символьную ссылку"
    "тут я успешно создал эту символьную ссылку"
    "ой ! а тут у меня вызвали такую-то процедуру"
    .....
    и т.д. и т.п. И такие сообщения идут на каждый его чих :)
  • Rouse_ © (26.09.08 11:25) [11]

    > И такие сообщения идут на каждый его чих :)

    В режиме отладки сообщений много не бывает :)
  • Игорь Шевченко © (26.09.08 12:58) [12]

    > Перечислите параметры "интересного мусора" плз, аж интересно
    > стало


    ошибки, предупреждения, все, что требует внимания пользователя.
    а когда оно замусоривается сообщения от SQL Server в какой операционной системе это чудо работает, то давить однозначно писателей.
  • Игорь Шевченко © (26.09.08 12:58) [13]
    Учитесь у Руссиновича - он плохому не научит
  • Rouse_ © (26.09.08 13:10) [14]

    > а когда оно замусоривается сообщения от SQL Server в какой
    > операционной системе это чудо работает, то давить однозначно
    > писателей.

    Если завести свой отладочный лог, как я собственно и сказал, то не вижу никаких сложностей, ничто не будет замусориваться акромя самой отдельной
    мусорки :)


    > Учитесь у Руссиновича - он плохому не научит

    Его и курим периодически ;)
  • Thomas Anders (27.09.08 01:46) [15]

    > Давить таких писателей. Давить всех, кто пишет в eventlog
    > всякий неинтересный мусор


    Есть драйвер дискового устройства, который обнаруживает, что физическая поверхность диска содержит неожиданно большое количество поврежденных секторов или драйвер обнаруживает неожиданно частые ошибки данных или испытывает трудности с настройкой конфигурации
    или запуском устройства (и Driver Verifier не поможет). И куда с такими ошибками? Можно еще, кстати, воспользоваться для обозначения непредвиденных ошибок, установкой события WMI (тоже давить?).
    Просить пользователя запустить DebugView? Мусорить файлами логов на диске? И зачем разработчику эти логи, если проблема не в драйвере а в железе (и об этом можно сразу сообщить пользователю)?


    > Учитесь у Руссиновича - он плохому не научит


    Необходимости в отладочных сообщениях и логах у меня уже давно нет, с тех пор как я научился внимательно читать DDK и пользоваться головой, а не Руссиновичем (извините за резкость).


    > FAST_MUTEX:
    > С ним, я совсем запуталась.


    Функция ExAcquireFastMutex - ожидает освобождения мьютекса, назначает его владельцем поток, от которого поступил вызов, а затем повышает текущий уровень IRQL процессора до APC_LEVEL, ExAcquireFastMutexUnsafe - уровня IRQL не изменяет.


    > Подскажите, пожалуйста, какие объекты синхронизации лучше
    > использовать
    > при данных требованиях и (главное) почему ?


    Для работы с файлами посредством функций ZWxx выполнение должно происходить на уровне PASSIVE_LEVEL в потоке, который может быть безопасно приостановлен. На практике последнее требование означает, что не должны запрещаться вызовы APC. Некоторые примитивы синхронизации (подробности в DDK) требуют повышения уровня IRQL выше уровня PASSIVE_LEVEL или запрета APC. Просто нужно запомнить, что эти примитивы синхронизации и операции с файлами несовместимы, вот и все.
  • Игорь Шевченко © (27.09.08 14:39) [16]

    > Есть драйвер дискового устройства, который обнаруживает,
    >  что физическая поверхность диска содержит неожиданно большое
    > количество поврежденных секторов или драйвер обнаруживает
    > неожиданно частые ошибки данных


    Собственно об этом он честно пишет в EventLog. Но при этом не рассказывает долго и интересно, каким именно образом и в каком именно из 1023 возможных мест он нашел эту ошибку и какие при этом были значения в регистрах, в стеке и в первых 20 мегабайтах виртуального адресного пространства текущего процесса.
  • Thomas Anders (27.09.08 23:39) [17]

    > Но при этом не рассказывает долго и интересно, каким именно
    > образом и в каком именно из 1023 возможных мест он нашел
    > эту ошибку и какие при этом были значения


    Во как! Прочитал я эти строки, и у меня глаза на лоб полезли. Такой неприкрытой софистики я уже давно не встречал. Где я об этом утверждал? И потом, никто разработчика и не обязывает все это записывать в журнал, да это зачастую, исходя из здравого смысла и не требуется. Достаточно известить пользователя, что у него проблемы. О чем я уже и говорил. Кому хочется приключений, ради бога (можно логи в файлы записать, или еще что-нибудь интересное сделать, никто Вас ничем не ограничивает). Но гораздо удобнее создать исходный файл сообщений, потом обработать его в mc.exe, включить все что он сгенерировал в сборку и иметь дистрибутив с файлами сообщений на различных локальных языках, который конечный пользователь может установить обычным inf-ом.
  • Игорь Шевченко © (28.09.08 01:07) [18]
    Thomas Anders   (27.09.08 23:39) [17]


    > Такой неприкрытой софистики я уже давно не встречал. Где
    > я об этом утверждал?


    Я где-то сказал, что ты это утверждаешь ?

    Я свое мнение высказал в постах [8] и [12], на сем дискуссию считаю завершенной.
  • Германн © (28.09.08 01:26) [19]

    > Rouse_ ©   (26.09.08 11:01) [9]
    >
    > ... Заводим собственный журнал,
    >  чтоб Application или System не замусоривать и резвимся
    > там вовсю

    +1

    > Rouse_ ©   (26.09.08 11:25) [11]
    >
    >
    > > И такие сообщения идут на каждый его чих :)
    >
    > В режиме отладки сообщений много не бывает :)
    >

    +2 :)
    А в режиме постоянной после продажи работы и не нужно в EventLog особо что-то писАть. Лучше составить подробный отчёт об ошибке и предложить переслать его авторам программы.

    <offtop>
    P.S. FF выучил наконец букву Ё! И даже подчеркнул ошибку в слове отчет! Я в шоке!
    </offtop>
  • Городской Шаман (28.09.08 06:31) [20]

    > +2 :)
    > А в режиме постоянной после продажи работы и не нужно в
    > EventLog особо что-то писАть. Лучше составить подробный
    > отчёт об ошибке и предложить переслать его авторам программы.



    Из режима ядра переслать? Для этого требуется чтобы в user-mode работал хоть один подконтрольный драйверу процесс. А не всем драйверам требуется режим пользователя для работы. Точнее даже очень малому числу драйверов требуется приложение в пользовательском режиме для интерактивного взаимодействия.
  • Riply © (28.09.08 16:02) [21]
    Т.к. я не исключаю варианта, что вместо посылания на 17-ю строчку,
    меня могут послать на 18-ю или даже 19-ю, :) спрашиваю:

    Попробовала перезагрузить компьютер при работающем драйвере.
    Перезагрузка прошла как обычно и никто ни на что не ругался.
    Но в логе драйвера я не нашла сообщений о его выгрузке.
    Он у меня в DriverUnload после освобождения каждого объекта
    записывает: "освободил того-то и того-то". А здесь пусто.
    Даже нет записи о вхождении в процедуру DriverUnload (это сообщение идет первым, до любых действий).
    (Лог ведется при помощи ZwWriteFile).
    Подскажите, пожалуйста, в чем может быть дело и на что стоит обратить внимание ?
  • Игорь Шевченко © (28.09.08 21:03) [22]
    Riply ©   (28.09.08 16:02) [21]

    А он должен выгружаться ?
  • Riply © (28.09.08 21:28) [23]
    > [22] Игорь Шевченко ©   (28.09.08 21:03)
    > А он должен выгружаться ?

    Игорь, а как это не выгружаться ?
    Ведь система рестартует... Разве она не перезагружает все (в т.ч. и драйвер) заново ?
  • Городской Шаман (28.09.08 22:24) [24]

    > Riply ©   (28.09.08 21:28) [23]


    При рестарте срабатывает обработчик shutdown а не Unload.

    Попробуйте этот код (нужно будет подправить)

    {*******************************************************************************
     uDriverLoader
     Автор:

     Модуль управления установкой и запуском драйвера
    *******************************************************************************}

    unit uDriverLoader;

    {******************************************************************************}
    interface
    {******************************************************************************}

    uses
     Windows, Messages, SysUtils, Variants, Classes, WinSvc, uLogger;

    {-------------------------------------------------------------------------------
    -------------------------------------------------------------------------------}


    function InstallDriver(scm: SC_HANDLE; const DriverName: WideString; const DriverExec: WideString): Boolean; overload;
    function RemoveDriver(scm: SC_HANDLE; const DriverName: WideString): Boolean;
    function StartDriver(scm: SC_HANDLE; const DriverName: WideString): Boolean;
    function StopDriver(scm: SC_HANDLE; const DriverName: WideString): Boolean;

    {******************************************************************************}
    implementation
    {******************************************************************************}

    function InstallDriver(scm: SC_HANDLE; const DriverName: WideString; const DriverExec: WideString): Boolean;
    var
     lService: SC_HANDLE;
     lErr: DWORD;
    begin
     //инициализация, проверки
     result := False;
     if (scm = 0) or (Length(DriverName) = 0) or (Length(DriverExec) = 0) then Exit;
     //создание сервиса/драйвера
     lService := CreateServiceW(
       scm,
       PWideChar(DriverName),
       PWideChar(DriverName),
       SERVICE_ALL_ACCESS,
       SERVICE_KERNEL_DRIVER,
       SERVICE_DEMAND_START,
       SERVICE_ERROR_NORMAL,
       PWideChar(DriverExec),
       nil, nil, nil, nil, nil);

     //проверка на ошибку
     if lService = 0 then
       begin
         lErr := GetLastError;
         if lErr = ERROR_SERVICE_EXISTS then Result := True;
         //Logger.DebugLog('uDriverLoader', 'InstallDriver', 'Error '+IntToStr(lErr));

         Exit;
       end;

     //закрываем указатель
     CloseServiceHandle(lService);
     Result := True;
    end;

    function RemoveDriver(scm: SC_HANDLE; const DriverName: WideString): Boolean;
    var
     lService: SC_HANDLE;
    begin
     //инициализация, проверки
     result := False;
     if (scm = 0) or (Length(DriverName) = 0) then Exit;

     //получение объекта драйвера
     lService := OpenServiceW(scm, PWideChar(DriverName), SERVICE_ALL_ACCESS);
     if lService <> 0 then
       begin
         Result := DeleteService(lService);
         if not Result then
           CloseServiceHandle(lService);
       end;
    end;

    function StartDriver(scm: SC_HANDLE; const DriverName: WideString): Boolean;
    var
     lService: SC_HANDLE;
     lErr: DWORD;
     lServiceArgs: PWideChar;
    begin
     //инициализация, проверки
     result := False;
     if (scm = 0) or (Length(DriverName) = 0) then Exit;

     //получение объекта драйвера
     lService := OpenServiceW(scm, PWideChar(DriverName), SERVICE_ALL_ACCESS);
     if lService <> 0 then
       begin
         lServiceArgs := '';
         Result := StartServiceW(lService, 0, lServiceArgs);
         //ошибка может быть еще потому что драйвер уже запущен
         if not Result then
           begin
             lErr := GetLastError;
             if lErr = ERROR_SERVICE_ALREADY_RUNNING then
               Result := True;
           end;
         //закрываем сервис
         CloseServiceHandle(lService);
       end;
    end;

    function StopDriver(scm: SC_HANDLE; const DriverName: WideString): Boolean;
    var
     lService: SC_HANDLE;
     lServiceStatus: TServiceStatus;
    begin
     //инициализация, проверки
     result := False;
     if (scm = 0) or (Length(DriverName) = 0) then Exit;

     //получение объекта драйвера
     lService := OpenServiceW(scm, PWideChar(DriverName), SERVICE_ALL_ACCESS);
     if lService <> 0 then
       begin
         Result := ControlService(lService, SERVICE_CONTROL_STOP, lServiceStatus);
         //закрываем сервис
         CloseServiceHandle(lService);
       end;
    end;

    end.

  • Городской Шаман (28.09.08 22:26) [25]
    Использовать так:


    unit uMainForm;

    interface

    uses
     Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
     Dialogs, StdCtrls, WinSvc, uDriverLoader, TntSysUtils;

    const
     DriverName = 'vsdriver.sys';

    type
     TForm1 = class(TForm)
       InstallDriverButton: TButton;
       RemoveDriverButton: TButton;
       StartDriverButton: TButton;
       StopDriverButton: TButton;
       procedure InstallDriverButtonClick(Sender: TObject);
       procedure RemoveDriverButtonClick(Sender: TObject);
       procedure StartDriverButtonClick(Sender: TObject);
       procedure StopDriverButtonClick(Sender: TObject);
     private
       { Private declarations }
     public
       { Public declarations }
     end;

    var
     Form1: TForm1;

    implementation

    {$R *.dfm}

    procedure TForm1.InstallDriverButtonClick(Sender: TObject);
    var
     scm: SC_HANDLE;
     lAppPath: WideString;
     lRes: Boolean;
    begin
     lAppPath := WideIncludeTrailingPathDelimiter(WideExtractFilePath(Application.ExeName));

     scm := OpenSCManagerW(nil, nil, SC_MANAGER_ALL_ACCESS);
     if scm <> 0 then
       begin
         lRes := InstallDriver(scm, DriverName, lAppPath + DriverName);
         Caption := FormatDateTime('hh:nn:ss.zzz', now) + ' install driver = ' + BoolToStr(lRes, True);

         CloseServiceHandle(scm);
       end;
    end;

    procedure TForm1.RemoveDriverButtonClick(Sender: TObject);
    var
     scm: SC_HANDLE;
     lRes: Boolean;
    begin
     scm := OpenSCManagerW(nil, nil, SC_MANAGER_ALL_ACCESS);
     if scm <> 0 then
       begin
         lRes := RemoveDriver(scm, DriverName);
         Caption := FormatDateTime('hh:nn:ss.zzz', now) + ' remove driver = ' + BoolToStr(lRes, True);

         CloseServiceHandle(scm);
       end;
    end;

    procedure TForm1.StartDriverButtonClick(Sender: TObject);
    var
     scm: SC_HANDLE;
     lRes: Boolean;
    begin
     scm := OpenSCManagerW(nil, nil, SC_MANAGER_ALL_ACCESS);
     if scm <> 0 then
       begin
         lRes := StartDriver(scm, DriverName);
         Caption := FormatDateTime('hh:nn:ss.zzz', now) + ' start driver = ' + BoolToStr(lRes, True);

         CloseServiceHandle(scm);
       end;
    end;

    procedure TForm1.StopDriverButtonClick(Sender: TObject);
    var
     scm: SC_HANDLE;
     lRes: Boolean;
    begin
     scm := OpenSCManagerW(nil, nil, SC_MANAGER_ALL_ACCESS);
     if scm <> 0 then
       begin
         lRes := StopDriver(scm, DriverName);
         Caption := FormatDateTime('hh:nn:ss.zzz', now) + ' stop driver = ' + BoolToStr(lRes, True);

         CloseServiceHandle(scm);
       end;
    end;

    end.

  • Riply © (28.09.08 23:19) [26]
    > [24] Городской Шаман   (28.09.08 22:24)
    > Попробуйте этот код (нужно будет подправить)

    Возможно, я неверно выразилась.
    При управлении драйвером через SCM у меня все работает как надо и никаких нареканий нет.
    При команде SERVICE_CONTROL_STOP процедура Unload отрабатывает и лог пишется.

    Нет отработки Unload при рестарте компьютера
    (или по каким-то причинам не идет запись в лог).
  • Городской Шаман (28.09.08 23:22) [27]

    > Riply ©   (28.09.08 23:19) [26]
    >
    > > [24] Городской Шаман   (28.09.08 22:24)
    > > Попробуйте этот код (нужно будет подправить)
    >
    > Возможно, я неверно выразилась.
    > При управлении драйвером через SCM у меня все работает как
    > надо и никаких нареканий нет.
    > При команде SERVICE_CONTROL_STOP процедура Unload отрабатывает
    > и лог пишется.
    >
    > Нет отработки Unload при рестарте компьютера
    > (или по каким-то причинам не идет запись в лог).


    При рестарте компьютера Unload не вызывается, вызывается Shutdown. Ну не поленитесь - пробегите глазами Солдатова.
  • Игорь Шевченко © (29.09.08 01:58) [28]

    > Нет отработки Unload при рестарте компьютера


    А должна быть ?
  • Riply © (29.09.08 08:57) [29]
    > [27] Городской Шаман (28.09.08 23:22)
    > При рестарте компьютера Unload не вызывается, вызывается Shutdown.

    > [28] Игорь Шевченко © (29.09.08 01:58)
    >> Нет отработки Unload при рестарте компьютера
    > А должна быть ?

    Вы абсолютно правы: и не должна отрабатывать.
    Попробовала использовать IoRegisterShutdownNotification - вроде получилось...
    Но... все это меня очень смущает.
    Во-первых, MSDN гласит:
    "If the driver ceases to require shutdown notification for the device,
    use IoUnregisterShutdownNotification to remove the driver from the shutdown notification queue"
    Где же предполагается вызов IoUnregisterShutdownNotification для убирания нашего драйвера из очереди ?
    Внутри ShutdownDispatch - не серьезно, DriverUnload - может быть не вызвана.
    Ну с ней-то (UnregisterShutdown) ладно - разберемся.
    А как же объекты, которые я насоздавала и память, которую заняла ?
    Кто их должен освобождать в случае рестарта ? Если мы - то где ?
    Ответ типа: "незачем это делать, ибо все равно система закрывается",
    на данном этапе меня не очень устраивает.
    А вдруг она передумает закрываться, или в процессе закрытия ей понадобится память
    для какой-то супер-пупер важной работы ?

    P.S.
    И вообще, мне с пеленок вбили в голову:
    "что-то взяла у системы - изволь отдать, причем собственнолапно" :)
    А то, что у нас (у меня) получается (неубирание за собой) не лезет ну ни в какие ворота :)
  • Игорь Шевченко © (29.09.08 11:29) [30]

    > А как же объекты, которые я насоздавала и память, которую
    > заняла ?


    А кому они при рестарте интересны ? К моменту удаления драйверов система уже не передумает закрываться. В книжке Руссиновича и Соломона процесс завершения работы подробно описан, что когда завершается. Устройства, возможно, надо остановить каким-то образом, для этого и регистрируется соответствующий обработчик, а память - а кому она нафиг может потребоваться ?
    Проще надо быть.
    Когда убивается процесс, мало кого интересует, как зарегистрировать обработчик на этот случай, чтобы за собой прибрать ресурсы - тут мы доверяем системе, что она уберет все. В случае драйвера и рестарта все тоже самое.
  • Riply © (29.09.08 11:45) [31]
    > [30] Игорь Шевченко ©   (29.09.08 11:29)
    > а память - а кому она нафиг может потребоваться ?

    Ну не знаю.
    Например, когда Windows закачает какие-то обновления,
    то при выключении компьютера (после выхода из Widows)
    появляется примерно такая строчка: "инсталируется 6-е обновление из 10...".
    Для чего-нибудь подобного память может понадобиться ?

    > Проще надо быть.
    Хорошо. Оставлю как есть, но это, IMHO, очень некузяво :)
  • Игорь Шевченко © (29.09.08 12:27) [32]

    > появляется примерно такая строчка: "инсталируется 6-е обновление
    > из 10...".


    К этому моменту наверное НЕ ВСЕ драйверы выгружены, нес па ?
  • slow!alfamoon!com (30.09.08 18:27) [33]
    Какая память? Неподкачиваемую надо возвращать сразу после использования. Остальное почти пофиг
 
Конференция "WinAPI" » kernel-mode и потоко-безопасный лог.
Есть новые Нет новых   [134435   +33][b:0][p:0.005]