[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.

svn path=/trunk/; revision=54715
This commit is contained in:
Rafal Harabien 2011-12-20 20:47:48 +00:00
parent 673f93ef3b
commit ed0656f56f
2 changed files with 56 additions and 36 deletions

View file

@ -56,6 +56,8 @@
#include <windows.h> #include <windows.h>
#include <ctype.h> #include <ctype.h>
EXTERN_C HRESULT WINAPI SHCreateSessionKey(REGSAM samDesired, PHKEY phKey);
/** /**
* Performs the rename operations dictated in %SystemRoot%\Wininit.ini. * Performs the rename operations dictated in %SystemRoot%\Wininit.ini.
* Returns FALSE if there was an error, or otherwise if all is ok. * Returns FALSE if there was an error, or otherwise if all is ok.
@ -429,6 +431,8 @@ int startup(int argc, const char *argv[])
/* First, set the current directory to SystemRoot */ /* First, set the current directory to SystemRoot */
TCHAR gen_path[MAX_PATH]; TCHAR gen_path[MAX_PATH];
DWORD res; DWORD res;
HKEY hSessionKey, hKey;
HRESULT hr;
res = GetWindowsDirectory(gen_path, sizeof(gen_path)); res = GetWindowsDirectory(gen_path, sizeof(gen_path));
@ -440,13 +444,6 @@ int startup(int argc, const char *argv[])
return 100; return 100;
} }
if (res>=sizeof(gen_path))
{
printf("Windows path too long (%ld)\n", res);
return 100;
}
if (!SetCurrentDirectory(gen_path)) if (!SetCurrentDirectory(gen_path))
{ {
wprintf(L"Cannot set the dir to %s (%ld)\n", gen_path, GetLastError()); wprintf(L"Cannot set the dir to %s (%ld)\n", gen_path, GetLastError());
@ -454,42 +451,64 @@ int startup(int argc, const char *argv[])
return 100; 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]) switch(argv[1][0])
{ {
case 'r': /* Restart */ case 'r': /* Restart */
ops=SETUP; ops = SETUP;
break; break;
case 's': /* Full start */ case 's': /* Full start */
ops=SESSION_START; ops = SESSION_START;
break; break;
default: default:
ops=DEFAULT; ops = DEFAULT;
break; break;
} }
} else } else
ops=DEFAULT; ops = DEFAULT;
/* do not run certain items in Safe Mode */ /* do not run certain items in Safe Mode */
if(GetSystemMetrics(SM_CLEANBOOT)) ops.startup = FALSE; if(GetSystemMetrics(SM_CLEANBOOT)) ops.startup = FALSE;
/* Perform the ops by order, stopping if one fails, skipping if necessary */ /* Perform the ops by order, stopping if one fails, skipping if necessary */
/* Shachar: Sorry for the perl syntax */ /* Shachar: Sorry for the perl syntax */
res=(ops.ntonly || !ops.preboot || wininit()) && res = TRUE;
(ops.w9xonly || !ops.preboot || pendingRename()) && if (res && !ops.ntonly && ops.preboot)
(ops.ntonly || !ops.prelogin || res = wininit();
ProcessRunKeys(HKEY_LOCAL_MACHINE, runkeys_names[RUNKEY_RUNSERVICESONCE], TRUE, FALSE)) && if (res && !ops.w9xonly && ops.preboot)
(ops.ntonly || !ops.prelogin || !ops.startup || res = pendingRename();
ProcessRunKeys(HKEY_LOCAL_MACHINE, runkeys_names[RUNKEY_RUNSERVICES], FALSE, FALSE)) && if (res && !ops.ntonly && ops.prelogin)
(!ops.postlogin || res = ProcessRunKeys(HKEY_LOCAL_MACHINE, runkeys_names[RUNKEY_RUNSERVICESONCE], TRUE, FALSE);
ProcessRunKeys(HKEY_LOCAL_MACHINE, runkeys_names[RUNKEY_RUNONCE], TRUE, TRUE)) && if (res && !ops.ntonly && ops.prelogin && ops.startup)
(!ops.postlogin || !ops.startup || res = ProcessRunKeys(HKEY_LOCAL_MACHINE, runkeys_names[RUNKEY_RUNSERVICES], FALSE, FALSE);
ProcessRunKeys(HKEY_LOCAL_MACHINE, runkeys_names[RUNKEY_RUN], FALSE, FALSE)) && if (res && ops.postlogin)
(!ops.postlogin || !ops.startup || res = ProcessRunKeys(HKEY_LOCAL_MACHINE, runkeys_names[RUNKEY_RUNONCE], TRUE, TRUE);
ProcessRunKeys(HKEY_CURRENT_USER, runkeys_names[RUNKEY_RUN], FALSE, FALSE)); 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"); printf("Operation done\n");
return res?0:101; return res ? 0 : 101;
} }

View file

@ -149,10 +149,11 @@ EXTERN_C HRESULT
WINAPI WINAPI
SHCreateSessionKey(REGSAM samDesired, PHKEY phKey) SHCreateSessionKey(REGSAM samDesired, PHKEY phKey)
{ {
static HKEY hSessionKey = NULL;
HRESULT hr = S_OK; HRESULT hr = S_OK;
static WCHAR wszSessionKey[256];
LONG Error;
if (!hSessionKey) if (!wszSessionKey[0]) // FIXME: Critical Section
{ {
HANDLE hToken; HANDLE hToken;
@ -163,16 +164,9 @@ SHCreateSessionKey(REGSAM samDesired, PHKEY phKey)
if (GetTokenInformation(hToken, TokenStatistics, &Stats, sizeof(Stats), &ReturnLength)) if (GetTokenInformation(hToken, TokenStatistics, &Stats, sizeof(Stats), &ReturnLength))
{ {
WCHAR wszBuf[256]; swprintf(wszSessionKey,
LONG Error;
swprintf(wszBuf,
L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\SessionInfo\\%08x%08x", L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\SessionInfo\\%08x%08x",
Stats.AuthenticationId.HighPart, Stats.AuthenticationId.LowPart); 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 else
hr = HRESULT_FROM_WIN32(GetLastError()); hr = HRESULT_FROM_WIN32(GetLastError());
@ -183,6 +177,13 @@ SHCreateSessionKey(REGSAM samDesired, PHKEY phKey)
hr = HRESULT_FROM_WIN32(GetLastError()); 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; return hr;
} }