2012-10-20 21:03:32 +00:00
|
|
|
/*
|
|
|
|
* COPYRIGHT: See COPYING in the top level directory
|
2013-04-07 23:39:39 +00:00
|
|
|
* PROJECT: ReactOS Base API Server DLL
|
2012-10-20 21:03:32 +00:00
|
|
|
* FILE: subsystems/win/basesrv/init.c
|
|
|
|
* PURPOSE: Initialization
|
2016-06-01 13:22:33 +00:00
|
|
|
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
|
|
|
* Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
2019-05-18 11:37:35 +00:00
|
|
|
* Pierre Schweitzer (pierre@reactos.org)
|
2005-08-12 12:22:02 +00:00
|
|
|
*/
|
2012-10-20 21:03:32 +00:00
|
|
|
|
2013-03-09 21:08:23 +00:00
|
|
|
/* INCLUDES *******************************************************************/
|
|
|
|
|
2005-08-12 12:22:02 +00:00
|
|
|
#include "basesrv.h"
|
2014-02-09 17:37:35 +00:00
|
|
|
#include "vdm.h"
|
2014-01-04 10:29:54 +00:00
|
|
|
|
|
|
|
#include <winreg.h>
|
2005-08-12 12:22:02 +00:00
|
|
|
|
|
|
|
#define NDEBUG
|
|
|
|
#include <debug.h>
|
|
|
|
|
2014-01-04 10:29:54 +00:00
|
|
|
#include "api.h"
|
|
|
|
|
2013-03-09 21:08:23 +00:00
|
|
|
/* GLOBALS ********************************************************************/
|
|
|
|
|
|
|
|
HANDLE BaseSrvDllInstance = NULL;
|
2013-08-29 20:13:31 +00:00
|
|
|
extern UNICODE_STRING BaseSrvKernel32DllPath;
|
2005-08-12 12:22:02 +00:00
|
|
|
|
2012-10-21 17:18:33 +00:00
|
|
|
/* Memory */
|
|
|
|
HANDLE BaseSrvHeap = NULL; // Our own heap.
|
|
|
|
HANDLE BaseSrvSharedHeap = NULL; // Shared heap with CSR. (CsrSrvSharedSectionHeap)
|
|
|
|
PBASE_STATIC_SERVER_DATA BaseStaticServerData = NULL; // Data that we can share amongst processes. Initialized inside BaseSrvSharedHeap.
|
|
|
|
|
2019-05-07 20:41:30 +00:00
|
|
|
ULONG SessionId = 0;
|
2019-05-07 20:48:41 +00:00
|
|
|
ULONG ProtectionMode = 0;
|
2019-05-07 20:41:30 +00:00
|
|
|
|
2013-09-04 07:07:08 +00:00
|
|
|
PINIFILE_MAPPING BaseSrvIniFileMapping;
|
|
|
|
|
2013-03-09 21:08:23 +00:00
|
|
|
// Windows Server 2003 table from http://j00ru.vexillium.org/csrss_list/api_list.html#Windows_2k3
|
2013-03-10 19:37:33 +00:00
|
|
|
PCSR_API_ROUTINE BaseServerApiDispatchTable[BasepMaxApiNumber - BASESRV_FIRST_API_NUMBER] =
|
2012-10-20 21:03:32 +00:00
|
|
|
{
|
|
|
|
BaseSrvCreateProcess,
|
|
|
|
BaseSrvCreateThread,
|
|
|
|
BaseSrvGetTempFile,
|
|
|
|
BaseSrvExitProcess,
|
2013-08-29 17:00:10 +00:00
|
|
|
BaseSrvDebugProcess,
|
|
|
|
BaseSrvCheckVDM,
|
|
|
|
BaseSrvUpdateVDMEntry,
|
|
|
|
BaseSrvGetNextVDMCommand,
|
|
|
|
BaseSrvExitVDM,
|
|
|
|
BaseSrvIsFirstVDM,
|
|
|
|
BaseSrvGetVDMExitCode,
|
|
|
|
BaseSrvSetReenterCount,
|
2012-10-20 21:03:32 +00:00
|
|
|
BaseSrvSetProcessShutdownParam,
|
|
|
|
BaseSrvGetProcessShutdownParam,
|
2013-08-29 17:00:10 +00:00
|
|
|
BaseSrvNlsSetUserInfo,
|
|
|
|
BaseSrvNlsSetMultipleUserInfo,
|
|
|
|
BaseSrvNlsCreateSection,
|
|
|
|
BaseSrvSetVDMCurDirs,
|
|
|
|
BaseSrvGetVDMCurDirs,
|
|
|
|
BaseSrvBatNotification,
|
|
|
|
BaseSrvRegisterWowExec,
|
2012-10-20 21:03:32 +00:00
|
|
|
BaseSrvSoundSentryNotification,
|
2013-08-29 17:00:10 +00:00
|
|
|
BaseSrvRefreshIniFileMapping,
|
2013-03-09 21:08:23 +00:00
|
|
|
BaseSrvDefineDosDevice,
|
2013-08-29 17:00:10 +00:00
|
|
|
BaseSrvSetTermsrvAppInstallMode,
|
|
|
|
BaseSrvNlsUpdateCacheCount,
|
|
|
|
BaseSrvSetTermsrvClientTimeZone,
|
|
|
|
BaseSrvSxsCreateActivationContext,
|
2014-12-16 20:15:35 +00:00
|
|
|
BaseSrvDebugProcess,
|
2013-08-29 17:00:10 +00:00
|
|
|
BaseSrvRegisterThread,
|
|
|
|
BaseSrvNlsGetUserInfo,
|
2012-10-20 21:03:32 +00:00
|
|
|
};
|
|
|
|
|
2013-03-10 19:37:33 +00:00
|
|
|
BOOLEAN BaseServerApiServerValidTable[BasepMaxApiNumber - BASESRV_FIRST_API_NUMBER] =
|
2012-10-20 21:03:32 +00:00
|
|
|
{
|
2013-03-09 21:08:23 +00:00
|
|
|
TRUE, // BaseSrvCreateProcess
|
|
|
|
TRUE, // BaseSrvCreateThread
|
|
|
|
TRUE, // BaseSrvGetTempFile
|
|
|
|
FALSE, // BaseSrvExitProcess
|
2013-08-29 17:00:10 +00:00
|
|
|
FALSE, // BaseSrvDebugProcess
|
|
|
|
TRUE, // BaseSrvCheckVDM
|
|
|
|
TRUE, // BaseSrvUpdateVDMEntry
|
|
|
|
TRUE, // BaseSrvGetNextVDMCommand
|
|
|
|
TRUE, // BaseSrvExitVDM
|
|
|
|
TRUE, // BaseSrvIsFirstVDM
|
|
|
|
TRUE, // BaseSrvGetVDMExitCode
|
|
|
|
TRUE, // BaseSrvSetReenterCount
|
2013-03-09 21:08:23 +00:00
|
|
|
TRUE, // BaseSrvSetProcessShutdownParam
|
|
|
|
TRUE, // BaseSrvGetProcessShutdownParam
|
2013-08-29 17:00:10 +00:00
|
|
|
TRUE, // BaseSrvNlsSetUserInfo
|
|
|
|
TRUE, // BaseSrvNlsSetMultipleUserInfo
|
|
|
|
TRUE, // BaseSrvNlsCreateSection
|
|
|
|
TRUE, // BaseSrvSetVDMCurDirs
|
|
|
|
TRUE, // BaseSrvGetVDMCurDirs
|
|
|
|
TRUE, // BaseSrvBatNotification
|
|
|
|
TRUE, // BaseSrvRegisterWowExec
|
2013-03-09 21:08:23 +00:00
|
|
|
TRUE, // BaseSrvSoundSentryNotification
|
2013-08-29 17:00:10 +00:00
|
|
|
TRUE, // BaseSrvRefreshIniFileMapping
|
2013-03-09 21:08:23 +00:00
|
|
|
TRUE, // BaseSrvDefineDosDevice
|
2013-08-29 20:13:31 +00:00
|
|
|
TRUE, // BaseSrvSetTermsrvAppInstallMode
|
|
|
|
TRUE, // BaseSrvNlsUpdateCacheCount
|
|
|
|
TRUE, // BaseSrvSetTermsrvClientTimeZone
|
|
|
|
TRUE, // BaseSrvSxsCreateActivationContext
|
2014-12-16 20:15:35 +00:00
|
|
|
FALSE, // BaseSrvDebugProcess
|
2013-08-29 20:13:31 +00:00
|
|
|
TRUE, // BaseSrvRegisterThread
|
|
|
|
TRUE, // BaseSrvNlsGetUserInfo
|
2012-10-20 21:03:32 +00:00
|
|
|
};
|
|
|
|
|
[CSR]
During my investigations for making working Win2k3 csrsrv.dll (or other CSR servers) into ROS (to compare our behaviour with our own csrsrv.dll and Win2k3 one), I hit a problem: if I test a checked-build version of csrsrv (or other CSR servers), everything was fine when they were loaded, but if I use a release-build version (i.e. without any debug information), I systematically hit a memory access violation which was traced back to the moment when a CSR server's CsrInitialization entry point was called.
So I did the experiment, where I used our (debug-build) csrsrv with a free-build win2k3 CSR server dll (it was winsrv.dll, and I retested with basesrv.dll after). I hit the access violation. But if I took a debug-build version of winsrv.dll, everything was OK.
I then added in our csrsrv' server.c file the following line (around line 212 of the current file version):
DPRINT1("%s ; ServerDll->ValidTable = 0x%p ; ServerDll->NameTable = 0x%p ; ServerDll->SizeOfProcessData = %d ; ServerDll->ConnectCallback = 0x%p\n", DllString, ServerDll->ValidTable, ServerDll->NameTable, ServerDll->SizeOfProcessData, ServerDll->ConnectCallback);
and I saw that, when using a debug-build win2k3 CSR server, everything was fine (in particular the ServerDll->SizeOfProcessData member contained a reasonable value, e.g. a size of 88 bytes), whereas if I used a free-build version, I got an off-by-one problem, with the ServerDll->ValidTable pointer valid but the ServerDll->NameTable member being equal to 88 (i.e. invalid pointer) and the ServerDll->SizeOfProcessData member being equal to a very large value, which looked like a pointer value.
After more investigations, I saw that in debug-build CSR servers the list of API names were stored, whereas it was not the case in free-build versions. Therefore I concluded that the API names table was included *ONLY* in debug builds and not in release builds.
Hence, to be able to test in ROS either debug-builds or release-builds versions of Windows CSR servers in ROS (and vice-versa), I introduced a #define called CSR_DBG, which is defined only if the DBG macro is != 0, and which is not defined otherwise. When the CSR_DBG flag is defined, API names tables are added in CSR servers and otherwise, they are not.
Therefore, we are now able to test debug-build Windows CSR servers in ROS (the default possibility) or free-build versions of these CSR servers (but first, we have to build the other ones without the CSR_DBG flag, to avoid the off-by-one problem described above).
svn path=/trunk/; revision=60560
2013-10-06 13:33:17 +00:00
|
|
|
/*
|
|
|
|
* On Windows Server 2003, CSR Servers contain
|
|
|
|
* the API Names Table only in Debug Builds.
|
|
|
|
*/
|
|
|
|
#ifdef CSR_DBG
|
2013-03-10 19:37:33 +00:00
|
|
|
PCHAR BaseServerApiNameTable[BasepMaxApiNumber - BASESRV_FIRST_API_NUMBER] =
|
2012-10-20 21:03:32 +00:00
|
|
|
{
|
|
|
|
"BaseCreateProcess",
|
|
|
|
"BaseCreateThread",
|
|
|
|
"BaseGetTempFile",
|
|
|
|
"BaseExitProcess",
|
2013-08-29 17:00:10 +00:00
|
|
|
"BaseDebugProcess",
|
|
|
|
"BaseCheckVDM",
|
|
|
|
"BaseUpdateVDMEntry",
|
|
|
|
"BaseGetNextVDMCommand",
|
|
|
|
"BaseExitVDM",
|
|
|
|
"BaseIsFirstVDM",
|
|
|
|
"BaseGetVDMExitCode",
|
|
|
|
"BaseSetReenterCount",
|
2012-10-20 21:03:32 +00:00
|
|
|
"BaseSetProcessShutdownParam",
|
|
|
|
"BaseGetProcessShutdownParam",
|
2013-08-29 17:00:10 +00:00
|
|
|
"BaseNlsSetUserInfo",
|
|
|
|
"BaseNlsSetMultipleUserInfo",
|
|
|
|
"BaseNlsCreateSection",
|
|
|
|
"BaseSetVDMCurDirs",
|
|
|
|
"BaseGetVDMCurDirs",
|
|
|
|
"BaseBatNotification",
|
|
|
|
"BaseRegisterWowExec",
|
2012-10-20 21:03:32 +00:00
|
|
|
"BaseSoundSentryNotification",
|
2013-08-29 17:00:10 +00:00
|
|
|
"BaseRefreshIniFileMapping",
|
2012-10-20 21:03:32 +00:00
|
|
|
"BaseDefineDosDevice",
|
2013-08-29 17:00:10 +00:00
|
|
|
"BaseSetTermsrvAppInstallMode",
|
|
|
|
"BaseNlsUpdateCacheCount",
|
|
|
|
"BaseSetTermsrvClientTimeZone",
|
|
|
|
"BaseSxsCreateActivationContext",
|
2014-12-16 20:15:35 +00:00
|
|
|
"BaseSrvDebugProcessStop",
|
2013-08-29 17:00:10 +00:00
|
|
|
"BaseRegisterThread",
|
2013-08-29 18:13:24 +00:00
|
|
|
"BaseNlsGetUserInfo",
|
2012-10-20 21:03:32 +00:00
|
|
|
};
|
[CSR]
During my investigations for making working Win2k3 csrsrv.dll (or other CSR servers) into ROS (to compare our behaviour with our own csrsrv.dll and Win2k3 one), I hit a problem: if I test a checked-build version of csrsrv (or other CSR servers), everything was fine when they were loaded, but if I use a release-build version (i.e. without any debug information), I systematically hit a memory access violation which was traced back to the moment when a CSR server's CsrInitialization entry point was called.
So I did the experiment, where I used our (debug-build) csrsrv with a free-build win2k3 CSR server dll (it was winsrv.dll, and I retested with basesrv.dll after). I hit the access violation. But if I took a debug-build version of winsrv.dll, everything was OK.
I then added in our csrsrv' server.c file the following line (around line 212 of the current file version):
DPRINT1("%s ; ServerDll->ValidTable = 0x%p ; ServerDll->NameTable = 0x%p ; ServerDll->SizeOfProcessData = %d ; ServerDll->ConnectCallback = 0x%p\n", DllString, ServerDll->ValidTable, ServerDll->NameTable, ServerDll->SizeOfProcessData, ServerDll->ConnectCallback);
and I saw that, when using a debug-build win2k3 CSR server, everything was fine (in particular the ServerDll->SizeOfProcessData member contained a reasonable value, e.g. a size of 88 bytes), whereas if I used a free-build version, I got an off-by-one problem, with the ServerDll->ValidTable pointer valid but the ServerDll->NameTable member being equal to 88 (i.e. invalid pointer) and the ServerDll->SizeOfProcessData member being equal to a very large value, which looked like a pointer value.
After more investigations, I saw that in debug-build CSR servers the list of API names were stored, whereas it was not the case in free-build versions. Therefore I concluded that the API names table was included *ONLY* in debug builds and not in release builds.
Hence, to be able to test in ROS either debug-builds or release-builds versions of Windows CSR servers in ROS (and vice-versa), I introduced a #define called CSR_DBG, which is defined only if the DBG macro is != 0, and which is not defined otherwise. When the CSR_DBG flag is defined, API names tables are added in CSR servers and otherwise, they are not.
Therefore, we are now able to test debug-build Windows CSR servers in ROS (the default possibility) or free-build versions of these CSR servers (but first, we have to build the other ones without the CSR_DBG flag, to avoid the off-by-one problem described above).
svn path=/trunk/; revision=60560
2013-10-06 13:33:17 +00:00
|
|
|
#endif
|
2012-10-20 21:03:32 +00:00
|
|
|
|
|
|
|
/* FUNCTIONS ******************************************************************/
|
|
|
|
|
2013-09-04 07:07:08 +00:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
BaseSrvInitializeIniFileMappings(IN PBASE_STATIC_SERVER_DATA StaticServerData)
|
|
|
|
{
|
|
|
|
/* Allocate the mapping blob */
|
This commit, in my opinion, marks an important milestone in ReactOS development. One is now able to boot to desktop, launch applications, download through the application manager, play solitaire, minesweeper, launch Task Manager, etc... by using an unmodified Windows 2003 kernel32.dll binary (and, until our NPFS driver is fixed, the unmodified Windows 2003 NPFS driver). Additionally, one is able to achieve the same by booting with an unmodified Windows 2003 ntdll.dll, including a combination of both. The capability to mix-and-match components such as kernel32 and ntdll, at the heart of the system, will allow to better understand apitest failures (just as Wine has long had the capability to use Windows DLLs instead). With these two building blocks, additional Windows 2003 DLLs can be dropped in/tested, etc, and where failures are seen, a likely component can now be blamed. Furthermore, debugging with public symbols for these DLLs is now possible with WinDBG (in fact, this is how many bugs were fixed in this attempt). Many issues already exist when running with this combination FYI, for example, I was not able to launch any installers (tested Firefox and MIRC). This already demonstrates either missing functionality or ReactOS-specific functionality in components which depend on kernel32. I suspect the next step is infrastructure work to get special patchbot/builders to try and report back winetest results, and for additional DLLs to be "ported"/made to work. On a final note, this mixing and matching has benefits on both ends -- it's now likely that ReactOS' ntdll can run on Server 2003, at least far enough to get to Explorer or Task Manager. Running apitests on Server 2003 with and without reactos DLLs should also easily identify if certain DLLs are directly to blame for certain regressions/failures. </end excited rant>
[BASESRV]: Allocate the INI mappings from the right heap.
svn path=/trunk/; revision=59985
2013-09-04 07:28:15 +00:00
|
|
|
BaseSrvIniFileMapping = RtlAllocateHeap(BaseSrvSharedHeap,
|
2013-09-04 07:07:08 +00:00
|
|
|
HEAP_ZERO_MEMORY,
|
|
|
|
sizeof(*BaseSrvIniFileMapping));
|
|
|
|
if (BaseSrvIniFileMapping == NULL)
|
|
|
|
{
|
|
|
|
DPRINT1("BASESRV: Unable to allocate memory in shared heap for IniFileMapping\n");
|
|
|
|
return STATUS_NO_MEMORY;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set it*/
|
|
|
|
StaticServerData->IniFileMapping = BaseSrvIniFileMapping;
|
|
|
|
|
|
|
|
/* FIXME: Do the work to initialize the mappings */
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2012-10-21 17:18:33 +00:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
CreateBaseAcls(OUT PACL* Dacl,
|
|
|
|
OUT PACL* RestrictedDacl)
|
|
|
|
{
|
|
|
|
PSID SystemSid, WorldSid, RestrictedSid;
|
|
|
|
SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
|
|
|
|
SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY};
|
|
|
|
NTSTATUS Status;
|
2013-04-14 12:14:00 +00:00
|
|
|
UCHAR KeyValueBuffer[0x40];
|
|
|
|
PKEY_VALUE_PARTIAL_INFORMATION KeyValuePartialInfo;
|
|
|
|
UNICODE_STRING KeyName;
|
|
|
|
ULONG AclLength;
|
|
|
|
ULONG ResultLength;
|
|
|
|
HANDLE hKey;
|
|
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
2019-05-18 09:05:30 +00:00
|
|
|
ULONG ObjectSecurityMode;
|
|
|
|
ACCESS_MASK WorldAccess, RestrictedAccess;
|
2012-10-21 17:18:33 +00:00
|
|
|
|
|
|
|
/* Open the Session Manager Key */
|
|
|
|
RtlInitUnicodeString(&KeyName, SM_REG_KEY);
|
|
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
|
|
&KeyName,
|
|
|
|
OBJ_CASE_INSENSITIVE,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
|
|
|
Status = NtOpenKey(&hKey, KEY_READ, &ObjectAttributes);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
2013-04-14 12:14:00 +00:00
|
|
|
/* Read the key value */
|
2012-10-21 17:18:33 +00:00
|
|
|
RtlInitUnicodeString(&KeyName, L"ProtectionMode");
|
|
|
|
Status = NtQueryValueKey(hKey,
|
|
|
|
&KeyName,
|
|
|
|
KeyValuePartialInformation,
|
|
|
|
KeyValueBuffer,
|
|
|
|
sizeof(KeyValueBuffer),
|
|
|
|
&ResultLength);
|
|
|
|
|
2013-04-14 12:14:00 +00:00
|
|
|
/* Make sure it's what we expect it to be */
|
2012-10-21 17:18:33 +00:00
|
|
|
KeyValuePartialInfo = (PKEY_VALUE_PARTIAL_INFORMATION)KeyValueBuffer;
|
|
|
|
if ((NT_SUCCESS(Status)) && (KeyValuePartialInfo->Type == REG_DWORD) &&
|
|
|
|
(*(PULONG)KeyValuePartialInfo->Data))
|
|
|
|
{
|
2013-04-14 12:14:00 +00:00
|
|
|
/* Save the Protection Mode */
|
|
|
|
ProtectionMode = *(PULONG)KeyValuePartialInfo->Data;
|
2012-10-21 17:18:33 +00:00
|
|
|
}
|
|
|
|
|
2013-04-14 12:14:00 +00:00
|
|
|
/* Close the handle */
|
2012-10-21 17:18:33 +00:00
|
|
|
NtClose(hKey);
|
|
|
|
}
|
|
|
|
|
2019-05-18 09:05:30 +00:00
|
|
|
/* Get object security mode */
|
|
|
|
if (SessionId == 0 ||
|
|
|
|
!NT_SUCCESS(NtQuerySystemInformation(SystemObjectSecurityMode, &ObjectSecurityMode, sizeof(ULONG), NULL)))
|
|
|
|
{
|
|
|
|
ObjectSecurityMode = 0;
|
|
|
|
}
|
|
|
|
|
2012-10-21 17:18:33 +00:00
|
|
|
/* Allocate the System SID */
|
|
|
|
Status = RtlAllocateAndInitializeSid(&NtAuthority,
|
|
|
|
1, SECURITY_LOCAL_SYSTEM_RID,
|
|
|
|
0, 0, 0, 0, 0, 0, 0,
|
|
|
|
&SystemSid);
|
2019-05-18 11:37:35 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
return Status;
|
|
|
|
}
|
2012-10-21 17:18:33 +00:00
|
|
|
|
|
|
|
/* Allocate the World SID */
|
|
|
|
Status = RtlAllocateAndInitializeSid(&WorldAuthority,
|
|
|
|
1, SECURITY_WORLD_RID,
|
|
|
|
0, 0, 0, 0, 0, 0, 0,
|
|
|
|
&WorldSid);
|
2019-05-18 11:37:35 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
RtlFreeSid(SystemSid);
|
|
|
|
goto Return;
|
|
|
|
}
|
2012-10-21 17:18:33 +00:00
|
|
|
|
|
|
|
/* Allocate the restricted SID */
|
|
|
|
Status = RtlAllocateAndInitializeSid(&NtAuthority,
|
|
|
|
1, SECURITY_RESTRICTED_CODE_RID,
|
|
|
|
0, 0, 0, 0, 0, 0, 0,
|
|
|
|
&RestrictedSid);
|
2019-05-18 11:37:35 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
RtlFreeSid(WorldSid);
|
|
|
|
RtlFreeSid(SystemSid);
|
|
|
|
goto Return;
|
|
|
|
}
|
2012-10-21 17:18:33 +00:00
|
|
|
|
|
|
|
/* Allocate one ACL with 3 ACEs each for one SID */
|
|
|
|
AclLength = sizeof(ACL) + 3 * sizeof(ACCESS_ALLOWED_ACE) +
|
2013-04-07 18:28:38 +00:00
|
|
|
RtlLengthSid(SystemSid) +
|
|
|
|
RtlLengthSid(WorldSid) +
|
|
|
|
RtlLengthSid(RestrictedSid);
|
2012-10-21 17:18:33 +00:00
|
|
|
*Dacl = RtlAllocateHeap(BaseSrvHeap, 0, AclLength);
|
2019-05-18 11:37:35 +00:00
|
|
|
if (*Dacl == NULL)
|
|
|
|
{
|
|
|
|
Status = STATUS_NO_MEMORY;
|
|
|
|
goto FreeAndReturn;
|
|
|
|
}
|
2012-10-21 17:18:33 +00:00
|
|
|
|
|
|
|
/* Set the correct header fields */
|
|
|
|
Status = RtlCreateAcl(*Dacl, AclLength, ACL_REVISION2);
|
2019-05-18 11:37:35 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
RtlFreeHeap(BaseSrvHeap, 0, *Dacl);
|
|
|
|
goto FreeAndReturn;
|
|
|
|
}
|
2012-10-21 17:18:33 +00:00
|
|
|
|
2019-05-18 09:05:30 +00:00
|
|
|
/* Setup access for anyone depending on object security mode */
|
|
|
|
if (ObjectSecurityMode != 0)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* If we have restrictions on security mode, make it read only
|
|
|
|
* it also means session ID is not 0
|
|
|
|
*/
|
|
|
|
WorldAccess = DIRECTORY_QUERY | DIRECTORY_TRAVERSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Otherwise, open wide */
|
|
|
|
WorldAccess = READ_CONTROL | DIRECTORY_QUERY | DIRECTORY_TRAVERSE | DIRECTORY_CREATE_OBJECT | DIRECTORY_CREATE_SUBDIRECTORY;
|
|
|
|
}
|
|
|
|
|
2012-10-21 17:18:33 +00:00
|
|
|
/* Give the appropriate rights to each SID */
|
2019-05-18 11:37:35 +00:00
|
|
|
if (NT_SUCCESS(RtlAddAccessAllowedAce(*Dacl, ACL_REVISION2, WorldAccess, WorldSid)) &&
|
|
|
|
NT_SUCCESS(RtlAddAccessAllowedAce(*Dacl, ACL_REVISION2, DIRECTORY_ALL_ACCESS, SystemSid)))
|
|
|
|
{
|
|
|
|
RtlAddAccessAllowedAce(*Dacl, ACL_REVISION2, DIRECTORY_TRAVERSE, RestrictedSid);
|
|
|
|
}
|
2012-10-21 17:18:33 +00:00
|
|
|
|
|
|
|
/* Now allocate the restricted DACL */
|
|
|
|
*RestrictedDacl = RtlAllocateHeap(BaseSrvHeap, 0, AclLength);
|
2019-05-18 11:37:35 +00:00
|
|
|
if (*RestrictedDacl == NULL)
|
|
|
|
{
|
|
|
|
Status = STATUS_NO_MEMORY;
|
|
|
|
RtlFreeHeap(BaseSrvHeap, 0, *Dacl);
|
|
|
|
goto FreeAndReturn;
|
|
|
|
}
|
2012-10-21 17:18:33 +00:00
|
|
|
|
|
|
|
/* Initialize it */
|
|
|
|
Status = RtlCreateAcl(*RestrictedDacl, AclLength, ACL_REVISION2);
|
2019-05-18 11:37:35 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
RtlFreeHeap(BaseSrvHeap, 0, *RestrictedDacl);
|
|
|
|
RtlFreeHeap(BaseSrvHeap, 0, *Dacl);
|
|
|
|
goto FreeAndReturn;
|
|
|
|
}
|
2012-10-21 17:18:33 +00:00
|
|
|
|
2019-05-18 09:05:30 +00:00
|
|
|
/* Setup access for restricted sid depending on session id and protection mode */
|
|
|
|
if (SessionId == 0 || (ProtectionMode & 3) == 0)
|
|
|
|
{
|
|
|
|
/* If we have no session ID or if protection mode is not set, then open wide */
|
|
|
|
RestrictedAccess = READ_CONTROL | DIRECTORY_QUERY | DIRECTORY_TRAVERSE | DIRECTORY_CREATE_OBJECT | DIRECTORY_CREATE_SUBDIRECTORY;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Otherwise, make read only */
|
|
|
|
RestrictedAccess = READ_CONTROL | DIRECTORY_QUERY | DIRECTORY_TRAVERSE;
|
|
|
|
}
|
|
|
|
|
2012-10-21 17:18:33 +00:00
|
|
|
/* And add the same ACEs as before */
|
2019-05-18 09:05:30 +00:00
|
|
|
Status = RtlAddAccessAllowedAce(*RestrictedDacl, ACL_REVISION2, WorldAccess, WorldSid);
|
2019-05-18 11:37:35 +00:00
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
Status = RtlAddAccessAllowedAce(*RestrictedDacl, ACL_REVISION2, DIRECTORY_ALL_ACCESS, SystemSid);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
Status = RtlAddAccessAllowedAce(*RestrictedDacl, ACL_REVISION2, RestrictedAccess, RestrictedSid);
|
|
|
|
}
|
|
|
|
}
|
2012-10-21 17:18:33 +00:00
|
|
|
|
|
|
|
/* The SIDs are captured, can free them now */
|
2019-05-18 11:37:35 +00:00
|
|
|
FreeAndReturn:
|
2013-04-07 18:28:38 +00:00
|
|
|
RtlFreeSid(RestrictedSid);
|
|
|
|
RtlFreeSid(WorldSid);
|
|
|
|
RtlFreeSid(SystemSid);
|
2019-05-18 11:37:35 +00:00
|
|
|
|
|
|
|
Return:
|
2012-10-21 17:18:33 +00:00
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
2012-10-20 21:03:32 +00:00
|
|
|
VOID
|
|
|
|
NTAPI
|
2012-10-21 17:18:33 +00:00
|
|
|
BaseInitializeStaticServerData(IN PCSR_SERVER_DLL LoadedServerDll)
|
2012-10-20 21:03:32 +00:00
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
2013-09-10 20:45:53 +00:00
|
|
|
BOOLEAN Success;
|
2019-05-08 18:06:49 +00:00
|
|
|
WCHAR BnoBuffer[100];
|
2019-05-08 18:39:57 +00:00
|
|
|
WCHAR Buffer[MAX_PATH];
|
2012-10-20 21:03:32 +00:00
|
|
|
PWCHAR HeapBuffer;
|
|
|
|
UNICODE_STRING SystemRootString;
|
|
|
|
UNICODE_STRING UnexpandedSystemRootString = RTL_CONSTANT_STRING(L"%SystemRoot%");
|
|
|
|
UNICODE_STRING BaseSrvCSDString;
|
|
|
|
UNICODE_STRING BaseSrvWindowsDirectory;
|
|
|
|
UNICODE_STRING BaseSrvWindowsSystemDirectory;
|
|
|
|
UNICODE_STRING BnoString;
|
|
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
|
|
HANDLE BaseSrvNamedObjectDirectory;
|
|
|
|
HANDLE BaseSrvRestrictedObjectDirectory;
|
|
|
|
PACL BnoDacl, BnoRestrictedDacl;
|
|
|
|
PSECURITY_DESCRIPTOR BnoSd;
|
|
|
|
HANDLE SymHandle;
|
|
|
|
UNICODE_STRING DirectoryName, SymlinkName;
|
|
|
|
ULONG LuidEnabled;
|
|
|
|
RTL_QUERY_REGISTRY_TABLE BaseServerRegistryConfigurationTable[2] =
|
|
|
|
{
|
|
|
|
{
|
|
|
|
NULL,
|
|
|
|
RTL_QUERY_REGISTRY_DIRECT,
|
|
|
|
L"CSDVersion",
|
|
|
|
&BaseSrvCSDString,
|
|
|
|
REG_NONE, NULL, 0
|
|
|
|
},
|
|
|
|
|
|
|
|
{0}
|
|
|
|
};
|
|
|
|
|
2013-03-09 21:08:23 +00:00
|
|
|
/* Initialize the memory */
|
|
|
|
BaseSrvHeap = RtlGetProcessHeap(); // Initialize our own heap.
|
2012-10-21 17:18:33 +00:00
|
|
|
BaseSrvSharedHeap = LoadedServerDll->SharedSection; // Get the CSR shared heap.
|
|
|
|
|
2012-10-20 21:03:32 +00:00
|
|
|
/* Get the session ID */
|
|
|
|
SessionId = NtCurrentPeb()->SessionId;
|
|
|
|
|
|
|
|
/* Get the Windows directory */
|
|
|
|
RtlInitEmptyUnicodeString(&SystemRootString, Buffer, sizeof(Buffer));
|
|
|
|
Status = RtlExpandEnvironmentStrings_U(NULL,
|
|
|
|
&UnexpandedSystemRootString,
|
|
|
|
&SystemRootString,
|
|
|
|
NULL);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
|
|
|
|
/* Create the base directory */
|
|
|
|
Buffer[SystemRootString.Length / sizeof(WCHAR)] = UNICODE_NULL;
|
2013-09-10 20:45:53 +00:00
|
|
|
Success = RtlCreateUnicodeString(&BaseSrvWindowsDirectory,
|
|
|
|
SystemRootString.Buffer);
|
|
|
|
ASSERT(Success);
|
2012-10-20 21:03:32 +00:00
|
|
|
|
|
|
|
/* Create the system directory */
|
|
|
|
wcscat(SystemRootString.Buffer, L"\\System32");
|
2013-09-10 20:45:53 +00:00
|
|
|
Success = RtlCreateUnicodeString(&BaseSrvWindowsSystemDirectory,
|
|
|
|
SystemRootString.Buffer);
|
|
|
|
ASSERT(Success);
|
2012-10-20 21:03:32 +00:00
|
|
|
|
2013-08-29 20:13:31 +00:00
|
|
|
/* Create the kernel32 path */
|
|
|
|
wcscat(SystemRootString.Buffer, L"\\kernel32.dll");
|
2013-09-10 20:45:53 +00:00
|
|
|
Success = RtlCreateUnicodeString(&BaseSrvKernel32DllPath,
|
|
|
|
SystemRootString.Buffer);
|
|
|
|
ASSERT(Success);
|
2013-08-29 20:13:31 +00:00
|
|
|
|
2019-05-08 18:35:31 +00:00
|
|
|
if (SessionId != 0)
|
|
|
|
{
|
|
|
|
swprintf(BnoBuffer, L"\\Sessions\\%ld\\BaseNamedObjects", SessionId);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
wcscpy(BnoBuffer, L"\\BaseNamedObjects");
|
|
|
|
}
|
2019-05-08 18:06:49 +00:00
|
|
|
RtlInitUnicodeString(&BnoString, BnoBuffer);
|
2012-10-20 21:03:32 +00:00
|
|
|
|
|
|
|
/* Allocate the server data */
|
2012-10-21 17:18:33 +00:00
|
|
|
BaseStaticServerData = RtlAllocateHeap(BaseSrvSharedHeap,
|
2012-10-20 21:03:32 +00:00
|
|
|
HEAP_ZERO_MEMORY,
|
|
|
|
sizeof(BASE_STATIC_SERVER_DATA));
|
|
|
|
ASSERT(BaseStaticServerData != NULL);
|
|
|
|
|
|
|
|
/* Process timezone information */
|
|
|
|
BaseStaticServerData->TermsrvClientTimeZoneId = TIME_ZONE_ID_INVALID;
|
|
|
|
BaseStaticServerData->TermsrvClientTimeZoneChangeNum = 0;
|
|
|
|
Status = NtQuerySystemInformation(SystemTimeOfDayInformation,
|
|
|
|
&BaseStaticServerData->TimeOfDay,
|
|
|
|
sizeof(BaseStaticServerData->TimeOfDay),
|
|
|
|
NULL);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
|
|
|
|
/* Make a shared heap copy of the Windows directory */
|
|
|
|
BaseStaticServerData->WindowsDirectory = BaseSrvWindowsDirectory;
|
2012-10-21 17:18:33 +00:00
|
|
|
HeapBuffer = RtlAllocateHeap(BaseSrvSharedHeap,
|
2012-10-20 21:03:32 +00:00
|
|
|
0,
|
|
|
|
BaseSrvWindowsDirectory.MaximumLength);
|
|
|
|
ASSERT(HeapBuffer);
|
|
|
|
RtlCopyMemory(HeapBuffer,
|
|
|
|
BaseStaticServerData->WindowsDirectory.Buffer,
|
|
|
|
BaseSrvWindowsDirectory.MaximumLength);
|
|
|
|
BaseStaticServerData->WindowsDirectory.Buffer = HeapBuffer;
|
|
|
|
|
|
|
|
/* Make a shared heap copy of the System directory */
|
|
|
|
BaseStaticServerData->WindowsSystemDirectory = BaseSrvWindowsSystemDirectory;
|
2012-10-21 17:18:33 +00:00
|
|
|
HeapBuffer = RtlAllocateHeap(BaseSrvSharedHeap,
|
2012-10-20 21:03:32 +00:00
|
|
|
0,
|
|
|
|
BaseSrvWindowsSystemDirectory.MaximumLength);
|
|
|
|
ASSERT(HeapBuffer);
|
|
|
|
RtlCopyMemory(HeapBuffer,
|
|
|
|
BaseStaticServerData->WindowsSystemDirectory.Buffer,
|
|
|
|
BaseSrvWindowsSystemDirectory.MaximumLength);
|
|
|
|
BaseStaticServerData->WindowsSystemDirectory.Buffer = HeapBuffer;
|
|
|
|
|
|
|
|
/* This string is not used */
|
|
|
|
RtlInitEmptyUnicodeString(&BaseStaticServerData->WindowsSys32x86Directory,
|
|
|
|
NULL,
|
|
|
|
0);
|
|
|
|
|
|
|
|
/* Make a shared heap copy of the BNO directory */
|
|
|
|
BaseStaticServerData->NamedObjectDirectory = BnoString;
|
|
|
|
BaseStaticServerData->NamedObjectDirectory.MaximumLength = BnoString.Length +
|
|
|
|
sizeof(UNICODE_NULL);
|
2012-10-21 17:18:33 +00:00
|
|
|
HeapBuffer = RtlAllocateHeap(BaseSrvSharedHeap,
|
2012-10-20 21:03:32 +00:00
|
|
|
0,
|
|
|
|
BaseStaticServerData->NamedObjectDirectory.MaximumLength);
|
|
|
|
ASSERT(HeapBuffer);
|
|
|
|
RtlCopyMemory(HeapBuffer,
|
|
|
|
BaseStaticServerData->NamedObjectDirectory.Buffer,
|
|
|
|
BaseStaticServerData->NamedObjectDirectory.MaximumLength);
|
|
|
|
BaseStaticServerData->NamedObjectDirectory.Buffer = HeapBuffer;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Confirmed that in Windows, CSDNumber and RCNumber are actually Length
|
|
|
|
* and MaximumLength of the CSD String, since the same UNICODE_STRING is
|
|
|
|
* being queried twice, the first time as a ULONG!
|
|
|
|
*
|
|
|
|
* Somehow, in Windows this doesn't cause a buffer overflow, but it might
|
|
|
|
* in ReactOS, so this code is disabled until someone figures out WTF.
|
|
|
|
*/
|
|
|
|
BaseStaticServerData->CSDNumber = 0;
|
|
|
|
BaseStaticServerData->RCNumber = 0;
|
|
|
|
|
|
|
|
/* Initialize the CSD string and query its value from the registry */
|
|
|
|
RtlInitEmptyUnicodeString(&BaseSrvCSDString, Buffer, sizeof(Buffer));
|
|
|
|
Status = RtlQueryRegistryValues(RTL_REGISTRY_WINDOWS_NT,
|
|
|
|
L"",
|
|
|
|
BaseServerRegistryConfigurationTable,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Copy into the shared buffer */
|
|
|
|
wcsncpy(BaseStaticServerData->CSDVersion,
|
|
|
|
BaseSrvCSDString.Buffer,
|
|
|
|
BaseSrvCSDString.Length / sizeof(WCHAR));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-06-01 13:22:33 +00:00
|
|
|
/* Indicate nothing is there */
|
|
|
|
BaseSrvCSDString.Length = 0;
|
2012-10-20 21:03:32 +00:00
|
|
|
}
|
2016-06-01 13:22:33 +00:00
|
|
|
/* NULL-terminate */
|
|
|
|
BaseStaticServerData->CSDVersion[BaseSrvCSDString.Length / sizeof(WCHAR)] = UNICODE_NULL;
|
2012-10-20 21:03:32 +00:00
|
|
|
|
|
|
|
/* Cache the system information */
|
|
|
|
Status = NtQuerySystemInformation(SystemBasicInformation,
|
|
|
|
&BaseStaticServerData->SysInfo,
|
|
|
|
sizeof(BaseStaticServerData->SysInfo),
|
|
|
|
NULL);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
|
2013-09-04 07:07:08 +00:00
|
|
|
/* Setup the ini file mappings */
|
|
|
|
Status = BaseSrvInitializeIniFileMappings(BaseStaticServerData);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
|
2012-10-20 21:03:32 +00:00
|
|
|
/* FIXME: Should query the registry for these */
|
|
|
|
BaseStaticServerData->DefaultSeparateVDM = FALSE;
|
|
|
|
BaseStaticServerData->IsWowTaskReady = FALSE;
|
|
|
|
|
|
|
|
/* Allocate a security descriptor and create it */
|
2012-10-21 17:18:33 +00:00
|
|
|
BnoSd = RtlAllocateHeap(BaseSrvHeap, 0, 1024);
|
2012-10-20 21:03:32 +00:00
|
|
|
ASSERT(BnoSd);
|
|
|
|
Status = RtlCreateSecurityDescriptor(BnoSd, SECURITY_DESCRIPTOR_REVISION);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
|
|
|
|
/* Create the BNO and \Restricted DACLs */
|
|
|
|
Status = CreateBaseAcls(&BnoDacl, &BnoRestrictedDacl);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
|
|
|
|
/* Set the BNO DACL as active for now */
|
|
|
|
Status = RtlSetDaclSecurityDescriptor(BnoSd, TRUE, BnoDacl, FALSE);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
|
|
|
|
/* Create the BNO directory */
|
|
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
|
|
&BnoString,
|
|
|
|
OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
|
|
|
|
NULL,
|
|
|
|
BnoSd);
|
|
|
|
Status = NtCreateDirectoryObject(&BaseSrvNamedObjectDirectory,
|
|
|
|
DIRECTORY_ALL_ACCESS,
|
|
|
|
&ObjectAttributes);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
|
|
|
|
/* Check if we are session 0 */
|
|
|
|
if (SessionId == 0)
|
|
|
|
{
|
|
|
|
/* Mark this as a session 0 directory */
|
|
|
|
Status = NtSetInformationObject(BaseSrvNamedObjectDirectory,
|
|
|
|
ObjectSessionInformation,
|
|
|
|
NULL,
|
|
|
|
0);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if LUID device maps are enabled */
|
|
|
|
Status = NtQueryInformationProcess(NtCurrentProcess(),
|
|
|
|
ProcessLUIDDeviceMapsEnabled,
|
|
|
|
&LuidEnabled,
|
|
|
|
sizeof(LuidEnabled),
|
|
|
|
NULL);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
2013-04-14 16:04:46 +00:00
|
|
|
BaseStaticServerData->LUIDDeviceMapsEnabled = (BOOLEAN)LuidEnabled;
|
2019-06-20 07:00:07 +00:00
|
|
|
|
|
|
|
/* Initialize Global */
|
|
|
|
if (!BaseStaticServerData->LUIDDeviceMapsEnabled ||
|
|
|
|
NT_SUCCESS(RtlInitializeCriticalSectionAndSpinCount(&BaseSrvDDDBSMCritSec, 0x80000000)))
|
2012-10-20 21:03:32 +00:00
|
|
|
{
|
|
|
|
/* Make Global point back to BNO */
|
|
|
|
RtlInitUnicodeString(&DirectoryName, L"Global");
|
|
|
|
RtlInitUnicodeString(&SymlinkName, L"\\BaseNamedObjects");
|
|
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
|
|
&DirectoryName,
|
|
|
|
OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
|
|
|
|
BaseSrvNamedObjectDirectory,
|
|
|
|
BnoSd);
|
|
|
|
Status = NtCreateSymbolicLinkObject(&SymHandle,
|
|
|
|
SYMBOLIC_LINK_ALL_ACCESS,
|
|
|
|
&ObjectAttributes,
|
|
|
|
&SymlinkName);
|
|
|
|
if ((NT_SUCCESS(Status)) && SessionId == 0) NtClose(SymHandle);
|
|
|
|
|
|
|
|
/* Make local point back to \Sessions\x\BNO */
|
|
|
|
RtlInitUnicodeString(&DirectoryName, L"Local");
|
|
|
|
ASSERT(SessionId == 0);
|
|
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
|
|
&DirectoryName,
|
|
|
|
OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
|
|
|
|
BaseSrvNamedObjectDirectory,
|
|
|
|
BnoSd);
|
|
|
|
Status = NtCreateSymbolicLinkObject(&SymHandle,
|
|
|
|
SYMBOLIC_LINK_ALL_ACCESS,
|
|
|
|
&ObjectAttributes,
|
2019-05-08 18:35:31 +00:00
|
|
|
&BnoString);
|
2012-10-20 21:03:32 +00:00
|
|
|
if ((NT_SUCCESS(Status)) && SessionId == 0) NtClose(SymHandle);
|
|
|
|
|
|
|
|
/* Make Session point back to BNOLINKS */
|
|
|
|
RtlInitUnicodeString(&DirectoryName, L"Session");
|
|
|
|
RtlInitUnicodeString(&SymlinkName, L"\\Sessions\\BNOLINKS");
|
|
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
|
|
&DirectoryName,
|
|
|
|
OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
|
|
|
|
BaseSrvNamedObjectDirectory,
|
|
|
|
BnoSd);
|
|
|
|
Status = NtCreateSymbolicLinkObject(&SymHandle,
|
|
|
|
SYMBOLIC_LINK_ALL_ACCESS,
|
|
|
|
&ObjectAttributes,
|
|
|
|
&SymlinkName);
|
|
|
|
if ((NT_SUCCESS(Status)) && SessionId == 0) NtClose(SymHandle);
|
|
|
|
|
|
|
|
/* Create the BNO\Restricted directory and set the restricted DACL */
|
|
|
|
RtlInitUnicodeString(&DirectoryName, L"Restricted");
|
|
|
|
Status = RtlSetDaclSecurityDescriptor(BnoSd, TRUE, BnoRestrictedDacl, FALSE);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
|
|
&DirectoryName,
|
|
|
|
OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
|
|
|
|
BaseSrvNamedObjectDirectory,
|
|
|
|
BnoSd);
|
|
|
|
Status = NtCreateDirectoryObject(&BaseSrvRestrictedObjectDirectory,
|
|
|
|
DIRECTORY_ALL_ACCESS,
|
|
|
|
&ObjectAttributes);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
}
|
2019-06-20 07:00:07 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
/* That should never happen */
|
|
|
|
ASSERT(FALSE);
|
|
|
|
}
|
2012-10-20 21:03:32 +00:00
|
|
|
|
2013-08-29 21:00:54 +00:00
|
|
|
/* Initialize NLS */
|
|
|
|
BaseSrvNLSInit(BaseStaticServerData);
|
|
|
|
|
2012-10-20 21:03:32 +00:00
|
|
|
/* Finally, set the pointer */
|
2012-10-21 17:18:33 +00:00
|
|
|
LoadedServerDll->SharedSection = BaseStaticServerData;
|
2012-10-20 21:03:32 +00:00
|
|
|
}
|
|
|
|
|
2014-12-16 20:15:35 +00:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
BaseClientConnectRoutine(IN PCSR_PROCESS CsrProcess,
|
|
|
|
IN OUT PVOID ConnectionInfo,
|
|
|
|
IN OUT PULONG ConnectionInfoLength)
|
|
|
|
{
|
|
|
|
PBASESRV_API_CONNECTINFO ConnectInfo = (PBASESRV_API_CONNECTINFO)ConnectionInfo;
|
|
|
|
|
|
|
|
if ( ConnectionInfo == NULL ||
|
|
|
|
ConnectionInfoLength == NULL ||
|
|
|
|
*ConnectionInfoLength != sizeof(*ConnectInfo) )
|
|
|
|
{
|
|
|
|
DPRINT1("BASESRV: Connection failed - ConnectionInfo = 0x%p ; ConnectionInfoLength = 0x%p (%lu), expected %lu\n",
|
|
|
|
ConnectionInfo,
|
|
|
|
ConnectionInfoLength,
|
|
|
|
ConnectionInfoLength ? *ConnectionInfoLength : (ULONG)-1,
|
|
|
|
sizeof(*ConnectInfo));
|
|
|
|
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Do the NLS connection */
|
|
|
|
return BaseSrvNlsConnect(CsrProcess, ConnectionInfo, ConnectionInfoLength);
|
|
|
|
}
|
|
|
|
|
2014-04-29 00:41:48 +00:00
|
|
|
VOID
|
|
|
|
NTAPI
|
2014-12-16 20:15:35 +00:00
|
|
|
BaseClientDisconnectRoutine(IN PCSR_PROCESS CsrProcess)
|
2014-04-29 00:41:48 +00:00
|
|
|
{
|
2014-12-16 20:28:44 +00:00
|
|
|
/* Cleanup VDM resources */
|
|
|
|
BaseSrvCleanupVDMResources(CsrProcess);
|
2014-04-29 00:41:48 +00:00
|
|
|
}
|
|
|
|
|
2012-10-20 21:03:32 +00:00
|
|
|
CSR_SERVER_DLL_INIT(ServerDllInitialization)
|
|
|
|
{
|
|
|
|
/* Setup the DLL Object */
|
2013-04-14 12:14:00 +00:00
|
|
|
LoadedServerDll->ApiBase = BASESRV_FIRST_API_NUMBER;
|
|
|
|
LoadedServerDll->HighestApiSupported = BasepMaxApiNumber;
|
2012-10-20 21:03:32 +00:00
|
|
|
LoadedServerDll->DispatchTable = BaseServerApiDispatchTable;
|
|
|
|
LoadedServerDll->ValidTable = BaseServerApiServerValidTable;
|
[CSR]
During my investigations for making working Win2k3 csrsrv.dll (or other CSR servers) into ROS (to compare our behaviour with our own csrsrv.dll and Win2k3 one), I hit a problem: if I test a checked-build version of csrsrv (or other CSR servers), everything was fine when they were loaded, but if I use a release-build version (i.e. without any debug information), I systematically hit a memory access violation which was traced back to the moment when a CSR server's CsrInitialization entry point was called.
So I did the experiment, where I used our (debug-build) csrsrv with a free-build win2k3 CSR server dll (it was winsrv.dll, and I retested with basesrv.dll after). I hit the access violation. But if I took a debug-build version of winsrv.dll, everything was OK.
I then added in our csrsrv' server.c file the following line (around line 212 of the current file version):
DPRINT1("%s ; ServerDll->ValidTable = 0x%p ; ServerDll->NameTable = 0x%p ; ServerDll->SizeOfProcessData = %d ; ServerDll->ConnectCallback = 0x%p\n", DllString, ServerDll->ValidTable, ServerDll->NameTable, ServerDll->SizeOfProcessData, ServerDll->ConnectCallback);
and I saw that, when using a debug-build win2k3 CSR server, everything was fine (in particular the ServerDll->SizeOfProcessData member contained a reasonable value, e.g. a size of 88 bytes), whereas if I used a free-build version, I got an off-by-one problem, with the ServerDll->ValidTable pointer valid but the ServerDll->NameTable member being equal to 88 (i.e. invalid pointer) and the ServerDll->SizeOfProcessData member being equal to a very large value, which looked like a pointer value.
After more investigations, I saw that in debug-build CSR servers the list of API names were stored, whereas it was not the case in free-build versions. Therefore I concluded that the API names table was included *ONLY* in debug builds and not in release builds.
Hence, to be able to test in ROS either debug-builds or release-builds versions of Windows CSR servers in ROS (and vice-versa), I introduced a #define called CSR_DBG, which is defined only if the DBG macro is != 0, and which is not defined otherwise. When the CSR_DBG flag is defined, API names tables are added in CSR servers and otherwise, they are not.
Therefore, we are now able to test debug-build Windows CSR servers in ROS (the default possibility) or free-build versions of these CSR servers (but first, we have to build the other ones without the CSR_DBG flag, to avoid the off-by-one problem described above).
svn path=/trunk/; revision=60560
2013-10-06 13:33:17 +00:00
|
|
|
#ifdef CSR_DBG
|
2012-10-20 21:03:32 +00:00
|
|
|
LoadedServerDll->NameTable = BaseServerApiNameTable;
|
[CSR]
During my investigations for making working Win2k3 csrsrv.dll (or other CSR servers) into ROS (to compare our behaviour with our own csrsrv.dll and Win2k3 one), I hit a problem: if I test a checked-build version of csrsrv (or other CSR servers), everything was fine when they were loaded, but if I use a release-build version (i.e. without any debug information), I systematically hit a memory access violation which was traced back to the moment when a CSR server's CsrInitialization entry point was called.
So I did the experiment, where I used our (debug-build) csrsrv with a free-build win2k3 CSR server dll (it was winsrv.dll, and I retested with basesrv.dll after). I hit the access violation. But if I took a debug-build version of winsrv.dll, everything was OK.
I then added in our csrsrv' server.c file the following line (around line 212 of the current file version):
DPRINT1("%s ; ServerDll->ValidTable = 0x%p ; ServerDll->NameTable = 0x%p ; ServerDll->SizeOfProcessData = %d ; ServerDll->ConnectCallback = 0x%p\n", DllString, ServerDll->ValidTable, ServerDll->NameTable, ServerDll->SizeOfProcessData, ServerDll->ConnectCallback);
and I saw that, when using a debug-build win2k3 CSR server, everything was fine (in particular the ServerDll->SizeOfProcessData member contained a reasonable value, e.g. a size of 88 bytes), whereas if I used a free-build version, I got an off-by-one problem, with the ServerDll->ValidTable pointer valid but the ServerDll->NameTable member being equal to 88 (i.e. invalid pointer) and the ServerDll->SizeOfProcessData member being equal to a very large value, which looked like a pointer value.
After more investigations, I saw that in debug-build CSR servers the list of API names were stored, whereas it was not the case in free-build versions. Therefore I concluded that the API names table was included *ONLY* in debug builds and not in release builds.
Hence, to be able to test in ROS either debug-builds or release-builds versions of Windows CSR servers in ROS (and vice-versa), I introduced a #define called CSR_DBG, which is defined only if the DBG macro is != 0, and which is not defined otherwise. When the CSR_DBG flag is defined, API names tables are added in CSR servers and otherwise, they are not.
Therefore, we are now able to test debug-build Windows CSR servers in ROS (the default possibility) or free-build versions of these CSR servers (but first, we have to build the other ones without the CSR_DBG flag, to avoid the off-by-one problem described above).
svn path=/trunk/; revision=60560
2013-10-06 13:33:17 +00:00
|
|
|
#endif
|
2012-10-20 21:03:32 +00:00
|
|
|
LoadedServerDll->SizeOfProcessData = 0;
|
2014-12-16 20:15:35 +00:00
|
|
|
LoadedServerDll->ConnectCallback = BaseClientConnectRoutine;
|
|
|
|
LoadedServerDll->DisconnectCallback = BaseClientDisconnectRoutine;
|
2013-03-09 21:08:23 +00:00
|
|
|
LoadedServerDll->ShutdownProcessCallback = NULL;
|
|
|
|
|
|
|
|
BaseSrvDllInstance = LoadedServerDll->ServerHandle;
|
|
|
|
|
2012-10-21 17:18:33 +00:00
|
|
|
BaseInitializeStaticServerData(LoadedServerDll);
|
2012-10-20 21:03:32 +00:00
|
|
|
|
2013-03-09 21:08:23 +00:00
|
|
|
/* Initialize DOS devices management */
|
|
|
|
BaseInitDefineDosDevice();
|
2012-10-20 21:03:32 +00:00
|
|
|
|
2014-02-09 17:37:35 +00:00
|
|
|
/* Initialize VDM support */
|
|
|
|
BaseInitializeVDM();
|
|
|
|
|
2012-10-20 21:03:32 +00:00
|
|
|
/* All done */
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL
|
|
|
|
NTAPI
|
2012-11-07 22:08:38 +00:00
|
|
|
DllMain(IN HINSTANCE hInstanceDll,
|
2012-10-20 21:03:32 +00:00
|
|
|
IN DWORD dwReason,
|
|
|
|
IN LPVOID lpReserved)
|
2005-08-12 12:22:02 +00:00
|
|
|
{
|
2013-03-09 21:08:23 +00:00
|
|
|
UNREFERENCED_PARAMETER(hInstanceDll);
|
2012-10-20 21:03:32 +00:00
|
|
|
UNREFERENCED_PARAMETER(dwReason);
|
|
|
|
UNREFERENCED_PARAMETER(lpReserved);
|
2005-08-12 12:22:02 +00:00
|
|
|
|
2013-03-09 21:08:23 +00:00
|
|
|
if (DLL_PROCESS_DETACH == dwReason)
|
2012-10-20 21:03:32 +00:00
|
|
|
{
|
|
|
|
BaseCleanupDefineDosDevice();
|
|
|
|
}
|
2005-08-12 12:22:02 +00:00
|
|
|
|
2012-10-20 21:03:32 +00:00
|
|
|
return TRUE;
|
2005-08-12 12:22:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* EOF */
|