mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +00:00
3d3a5aa02e
Following commit 24a727a23
, give a lift to the SVCHOST global header
and add & complete all the missing definitions.
- Based on https://www.geoffchappell.com/studies/windows/win32/services/svchost/process/globaldata.htm
from public debug symbols (e.g. svchost, mswsock, w32time, wscsvc...),
adjust some of our symbols' names.
- Make the header C++-compatible.
- Even if the start/stop RPC server functions return an error code whose
underlying storage type is a 32-bit long, they don't return an RPC
status error code, but an NT status. Thus, use the adequate type
instead.
- The PSVCHOST_STOP_CALLBACK is nothing but a WAITORTIMERCALLBACK function.
- Take the opportunity to fix some of these functions' SAL annotations.
- Remark: "LP" for pointers is old-fashioned Windows, avoid this in NT code.
[MSWSOCK][SECLOGON] Do the minor adjustments. Remove unnecessary function casts.
308 lines
9.3 KiB
C
308 lines
9.3 KiB
C
/*
|
|
* PROJECT: ReactOS Service Host
|
|
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
|
* FILE: base/services/svchost/globals.c
|
|
* PURPOSE: Functions to initialize global settings and support
|
|
* PROGRAMMERS: ReactOS Portable Systems Group
|
|
*/
|
|
|
|
/* INCLUDES ******************************************************************/
|
|
|
|
#include "svchost.h"
|
|
|
|
/* GLOBALS *******************************************************************/
|
|
|
|
PSID NullSid, WorldSid, LocalSid, NetworkSid, InteractiveSid, ServiceLogonSid;
|
|
PSID LocalSystemSid, LocalServiceSid, NetworkServiceSid, BuiltinDomainSid;
|
|
PSID AuthenticatedUserSid, AnonymousLogonSid, AliasAdminsSid, AliasUsersSid;
|
|
PSID AliasGuestsSid, AliasPowerUsersSid, AliasAccountOpsSid, AliasSystemOpsSid;
|
|
PSID AliasPrintOpsSid;
|
|
PSID AliasBackupOpsSid;
|
|
|
|
SID_DATA SidData[12] =
|
|
{
|
|
{ &NullSid, { SECURITY_NULL_SID_AUTHORITY }, SECURITY_NULL_RID },
|
|
{ &WorldSid, { SECURITY_WORLD_SID_AUTHORITY }, SECURITY_WORLD_RID },
|
|
{ &LocalSid, { SECURITY_LOCAL_SID_AUTHORITY }, SECURITY_LOCAL_RID },
|
|
{ &NetworkSid, { SECURITY_NT_AUTHORITY }, SECURITY_NETWORK_RID },
|
|
{ &InteractiveSid, { SECURITY_NT_AUTHORITY }, SECURITY_INTERACTIVE_RID },
|
|
{ &ServiceLogonSid, { SECURITY_NT_AUTHORITY }, SECURITY_SERVICE_RID },
|
|
{ &LocalSystemSid, { SECURITY_NT_AUTHORITY }, SECURITY_LOCAL_SYSTEM_RID },
|
|
{ &LocalServiceSid, { SECURITY_NT_AUTHORITY }, SECURITY_LOCAL_SERVICE_RID },
|
|
{ &NetworkServiceSid, { SECURITY_NT_AUTHORITY }, SECURITY_NETWORK_SERVICE_RID },
|
|
{ &BuiltinDomainSid, { SECURITY_NT_AUTHORITY }, SECURITY_BUILTIN_DOMAIN_RID },
|
|
{ &AuthenticatedUserSid, { SECURITY_NT_AUTHORITY }, SECURITY_AUTHENTICATED_USER_RID },
|
|
{ &AnonymousLogonSid, { SECURITY_NT_AUTHORITY }, SECURITY_ANONYMOUS_LOGON_RID },
|
|
};
|
|
|
|
DOMAIN_SID_DATA DomainSidData[8] =
|
|
{
|
|
{ &AliasAdminsSid, DOMAIN_ALIAS_RID_ADMINS },
|
|
{ &AliasUsersSid, DOMAIN_ALIAS_RID_USERS },
|
|
{ &AliasGuestsSid, DOMAIN_ALIAS_RID_GUESTS },
|
|
{ &AliasPowerUsersSid, DOMAIN_ALIAS_RID_POWER_USERS },
|
|
{ &AliasAccountOpsSid, DOMAIN_ALIAS_RID_ACCOUNT_OPS },
|
|
{ &AliasSystemOpsSid, DOMAIN_ALIAS_RID_SYSTEM_OPS },
|
|
{ &AliasPrintOpsSid, DOMAIN_ALIAS_RID_PRINT_OPS },
|
|
{ &AliasBackupOpsSid, DOMAIN_ALIAS_RID_BACKUP_OPS },
|
|
};
|
|
|
|
PSVCHOST_GLOBAL_DATA g_pSvchostSharedGlobals;
|
|
DWORD g_SvchostInitFlag;
|
|
HANDLE g_hHeap;
|
|
|
|
/* FUNCTIONS *****************************************************************/
|
|
|
|
VOID
|
|
WINAPI
|
|
MemInit (
|
|
_In_ HANDLE Heap
|
|
)
|
|
{
|
|
/* Save the heap handle */
|
|
g_hHeap = Heap;
|
|
}
|
|
|
|
BOOL
|
|
WINAPI
|
|
MemFree (
|
|
_In_ LPVOID lpMem
|
|
)
|
|
{
|
|
/* Free memory back into the heap */
|
|
return HeapFree(g_hHeap, 0, lpMem);
|
|
}
|
|
|
|
PVOID
|
|
WINAPI
|
|
MemAlloc (
|
|
_In_ DWORD dwFlags,
|
|
_In_ DWORD dwBytes
|
|
)
|
|
{
|
|
/* Allocate memory from the heap */
|
|
return HeapAlloc(g_hHeap, dwFlags, dwBytes);
|
|
}
|
|
|
|
VOID
|
|
WINAPI
|
|
SvchostBuildSharedGlobals (
|
|
VOID
|
|
)
|
|
{
|
|
ASSERT(g_pSvchostSharedGlobals == NULL);
|
|
|
|
/* Is RPC initialized? */
|
|
if (!(g_SvchostInitFlag & SVCHOST_RPC_INIT_COMPLETE))
|
|
{
|
|
/* Nope, go initialize it */
|
|
if (!NT_SUCCESS(RpcpInitRpcServer())) return;
|
|
|
|
/* This is now done */
|
|
g_SvchostInitFlag |= SVCHOST_RPC_INIT_COMPLETE;
|
|
}
|
|
|
|
/* Is NetBIOS initialized? */
|
|
if (!(g_SvchostInitFlag & SVCHOST_NBT_INIT_COMPLETE))
|
|
{
|
|
/* Nope, set it up */
|
|
SvcNetBiosInit();
|
|
|
|
/* This is now done */
|
|
g_SvchostInitFlag |= SVCHOST_NBT_INIT_COMPLETE;
|
|
}
|
|
|
|
/* Do we have the global SIDs initialized? */
|
|
if (!(g_SvchostInitFlag & SVCHOST_SID_INIT_COMPLETE))
|
|
{
|
|
/* Create the SIDs we'll export in the global structure */
|
|
if (!NT_SUCCESS(ScCreateWellKnownSids())) return;
|
|
|
|
/* This is now done */
|
|
g_SvchostInitFlag |= SVCHOST_SID_INIT_COMPLETE;
|
|
}
|
|
|
|
/* Allocate memory for the globals */
|
|
g_pSvchostSharedGlobals = MemAlloc(HEAP_ZERO_MEMORY,
|
|
sizeof(*g_pSvchostSharedGlobals));
|
|
if (g_pSvchostSharedGlobals == NULL) return;
|
|
|
|
/* Write the pointers to the SIDs */
|
|
g_pSvchostSharedGlobals->NullSid = NullSid;
|
|
g_pSvchostSharedGlobals->WorldSid = WorldSid;
|
|
g_pSvchostSharedGlobals->LocalSid = LocalSid;
|
|
g_pSvchostSharedGlobals->NetworkSid = NetworkSid;
|
|
g_pSvchostSharedGlobals->LocalSystemSid = LocalSystemSid;
|
|
g_pSvchostSharedGlobals->LocalServiceSid = LocalServiceSid;
|
|
g_pSvchostSharedGlobals->NetworkServiceSid = NetworkServiceSid;
|
|
g_pSvchostSharedGlobals->BuiltinDomainSid = BuiltinDomainSid;
|
|
g_pSvchostSharedGlobals->AuthenticatedUserSid = AuthenticatedUserSid;
|
|
g_pSvchostSharedGlobals->AnonymousLogonSid = AnonymousLogonSid;
|
|
g_pSvchostSharedGlobals->AliasAdminsSid = AliasAdminsSid;
|
|
g_pSvchostSharedGlobals->AliasUsersSid = AliasUsersSid;
|
|
g_pSvchostSharedGlobals->AliasGuestsSid = AliasGuestsSid;
|
|
g_pSvchostSharedGlobals->AliasPowerUsersSid = AliasPowerUsersSid;
|
|
g_pSvchostSharedGlobals->AliasAccountOpsSid = AliasAccountOpsSid;
|
|
g_pSvchostSharedGlobals->AliasSystemOpsSid = AliasSystemOpsSid;
|
|
g_pSvchostSharedGlobals->AliasPrintOpsSid = AliasPrintOpsSid;
|
|
g_pSvchostSharedGlobals->AliasBackupOpsSid = AliasBackupOpsSid;
|
|
|
|
/* Write the pointers to the callbacks */
|
|
g_pSvchostSharedGlobals->StartRpcServer = RpcpStartRpcServer;
|
|
g_pSvchostSharedGlobals->StopRpcServer = RpcpStopRpcServer;
|
|
g_pSvchostSharedGlobals->StopRpcServerEx = RpcpStopRpcServerEx;
|
|
g_pSvchostSharedGlobals->NetBiosOpen = SvcNetBiosOpen;
|
|
g_pSvchostSharedGlobals->NetBiosClose = SvcNetBiosClose;
|
|
g_pSvchostSharedGlobals->NetBiosReset = SvcNetBiosReset;
|
|
g_pSvchostSharedGlobals->RegisterStopCallback = SvcRegisterStopCallback;
|
|
}
|
|
|
|
VOID
|
|
WINAPI
|
|
SvchostCharLowerW (
|
|
_In_ LPCWSTR lpSrcStr
|
|
)
|
|
{
|
|
DWORD cchSrc;
|
|
|
|
/* If there's nothing to do, bail out */
|
|
if (lpSrcStr == NULL) return;
|
|
|
|
/* Get the length of the input string */
|
|
cchSrc = wcslen(lpSrcStr);
|
|
|
|
/* Call the locale API to lower-case it */
|
|
if (LCMapStringW(LANG_USER_DEFAULT,
|
|
LCMAP_LOWERCASE,
|
|
lpSrcStr,
|
|
cchSrc + 1,
|
|
(LPWSTR)lpSrcStr,
|
|
cchSrc + 1) == FALSE)
|
|
{
|
|
DBG_ERR("SvchostCharLowerW failed for %ws\n", lpSrcStr);
|
|
}
|
|
}
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
ScDomainIdToSid (
|
|
_In_ PSID SourceSid,
|
|
_In_ ULONG DomainId,
|
|
_Out_ PSID *DestinationSid
|
|
)
|
|
{
|
|
ULONG sidCount, sidLength;
|
|
NTSTATUS status;
|
|
|
|
/* Get the length of the SID based onthe number of subauthorities */
|
|
sidCount = *RtlSubAuthorityCountSid(SourceSid);
|
|
sidLength = RtlLengthRequiredSid(sidCount + 1);
|
|
|
|
/* Allocate it */
|
|
*DestinationSid = RtlAllocateHeap(RtlGetProcessHeap(), 0, sidLength);
|
|
if (*DestinationSid)
|
|
{
|
|
/* Make a copy of it */
|
|
status = RtlCopySid(sidLength, *DestinationSid, SourceSid);
|
|
if (NT_SUCCESS(status))
|
|
{
|
|
/* Increase the subauthority count */
|
|
++*RtlSubAuthorityCountSid(*DestinationSid);
|
|
|
|
/* And add the specific domain RID we're creating */
|
|
*RtlSubAuthoritySid(*DestinationSid, sidCount) = DomainId;
|
|
|
|
/* Everything worked */
|
|
status = STATUS_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
/* The SID copy failed, so free the SID we just allocated */
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, *DestinationSid);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* No space for the SID, bail out */
|
|
status = STATUS_NO_MEMORY;
|
|
}
|
|
|
|
/* Return back to the caller */
|
|
return status;
|
|
}
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
ScAllocateAndInitializeSid (
|
|
_Out_ PSID *Sid,
|
|
_In_ PSID_IDENTIFIER_AUTHORITY IdentifierAuthority,
|
|
_In_ ULONG SubAuthorityCount
|
|
)
|
|
{
|
|
NTSTATUS Status;
|
|
|
|
/* Allocate room for the SID */
|
|
*Sid = RtlAllocateHeap(RtlGetProcessHeap(),
|
|
0,
|
|
RtlLengthRequiredSid(SubAuthorityCount));
|
|
if (*Sid)
|
|
{
|
|
/* Initialize it, we're done */
|
|
RtlInitializeSid(*Sid, IdentifierAuthority, SubAuthorityCount);
|
|
Status = STATUS_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
/* No memory, we'll fail */
|
|
Status = STATUS_NO_MEMORY;
|
|
}
|
|
|
|
/* Return what happened */
|
|
return Status;
|
|
}
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
ScCreateWellKnownSids (
|
|
VOID
|
|
)
|
|
{
|
|
ULONG i;
|
|
NTSTATUS Status;
|
|
|
|
/* Loop the non-domain SIDs */
|
|
for (i = 0; i < RTL_NUMBER_OF(SidData); i++)
|
|
{
|
|
/* Convert our optimized structure into an actual SID */
|
|
Status = ScAllocateAndInitializeSid(SidData[i].Sid,
|
|
&SidData[i].Authority,
|
|
1);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DBG_ERR("ScAllocateAndInitializeSid failed for %u\n", i);
|
|
break;
|
|
}
|
|
|
|
/* Write the correct sub-authority */
|
|
*RtlSubAuthoritySid(*SidData[i].Sid, 0) = SidData[i].SubAuthority;
|
|
}
|
|
|
|
/* Now loop the domain SIDs */
|
|
for (i = 0; i < RTL_NUMBER_OF(DomainSidData); i++)
|
|
{
|
|
/* Convert our optimized structure into an actual SID */
|
|
Status = ScDomainIdToSid(BuiltinDomainSid,
|
|
DomainSidData[i].SubAuthority,
|
|
DomainSidData[i].Sid);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DBG_ERR("ScDomainIdToSid failed for %u\n", i);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* If we got to the end, return success */
|
|
return (i == RTL_NUMBER_OF(DomainSidData)) ? STATUS_SUCCESS : STATUS_NO_MEMORY;
|
|
}
|
|
|