Author: ion
Date: Sun Jan 15 14:49:49 2012
New Revision: 54975
URL:
http://svn.reactos.org/svn/reactos?rev=54975&view=rev
Log:
Note, none of this code is being used/called yet.
[KERNEL32]: Implement BasepSxsCloseHandles, BasepReplaceProcessThreadTokens,
BasepIsProcessAllowed, BasepCheckWebBladeHashes, BasepIsImageVersionOk which will be
needed for the future CreateProcess re-implementation. These functions partly support SxS,
Safer (Authz) and Application Certification features added in XP/2003. We also emulate
support for Computer Server, Web Blade Server and Embedded ReactOS. The last function does
correct image version checks to prevent invalid binaries from running.
[KERNEL32]: Implement BaseUpdateVDMEntry and BaseCheckForVDM using the new CSRSS messages
(not implemented on the server-side yet). Stubplement BaseCheckVDM. These will be needed
for future VDM-stub-support (primarly so we can run 16-bit installers).
[KERNEL32]: Implement BasepFreeAppCompatData, BasepCheckBadapp, and
IsShimInfrastructureDisabled (exported as BaseIsAppcompatInfrastructureDisabled). These
stub most of the required/exported application compatibility APIs, as long as someone sets
DisableAppCompat in \\Registry\\MACHINE\\System\\CurrentControlSet\\Control\\Session
Manager\\AppCompatibility.
Modified:
trunk/reactos/dll/win32/kernel32/client/appcache.c
trunk/reactos/dll/win32/kernel32/client/dllmain.c
trunk/reactos/dll/win32/kernel32/client/proc.c
trunk/reactos/dll/win32/kernel32/client/utils.c
trunk/reactos/dll/win32/kernel32/client/vdm.c
trunk/reactos/dll/win32/kernel32/include/kernel32.h
trunk/reactos/dll/win32/kernel32/kernel32.pspec
trunk/reactos/dll/win32/kernel32/kernel32.spec
Modified: trunk/reactos/dll/win32/kernel32/client/appcache.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/…
==============================================================================
--- trunk/reactos/dll/win32/kernel32/client/appcache.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/client/appcache.c [iso-8859-1] Sun Jan 15 14:49:49
2012
@@ -13,17 +13,171 @@
#define NDEBUG
#include <debug.h>
+/* GLOBALS ********************************************************************/
+
+ULONG g_ShimsEnabled;
+
/* FUNCTIONS ******************************************************************/
-/*
- * @unimplemented
+BOOLEAN
+WINAPI
+IsShimInfrastructureDisabled(VOID)
+{
+ HANDLE KeyHandle;
+ NTSTATUS Status;
+ KEY_VALUE_PARTIAL_INFORMATION KeyInfo;
+ ULONG ResultLength;
+ UNICODE_STRING OptionKey =
RTL_CONSTANT_STRING(L"\\Registry\\MACHINE\\System\\CurrentControlSet\\Control\\SafeBoot\\Option");
+ UNICODE_STRING AppCompatKey =
RTL_CONSTANT_STRING(L"\\Registry\\MACHINE\\System\\CurrentControlSet\\Control\\Session
Manager\\AppCompatibility");
+ UNICODE_STRING PolicyKey =
RTL_CONSTANT_STRING(L"\\Registry\\MACHINE\\Software\\Policies\\Microsoft\\Windows\\AppCompat");
+ UNICODE_STRING OptionValue = RTL_CONSTANT_STRING(L"OptionValue");
+ UNICODE_STRING DisableAppCompat =
RTL_CONSTANT_STRING(L"DisableAppCompat");
+ UNICODE_STRING DisableEngine = RTL_CONSTANT_STRING(L"DisableEngine");
+ OBJECT_ATTRIBUTES OptionKeyAttributes =
RTL_CONSTANT_OBJECT_ATTRIBUTES(&OptionKey, OBJ_CASE_INSENSITIVE);
+ OBJECT_ATTRIBUTES AppCompatKeyAttributes =
RTL_CONSTANT_OBJECT_ATTRIBUTES(&AppCompatKey, OBJ_CASE_INSENSITIVE);
+ OBJECT_ATTRIBUTES PolicyKeyAttributes =
RTL_CONSTANT_OBJECT_ATTRIBUTES(&PolicyKey, OBJ_CASE_INSENSITIVE);
+
+ /*
+ * This is a TROOLEAN, -1 means we haven't yet figured it out.
+ * 0 means shims are enabled, and 1 means shims are disabled!
+ */
+ if (g_ShimsEnabled == -1)
+ {
+ /* Open the safe mode key */
+ Status = NtOpenKey(&KeyHandle, 1, &OptionKeyAttributes);
+ if (NT_SUCCESS(Status))
+ {
+ /* Check if this is safemode */
+ Status = NtQueryValueKey(KeyHandle,
+ &OptionValue,
+ KeyValuePartialInformation,
+ &KeyInfo,
+ sizeof(KeyInfo),
+ &ResultLength);
+ NtClose(KeyHandle);
+ if ((NT_SUCCESS(Status)) &&
+ (KeyInfo.Type == REG_DWORD) &&
+ (KeyInfo.DataLength == sizeof(ULONG)) &&
+ (KeyInfo.Data[0] == TRUE))
+ {
+ /* It is, so disable shims! */
+ g_ShimsEnabled = TRUE;
+ }
+ else
+ {
+ /* Open the app compatibility engine settings key */
+ Status = NtOpenKey(&KeyHandle, 1, &AppCompatKeyAttributes);
+ if (NT_SUCCESS(Status))
+ {
+ /* Check if the app compat engine is turned off */
+ Status = NtQueryValueKey(KeyHandle,
+ &DisableAppCompat,
+ KeyValuePartialInformation,
+ &KeyInfo,
+ sizeof(KeyInfo),
+ &ResultLength);
+ NtClose(KeyHandle);
+ if ((NT_SUCCESS(Status)) &&
+ (KeyInfo.Type == REG_DWORD) &&
+ (KeyInfo.DataLength == sizeof(ULONG)) &&
+ (KeyInfo.Data[0] == TRUE))
+ {
+ /* It is, so disable shims! */
+ g_ShimsEnabled = TRUE;
+ }
+ else
+ {
+ /* Finally, open the app compatibility policy key */
+ Status = NtOpenKey(&KeyHandle, 1, &PolicyKeyAttributes);
+ if (NT_SUCCESS(Status))
+ {
+ /* Check if the system policy disables app compat */
+ Status = NtQueryValueKey(KeyHandle,
+ &DisableEngine,
+ KeyValuePartialInformation,
+ &KeyInfo,
+ sizeof(KeyInfo),
+ &ResultLength),
+ NtClose(KeyHandle);
+ if ((NT_SUCCESS(Status)) &&
+ (KeyInfo.Type == REG_DWORD) &&
+ (KeyInfo.DataLength == sizeof(ULONG)) &&
+ (KeyInfo.Data[0] == TRUE))
+ {
+ /* It does, so disable shims! */
+ g_ShimsEnabled = TRUE;
+ }
+ else
+ {
+ /* No keys are set, so enable shims! */
+ g_ShimsEnabled = FALSE;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* Return if shims are disabled or not ("Enabled == 1" means disabled!) */
+ return g_ShimsEnabled ? TRUE : FALSE;
+}
+
+/*
+ * @unimplemented
+ */
+BOOL
+WINAPI
+BaseCheckAppcompatCache(IN PWCHAR ApplicationName,
+ IN HANDLE FileHandle,
+ IN PWCHAR Environment,
+ OUT PULONG Reason)
+{
+ UNIMPLEMENTED;
+ if (Reason) *Reason = 0;
+ return TRUE;
+}
+
+/*
+ * @implemented
*/
NTSTATUS
WINAPI
-BasepCheckBadapp(int a, wchar_t *Str, int b, int c, int d, int e, int f, int g, int h)
-{
- STUB;
- return STATUS_NOT_IMPLEMENTED;
+BasepCheckBadapp(IN HANDLE FileHandle,
+ IN PWCHAR ApplicationName,
+ IN PWCHAR Environment,
+ IN USHORT ExeType,
+ IN PVOID* SdbQueryAppCompatData,
+ IN PULONG SdbQueryAppCompatDataSize,
+ IN PVOID* SxsData,
+ IN PULONG SxsDataSize,
+ OUT PULONG FusionFlags)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+ ULONG Reason = 0;
+
+ /* Is shimming enabled by group policy? */
+ if (IsShimInfrastructureDisabled())
+ {
+ /* Nothing to worry about */
+ Status = STATUS_SUCCESS;
+ }
+ else
+ {
+ /* It is, check if we know about this app */
+ if (!BaseCheckAppcompatCache(ApplicationName,
+ FileHandle,
+ Environment,
+ &Reason))
+ {
+ /* We don't support this yet */
+ UNIMPLEMENTED;
+ Status = STATUS_ACCESS_DENIED;
+ }
+ }
+
+ /* Return caller the status */
+ return Status;
}
/*
@@ -47,39 +201,16 @@
}
/*
- * @unimplemented
- */
-VOID
-WINAPI
-BasepFreeAppCompatData(PVOID A, PVOID B)
-{
- STUB;
-}
-
-/*
- * @unimplemented
- */
-BOOL
-WINAPI
-BaseIsAppcompatInfrastructureDisabled(VOID)
-{
- STUB;
- return TRUE;
-}
-
-/*
- * @unimplemented
- */
-BOOL
-WINAPI
-BaseCheckAppcompatCache(ULONG Unknown1,
- ULONG Unknown2,
- ULONG Unknown3,
- PULONG Unknown4)
-{
- STUB;
- if (Unknown4) *Unknown4 = 0;
- return TRUE;
+ * @implemented
+ */
+VOID
+WINAPI
+BasepFreeAppCompatData(IN PVOID AppCompatData,
+ IN PVOID AppCompatSxsData)
+{
+ /* Free the input pointers if present */
+ if (AppCompatData) RtlFreeHeap(RtlGetProcessHeap(), 0, AppCompatData);
+ if (AppCompatSxsData) RtlFreeHeap(RtlGetProcessHeap(), 0, AppCompatSxsData);
}
/*
@@ -94,6 +225,9 @@
STUB;
}
+/*
+ * @unimplemented
+ */
NTSTATUS
WINAPI
BaseCleanupAppcompatCache(VOID)
@@ -102,6 +236,9 @@
return STATUS_NOT_IMPLEMENTED;
}
+/*
+ * @unimplemented
+ */
NTSTATUS
WINAPI
BaseCleanupAppcompatCacheSupport(PVOID pUnknown)
@@ -110,6 +247,9 @@
return STATUS_NOT_IMPLEMENTED;
}
+/*
+ * @unimplemented
+ */
BOOL
WINAPI
BaseInitAppcompatCache(VOID)
@@ -118,6 +258,9 @@
return FALSE;
}
+/*
+ * @unimplemented
+ */
BOOL
WINAPI
BaseInitAppcompatCacheSupport(VOID)
@@ -126,6 +269,9 @@
return FALSE;
}
+/*
+ * @unimplemented
+ */
PVOID
WINAPI
GetComPlusPackageInstallStatus(VOID)
@@ -134,15 +280,18 @@
return NULL;
}
+/*
+ * @unimplemented
+ */
BOOL
WINAPI
SetComPlusPackageInstallStatus(LPVOID lpInfo)
-{
+{
STUB;
return FALSE;
}
-
- /*
+
+/*
* @unimplemented
*/
VOID
Modified: trunk/reactos/dll/win32/kernel32/client/dllmain.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/…
==============================================================================
--- trunk/reactos/dll/win32/kernel32/client/dllmain.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/client/dllmain.c [iso-8859-1] Sun Jan 15 14:49:49
2012
@@ -303,6 +303,10 @@
return FALSE;
}
+ /* Initialize application certification globals */
+ InitializeListHead(&BasepAppCertDllsList);
+ RtlInitializeCriticalSection(&gcsAppCert);
+
/* Insert more dll attach stuff here! */
DllInitialized = TRUE;
DPRINT("Initialization complete\n");
Modified: trunk/reactos/dll/win32/kernel32/client/proc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/…
==============================================================================
--- trunk/reactos/dll/win32/kernel32/client/proc.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/client/proc.c [iso-8859-1] Sun Jan 15 14:49:49 2012
@@ -42,7 +42,406 @@
CALLBACK
ConsoleControlDispatcher(DWORD CodeAndFlag);
+BOOLEAN g_AppCertInitialized;
+BOOLEAN g_HaveAppCerts;
+LIST_ENTRY BasepAppCertDllsList;
+RTL_CRITICAL_SECTION gcsAppCert;
+PBASEP_APPCERT_EMBEDDED_FUNC fEmbeddedCertFunc;
+NTSTATUS g_AppCertStatus;
+
+RTL_QUERY_REGISTRY_TABLE BasepAppCertTable[2] =
+{
+ {
+ BasepConfigureAppCertDlls,
+ 1,
+ L"AppCertDlls",
+ &BasepAppCertDllsList,
+ 0,
+ NULL,
+ 0
+ },
+ {}
+};
+
+PSAFER_REPLACE_PROCESS_THREAD_TOKENS g_SaferReplaceProcessThreadTokens;
+HMODULE gSaferHandle = (HMODULE)-1;
+
/* FUNCTIONS ****************************************************************/
+
+VOID
+WINAPI
+StuffStdHandle(IN HANDLE ProcessHandle,
+ IN HANDLE StandardHandle,
+ IN PHANDLE Address)
+{
+ NTSTATUS Status;
+ HANDLE DuplicatedHandle;
+ SIZE_T Dummy;
+
+ /* Duplicate the handle */
+ Status = NtDuplicateObject(NtCurrentProcess(),
+ StandardHandle,
+ ProcessHandle,
+ &DuplicatedHandle,
+ DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES,
+ 0,
+ 0);
+ if (NT_SUCCESS(Status))
+ {
+ /* Write it */
+ NtWriteVirtualMemory(ProcessHandle,
+ Address,
+ &DuplicatedHandle,
+ sizeof(HANDLE),
+ &Dummy);
+ }
+}
+
+BOOLEAN
+WINAPI
+BuildSubSysCommandLine(IN LPWSTR SubsystemName,
+ IN LPWSTR ApplicationName,
+ IN LPWSTR CommandLine,
+ OUT PUNICODE_STRING SubsysCommandLine)
+{
+ UNICODE_STRING CommandLineString, ApplicationNameString;
+ PWCHAR Buffer;
+ ULONG Length;
+
+ /* Convert to unicode strings */
+ RtlInitUnicodeString(&CommandLineString, ApplicationName);
+ RtlInitUnicodeString(&ApplicationNameString, CommandLine);
+
+ /* Allocate buffer for the output string */
+ Length = CommandLineString.MaximumLength + ApplicationNameString.MaximumLength + 32;
+ Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length);
+ RtlInitEmptyUnicodeString(SubsysCommandLine, Buffer, Length);
+ if (!Buffer)
+ {
+ /* Fail, no memory */
+ BaseSetLastNTError(STATUS_NO_MEMORY);
+ return FALSE;
+ }
+
+ /* Build the final subsystem command line */
+ RtlAppendUnicodeToString(SubsysCommandLine, SubsystemName);
+ RtlAppendUnicodeStringToString(SubsysCommandLine, &CommandLineString);
+ RtlAppendUnicodeToString(SubsysCommandLine, L" /C ");
+ RtlAppendUnicodeStringToString(SubsysCommandLine, &ApplicationNameString);
+ return TRUE;
+}
+
+BOOLEAN
+WINAPI
+BasepIsImageVersionOk(IN ULONG ImageMajorVersion,
+ IN ULONG ImageMinorVersion)
+{
+ /* Accept images for NT 3.1 or higher, as long as they're not newer than us */
+ return ((ImageMajorVersion >= 3) &&
+ ((ImageMajorVersion != 3) ||
+ (ImageMinorVersion >= 10)) &&
+ (ImageMajorVersion <= SharedUserData->NtMajorVersion) &&
+ ((ImageMajorVersion != SharedUserData->NtMajorVersion) ||
+ (ImageMinorVersion <= SharedUserData->NtMinorVersion)));
+}
+
+NTSTATUS
+WINAPI
+BasepCheckWebBladeHashes(IN HANDLE FileHandle)
+{
+ NTSTATUS Status;
+ CHAR Hash[16];
+
+ /* Get all the MD5 hashes */
+ Status = RtlComputeImportTableHash(FileHandle, Hash, 1);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ /* Depending on which suite this is, run a bsearch and block the appropriate ones */
+ if (SharedUserData->SuiteMask & VER_SUITE_COMPUTE_SERVER)
+ {
+ DPRINT1("Egad! This is a ReactOS Compute Server and we should prevent you
from using certain APIs...but we won't.");
+ }
+ else if (SharedUserData->SuiteMask & VER_SUITE_STORAGE_SERVER)
+ {
+ DPRINT1("Gasp! This is a ReactOS Storage Server and we should prevent you
from using certain APIs...but we won't.");
+ }
+ else if (SharedUserData->SuiteMask & VER_SUITE_BLADE)
+ {
+ DPRINT1("Golly! This is a ReactOS Web Blade Server and we should prevent you
from using certain APIs...but we won't.");
+ }
+
+ /* Actually, fuck it, don't block anything, we're open source */
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+BasepSaveAppCertRegistryValue(IN PLIST_ENTRY List,
+ IN PWCHAR ComponentName,
+ IN PWCHAR DllName)
+{
+ /* Pretty much the only thing this key is used for, is malware */
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS
+NTAPI
+BasepConfigureAppCertDlls(IN PWSTR ValueName,
+ IN ULONG ValueType,
+ IN PVOID ValueData,
+ IN ULONG ValueLength,
+ IN PVOID Context,
+ IN PVOID EntryContext)
+{
+ /* Add this to the certification list */
+ return BasepSaveAppCertRegistryValue(Context, ValueName, ValueData);
+}
+
+NTSTATUS
+WINAPI
+BasepIsProcessAllowed(IN PCHAR ApplicationName)
+{
+ NTSTATUS Status;
+ PWCHAR Buffer;
+ UINT Length;
+ HMODULE TrustLibrary;
+ PBASEP_APPCERT_ENTRY Entry;
+ ULONG CertFlag;
+ PLIST_ENTRY NextEntry;
+ HANDLE KeyHandle;
+ UNICODE_STRING CertKey =
RTL_CONSTANT_STRING(L"\\Registry\\MACHINE\\System\\CurrentControlSet\\Control\\Session
Manager\\AppCertDlls");
+ OBJECT_ATTRIBUTES KeyAttributes = RTL_CONSTANT_OBJECT_ATTRIBUTES(&CertKey,
OBJ_CASE_INSENSITIVE);
+
+ /* Try to initialize the certification subsystem */
+ while (!g_AppCertInitialized)
+ {
+ /* Defaults */
+ Status = STATUS_SUCCESS;
+ Buffer = NULL;
+
+ /* Acquire the lock while initializing and see if we lost a race */
+ RtlEnterCriticalSection(&gcsAppCert);
+ if (g_AppCertInitialized) break;
+
+ /* On embedded, there is a special DLL */
+ if (SharedUserData->SuiteMask & VER_SUITE_EMBEDDEDNT)
+ {
+ /* Allocate a buffer for the name */
+ Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
+ 0,
+ MAX_PATH * sizeof(WCHAR) +
+ sizeof(UNICODE_NULL));
+ if (!Buffer)
+ {
+ /* Fail if no memory */
+ Status = STATUS_NO_MEMORY;
+ }
+ else
+ {
+ /* Now get the system32 directory in our buffer, make sure it fits */
+ Length = GetSystemDirectoryW(Buffer, MAX_PATH -
sizeof("EmbdTrst.DLL"));
+ if ((Length) && (Length <= MAX_PATH -
sizeof("EmbdTrst.DLL")))
+ {
+ /* Add a slash if needed, and add the embedded cert DLL name */
+ if (Buffer[Length - 1] != '\\') Buffer[Length++] =
'\\';
+ RtlCopyMemory(&Buffer[Length],
+ L"EmbdTrst.DLL",
+ sizeof(L"EmbdTrst.DLL"));
+
+ /* Try to load it */
+ TrustLibrary = LoadLibraryW(Buffer);
+ if (TrustLibrary)
+ {
+ /* And extract the special function out of it */
+ fEmbeddedCertFunc = (PVOID)GetProcAddress(TrustLibrary,
+
"ImageOkToRunOnEmbeddedNT");
+ }
+ }
+
+ /* If we didn't get this far, set a failure code */
+ if (!fEmbeddedCertFunc) Status = STATUS_UNSUCCESSFUL;
+ }
+ }
+ else
+ {
+ /* Other systems have a registry entry for this */
+ Status = NtOpenKey(&KeyHandle, KEY_READ, &KeyAttributes);
+ if (NT_SUCCESS(Status))
+ {
+ /* Close it, we'll query it through Rtl */
+ NtClose(KeyHandle);
+
+ /* Do the query, which will call a special callback */
+ Status = RtlQueryRegistryValues(2,
+ L"Session Manager",
+ BasepAppCertTable,
+ 0,
+ 0);
+ if (Status == 0xC0000034) Status = STATUS_SUCCESS;
+ }
+ }
+
+ /* Free any buffer if we had one */
+ if (Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
+
+ /* Check for errors, or a missing embedded/custom certification DLL */
+ if (!NT_SUCCESS(Status) ||
+ (!(fEmbeddedCertFunc) && (IsListEmpty(&BasepAppCertDllsList))))
+ {
+ /* The subsystem is not active on this machine, so give up */
+ g_HaveAppCerts = FALSE;
+ g_AppCertStatus = Status;
+ }
+ else
+ {
+ /* We have certification DLLs active, remember this */
+ g_HaveAppCerts = TRUE;
+ }
+
+ /* We are done the initialization phase, release the lock */
+ g_AppCertInitialized = TRUE;
+ RtlLeaveCriticalSection(&gcsAppCert);
+ }
+
+ /* If there's no certification DLLs present, return the failure code */
+ if (!g_HaveAppCerts) return g_AppCertStatus;
+
+ /* Otherwise, assume success and make sure we have *something* */
+ ASSERT(fEmbeddedCertFunc || !IsListEmpty(&BasepAppCertDllsList));
+ Status = STATUS_SUCCESS;
+
+ /* If the something is an embedded certification DLL, call it and return */
+ if (fEmbeddedCertFunc) return fEmbeddedCertFunc(ApplicationName);
+
+ /* Otherwise we have custom certification DLLs, parse them */
+ NextEntry = BasepAppCertDllsList.Flink;
+ CertFlag = 2;
+ while (NextEntry != &BasepAppCertDllsList)
+ {
+ /* Make sure the entry has a callback */
+ Entry = CONTAINING_RECORD(NextEntry, BASEP_APPCERT_ENTRY, Entry);
+ ASSERT(Entry->fPluginCertFunc != NULL);
+
+ /* Call it and check if it failed */
+ Status = Entry->fPluginCertFunc(ApplicationName, 1);
+ if (!NT_SUCCESS(Status)) CertFlag = 3;
+
+ /* Move on */
+ NextEntry = NextEntry->Flink;
+ }
+
+ /* Now loop them again */
+ NextEntry = BasepAppCertDllsList.Flink;
+ while (NextEntry != &BasepAppCertDllsList)
+ {
+ /* Make sure the entry has a callback */
+ Entry = CONTAINING_RECORD(NextEntry, BASEP_APPCERT_ENTRY, Entry);
+ ASSERT(Entry->fPluginCertFunc != NULL);
+
+ /* Call it, this time with the flag from the loop above */
+ Status = Entry->fPluginCertFunc(ApplicationName, CertFlag);
+ }
+
+ /* All done, return the status */
+ return Status;
+}
+
+NTSTATUS
+WINAPI
+BasepReplaceProcessThreadTokens(IN HANDLE TokenHandle,
+ IN HANDLE ProcessHandle,
+ IN HANDLE ThreadHandle)
+{
+ NTSTATUS Status;
+ ANSI_STRING SaferiReplaceProcessThreadTokens =
RTL_CONSTANT_STRING("SaferiReplaceProcessThreadTokens");
+
+ /* Enter the application certification lock */
+ RtlEnterCriticalSection(&gcsAppCert);
+
+ /* Check if we already know the function */
+ if (g_SaferReplaceProcessThreadTokens)
+ {
+ /* Call it */
+ Status = g_SaferReplaceProcessThreadTokens(TokenHandle,
+ ProcessHandle,
+ ThreadHandle) ?
+ STATUS_SUCCESS :
+ STATUS_UNSUCCESSFUL;
+ }
+ else
+ {
+ /* Check if the app certification DLL isn't loaded */
+ if (!(gSaferHandle) ||
+ (gSaferHandle == (HMODULE)-1) ||
+ (gSaferHandle == (HMODULE)-2))
+ {
+ /* Then we can't call the function */
+ Status = STATUS_ENTRYPOINT_NOT_FOUND;
+ }
+ else
+ {
+ /* We have the DLL, find the address of the Safer function */
+ Status = LdrGetProcedureAddress(gSaferHandle,
+ &SaferiReplaceProcessThreadTokens,
+ 0,
+
(PVOID*)&g_SaferReplaceProcessThreadTokens);
+ if (NT_SUCCESS(Status))
+ {
+ /* Found it, now call it */
+ Status = g_SaferReplaceProcessThreadTokens(TokenHandle,
+ ProcessHandle,
+ ThreadHandle) ?
+ STATUS_SUCCESS :
+ STATUS_UNSUCCESSFUL;
+ }
+ else
+ {
+ /* We couldn't find it, so this must be an unsupported DLL */
+ LdrUnloadDll(gSaferHandle);
+ gSaferHandle = NULL;
+ Status = STATUS_ENTRYPOINT_NOT_FOUND;
+ }
+ }
+ }
+
+ /* Release the lock and return the result */
+ RtlLeaveCriticalSection(&gcsAppCert);
+ return Status;
+}
+
+VOID
+WINAPI
+BasepSxsCloseHandles(IN PBASE_MSG_SXS_HANDLES Handles)
+{
+ NTSTATUS Status;
+
+ /* Sanity checks */
+ ASSERT(Handles != NULL);
+ ASSERT(Handles->Process == NULL || Handles->Process == NtCurrentProcess());
+
+ /* Close the file handle */
+ if (Handles->File)
+ {
+ Status = NtClose(Handles->File);
+ ASSERT(NT_SUCCESS(Status));
+ }
+
+ /* Close the section handle */
+ if (Handles->Section)
+ {
+ Status = NtClose(Handles->Section);
+ ASSERT(NT_SUCCESS(Status));
+ }
+
+ /* Unmap the section view */
+ if (Handles->ViewBase.QuadPart)
+ {
+ Status = NtUnmapViewOfSection(NtCurrentProcess(),
+ (PVOID)Handles->ViewBase.LowPart);
+ ASSERT(NT_SUCCESS(Status));
+ }
+}
static
LONG BaseExceptionFilter(EXCEPTION_POINTERS *ExceptionInfo)
@@ -608,7 +1007,7 @@
{
ProcessParameters->ConsoleFlags = 1;
}
-
+
/* See if the first 1MB should be reserved */
if ((ULONG_PTR)ApplicationPathName & 1)
{
Modified: trunk/reactos/dll/win32/kernel32/client/utils.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/…
==============================================================================
--- trunk/reactos/dll/win32/kernel32/client/utils.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/client/utils.c [iso-8859-1] Sun Jan 15 14:49:49 2012
@@ -131,7 +131,7 @@
}
}
-
+
if (NT_SUCCESS(Status)) BaseNamedObjectDirectory = BnoHandle;
Quickie:
@@ -812,7 +812,7 @@
BasepUnicodeStringTo8BitString = RtlUnicodeStringToAnsiString;
BasepUnicodeStringTo8BitSize = BasepUnicodeStringToAnsiSize;
Basep8BitStringToUnicodeSize = BasepAnsiStringToUnicodeSize;
-
+
/* FIXME: Old, deprecated way */
bIsFileApiAnsi = TRUE;
}
@@ -895,15 +895,39 @@
/*
* @unimplemented
*/
-BOOL
-WINAPI
-BasepCheckWinSaferRestrictions(IN DWORD Unknown1,
- IN DWORD Unknown2,
- IN DWORD Unknown3,
- IN DWORD Unknown4,
- IN DWORD Unknown5,
- IN DWORD Unknown6)
-{
- STUB;
- return FALSE;
-}
+NTSTATUS
+WINAPI
+BasepCheckWinSaferRestrictions(IN HANDLE UserToken,
+ IN LPWSTR ApplicationName,
+ IN HANDLE FileHandle,
+ OUT PBOOLEAN InJob,
+ OUT PHANDLE NewToken,
+ OUT PHANDLE JobHandle)
+{
+ NTSTATUS Status;
+
+ /* Validate that there's a name */
+ if ((ApplicationName) && *(ApplicationName))
+ {
+ /* Validate that the required output parameters are there */
+ if ((InJob) && (NewToken) && (JobHandle))
+ {
+ /* Do the work (one day...) */
+ UNIMPLEMENTED;
+ Status = STATUS_SUCCESS;
+ }
+ else
+ {
+ /* Act as if SEH hit this */
+ Status = STATUS_ACCESS_VIOLATION;
+ }
+ }
+ else
+ {
+ /* Input is invalid */
+ Status = STATUS_INVALID_PARAMETER;
+ }
+
+ /* Return the status */
+ return Status;
+}
Modified: trunk/reactos/dll/win32/kernel32/client/vdm.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/…
==============================================================================
--- trunk/reactos/dll/win32/kernel32/client/vdm.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/client/vdm.c [iso-8859-1] Sun Jan 15 14:49:49 2012
@@ -65,22 +65,122 @@
BOOL
WINAPI
-BaseCheckForVDM(IN HANDLE hProcess,
- OUT LPDWORD lpExitCode)
+BaseCheckVDM(IN ULONG BinaryType,
+ IN PCWCH ApplicationName,
+ IN PCWCH CommandLine,
+ IN PCWCH CurrentDirectory,
+ IN PANSI_STRING AnsiEnvironment,
+ IN PCSR_API_MESSAGE Msg,
+ IN OUT PULONG iTask,
+ IN DWORD CreationFlags,
+ IN LPSTARTUPINFOW StartupInfo)
+{
+ /* This is not supported */
+ UNIMPLEMENTED;
+ return FALSE;
+}
+
+BOOL
+WINAPI
+BaseUpdateVDMEntry(IN ULONG UpdateIndex,
+ IN OUT PHANDLE WaitHandle,
+ IN ULONG IndexInfo,
+ IN ULONG BinaryType)
+{
+ NTSTATUS Status;
+ CSR_API_MESSAGE Msg;
+ ULONG CsrRequest = MAKE_CSR_API(UPDATE_VDM_ENTRY, CSR_CONSOLE);
+
+ /* Check what update is being sent */
+ switch (UpdateIndex)
+ {
+ /* VDM is being undone */
+ case VdmEntryUndo:
+
+ /* Tell the server how far we had gotten along */
+ Msg.Data.UpdateVdmEntry.iTask = (ULONG)*WaitHandle;
+ Msg.Data.UpdateVdmEntry.VDMCreationState = IndexInfo;
+ break;
+
+ /* VDM is ready with a new process handle */
+ case VdmEntryUpdateProcess:
+
+ /* Send it the process handle */
+ Msg.Data.UpdateVdmEntry.VDMProcessHandle = *WaitHandle;
+ Msg.Data.UpdateVdmEntry.iTask = IndexInfo;
+ break;
+ }
+
+ /* Also check what kind of binary this is for the console handle */
+ if (BinaryType == BINARY_TYPE_WOW)
+ {
+ /* Magic value for 16-bit apps */
+ Msg.Data.UpdateVdmEntry.ConsoleHandle = (HANDLE)-1;
+ }
+ else if (Msg.Data.UpdateVdmEntry.iTask)
+ {
+ /* No handle for true VDM */
+ Msg.Data.UpdateVdmEntry.ConsoleHandle = 0;
+ }
+ else
+ {
+ /* Otherwise, send the regular consoel handle */
+ Msg.Data.UpdateVdmEntry.ConsoleHandle =
NtCurrentPeb()->ProcessParameters->ConsoleHandle;
+ }
+
+ /* Finally write the index and binary type */
+ Msg.Data.UpdateVdmEntry.EntryIndex = UpdateIndex;
+ Msg.Data.UpdateVdmEntry.BinaryType = BinaryType;
+
+ /* Send the message to CSRSS */
+ Status = CsrClientCallServer(&Msg, NULL, CsrRequest, sizeof(Msg));
+ if (!(NT_SUCCESS(Status)) || !(NT_SUCCESS(Msg.Status)))
+ {
+ /* Handle failure */
+ BaseSetLastNTError(Msg.Status);
+ return FALSE;
+ }
+
+ /* If this was an update, CSRSS returns a new wait handle */
+ if (UpdateIndex == VdmEntryUpdateProcess)
+ {
+ /* Return it to the caller */
+ *WaitHandle = Msg.Data.UpdateVdmEntry.WaitObjectForParent;
+ }
+
+ /* We made it */
+ return TRUE;
+}
+
+BOOL
+WINAPI
+BaseCheckForVDM(IN HANDLE ProcessHandle,
+ OUT LPDWORD ExitCode)
{
NTSTATUS Status;
EVENT_BASIC_INFORMATION EventBasicInfo;
+ CSR_API_MESSAGE Msg;
+ ULONG CsrRequest = MAKE_CSR_API(GET_VDM_EXIT_CODE, CSR_CONSOLE);
/* It's VDM if the process is actually a wait handle (an event) */
- Status = NtQueryEvent(hProcess,
+ Status = NtQueryEvent(ProcessHandle,
EventBasicInformation,
&EventBasicInfo,
sizeof(EventBasicInfo),
NULL);
if (!NT_SUCCESS(Status)) return FALSE;
- /* FIXME: Send a message to csrss */
- return FALSE;
+ /* Setup the input parameters */
+ Msg.Data.GetVdmExitCode.ConsoleHandle =
NtCurrentPeb()->ProcessParameters->ConsoleHandle;
+ Msg.Data.GetVdmExitCode.hParent = ProcessHandle;
+
+ /* Call CSRSS */
+ Status = CsrClientCallServer(&Msg, NULL, CsrRequest, sizeof(Msg));
+ if (!NT_SUCCESS(Status)) return FALSE;
+
+ /* Get the exit code from the reply */
+ *ExitCode = Msg.Data.GetVdmExitCode.ExitCode;
+ return TRUE;
}
BOOL
@@ -97,7 +197,7 @@
/* Clear the buffer in case we fail */
CmdLineString->Buffer = 0;
-
+
/* Always return the same size */
*VdmSize = 0x1000000;
@@ -109,7 +209,7 @@
SetLastError(ERROR_INVALID_NAME);
return FALSE;
}
-
+
/* Check if this is VDM with a DOS Sequence ID */
if (DosSeqId)
{
@@ -132,7 +232,7 @@
(BinaryType == 0x10) ? L" " : L"-w",
(BinaryType == 0x40) ? 's' : ' ');
}
-
+
/* Create the actual string */
return RtlCreateUnicodeString(CmdLineString, CommandLine);
}
@@ -147,13 +247,13 @@
/* Start by assuming unknown type */
NameType = 1;
-
+
/* Loop all the environment names */
for (i = 0; i < (sizeof(BasepEnvNameType) / sizeof(ENV_INFO)); i++)
{
/* Get this entry */
EnvInfo = &BasepEnvNameType[i];
-
+
/* Check if it matches the name */
if ((EnvInfo->NameLength == NameLength) &&
!(_wcsnicmp(EnvInfo->Name, Name, NameLength)))
@@ -163,7 +263,7 @@
break;
}
}
-
+
/* Return what we found, or unknown if nothing */
return NameType;
}
@@ -174,10 +274,10 @@
IN PUNICODE_STRING UnicodeEnv)
{
ULONG Dummy = 0;
-
+
/* Clear the ASCII buffer since Rtl creates this for us */
if (AnsiEnv->Buffer) RtlFreeAnsiString(AnsiEnv);
-
+
/* The Unicode buffer is build by hand, though */
if (UnicodeEnv->Buffer)
{
@@ -231,7 +331,7 @@
SetLastError(ERROR_BAD_ENVIRONMENT);
goto Quickie;
}
-
+
/* Count how much space the whole environment takes */
p = Environment;
while ((*p++ != UNICODE_NULL) && (*p != UNICODE_NULL)) EnvironmentSize++;
@@ -251,7 +351,7 @@
NewEnvironment = NULL;
goto Quickie;
}
-
+
/* Begin parsing the new environment */
p = NewEnvironment;
@@ -259,12 +359,12 @@
/* Terminate it */
*p++ = UNICODE_NULL;
-
+
/* Initialize the unicode string to hold it */
EnvironmentSize = (p - NewEnvironment) * sizeof(WCHAR);
RtlInitEmptyUnicodeString(UnicodeEnv, NewEnvironment, EnvironmentSize);
UnicodeEnv->Length = EnvironmentSize;
-
+
/* Create the ASCII version of it */
Status = RtlUnicodeStringToAnsiString(AnsiEnv, UnicodeEnv, TRUE);
if (!NT_SUCCESS(Status))
@@ -282,14 +382,14 @@
Quickie:
/* Cleanup path starts here, start by destroying the envrionment copy */
if (!(lpEnvironment) && (Environment)) RtlDestroyEnvironment(Environment);
-
+
/* See if we are here due to failure */
if (NewEnvironment)
{
/* Initialize the paths to be empty */
RtlInitEmptyUnicodeString(UnicodeEnv, NULL, 0);
RtlInitEmptyAnsiString(AnsiEnv, NULL, 0);
-
+
/* Free the environment copy */
RegionSize = 0;
Status = NtFreeVirtualMemory(NtCurrentProcess(),
@@ -298,7 +398,7 @@
MEM_RELEASE);
ASSERT(NT_SUCCESS(Status));
}
-
+
/* Return the result */
return Result;
}
Modified: trunk/reactos/dll/win32/kernel32/include/kernel32.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/include…
==============================================================================
--- trunk/reactos/dll/win32/kernel32/include/kernel32.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/include/kernel32.h [iso-8859-1] Sun Jan 15 14:49:49
2012
@@ -68,6 +68,42 @@
#define HANDLE_CREATE_NEW_CONSOLE (HANDLE)-3
#define HANDLE_CREATE_NO_WINDOW (HANDLE)-4
+//
+// This stuff maybe should go in a vdm.h?
+//
+typedef enum _VDM_ENTRY_CODE
+{
+ VdmEntryUndo,
+ VdmEntryUpdateProcess,
+ VdmEntryUpdateControlCHandler
+} VDM_ENTRY_CODE;
+
+//
+// Undo States
+//
+#define VDM_UNDO_PARTIAL 0x01
+#define VDM_UNDO_FULL 0x02
+#define VDM_UNDO_REUSE 0x04
+#define VDM_UNDO_COMPLETED 0x08
+
+//
+// Binary Types to share with VDM
+//
+#define BINARY_TYPE_EXE 0x01
+#define BINARY_TYPE_COM 0x02
+#define BINARY_TYPE_PIF 0x03
+#define BINARY_TYPE_DOS 0x10
+#define BINARY_TYPE_SEPARATE_WOW 0x20
+#define BINARY_TYPE_WOW 0x40
+#define BINARY_TYPE_WOW_EX 0x80
+
+//
+// VDM States
+//
+#define VDM_NOT_LOADED 0x01
+#define VDM_NOT_READY 0x02
+#define VDM_READY 0x04
+
/* Undocumented CreateProcess flag */
#define STARTF_SHELLPRIVATE 0x400
@@ -299,6 +335,64 @@
IN PVOID Environment
);
+LPWSTR
+WINAPI
+BaseComputeProcessExePath(
+ IN LPWSTR FullPath
+);
+
+ULONG
+WINAPI
+BaseIsDosApplication(
+ IN PUNICODE_STRING PathName,
+ IN NTSTATUS Status
+);
+
+NTSTATUS
+WINAPI
+BasepCheckBadapp(
+ IN HANDLE FileHandle,
+ IN PWCHAR ApplicationName,
+ IN PWCHAR Environment,
+ IN USHORT ExeType,
+ IN PVOID* SdbQueryAppCompatData,
+ IN PULONG SdbQueryAppCompatDataSize,
+ IN PVOID* SxsData,
+ IN PULONG SxsDataSize,
+ OUT PULONG FusionFlags
+);
+
+BOOLEAN
+WINAPI
+IsShimInfrastructureDisabled(
+ VOID
+);
+
+BOOL
+NTAPI
+BaseDestroyVDMEnvironment(
+ IN PANSI_STRING AnsiEnv,
+ IN PUNICODE_STRING UnicodeEnv
+);
+
+BOOL
+WINAPI
+BaseGetVdmConfigInfo(
+ IN LPCWSTR Reserved,
+ IN ULONG DosSeqId,
+ IN ULONG BinaryType,
+ IN PUNICODE_STRING CmdLineString,
+ OUT PULONG VdmSize
+);
+
+BOOL
+NTAPI
+BaseCreateVDMEnvironment(
+ IN PWCHAR lpEnvironment,
+ IN PANSI_STRING AnsiEnv,
+ IN PUNICODE_STRING UnicodeEnv
+);
+
VOID
WINAPI
InitCommandLines(VOID);
@@ -323,7 +417,57 @@
IN PVOID Context,
OUT BOOLEAN *StopEnumeration);
-VOID
-WINAPI
-BaseMarkFileForDelete(IN HANDLE FileHandle,
- IN ULONG FileAttributes);
+typedef NTSTATUS
+(NTAPI *PBASEP_APPCERT_PLUGIN_FUNC)(
+ IN PCHAR ApplicationName,
+ IN ULONG CertFlag
+);
+
+typedef NTSTATUS
+(NTAPI *PBASEP_APPCERT_EMBEDDED_FUNC)(
+ IN PCHAR ApplicationName
+);
+
+typedef NTSTATUS
+(NTAPI *PSAFER_REPLACE_PROCESS_THREAD_TOKENS)(
+ IN HANDLE Token,
+ IN HANDLE Process,
+ IN HANDLE Thread
+);
+
+typedef struct _BASEP_APPCERT_ENTRY
+{
+ LIST_ENTRY Entry;
+ UNICODE_STRING Name;
+ PBASEP_APPCERT_PLUGIN_FUNC fPluginCertFunc;
+} BASEP_APPCERT_ENTRY, *PBASEP_APPCERT_ENTRY;
+
+typedef struct _BASE_MSG_SXS_HANDLES
+{
+ HANDLE File;
+ HANDLE Process;
+ HANDLE Section;
+ LARGE_INTEGER ViewBase;
+} BASE_MSG_SXS_HANDLES, *PBASE_MSG_SXS_HANDLES;
+
+NTSTATUS
+NTAPI
+BasepConfigureAppCertDlls(
+ IN PWSTR ValueName,
+ IN ULONG ValueType,
+ IN PVOID ValueData,
+ IN ULONG ValueLength,
+ IN PVOID Context,
+ IN PVOID EntryContext
+);
+
+extern LIST_ENTRY BasepAppCertDllsList;
+extern RTL_CRITICAL_SECTION gcsAppCert;
+
+VOID
+WINAPI
+BaseMarkFileForDelete(
+ IN HANDLE FileHandle,
+ IN ULONG FileAttributes
+);
+
Modified: trunk/reactos/dll/win32/kernel32/kernel32.pspec
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/kernel3…
==============================================================================
--- trunk/reactos/dll/win32/kernel32/kernel32.pspec [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/kernel32.pspec [iso-8859-1] Sun Jan 15 14:49:49 2012
@@ -23,7 +23,7 @@
@ stdcall BaseDumpAppcompatCache()
@ stdcall BaseFlushAppcompatCache()
@ stdcall BaseInitAppcompatCacheSupport()
-@ stdcall BaseIsAppcompatInfrastructureDisabled()
+@ stdcall BaseIsAppcompatInfrastructureDisabled() IsShimInfrastructureDisabled
@ stdcall BaseProcessInitPostImport() ; missing in Win 7
@ stdcall BaseQueryModuleData(str str ptr ptr ptr) ;check
@ stdcall BaseUpdateAppcompatCache(long long long)
Modified: trunk/reactos/dll/win32/kernel32/kernel32.spec
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/kernel3…
==============================================================================
--- trunk/reactos/dll/win32/kernel32/kernel32.spec [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/kernel32.spec [iso-8859-1] Sun Jan 15 14:49:49 2012
@@ -23,7 +23,7 @@
@ stdcall BaseDumpAppcompatCache()
@ stdcall BaseFlushAppcompatCache()
@ stdcall BaseInitAppcompatCacheSupport()
-@ stdcall BaseIsAppcompatInfrastructureDisabled()
+@ stdcall BaseIsAppcompatInfrastructureDisabled() IsShimInfrastructureDisabled
@ stdcall BaseProcessInitPostImport() ; missing in Win 7
@ stdcall BaseQueryModuleData(str str ptr ptr ptr) ;check
@ stdcall BaseUpdateAppcompatCache(long long long)