[ros-diffs] [ion] 54975: Note, none of this code is being used/called yet. [KERNEL32]: Implement BasepSxsCloseHandles, BasepReplaceProcessThreadTokens, BasepIsProcessAllowed, BasepCheckWebBladeHashes, BasepIsI...

ion at svn.reactos.org ion at svn.reactos.org
Sun Jan 15 14:49:49 UTC 2012


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/appcache.c?rev=54975&r1=54974&r2=54975&view=diff
==============================================================================
--- 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/dllmain.c?rev=54975&r1=54974&r2=54975&view=diff
==============================================================================
--- 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/proc.c?rev=54975&r1=54974&r2=54975&view=diff
==============================================================================
--- 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/utils.c?rev=54975&r1=54974&r2=54975&view=diff
==============================================================================
--- 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/vdm.c?rev=54975&r1=54974&r2=54975&view=diff
==============================================================================
--- 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/kernel32.h?rev=54975&r1=54974&r2=54975&view=diff
==============================================================================
--- 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.pspec?rev=54975&r1=54974&r2=54975&view=diff
==============================================================================
--- 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.spec?rev=54975&r1=54974&r2=54975&view=diff
==============================================================================
--- 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)




More information about the Ros-diffs mailing list