Indice

Spegnere o riavviare windows

Autore: Fabio Di Matteo
Ultima revisione: 29/03/2013

Di seguito il codice per spegnere o riavviare windows. Il codice in questione fa essenzialmente due cose: ottenere i privilegi e usa ExitWindowsEx() per eseguire l'operazione. Ovviamente cross-compileremo tutto sulla nostra Linuxbox tramite mingw .A questo indirizzo (ExitWindowsEx function) troviamo la documentazione ufficiale microsoft. Basti a noi sapere che la funzione ha il seguente prototipo:

#include <windows.h>
...
 
BOOL WINAPI ExitWindowsEx(
  _In_  UINT uFlags,
  _In_  DWORD dwReason
);

dove uFlags è l'azione che vogliamo svolgere (riavvio, spegnimento, logout etc…) e dwReason(opzionale) la ragione ,che vogliamo comunicare al sistema operativo, per la quale abbiamo invocato ExitWindowsEx() .

Il codice

spegni-windows.c

#include <windows.h>
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "advapi32.lib")
 
 
//Documentazione su http://msdn.microsoft.com/en-us/library/windows/desktop/aa376868%28v=vs.85%29.aspx
 
// Con questa funzione richiediamo i privilegi (per questo processo)
// di spegnere il computer
 
int RichiediPrivilegi()
{
	HANDLE hToken; 
	TOKEN_PRIVILEGES tkp; 
 
   // Prende un token per i concedere i privilegi a questo processo
	if (!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) 
	{
	  wprintf(L"Qualcosa e' andato storto ...\n");			
      return( FALSE ); 
	}
   // Prende il LogonID (LUID)
   LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid); 
 
   //Quanti e che tipo di privilegi servono
   tkp.PrivilegeCount = 1;      
   tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 
 
   // Get the shutdown privilege for this process. 
 
   AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, 
        (PTOKEN_PRIVILEGES)NULL, 0); 
 
 
   //Verifica se alla fine della richiesta dei privilegi ci siano stati problemi
   if (GetLastError() != ERROR_SUCCESS)
   { 
      wprintf(L"Qualcosa e' andato storto ...\n");
      return FALSE; 
	}
}
 
int Spegni()
{
	//Richiedo i privilegi necessari
	RichiediPrivilegi();
 
	// ExitWindowsEx() fa il lavoro sporco. Puo' spegnere o riavviare il sistema
	// in base ai vari flag che gli siano dati come parametro.
	if (!ExitWindowsEx(EWX_POWEROFF, 0) )
    {
		wprintf(L"Non e' stato possibile spegnere il computer\n");
		return FALSE ;             
	}else{
		wprintf(L"spegnimento in corso...\n");
	}
}
 
int Riavvia()
{
	//Richiedo i privilegi necessari
	RichiediPrivilegi();
 
	// ExitWindowsEx() fa il lavoro sporco. Puo' spegnere o riavviare il sistema
	// in base ai vari flag che gli siano dati come parametro.
	if (!ExitWindowsEx(EWX_REBOOT, 0) )
    {
		wprintf(L"Non e' stato possibile spegnere il computer\n");
		return FALSE ;            
	}else{
		wprintf(L"spegnimento in corso...\n");
	}
}
 
 
 
 
int main(int argc, char** argv)
{
	// Spegni() spegne il sistema e Riavvia() lo riavvia :)
	//Spegni();
	Riavvia();
 
 
 
	// Attendo lo stdinput giusto per non far sparire 
	// la finestrella del terminale subito nel caso in
	// cui ci siano errori da vedere
	int a;	wscanf(" %f", &a);
 
	return 0;
}

Il makefile

makefile

CPP = /usr/bin/i486-mingw32-gcc



all:
	$(CPP)  spegni-windows.c -o spegni-windows.exe

clean:
	rm spegni-windows.exe