Author: rharabien Date: Tue Dec 20 20:47:48 2011 New Revision: 54715
URL: http://svn.reactos.org/svn/reactos?rev=54715&view=rev Log: [SHELL32] - Fix SHCreateSessionKey [EXPLORER] - Don't run startup applications if StartupHasBeenRun key exists. If it doesn't, create new key. - Make startup code readable See issue #1801 for more details.
Modified: trunk/reactos/base/shell/explorer/services/startup.c trunk/reactos/dll/win32/shell32/shellreg.cpp
Modified: trunk/reactos/base/shell/explorer/services/startup.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/explorer/service... ============================================================================== --- trunk/reactos/base/shell/explorer/services/startup.c [iso-8859-1] (original) +++ trunk/reactos/base/shell/explorer/services/startup.c [iso-8859-1] Tue Dec 20 20:47:48 2011 @@ -55,6 +55,8 @@ #include <stdio.h> #include <windows.h> #include <ctype.h> + +EXTERN_C HRESULT WINAPI SHCreateSessionKey(REGSAM samDesired, PHKEY phKey);
/** * Performs the rename operations dictated in %SystemRoot%\Wininit.ini. @@ -429,6 +431,8 @@ /* First, set the current directory to SystemRoot */ TCHAR gen_path[MAX_PATH]; DWORD res; + HKEY hSessionKey, hKey; + HRESULT hr;
res = GetWindowsDirectory(gen_path, sizeof(gen_path));
@@ -440,13 +444,6 @@ return 100; }
- if (res>=sizeof(gen_path)) - { - printf("Windows path too long (%ld)\n", res); - - return 100; - } - if (!SetCurrentDirectory(gen_path)) { wprintf(L"Cannot set the dir to %s (%ld)\n", gen_path, GetLastError()); @@ -454,42 +451,64 @@ return 100; }
- if (argc>1) + hr = SHCreateSessionKey(KEY_WRITE, &hSessionKey); + if (SUCCEEDED(hr)) + { + LONG Error; + DWORD dwDisp; + + Error = RegCreateKeyEx(hSessionKey, L"StartupHasBeenRun", 0, NULL, REG_OPTION_VOLATILE, KEY_WRITE, NULL, &hKey, &dwDisp); + RegCloseKey(hSessionKey); + if (Error == ERROR_SUCCESS) + { + RegCloseKey(hKey); + if (dwDisp == REG_OPENED_EXISTING_KEY) + { + /* Startup programs has already been run */ + return 0; + } + } + } + + if (argc > 1) { switch(argv[1][0]) { case 'r': /* Restart */ - ops=SETUP; + ops = SETUP; break; case 's': /* Full start */ - ops=SESSION_START; + ops = SESSION_START; break; default: - ops=DEFAULT; + ops = DEFAULT; break; } } else - ops=DEFAULT; + ops = DEFAULT;
/* do not run certain items in Safe Mode */ if(GetSystemMetrics(SM_CLEANBOOT)) ops.startup = FALSE;
/* Perform the ops by order, stopping if one fails, skipping if necessary */ /* Shachar: Sorry for the perl syntax */ - res=(ops.ntonly || !ops.preboot || wininit()) && - (ops.w9xonly || !ops.preboot || pendingRename()) && - (ops.ntonly || !ops.prelogin || - ProcessRunKeys(HKEY_LOCAL_MACHINE, runkeys_names[RUNKEY_RUNSERVICESONCE], TRUE, FALSE)) && - (ops.ntonly || !ops.prelogin || !ops.startup || - ProcessRunKeys(HKEY_LOCAL_MACHINE, runkeys_names[RUNKEY_RUNSERVICES], FALSE, FALSE)) && - (!ops.postlogin || - ProcessRunKeys(HKEY_LOCAL_MACHINE, runkeys_names[RUNKEY_RUNONCE], TRUE, TRUE)) && - (!ops.postlogin || !ops.startup || - ProcessRunKeys(HKEY_LOCAL_MACHINE, runkeys_names[RUNKEY_RUN], FALSE, FALSE)) && - (!ops.postlogin || !ops.startup || - ProcessRunKeys(HKEY_CURRENT_USER, runkeys_names[RUNKEY_RUN], FALSE, FALSE)); + res = TRUE; + if (res && !ops.ntonly && ops.preboot) + res = wininit(); + if (res && !ops.w9xonly && ops.preboot) + res = pendingRename(); + if (res && !ops.ntonly && ops.prelogin) + res = ProcessRunKeys(HKEY_LOCAL_MACHINE, runkeys_names[RUNKEY_RUNSERVICESONCE], TRUE, FALSE); + if (res && !ops.ntonly && ops.prelogin && ops.startup) + res = ProcessRunKeys(HKEY_LOCAL_MACHINE, runkeys_names[RUNKEY_RUNSERVICES], FALSE, FALSE); + if (res && ops.postlogin) + res = ProcessRunKeys(HKEY_LOCAL_MACHINE, runkeys_names[RUNKEY_RUNONCE], TRUE, TRUE); + if (res && ops.postlogin && ops.startup) + res = ProcessRunKeys(HKEY_LOCAL_MACHINE, runkeys_names[RUNKEY_RUN], FALSE, FALSE); + if (res && ops.postlogin && ops.startup) + res = ProcessRunKeys(HKEY_CURRENT_USER, runkeys_names[RUNKEY_RUN], FALSE, FALSE);
printf("Operation done\n");
- return res?0:101; + return res ? 0 : 101; }
Modified: trunk/reactos/dll/win32/shell32/shellreg.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/shellreg.... ============================================================================== --- trunk/reactos/dll/win32/shell32/shellreg.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shell32/shellreg.cpp [iso-8859-1] Tue Dec 20 20:47:48 2011 @@ -149,10 +149,11 @@ WINAPI SHCreateSessionKey(REGSAM samDesired, PHKEY phKey) { - static HKEY hSessionKey = NULL; HRESULT hr = S_OK; + static WCHAR wszSessionKey[256]; + LONG Error;
- if (!hSessionKey) + if (!wszSessionKey[0]) // FIXME: Critical Section { HANDLE hToken;
@@ -163,16 +164,9 @@
if (GetTokenInformation(hToken, TokenStatistics, &Stats, sizeof(Stats), &ReturnLength)) { - WCHAR wszBuf[256]; - LONG Error; - - swprintf(wszBuf, + swprintf(wszSessionKey, L"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\SessionInfo\%08x%08x", Stats.AuthenticationId.HighPart, Stats.AuthenticationId.LowPart); - - Error = RegCreateKeyExW(HKEY_LOCAL_MACHINE, wszBuf, 0, NULL, REG_OPTION_VOLATILE, samDesired, NULL, &hSessionKey, NULL); - if (Error != ERROR_SUCCESS) - hr = HRESULT_FROM_WIN32(Error); } else hr = HRESULT_FROM_WIN32(GetLastError()); @@ -183,6 +177,13 @@ hr = HRESULT_FROM_WIN32(GetLastError()); }
- *phKey = hSessionKey; + if(SUCCEEDED(hr)) + { + Error = RegCreateKeyExW(HKEY_LOCAL_MACHINE, wszSessionKey, 0, NULL, + REG_OPTION_VOLATILE, samDesired, NULL, phKey, NULL); + if (Error != ERROR_SUCCESS) + hr = HRESULT_FROM_WIN32(Error); + } + return hr; }