Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > Каким образом можно приостановить загрузку ОС


Автор: Sleepman 30.8.2007, 09:11
Использую winlogon notification packeges. Создал dll, экспортирующую функцию, которая вызывается при событии Logon. Функция проверяет наличие в слоте смарт-карты, а также некоторые параметры в смарт-карте. Если параметры не верны, то вызываю LockWorkStation(), при этом станция блокируется, НО процесс загрузки продолжается. Например, если в автозагрузке стоит totalcommander, то он с успехом запустится. Вопрос: как предотвратить дальнейшую загрузку ОС, после вызова LockWorkStation().
    PS. Написать свою GINA - не предлагать.
    PPS. OC - Windows 2000/XP

Автор: NiJazz 30.8.2007, 09:55
Я не помню наверняка, можно ли получить описатель потока, созданного в чужом процессе. Но первое, что приходит на ум, это CreateToolhelp32Snapshot с флагом TH32CS_SNAPTHREAD. Далее, получив ThreadIDs, вызываем OpenThread и SuspendThread.

Автор: NiJazz 30.8.2007, 13:59
Вот примерчик на скорую руку:
Код

#include <windows.h>
#include <Tlhelp32.h>

int _tmain(int argc, _TCHAR* argv[])
{
    HANDLE snap = ::CreateToolhelp32Snapshot( TH32CS_SNAPALL, 0 );

    if ( INVALID_HANDLE_VALUE == snap )
        return ::GetLastError();

    __try
    {
        PROCESSENTRY32 entry = {0};

        entry.dwSize = sizeof entry;

        if ( !::Process32First( snap, &entry ) )
            return ::GetLastError();

        do
        {
            HANDLE snap_ = ::CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, entry.th32ProcessID );

            if ( INVALID_HANDLE_VALUE != snap_ )
            {
                THREADENTRY32 entry_ = {0};
                entry_.dwSize = sizeof entry_;

                if ( !!::Thread32First( snap_, &entry_ ) )
                {
                    do
                    {
                        HANDLE thread = ::OpenThread( THREAD_SUSPEND_RESUME, FALSE, entry_.th32ThreadID );
                        
                        if ( !!thread )
                        {
                            ::SuspendThread( thread );
                            ::CloseHandle( thread );
                        }
                    }
                    while ( !!::Thread32Next( snap_, &entry_ ) );
                }

                ::CloseHandle( snap_ );
            }
        }
        while ( !!::Process32Next( snap, &entry ) );
    }
    __finally
    {
        ::CloseHandle( snap );
    }    

    return 0;
}


Сразу несколько замечаний:
1. Нужна проверка на ошибки
2. Нужно проверять состояние каждого потока, если он спит, то потом его не будить.
3. Можно фильтровать процессы по именам их exe (свой, к примеру, трогать не стоит).
4. Обязательно будут проблемы с доступом (а ля access denied).

У себя запустил этот код, всё повисло, пришлось перезагрузку сделать. smile
Не забудь после разбудить усыплённые потоки.

Автор: Tectoder 1.9.2007, 09:54
SuspendThread это такая функция которую крайне нежелательно использовать для потоков, которые создавал не твой код. Чисто идеалогически.
Ну и кроме того, никто не гарантирует, что к тому моменту пока ты заморозишь все потоки у тебя не появяться новые потоки smile А тогда твоя функция не сделает того что должна

Автор: NiJazz 1.9.2007, 10:00
Да, могут родиться новые потоки. Можно попытаться отслеживать потоки каждого процесса в отдельности.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)