Установка системного времени Windows в стеке переполнения

У меня GPS-модуль подключен к COM-порту. Я хотел сделать свою систему сервером времени. Как это сделать?

Я пытался с помощью settime(), SetLocalTime(), SetSystemTime()и т.д. Никто не работает на меня. Используя system("cmd") Я пытался, но снова я не получаю привилегий администратора. Когда используешь system("runas cmd") командная строка открывается и закрывается как мигание. Невозможно понять, что происходит.

Как я могу сделать эту работу?

0

Решение

Управление привилегиями в Windows всегда сложная часть. MSoft предполагает, что нормальные смертные не должны заботиться об этом, и документация часто неполна.

Здесь у вас проблема, вероятно, в том, что обычные процессы (не работающие от имени администратора) не имеют права изменять системное время.

Но то, что возможно, это:

  • проверьте, предоставляется ли SeSystemtimePrivilege запущенному процессу
    • если это просто установить время
    • если нет, перезапустите процесс с тем же параметром, что и администратор, через ShellExectute, глагол ="runas"

Вот пример кода (часть для анализа строки времени и фактической установки времени не реализована):

#include <iostream>
#include <windows.h>
#include <tchar.h>

#ifdef UNICODE
#define tcout std::wcout
#else
#define tcout std::cout
#endif

// utility used to display error messages
void errmsg() {
DWORD err = ::GetLastError();
LPTSTR msg;
::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL,
err, LANG_NEUTRAL, (LPTSTR) &msg, 0, NULL);
tcout << _T("Error") << std::endl;
}

int _tmain(int argc, TCHAR *argv[]) {
// syntax check
if (argc != 2) {
tcout << _T("Usage ") << argv[0] << " _time_" << std::endl;
return 1;
}
LPCTSTR time = argv[1];
// get access to the current process token
HANDLE process = ::GetCurrentProcess();
HANDLE token;
if (! ::OpenProcessToken(process, TOKEN_ALL_ACCESS, &token)) {
errmsg();
return 1;
}
// get priviledges from current token
DWORD sz = 0, sz2;
TOKEN_PRIVILEGES *privs;
::GetTokenInformation(token, TokenPrivileges, NULL, 0, &sz); // first only size
if (sz == 0) {
errmsg();
return 1;
}
privs = (TOKEN_PRIVILEGES *) malloc(sz);
if (! ::GetTokenInformation(token, TokenPrivileges, privs, sz, &sz2)) {
errmsg();
return 1;
}

// display found priviledges and look if SE_SYSTEMTIME_NAME is present
BOOL ok = FALSE;
for (size_t i=0; i<privs->PrivilegeCount; i++) {
sz = 0;
::LookupPrivilegeName(NULL, &(privs->Privileges[i].Luid), NULL, &sz);
LPTSTR name = (LPTSTR) malloc(sz * sizeof(TCHAR));
if (! ::LookupPrivilegeName(NULL, &(privs->Privileges[i].Luid), name, &sz)) {
errmsg();
return 1;
}
if (0 == ::lstrcmp(name, SE_SYSTEMTIME_NAME)) {
ok = TRUE;
}
// tcout << name << std::endl;
free(name);
}
free(privs); // done with it
tcout << (ok ? _T("Can") : _T("Cannot")) << _T(" change time") << std::endl;

if (ok) {
tcout << _T("Setting time with ") << time << std::endl;
// actually parse the time string and call SetSystemTime
//...
}
else {
tcout << _T("Restart self as admin...") << std::endl;
// start as cmd /K "full path" to have a chance to see eventual errors
LPTSTR params = (LPTSTR) malloc(MAX_PATH + 7 + lstrlen(time));
lstrcpy(params, _T(" /K \""));
sz = ::GetModuleFileName(NULL, params + 5, MAX_PATH);
// tcout << params + 5 << std::endl;
::lstrcat(params,_T("\" "));  // do not forget the trailing "lstrcat(params, time);
// Let's go, the UAC control should pop to allow the privilege elevation
if (((int) ShellExecute(NULL, _T("runas"), _T("cmd.exe"), params,
_T("."), SW_SHOW)) < 32) {
tcout << _T("Could not start self with elevated privileges") << std::endl;
return 1;
}
free(params);
}
// time to clean...
::CloseHandle(token);
::CloseHandle(process);
return 0;
}

Вещи, чтобы еще работать над:

  • когда команда перезапускается в режиме администратора, используется консоль с cmd /K чтобы позволить пользователю увидеть, что случилось. Если вы предпочитаете быть более тихим, вы должны использовать cmd /C вместо этого и использовать SW_HIDE является ShellExecute,
  • эта программа предполагает, что новое время будет задано в виде простой строки, которая может быть или не иметь отношения к вашему варианту использования
  • многословие должно контролироваться необязательными аргументами
  • система должна мешать попробовать Runas Admin более одного раза (возможно, второй или необязательный параметр)
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]