|
Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » C/C++ *Example* | "Продвинутое" отключение XP |
|
C/C++ *Example* | "Продвинутое" отключение XP
|
Старый параноик Сообщения: 2423 |
Профиль | Отправить PM | Цитировать Несколько вопросов обсуждались в разное время на форуме.
1. Как заставить ХР предупредить о подключенных соединениях при выключении машины; 2. Как прервать отключение машины, если что-то забыл сделать. Поскольку я сейчас чем-то подобным занимаюсь, набросал небольшую программку, предназначенную для отключения XP машин. Её можно использовать вместо стандарного Shutdown в меню Пуск. #ifndef UNICODE #define UNICODE #endif #include <stdio.h> #include <string.h> #include <stdarg.h> #include <windows.h> #include <winuser.h> #include <lm.h> // собранная информация о сессиях static wchar_t * pszSessions = NULL; // добавление очередной записи к хранилищу void save_session(const wchar_t * fmt, ...) { // размер очередной строки, ориентировочно ~100 байт int size = 100; // память под очередную строку wchar_t *p = (wchar_t *) malloc(size * sizeof(wchar_t)); // безопасность if (!p) return; p[0] = '\0'; // формируем строку va_list ap; while (1) { // попытаемся вместиться в уже выделенную память va_start(ap, fmt); // реальная длина новой строки int n = _vsnwprintf(p, size, fmt, ap); va_end(ap); // если влезли, ок if (n > -1 && n < size) break; // иначе - увеличиваем буфер под строку size *= 2; if ((p = (wchar_t *) realloc(p, size * sizeof(wchar_t))) == NULL) return; //oops } // строку сформирована, надо её добавить к имеющимся size = lstrlen(p); if (pszSessions) size += lstrlen(pszSessions); wchar_t *pn = (wchar_t *)malloc((size + 1)*sizeof(wchar_t)); //eos if (!pn) return; pn[0] = '\0'; //складываем строки if (pszSessions) lstrcpy(pn, pszSessions); lstrcat(pn, p); free(p); free(pszSessions); pszSessions = pn; return; } //int main(int argc, wchar_t *argv[]) int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrev,LPSTR lpszCmd,int nCmd) { DWORD dwTotalCount = 0; NET_API_STATUS nStatus; // начальная фраза сообщения save_session(L"%s", L"Warning! Some sessions are not closed:\n\n"); // для всех имеющихся соединений do { LPSESSION_INFO_10 pBuf = NULL; DWORD dwEntriesRead = 0; DWORD dwTotalEntries = 0; DWORD dwResumeHandle = 0; // вызываем очередной NetSessionEnum nStatus = NetSessionEnum(NULL, //всё локально NULL, //для всех сессий NULL, //для всех пользователей 10, //тип запроса хост-юзер-время-простой (LPBYTE*)&pBuf, //данные на выходе MAX_PREFERRED_LENGTH, //длина записи &dwEntriesRead, //сколько считано &dwTotalEntries, //сколько всего &dwResumeHandle); //номер запроса // проверяем результат if ((nStatus == NERR_Success) || (nStatus == ERROR_MORE_DATA)) { // запоминаем сессии клиентов if (LPSESSION_INFO_10 pTmpBuf = pBuf) for (int i = 0; i < dwEntriesRead; i++) if (pTmpBuf) { save_session(L"Client: %s\tUser: %s\tActive: %d\tIdle: %d\n", pTmpBuf->sesi10_cname, pTmpBuf->sesi10_username, pTmpBuf->sesi10_time, pTmpBuf->sesi10_idle_time); pTmpBuf++; dwTotalCount++; } } // идём на следующий запрос if (pBuf) { NetApiBufferFree(pBuf); pBuf = NULL; } } while (nStatus == ERROR_MORE_DATA); // если есть сессии, сообщаем об этом выключателю if (dwTotalCount) { // финальная часть сообщения save_session(L"%s", L"\nDo you wish to cancel shutdown?\n"); // вывод сообщения if (IDYES == MessageBox(NULL, pszSessions, L"Warning!", MB_YESNO)) return 0; } //чистим память от сообщения - оно нам больше не нужно free(pszSessions); HANDLE hToken; // handle to process token TOKEN_PRIVILEGES tkp; // pointer to token structure // Get the current process token handle so we can get shutdown privilege. if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) return 1; // Get the LUID for shutdown privilege. LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid); tkp.PrivilegeCount = 1; // one privilege to set tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; // Get shutdown privilege for this process. AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0); if (GetLastError() != ERROR_SUCCESS) return 1; // Вывести окошечко обратного отсчёта if (!InitiateSystemShutdown( NULL, // shut down local computer L"We starts system shutdown.\nIf You have forget to do something, press " L"Ok in message box for stop shutdown.", // message for user 20, // time-out period FALSE, // ask user to close apps FALSE)) //shutdown, no reboot return 1; // Disable shutdown privilege. tkp.Privileges[0].Attributes = 0; AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0); MessageBox(NULL, L"Press OK to stop shutdown", L"Haves forget somehing?", MB_OK | MB_SYSTEMMODAL); // если мы сюда попали, надо отключать шатдаун if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) return 1; LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid); tkp.PrivilegeCount = 1; tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0); if (GetLastError() != ERROR_SUCCESS) return 1; // Prevent the system from shutting down. if ( !AbortSystemShutdown(NULL) ) return 1; // Disable shutdown privilege. tkp.Privileges[0].Attributes = 0; AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0); return 0; } Q. И как использовать? A. Компилите. Кладёте ярлык на рабочий стол. При необходимости выключить машину жмёте не Пуск->Выключить, а щёлкаете по этому ярлыку. Он Вас спросит про активные подключения (если они есть). Потом даст 20 секунд на раздумья. Потом выключится. Q. Почему C++, а не, скажем, VBS? A. Потому что C++ мне ближе. Q. Как компилить? A. Я использую Visual C++ Toolkit. Компиляция: cl enum_shares.cpp /GA /O1 /link /defaultlib:netapi32.lib /defaultlib:advapi32.lib /defaultlib:user32.lib Q. А в 9х будет работать? A. Нет. В 9х сообщение об активных подключениях и так выдается. Q. Почему UNICODE? A.Потому что NetSessionEnum Q. Что так странно (в смысле стиля написания) сформирован текст и комментарии? A. Потому что при написании использовались фрагменты из PSDK. Q. А есть ли бинарник? A. Есть. Тут пока лежит. Q. Можно использовать в моих программах куски текста? A. Да, сделано специально для посетителей www.oszone.net Q. У меня ещё вопросы... A. Задавайте здесь, я отвечу. |
|
Отправлено: 15:50, 28-06-2004 |
Старый параноик Сообщения: 2423
|
Профиль | Отправить PM | Цитировать Есть маленькая "учечка памяти". Чтобы убрать:
... // если есть сессии, сообщаем об этом выключателю if (dwTotalCount) { // финальная часть сообщения save_session(L"%s", L"\nDo you wish to cancel shutdown?\n"); // вывод сообщения if (IDYES == MessageBox(NULL, pszSessions, L"Warning!", MB_YESNO)) { return 0; free(pszSessions); // <--------- добавить. } } //чистим память от сообщения - оно нам больше не нужно free(pszSessions); ... |
Отправлено: 09:36, 29-06-2004 | #2 |
Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети. Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля. |
Старожил Сообщения: 185
|
Профиль | Отправить PM | Цитировать hasherfrog
Хорошая программа. Вопрос - как можно отслеживать все подключения (NetSessionEnum) и открытия файлов (NetFileEnum) для создания, скажем, своего журнала событий. Если вызывать эти функции по таймеру - есть вероятность, что какое-то подключение или открытие файла успеет открыться и закрыться. Возможно, нужно использовать механизм hook-ов, *можно ли сделать это без существенного снижения производительности системы? |
------- Отправлено: 21:13, 29-06-2004 | #3 |
Старый параноик Сообщения: 2423
|
Профиль | Отправить PM | Цитировать DAnG
Таймер однозначно "не катит". Хуки - это да . Снижение производительности будет очень незначительным. У Руссиновича на www.sysinternals.com есть исходник, правда, для линукса. Там же есть бинарники FileMon. Если залезть туда (через HIEW, или ещё как) и посмотреть таблицу используемых системных функций, то хуки наверняка найдутся. Впрочем, я не проверял, так что это только предположение! |
Отправлено: 09:02, 30-06-2004 | #4 |
Старый параноик Сообщения: 2423
|
Профиль | Отправить PM | Цитировать Некоторые замечания сделаны здесь.
|
|
Отправлено: 14:57, 30-06-2004 | #5 |
Старожил Сообщения: 185
|
Профиль | Отправить PM | Цитировать hasherfrog Кучу времени пользуюсь и tcpview и regmon и filemon, а на сайт авторов так и не заглянул. Позор. Очень много полезных вещей и с исходниками по windows, что редкость. Спасибо, огромное!. |
------- Отправлено: 03:53, 01-07-2004 | #6 |
Guest |
Для написания таких программ лучше использовать Visual Basic.
Добавлено: Кстати, кому надо, могу выложить исходник. Написал программку на VB, она умеет выключать/перезагружать комп, да ещё с такими наворотами (в смысле оформления)... Добавлено: И ещё, она может выключать/перезагружать комп в заданное время. |
Отправлено: 13:02, 15-08-2004 | #7 |
Линуксоид-стакановец Сообщения: 2391
|
Профиль | Отправить PM | Цитировать Guest
Для системного программирования, IMHO, лучше С++ ничего нет. VB для этого не разрабатывался [s]Исправлено: [mzd], 19:20 15-08-2004[/s] |
------- Отправлено: 19:18, 15-08-2004 | #8 |
Новый участник Сообщения: 4
|
Профиль | Сайт | Отправить PM | Цитировать Тема все еще акуальна а ссылки на скомпилиную прогу от hasherfrog уже мертвые
можно ли перезалить или на мыло stasisСОБАКАpisem.net сбросить? или кто перекомпилит поновой? |
------- Отправлено: 20:41, 12-09-2006 | #9 |
Старый параноик Сообщения: 2423
|
Профиль | Отправить PM | Цитировать Извиняюсь за задержку, в отпуске был.
http://hasherfrog.nm.ru/Trash/smrtdown.exe |
Отправлено: 11:35, 25-09-2006 | #10 |
Участник сейчас на форуме | Участник вне форума | Автор темы | Сообщение прикреплено |
| |||||
Название темы | Автор | Информация о форуме | Ответов | Последнее сообщение | |
7 / 2008 R2 - Отключение окна "Установить программное обеспечение для данного устройства" | SystemIntegrator | Автоматическая установка Windows 11 / 10 / 8 / 7 / Vista | 12 | 19-06-2024 14:36 | |
Интерфейс - [решено] Как удалить папку "Моя музыка","Мои Картинки", "Мое видео"? | verdix | Microsoft Windows 2000/XP | 3 | 03-10-2009 23:46 | |
Запретить/удалить пункт "Programs" ("Программы") из меню кнопки "Start" ("Пуск") | submaster | Microsoft Windows NT/2000/2003 | 5 | 13-09-2006 12:29 | |
Как убрать значек "безопасное отключение устройства" | Guest | Microsoft Windows 2000/XP | 6 | 24-03-2004 18:14 | |
[решено] Реестр - Отключение сообщения "Очистка диска" | bizart | Microsoft Windows 2000/XP | 1 | 13-02-2004 08:29 |
|