Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418/* * PROJECT: ReactOS Service Control Manager * LICENSE: GPL - See COPYING in the top level directory * FILE: base/system/services/controlset.c * PURPOSE: Control Set Management * COPYRIGHT: Copyright 2012 Eric Kohl * */
/* INCLUDES *****************************************************************/
#include "services.h"
#define NDEBUG#include <debug.h>
LSTATUS WINAPI RegCopyTreeW(_In_ HKEY, _In_opt_ LPCWSTR, _In_ HKEY);LSTATUS WINAPI RegDeleteTreeW(_In_ HKEY, _In_opt_ LPCWSTR);
/* GLOBALS *******************************************************************/
static BOOL bBootAccepted = FALSE;
/* FUNCTIONS *****************************************************************/
staticDWORDScmGetControlSetValues( PDWORD pdwCurrentControlSet, PDWORD pdwDefaultControlSet, PDWORD pdwFailedControlSet, PDWORD pdwLastKnownGoodControlSet){ HKEY hSelectKey; DWORD dwType; DWORD dwSize; DWORD dwError;
DPRINT("ScmGetControlSetValues() called\n");
dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"System\\Select", 0, KEY_READ, &hSelectKey); if (dwError != ERROR_SUCCESS) return dwError;
dwSize = sizeof(DWORD); dwError = RegQueryValueExW(hSelectKey, L"Current", 0, &dwType, (LPBYTE)pdwCurrentControlSet, &dwSize); if (dwError != ERROR_SUCCESS) { *pdwCurrentControlSet = 0; }
dwSize = sizeof(DWORD); dwError = RegQueryValueExW(hSelectKey, L"Default", 0, &dwType, (LPBYTE)pdwDefaultControlSet, &dwSize); if (dwError != ERROR_SUCCESS) { *pdwDefaultControlSet = 0; }
dwSize = sizeof(DWORD); dwError = RegQueryValueExW(hSelectKey, L"Failed", 0, &dwType, (LPBYTE)pdwFailedControlSet, &dwSize); if (dwError != ERROR_SUCCESS) { *pdwFailedControlSet = 0; }
dwSize = sizeof(DWORD); dwError = RegQueryValueExW(hSelectKey, L"LastKnownGood", 0, &dwType, (LPBYTE)pdwLastKnownGoodControlSet, &dwSize); if (dwError != ERROR_SUCCESS) { *pdwLastKnownGoodControlSet = 0; }
RegCloseKey(hSelectKey);
DPRINT("ControlSets:\n"); DPRINT("Current: %lu\n", *pdwCurrentControlSet); DPRINT("Default: %lu\n", *pdwDefaultControlSet); DPRINT("Failed: %lu\n", *pdwFailedControlSet); DPRINT("LastKnownGood: %lu\n", *pdwLastKnownGoodControlSet);
return dwError;}
staticDWORDScmSetLastKnownGoodControlSet( DWORD dwControlSet){ HKEY hSelectKey; DWORD dwError;
dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"System\\Select", 0, KEY_WRITE, &hSelectKey); if (dwError != ERROR_SUCCESS) return dwError;
dwError = RegSetValueExW(hSelectKey, L"LastKnownGood", 0, REG_DWORD, (LPBYTE)&dwControlSet, sizeof(dwControlSet));
RegFlushKey(hSelectKey); RegCloseKey(hSelectKey);
return dwError;}
staticDWORDScmGetSetupInProgress(VOID){ DWORD dwError; HKEY hKey; DWORD dwType; DWORD dwSize; DWORD dwSetupInProgress = (DWORD)-1;
DPRINT("ScmGetSetupInProgress()\n");
/* Open key */ dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\Setup", 0, KEY_QUERY_VALUE, &hKey); if (dwError == ERROR_SUCCESS) { /* Read key */ dwSize = sizeof(DWORD); RegQueryValueExW(hKey, L"SystemSetupInProgress", NULL, &dwType, (LPBYTE)&dwSetupInProgress, &dwSize); RegCloseKey(hKey); }
DPRINT("SetupInProgress: %lu\n", dwSetupInProgress); return dwSetupInProgress;}
staticDWORDScmCopyControlSet( DWORD dwSourceControlSet, DWORD dwDestinationControlSet){ WCHAR szSourceControlSetName[32]; WCHAR szDestinationControlSetName[32]; HKEY hSourceControlSetKey = NULL; HKEY hDestinationControlSetKey = NULL; DWORD dwDisposition; DWORD dwError;
/* Create the source control set name */ swprintf(szSourceControlSetName, L"SYSTEM\\ControlSet%03lu", dwSourceControlSet); DPRINT("Source control set: %S\n", szSourceControlSetName);
/* Create the destination control set name */ swprintf(szDestinationControlSetName, L"SYSTEM\\ControlSet%03lu", dwDestinationControlSet); DPRINT("Destination control set: %S\n", szDestinationControlSetName);
/* Open the source control set key */ dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE, szSourceControlSetName, 0, KEY_READ, &hSourceControlSetKey); if (dwError != ERROR_SUCCESS) goto done;
/* Create the destination control set key */ dwError = RegCreateKeyExW(HKEY_LOCAL_MACHINE, szDestinationControlSetName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hDestinationControlSetKey, &dwDisposition); if (dwError != ERROR_SUCCESS) goto done;
/* Copy the source control set to the destination control set */ dwError = RegCopyTreeW(hSourceControlSetKey, NULL, hDestinationControlSetKey); if (dwError != ERROR_SUCCESS) goto done;
RegFlushKey(hDestinationControlSetKey);
done: if (hDestinationControlSetKey != NULL) RegCloseKey(hDestinationControlSetKey);
if (hSourceControlSetKey != NULL) RegCloseKey(hSourceControlSetKey);
return dwError;}
staticDWORDScmDeleteControlSet( DWORD dwControlSet){ WCHAR szControlSetName[32]; HKEY hControlSetKey = NULL; DWORD dwError;
DPRINT("ScmDeleteControSet(%lu)\n", dwControlSet);
/* Create the control set name */ swprintf(szControlSetName, L"SYSTEM\\ControlSet%03lu", dwControlSet); DPRINT("Control set: %S\n", szControlSetName);
/* Open the system key */ dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE, szControlSetName, 0, DELETE | KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE | KEY_SET_VALUE, &hControlSetKey); if (dwError != ERROR_SUCCESS) return dwError;
/* Delete the control set */ dwError = RegDeleteTreeW(hControlSetKey, NULL);
/* Open the system key */ RegCloseKey(hControlSetKey);
return dwError;}
DWORDScmCreateLastKnownGoodControlSet(VOID){ DWORD dwCurrentControlSet, dwDefaultControlSet; DWORD dwFailedControlSet, dwLastKnownGoodControlSet; DWORD dwNewControlSet; DWORD dwError;
/* Get the control set values */ dwError = ScmGetControlSetValues(&dwCurrentControlSet, &dwDefaultControlSet, &dwFailedControlSet, &dwLastKnownGoodControlSet); if (dwError != ERROR_SUCCESS) return dwError;
/* First boot after setup? */ if ((ScmGetSetupInProgress() == 0) && (dwCurrentControlSet == dwLastKnownGoodControlSet)) { DPRINT("First boot after setup\n");
/* Search for a new control set number */ for (dwNewControlSet = 1; dwNewControlSet < 1000; dwNewControlSet++) { if ((dwNewControlSet != dwCurrentControlSet) && (dwNewControlSet != dwDefaultControlSet) && (dwNewControlSet != dwFailedControlSet) && (dwNewControlSet != dwLastKnownGoodControlSet)) break; }
/* Fail if we did not find an unused control set!*/ if (dwNewControlSet >= 1000) { DPRINT1("Too many control sets\n"); return ERROR_NO_MORE_ITEMS; }
/* Copy the current control set */ dwError = ScmCopyControlSet(dwCurrentControlSet, dwNewControlSet); if (dwError != ERROR_SUCCESS) return dwError;
/* Set the new 'LastKnownGood' control set */ dwError = ScmSetLastKnownGoodControlSet(dwNewControlSet); if (dwError == ERROR_SUCCESS) { /* * Accept the boot here in order to prevent the creation of * another control set when a user is going to get logged on */ bBootAccepted = TRUE; } }
return dwError;}
DWORDScmAcceptBoot(VOID){ DWORD dwCurrentControlSet, dwDefaultControlSet; DWORD dwFailedControlSet, dwLastKnownGoodControlSet; DWORD dwNewControlSet; DWORD dwError;
DPRINT("ScmAcceptBoot()\n");
if (bBootAccepted) { DPRINT1("Boot has already been accepted\n"); return ERROR_BOOT_ALREADY_ACCEPTED; }
/* Get the control set values */ dwError = ScmGetControlSetValues(&dwCurrentControlSet, &dwDefaultControlSet, &dwFailedControlSet, &dwLastKnownGoodControlSet); if (dwError != ERROR_SUCCESS) return dwError;
/* Search for a new control set number */ for (dwNewControlSet = 1; dwNewControlSet < 1000; dwNewControlSet++) { if ((dwNewControlSet != dwCurrentControlSet) && (dwNewControlSet != dwDefaultControlSet) && (dwNewControlSet != dwFailedControlSet) && (dwNewControlSet != dwLastKnownGoodControlSet)) break; }
/* Fail if we did not find an unused control set!*/ if (dwNewControlSet >= 1000) { DPRINT1("Too many control sets\n"); return ERROR_NO_MORE_ITEMS; }
/* Copy the current control set */ dwError = ScmCopyControlSet(dwCurrentControlSet, dwNewControlSet); if (dwError != ERROR_SUCCESS) return dwError;
/* Delete the current last known good contol set, if it is not used anywhere else */ if ((dwLastKnownGoodControlSet != dwCurrentControlSet) && (dwLastKnownGoodControlSet != dwDefaultControlSet) && (dwLastKnownGoodControlSet != dwFailedControlSet)) { ScmDeleteControlSet(dwLastKnownGoodControlSet); }
/* Set the new 'LastKnownGood' control set */ dwError = ScmSetLastKnownGoodControlSet(dwNewControlSet); if (dwError != ERROR_SUCCESS) return dwError;
bBootAccepted = TRUE;
return ERROR_SUCCESS;}
DWORDScmRunLastKnownGood(VOID){ DPRINT("ScmRunLastKnownGood()\n");
if (bBootAccepted) { DPRINT1("Boot has already been accepted\n"); return ERROR_BOOT_ALREADY_ACCEPTED; }
/* FIXME */
return ERROR_SUCCESS;}
/* EOF */