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/a... ============================================================================== --- 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/d... ============================================================================== --- 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/p... ============================================================================== --- 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/u... ============================================================================== --- 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/v... ============================================================================== --- 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/kernel32... ============================================================================== --- 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/kernel32... ============================================================================== --- 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)