ReactOS 0.4.16-dev-2613-g9533ad7
sminit.c File Reference
#include "smss.h"
#include <debug.h>
Include dependency graph for sminit.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define SMSS_CHECKPOINT(x, y)
 

Functions

NTSTATUS NTAPI SmpSaveRegistryValue (IN PLIST_ENTRY ListAddress, IN PWSTR Name, IN PWCHAR Value, IN BOOLEAN Flags)
 
PSMP_REGISTRY_VALUE NTAPI SmpFindRegistryValue (IN PLIST_ENTRY List, IN PWSTR ValueName)
 
NTSTATUS NTAPI SmpConfigureProtectionMode (IN PWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext)
 
NTSTATUS NTAPI SmpConfigureAllowProtectedRenames (IN PWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext)
 
NTSTATUS NTAPI SmpConfigureObjectDirectories (IN PWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext)
 
NTSTATUS NTAPI SmpConfigureMemoryMgmt (IN PWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext)
 
NTSTATUS NTAPI SmpConfigureFileRenames (IN PWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext)
 
NTSTATUS NTAPI SmpConfigureExcludeKnownDlls (IN PWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext)
 
NTSTATUS NTAPI SmpConfigureDosDevices (IN PWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext)
 
NTSTATUS NTAPI SmpInitializeKnownDllPath (IN PUNICODE_STRING DllPath, IN PWCHAR Buffer, IN ULONG Length)
 
NTSTATUS NTAPI SmpConfigureKnownDlls (IN PWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext)
 
NTSTATUS NTAPI SmpConfigureEnvironment (IN PWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext)
 
NTSTATUS NTAPI SmpConfigureSubSystems (IN PWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext)
 
VOID NTAPI SmpTranslateSystemPartitionInformation (VOID)
 
NTSTATUS NTAPI SmpCreateSecurityDescriptors (IN BOOLEAN InitialCall)
 
NTSTATUS NTAPI SmpInitializeDosDevices (VOID)
 
VOID NTAPI SmpProcessModuleImports (IN PVOID Unused, IN PCHAR ImportName)
 
NTSTATUS NTAPI SmpInitializeKnownDllsInternal (IN PUNICODE_STRING Directory, IN PUNICODE_STRING Path)
 
NTSTATUS NTAPI SmpInitializeKnownDlls (VOID)
 
NTSTATUS NTAPI SmpCreateDynamicEnvironmentVariables (VOID)
 
NTSTATUS NTAPI SmpProcessFileRenames (VOID)
 
NTSTATUS NTAPI SmpLoadDataFromRegistry (OUT PUNICODE_STRING InitialCommand)
 
NTSTATUS NTAPI SmpInit (IN PUNICODE_STRING InitialCommand, OUT PHANDLE ProcessHandle)
 

Variables

UNICODE_STRING SmpSubsystemName
 
UNICODE_STRING PosixName
 
UNICODE_STRING Os2Name
 
LIST_ENTRY SmpBootExecuteList
 
LIST_ENTRY SmpSetupExecuteList
 
LIST_ENTRY SmpPagingFileList
 
LIST_ENTRY SmpDosDevicesList
 
LIST_ENTRY SmpFileRenameList
 
LIST_ENTRY SmpKnownDllsList
 
LIST_ENTRY SmpExcludeKnownDllsList
 
LIST_ENTRY SmpSubSystemList
 
LIST_ENTRY SmpSubSystemsToLoad
 
LIST_ENTRY SmpSubSystemsToDefer
 
LIST_ENTRY SmpExecuteList
 
LIST_ENTRY NativeProcessList
 
PVOID SmpHeap
 
ULONG SmBaseTag
 
HANDLE SmpDebugPort
 
HANDLE SmpDosDevicesObjectDirectory
 
PWCHAR SmpDefaultEnvironment
 
PWCHAR SmpDefaultLibPathBuffer
 
UNICODE_STRING SmpKnownDllPath
 
UNICODE_STRING SmpDefaultLibPath
 
ULONG SmpCalledConfigEnv
 
ULONG SmpInitProgressByLine
 
NTSTATUS SmpInitReturnStatus
 
PVOID SmpInitLastCall
 
SECURITY_DESCRIPTOR SmpPrimarySDBody
 
SECURITY_DESCRIPTOR SmpLiberalSDBody
 
SECURITY_DESCRIPTOR SmpKnownDllsSDBody
 
SECURITY_DESCRIPTOR SmpApiPortSDBody
 
PISECURITY_DESCRIPTOR SmpPrimarySecurityDescriptor
 
PISECURITY_DESCRIPTOR SmpLiberalSecurityDescriptor
 
PISECURITY_DESCRIPTOR SmpKnownDllsSecurityDescriptor
 
PISECURITY_DESCRIPTOR SmpApiPortSecurityDescriptor
 
ULONG SmpAllowProtectedRenames
 
ULONG SmpProtectionMode = 1
 
BOOLEAN MiniNTBoot = FALSE
 
RTL_QUERY_REGISTRY_TABLE SmpRegistryConfigurationTable []
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file sminit.c.

◆ SMSS_CHECKPOINT

#define SMSS_CHECKPOINT (   x,
  y 
)
Value:
{ \
SmpInitProgressByLine = __LINE__; \
}
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
ULONG SmpInitProgressByLine
Definition: sminit.c:32
PVOID SmpInitLastCall
Definition: sminit.c:34
NTSTATUS SmpInitReturnStatus
Definition: sminit.c:33

Definition at line 44 of file sminit.c.

Function Documentation

◆ SmpConfigureAllowProtectedRenames()

NTSTATUS NTAPI SmpConfigureAllowProtectedRenames ( IN PWSTR  ValueName,
IN ULONG  ValueType,
IN PVOID  ValueData,
IN ULONG  ValueLength,
IN PVOID  Context,
IN PVOID  EntryContext 
)

Definition at line 247 of file sminit.c.

253{
254 /* Make sure the value is valid */
255 if (ValueLength == sizeof(ULONG))
256 {
257 /* Read it */
259 }
260 else
261 {
262 /* Default is to not allow protected renames */
264 }
265
266 DPRINT("SmpAllowProtectedRenames: %lu\n", SmpAllowProtectedRenames);
267 return STATUS_SUCCESS;
268}
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:312
#define STATUS_SUCCESS
Definition: shellext.h:65
ULONG SmpAllowProtectedRenames
Definition: sminit.c:41
#define DPRINT
Definition: sndvol32.h:73
uint32_t * PULONG
Definition: typedefs.h:59
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG ValueLength
Definition: wdfregistry.h:275

◆ SmpConfigureDosDevices()

NTSTATUS NTAPI SmpConfigureDosDevices ( IN PWSTR  ValueName,
IN ULONG  ValueType,
IN PVOID  ValueData,
IN ULONG  ValueLength,
IN PVOID  Context,
IN PVOID  EntryContext 
)

Definition at line 417 of file sminit.c.

423{
424 /* Save into linked list */
426}
#define TRUE
Definition: types.h:120
_In_ PCWSTR _Inout_ _At_ QueryTable EntryContext
Definition: rtlfuncs.h:4210
NTSTATUS NTAPI SmpSaveRegistryValue(IN PLIST_ENTRY ListAddress, IN PWSTR Name, IN PWCHAR Value, IN BOOLEAN Flags)
Definition: sminit.c:55
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243

◆ SmpConfigureEnvironment()

NTSTATUS NTAPI SmpConfigureEnvironment ( IN PWSTR  ValueName,
IN ULONG  ValueType,
IN PVOID  ValueData,
IN ULONG  ValueLength,
IN PVOID  Context,
IN PVOID  EntryContext 
)
Remarks
SmpConfigureEnvironment() should be called twice in order to resolve forward references to environment variables. See the two L"Environment" entries in SmpRegistryConfigurationTable[].

Definition at line 489 of file sminit.c.

495{
497 UNICODE_STRING ValueString, DataString;
498
499 /* Convert the strings into UNICODE_STRING and set the variable defined */
500 RtlInitUnicodeString(&ValueString, ValueName);
501 RtlInitUnicodeString(&DataString, ValueData);
502 DPRINT("Setting %wZ = %wZ\n", &ValueString, &DataString);
503 Status = RtlSetEnvironmentVariable(NULL, &ValueString, &DataString);
504 if (!NT_SUCCESS(Status))
505 {
506 DPRINT1("SMSS: 'SET %wZ = %wZ' failed - Status == %lx\n",
507 &ValueString, &DataString, Status);
508 return Status;
509 }
510
511 /* Check if the path is being set, and wait for the second instantiation */
512 if ((_wcsicmp(ValueName, L"Path") == 0) && (++SmpCalledConfigEnv == 2))
513 {
514 /* Allocate the path buffer */
515 SmpDefaultLibPathBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
516 SmBaseTag,
519
520 /* Copy the data into it and create the UNICODE_STRING to hold it */
523 }
524
525 /* All good */
526 return STATUS_SUCCESS;
527}
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:616
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
_ACRTIMP int __cdecl _wcsicmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:159
#define L(x)
Definition: resources.c:13
Status
Definition: gdiplustypes.h:25
NTSYSAPI NTSTATUS NTAPI RtlSetEnvironmentVariable(_In_z_ PWSTR *Environment, _In_ PUNICODE_STRING Name, _In_ PUNICODE_STRING Value)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
PWCHAR SmpDefaultLibPathBuffer
Definition: sminit.c:28
ULONG SmpCalledConfigEnv
Definition: sminit.c:30
ULONG SmBaseTag
Definition: sminit.c:26
UNICODE_STRING SmpDefaultLibPath
Definition: sminit.c:29
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263

◆ SmpConfigureExcludeKnownDlls()

NTSTATUS NTAPI SmpConfigureExcludeKnownDlls ( IN PWSTR  ValueName,
IN ULONG  ValueType,
IN PVOID  ValueData,
IN ULONG  ValueLength,
IN PVOID  Context,
IN PVOID  EntryContext 
)

Definition at line 382 of file sminit.c.

388{
389 PWCHAR DllName;
391
392 /* Make sure the value type is valid */
393 if ((ValueType == REG_MULTI_SZ) || (ValueType == REG_SZ))
394 {
395 /* Keep going for each DLL in the list */
396 DllName = ValueData;
397 while (*DllName)
398 {
399 /* Add this to the linked list */
400 DPRINT("Excluded DLL: %S\n", DllName);
402
403 /* Bail out on failure or if only one DLL name was present */
404 if (!(NT_SUCCESS(Status)) || (ValueType == REG_SZ)) return Status;
405
406 /* Otherwise, move to the next DLL name */
407 DllName += wcslen(DllName) + 1;
408 }
409 }
410
411 /* All done */
412 return STATUS_SUCCESS;
413}
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2983
#define REG_SZ
Definition: layer.c:22
#define REG_MULTI_SZ
Definition: nt_native.h:1504
uint16_t * PWCHAR
Definition: typedefs.h:56
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG _Out_opt_ PULONG _Out_opt_ PULONG ValueType
Definition: wdfregistry.h:282

◆ SmpConfigureFileRenames()

NTSTATUS NTAPI SmpConfigureFileRenames ( IN PWSTR  ValueName,
IN ULONG  ValueType,
IN PVOID  ValueData,
IN ULONG  ValueLength,
IN PVOID  Context,
IN PVOID  EntryContext 
)

Definition at line 351 of file sminit.c.

357{
359 static PWCHAR Canary = NULL;
360
361 /* Check if this is the second call */
362 if (Canary)
363 {
364 /* Save the data into the list */
365 DPRINT("Renamed file: '%S' - '%S'\n", Canary, ValueData);
367 Canary = NULL;
368 }
369 else
370 {
371 /* This it the first call, do nothing until we get the second call */
372 Canary = ValueData;
374 }
375
376 /* Return the status */
377 return Status;
378}
#define FALSE
Definition: types.h:117

◆ SmpConfigureKnownDlls()

NTSTATUS NTAPI SmpConfigureKnownDlls ( IN PWSTR  ValueName,
IN ULONG  ValueType,
IN PVOID  ValueData,
IN ULONG  ValueLength,
IN PVOID  Context,
IN PVOID  EntryContext 
)

Definition at line 460 of file sminit.c.

466{
467 /* Check which value is being set */
468 if (_wcsicmp(ValueName, L"DllDirectory") == 0)
469 {
470 /* This is the directory, initialize it */
471 DPRINT("KnownDll Path: %S\n", ValueData);
473 }
474 else
475 {
476 /* Add to the linked list -- this is a file */
478 }
479}
UNICODE_STRING SmpKnownDllPath
Definition: sminit.c:29
NTSTATUS NTAPI SmpInitializeKnownDllPath(IN PUNICODE_STRING DllPath, IN PWCHAR Buffer, IN ULONG Length)
Definition: sminit.c:430

◆ SmpConfigureMemoryMgmt()

NTSTATUS NTAPI SmpConfigureMemoryMgmt ( IN PWSTR  ValueName,
IN ULONG  ValueType,
IN PVOID  ValueData,
IN ULONG  ValueLength,
IN PVOID  Context,
IN PVOID  EntryContext 
)

Definition at line 338 of file sminit.c.

344{
345 /* Save this is into a list */
347}

◆ SmpConfigureObjectDirectories()

NTSTATUS NTAPI SmpConfigureObjectDirectories ( IN PWSTR  ValueName,
IN ULONG  ValueType,
IN PVOID  ValueData,
IN ULONG  ValueLength,
IN PVOID  Context,
IN PVOID  EntryContext 
)

Definition at line 272 of file sminit.c.

278{
279 PISECURITY_DESCRIPTOR SecDescriptor;
282 HANDLE DirHandle;
283 UNICODE_STRING RpcString, WindowsString, SearchString;
285
286 /* Initialize the two strings we will be looking for */
287 RtlInitUnicodeString(&RpcString, L"\\RPC Control");
288 RtlInitUnicodeString(&WindowsString, L"\\Windows");
289
290 /* Loop the registry data we received */
291 while (*SourceString)
292 {
293 /* Assume primary SD for most objects */
294 RtlInitUnicodeString(&SearchString, SourceString);
295 SecDescriptor = SmpPrimarySecurityDescriptor;
296
297 /* But for these two always set the liberal descriptor */
298 if ((RtlEqualUnicodeString(&SearchString, &RpcString, TRUE)) ||
299 (RtlEqualUnicodeString(&SearchString, &WindowsString, TRUE)))
300 {
301 SecDescriptor = SmpLiberalSecurityDescriptor;
302 }
303
304 /* Create the requested directory with the requested descriptor */
306 &SearchString,
308 OBJ_OPENIF |
310 NULL,
311 SecDescriptor);
312 DPRINT("Creating: %wZ directory\n", &SearchString);
313 Status = NtCreateDirectoryObject(&DirHandle,
316 if (!NT_SUCCESS(Status))
317 {
318 /* Failure case */
319 DPRINT1("SMSS: Unable to create %wZ object directory - Status == %lx\n",
320 &SearchString, Status);
321 }
322 else
323 {
324 /* It worked, now close the handle */
325 NtClose(DirHandle);
326 }
327
328 /* Move to the next requested object */
330 }
331
332 /* All done */
333 return STATUS_SUCCESS;
334}
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_Out_ _Inout_ POEM_STRING _In_ PCUNICODE_STRING SourceString
Definition: rtlfuncs.h:1957
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
#define DIRECTORY_ALL_ACCESS
Definition: nt_native.h:1262
NTSTATUS NTAPI NtCreateDirectoryObject(OUT PHANDLE DirectoryHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: obdir.c:765
#define OBJ_OPENIF
Definition: winternl.h:229
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define OBJ_PERMANENT
Definition: winternl.h:226
PISECURITY_DESCRIPTOR SmpLiberalSecurityDescriptor
Definition: sminit.c:38
PISECURITY_DESCRIPTOR SmpPrimarySecurityDescriptor
Definition: sminit.c:38

◆ SmpConfigureProtectionMode()

NTSTATUS NTAPI SmpConfigureProtectionMode ( IN PWSTR  ValueName,
IN ULONG  ValueType,
IN PVOID  ValueData,
IN ULONG  ValueLength,
IN PVOID  Context,
IN PVOID  EntryContext 
)

Definition at line 220 of file sminit.c.

226{
227 /* Make sure the value is valid */
228 if (ValueLength == sizeof(ULONG))
229 {
230 /* Read it */
232 }
233 else
234 {
235 /* Default is to protect stuff */
237 }
238
239 /* Recreate the security descriptors to take into account security mode */
241 DPRINT("SmpProtectionMode: %lu\n", SmpProtectionMode);
242 return STATUS_SUCCESS;
243}
ULONG SmpProtectionMode
Definition: sminit.c:41
NTSTATUS NTAPI SmpCreateSecurityDescriptors(IN BOOLEAN InitialCall)
Definition: sminit.c:977

◆ SmpConfigureSubSystems()

NTSTATUS NTAPI SmpConfigureSubSystems ( IN PWSTR  ValueName,
IN ULONG  ValueType,
IN PVOID  ValueData,
IN ULONG  ValueLength,
IN PVOID  Context,
IN PVOID  EntryContext 
)

Definition at line 531 of file sminit.c.

537{
538 PSMP_REGISTRY_VALUE RegEntry;
539 PWCHAR SubsystemName;
540
541 /* Is this a required or optional subsystem? */
542 if ((_wcsicmp(ValueName, L"Required") != 0) &&
543 (_wcsicmp(ValueName, L"Optional") != 0))
544 {
545 /* It isn't, is this the PSI flag? */
546 if ((_wcsicmp(ValueName, L"PosixSingleInstance") != 0) ||
547 (ValueType != REG_DWORD))
548 {
549 /* It isn't, must be a subsystem entry, add it to the list */
550 DPRINT("Subsystem entry: %S-%S\n", ValueName, ValueData);
552 }
553
554 /* This was the PSI flag, save it and exit */
556 return STATUS_SUCCESS;
557 }
558
559 /* This should be one of the required/optional lists. Is the type valid? */
560 if (ValueType == REG_MULTI_SZ)
561 {
562 /* It is, get the first subsystem */
563 SubsystemName = ValueData;
564 while (*SubsystemName)
565 {
566 /* We should have already put it into the list when we found it */
567 DPRINT("Found subsystem: %S\n", SubsystemName);
568 RegEntry = SmpFindRegistryValue(EntryContext, SubsystemName);
569 if (!RegEntry)
570 {
571 /* This subsystem doesn't exist, so skip it */
572 DPRINT1("SMSS: Invalid subsystem name - %ws\n", SubsystemName);
573 }
574 else
575 {
576 /* Found it -- remove it from the main list */
577 RemoveEntryList(&RegEntry->Entry);
578
579 /* Figure out which list to put it in */
580 if (_wcsicmp(ValueName, L"Required") == 0)
581 {
582 /* Put it into the required list */
583 DPRINT("Required\n");
585 }
586 else
587 {
588 /* Put it into the optional list */
589 DPRINT("Optional\n");
591 }
592 }
593
594 /* Move to the next name */
595 SubsystemName += wcslen(SubsystemName) + 1;
596 }
597 }
598
599 /* All done! */
600 return STATUS_SUCCESS;
601}
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define REG_DWORD
Definition: sdbapi.c:615
LIST_ENTRY SmpSubSystemsToLoad
Definition: sminit.c:22
PSMP_REGISTRY_VALUE NTAPI SmpFindRegistryValue(IN PLIST_ENTRY List, IN PWSTR ValueName)
Definition: sminit.c:189
LIST_ENTRY SmpSubSystemsToDefer
Definition: sminit.c:22
BOOLEAN RegPosixSingleInstance
Definition: smsubsys.c:22
LIST_ENTRY Entry
Definition: smss.h:57

◆ SmpCreateDynamicEnvironmentVariables()

NTSTATUS NTAPI SmpCreateDynamicEnvironmentVariables ( VOID  )

Definition at line 1685 of file sminit.c.

1686{
1688 SYSTEM_BASIC_INFORMATION BasicInfo;
1689 SYSTEM_PROCESSOR_INFORMATION ProcessorInfo;
1692 HANDLE KeyHandle, KeyHandle2;
1695 size_t StrLength;
1696 WCHAR ValueBuffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 512];
1697 WCHAR ValueBuffer2[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 512];
1698 PKEY_VALUE_PARTIAL_INFORMATION PartialInfo = (PVOID)ValueBuffer;
1699 PKEY_VALUE_PARTIAL_INFORMATION PartialInfo2 = (PVOID)ValueBuffer2;
1700
1701 /* Get system basic information -- we'll need the CPU count */
1703 &BasicInfo,
1704 sizeof(BasicInfo),
1705 NULL);
1706 if (!NT_SUCCESS(Status))
1707 {
1708 /* Bail out on failure */
1709 DPRINT1("SMSS: Unable to query system basic information - %x\n", Status);
1710 return Status;
1711 }
1712
1713 /* Get the processor information, we'll query a bunch of revision info */
1715 &ProcessorInfo,
1716 sizeof(ProcessorInfo),
1717 NULL);
1718 if (!NT_SUCCESS(Status))
1719 {
1720 /* Bail out on failure */
1721 DPRINT1("SMSS: Unable to query system processor information - %x\n", Status);
1722 return Status;
1723 }
1724
1725 /* We'll be writing all these environment variables over here */
1727 L"\\Registry\\Machine\\System\\CurrentControlSet\\"
1728 L"Control\\Session Manager\\Environment");
1732 NULL,
1733 NULL);
1735 if (!NT_SUCCESS(Status))
1736 {
1737 /* Bail out on failure */
1738 DPRINT1("SMSS: Unable to open %wZ - %x\n", &DestinationString, Status);
1739 return Status;
1740 }
1741
1742 /* First let's write the OS variable */
1744 ValueData = L"Windows_NT";
1745 DPRINT("Setting %wZ to %S\n", &ValueName, ValueData);
1747 &ValueName,
1748 0,
1749 REG_SZ,
1750 ValueData,
1751 (ULONG)(wcslen(ValueData) + 1) * sizeof(WCHAR));
1752 if (!NT_SUCCESS(Status))
1753 {
1754 DPRINT1("SMSS: Failed writing %wZ environment variable - %x\n",
1755 &ValueName, Status);
1757 return Status;
1758 }
1759
1760 /* Next, let's write the CPU architecture variable */
1761 RtlInitUnicodeString(&ValueName, L"PROCESSOR_ARCHITECTURE");
1762 switch (ProcessorInfo.ProcessorArchitecture)
1763 {
1764 /* Pick the correct string that matches the architecture */
1766 ValueData = L"x86";
1767 break;
1768
1770 ValueData = L"AMD64";
1771 break;
1772
1774 ValueData = L"IA64";
1775 break;
1776
1777 default:
1778 ValueData = L"Unknown";
1779 break;
1780 }
1781
1782 /* Set it */
1783 DPRINT("Setting %wZ to %S\n", &ValueName, ValueData);
1785 &ValueName,
1786 0,
1787 REG_SZ,
1788 ValueData,
1789 (ULONG)(wcslen(ValueData) + 1) * sizeof(WCHAR));
1790 if (!NT_SUCCESS(Status))
1791 {
1792 DPRINT1("SMSS: Failed writing %wZ environment variable - %x\n",
1793 &ValueName, Status);
1795 return Status;
1796 }
1797
1798 /* And now let's write the processor level */
1799 RtlInitUnicodeString(&ValueName, L"PROCESSOR_LEVEL");
1800 swprintf(ValueBuffer, L"%u", ProcessorInfo.ProcessorLevel);
1801 DPRINT("Setting %wZ to %S\n", &ValueName, ValueBuffer);
1803 &ValueName,
1804 0,
1805 REG_SZ,
1806 ValueBuffer,
1807 (ULONG)(wcslen(ValueBuffer) + 1) * sizeof(WCHAR));
1808 if (!NT_SUCCESS(Status))
1809 {
1810 DPRINT1("SMSS: Failed writing %wZ environment variable - %x\n",
1811 &ValueName, Status);
1813 return Status;
1814 }
1815
1816 /* Now open the hardware CPU key */
1818 L"\\Registry\\Machine\\Hardware\\Description\\System\\"
1819 L"CentralProcessor\\0");
1823 NULL,
1824 NULL);
1825 Status = NtOpenKey(&KeyHandle2, KEY_READ, &ObjectAttributes);
1826 if (!NT_SUCCESS(Status))
1827 {
1828 DPRINT1("SMSS: Unable to open %wZ - %x\n", &DestinationString, Status);
1830 return Status;
1831 }
1832
1833 /* So that we can read the identifier out of it... */
1834 RtlInitUnicodeString(&ValueName, L"Identifier");
1835 Status = NtQueryValueKey(KeyHandle2,
1836 &ValueName,
1838 PartialInfo,
1839 sizeof(ValueBuffer),
1840 &ResultLength);
1841 if (!NT_SUCCESS(Status) ||
1842 ((PartialInfo->Type != REG_SZ) && (PartialInfo->Type != REG_EXPAND_SZ)))
1843 {
1844 NtClose(KeyHandle2);
1846 DPRINT1("SMSS: Unable to read %wZ\\%wZ (Type %lu, Status 0x%x)\n",
1847 &DestinationString, &ValueName, PartialInfo->Type, Status);
1848 return Status;
1849 }
1850
1851 /* Initialize the string so that it can be large enough
1852 * to contain both the identifier and the vendor strings. */
1853 RtlInitEmptyUnicodeString(&DestinationString,
1854 (PWCHAR)PartialInfo->Data,
1855 sizeof(ValueBuffer) -
1858 PartialInfo->DataLength,
1859 &StrLength);
1860 DestinationString.Length = (USHORT)StrLength;
1861
1862 /* As well as the vendor... */
1863 RtlInitUnicodeString(&ValueName, L"VendorIdentifier");
1864 Status = NtQueryValueKey(KeyHandle2,
1865 &ValueName,
1867 PartialInfo2,
1868 sizeof(ValueBuffer2),
1869 &ResultLength);
1870 NtClose(KeyHandle2);
1871 if (NT_SUCCESS(Status) &&
1872 ((PartialInfo2->Type == REG_SZ) || (PartialInfo2->Type == REG_EXPAND_SZ)))
1873 {
1874 /* To combine it into a single string */
1877 L", %.*s",
1878 PartialInfo2->DataLength / sizeof(WCHAR),
1879 (PWCHAR)PartialInfo2->Data);
1881 }
1882
1883 /* So that we can set this as the PROCESSOR_IDENTIFIER variable */
1884 RtlInitUnicodeString(&ValueName, L"PROCESSOR_IDENTIFIER");
1885 DPRINT("Setting %wZ to %wZ\n", &ValueName, &DestinationString);
1887 &ValueName,
1888 0,
1889 REG_SZ,
1892 if (!NT_SUCCESS(Status))
1893 {
1894 DPRINT1("SMSS: Failed writing %wZ environment variable - %x\n",
1895 &ValueName, Status);
1897 return Status;
1898 }
1899
1900 /* Now let's get the processor architecture */
1901 RtlInitUnicodeString(&ValueName, L"PROCESSOR_REVISION");
1902 switch (ProcessorInfo.ProcessorArchitecture)
1903 {
1904 /* Check if this is an older Intel CPU */
1906 if ((ProcessorInfo.ProcessorRevision >> 8) == 0xFF)
1907 {
1908 /* These guys used a revision + stepping, so get the rev only */
1909 swprintf(ValueBuffer, L"%02x", ProcessorInfo.ProcessorRevision & 0xFF);
1910 _wcsupr(ValueBuffer);
1911 break;
1912 }
1913
1914 /* Modern Intel, as well as 64-bit CPUs use a revision without stepping */
1917 swprintf(ValueBuffer, L"%04x", ProcessorInfo.ProcessorRevision);
1918 break;
1919
1920 /* And anything else we'll just read the whole revision identifier */
1921 default:
1922 swprintf(ValueBuffer, L"%u", ProcessorInfo.ProcessorRevision);
1923 break;
1924 }
1925
1926 /* Write the revision to the registry */
1927 DPRINT("Setting %wZ to %S\n", &ValueName, ValueBuffer);
1929 &ValueName,
1930 0,
1931 REG_SZ,
1932 ValueBuffer,
1933 (ULONG)(wcslen(ValueBuffer) + 1) * sizeof(WCHAR));
1934 if (!NT_SUCCESS(Status))
1935 {
1936 DPRINT1("SMSS: Failed writing %wZ environment variable - %x\n",
1937 &ValueName, Status);
1939 return Status;
1940 }
1941
1942 /* And finally, write the number of CPUs */
1943 RtlInitUnicodeString(&ValueName, L"NUMBER_OF_PROCESSORS");
1944 swprintf(ValueBuffer, L"%d", BasicInfo.NumberOfProcessors);
1945 DPRINT("Setting %wZ to %S\n", &ValueName, ValueBuffer);
1947 &ValueName,
1948 0,
1949 REG_SZ,
1950 ValueBuffer,
1951 (ULONG)(wcslen(ValueBuffer) + 1) * sizeof(WCHAR));
1952 if (!NT_SUCCESS(Status))
1953 {
1954 DPRINT1("SMSS: Failed writing %wZ environment variable - %x\n",
1955 &ValueName, Status);
1957 return Status;
1958 }
1959
1960 /* Now we need to write the safeboot option key in a different format */
1962 L"\\Registry\\Machine\\System\\CurrentControlSet\\"
1963 L"Control\\Safeboot\\Option");
1967 NULL,
1968 NULL);
1970 if (NT_SUCCESS(Status))
1971 {
1972 /* This was indeed a safeboot, so check what kind of safeboot it was */
1973 RtlInitUnicodeString(&ValueName, L"OptionValue");
1974 Status = NtQueryValueKey(KeyHandle2,
1975 &ValueName,
1977 PartialInfo,
1978 sizeof(ValueBuffer),
1979 &ResultLength);
1980 NtClose(KeyHandle2);
1981 if (NT_SUCCESS(Status) &&
1982 (PartialInfo->Type == REG_DWORD) &&
1983 (PartialInfo->DataLength >= sizeof(ULONG)))
1984 {
1985 /* Convert from the integer value to the correct specifier */
1986 RtlInitUnicodeString(&ValueName, L"SAFEBOOT_OPTION");
1987 switch (*(PULONG)PartialInfo->Data)
1988 {
1989 case 1:
1990 wcscpy(ValueBuffer, L"MINIMAL");
1991 break;
1992 case 2:
1993 wcscpy(ValueBuffer, L"NETWORK");
1994 break;
1995 case 3:
1996 wcscpy(ValueBuffer, L"DSREPAIR");
1997 break;
1998 }
1999
2000 /* And write it in the environment! */
2001 DPRINT("Setting %wZ to %S\n", &ValueName, ValueBuffer);
2003 &ValueName,
2004 0,
2005 REG_SZ,
2006 ValueBuffer,
2007 (ULONG)(wcslen(ValueBuffer) + 1) * sizeof(WCHAR));
2008 if (!NT_SUCCESS(Status))
2009 {
2010 DPRINT1("SMSS: Failed writing %wZ environment variable - %x\n",
2011 &ValueName, Status);
2013 return Status;
2014 }
2015 }
2016 else
2017 {
2018 DPRINT1("SMSS: Failed to query SAFEBOOT option (Type %lu, Status 0x%x)\n",
2019 PartialInfo->Type, Status);
2020 }
2021 }
2022
2023 /* We are all done now */
2025 return STATUS_SUCCESS;
2026}
#define swprintf
Definition: precomp.h:40
@ SystemProcessorInformation
Definition: ntddk_ex.h:12
@ SystemBasicInformation
Definition: ntddk_ex.h:11
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
#define PROCESSOR_ARCHITECTURE_IA64
Definition: ketypes.h:111
#define PROCESSOR_ARCHITECTURE_AMD64
Definition: ketypes.h:114
#define PROCESSOR_ARCHITECTURE_INTEL
Definition: ketypes.h:105
_Out_ _Inout_ POEM_STRING DestinationString
Definition: rtlfuncs.h:1956
NTSYSAPI NTSTATUS NTAPI NtOpenKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: ntapi.c:336
NTSYSAPI NTSTATUS NTAPI NtSetValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName, IN ULONG TitleIndex OPTIONAL, IN ULONG Type, IN PVOID Data, IN ULONG DataSize)
Definition: ntapi.c:859
@ KeyValuePartialInformation
Definition: nt_native.h:1185
#define KEY_ALL_ACCESS
Definition: nt_native.h:1044
#define KEY_READ
Definition: nt_native.h:1026
NTSYSAPI NTSTATUS NTAPI NtQueryValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName, IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, IN PVOID KeyValueInformation, IN ULONG Length, IN PULONG ResultLength)
struct _KEY_VALUE_PARTIAL_INFORMATION KEY_VALUE_PARTIAL_INFORMATION
#define GENERIC_WRITE
Definition: nt_native.h:90
#define REG_EXPAND_SZ
Definition: nt_native.h:1497
#define UNICODE_NULL
_Must_inspect_result_ NTSTRSAFEAPI RtlStringCbLengthW(_In_reads_or_z_(cbMax/sizeof(wchar_t)) STRSAFE_LPCWSTR psz, _In_ _In_range_(1, NTSTRSAFE_MAX_CCH *sizeof(wchar_t)) size_t cbMax, _Out_opt_ _Deref_out_range_(<, cbMax - 1) size_t *pcbLength)
Definition: ntstrsafe.h:1641
NTSTRSAFEVAPI RtlStringCbPrintfW(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1173
short WCHAR
Definition: pedump.c:58
unsigned short USHORT
Definition: pedump.c:61
_wcsupr
wcscpy
NTSYSAPI NTSTATUS NTAPI NtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInfoClass, OUT PVOID SystemInfoBuffer, IN ULONG SystemInfoBufferSize, OUT PULONG BytesReturned OPTIONAL)
unsigned short Length
Definition: sprintf.c:451
void * Buffer
Definition: sprintf.c:453
unsigned short MaximumLength
Definition: sprintf.c:452
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
void * PVOID
Definition: typedefs.h:50
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG _Out_ PULONG ResultLength
Definition: wdfdevice.h:3782

Referenced by SmpLoadDataFromRegistry().

◆ SmpCreateSecurityDescriptors()

NTSTATUS NTAPI SmpCreateSecurityDescriptors ( IN BOOLEAN  InitialCall)

Definition at line 977 of file sminit.c.

978{
980 PSID WorldSid = NULL, AdminSid = NULL, SystemSid = NULL;
981 PSID RestrictedSid = NULL, OwnerSid = NULL;
985 ULONG AclLength, SidLength;
986 PACL Acl;
988 BOOLEAN ProtectionRequired = FALSE;
989
990 /* Check if this is the first call */
991 if (InitialCall)
992 {
993 /* Create and set the primary descriptor */
999 TRUE,
1000 NULL,
1001 FALSE);
1003
1004 /* Create and set the liberal descriptor */
1010 TRUE,
1011 NULL,
1012 FALSE);
1014
1015 /* Create and set the \KnownDlls descriptor */
1021 TRUE,
1022 NULL,
1023 FALSE);
1025
1026 /* Create and Set the \ApiPort descriptor */
1032 TRUE,
1033 NULL,
1034 FALSE);
1036 }
1037
1038 /* Check if protection was requested in the registry (on by default) */
1039 if (SmpProtectionMode & 1) ProtectionRequired = TRUE;
1040
1041 /* Exit if there's nothing to do */
1042 if (!(InitialCall || ProtectionRequired)) return STATUS_SUCCESS;
1043
1044 /* Build the world SID */
1047 0, 0, 0, 0, 0, 0, 0,
1048 &WorldSid);
1049 if (!NT_SUCCESS(Status))
1050 {
1051 WorldSid = NULL;
1052 goto Quickie;
1053 }
1054
1055 /* Build the admin SID */
1059 0, 0, 0, 0, 0, 0,
1060 &AdminSid);
1061 if (!NT_SUCCESS(Status))
1062 {
1063 AdminSid = NULL;
1064 goto Quickie;
1065 }
1066
1067 /* Build the owner SID */
1068 Status = RtlAllocateAndInitializeSid(&CreatorAuthority, 1,
1070 0, 0, 0, 0, 0, 0, 0,
1071 &OwnerSid);
1072 if (!NT_SUCCESS(Status))
1073 {
1074 OwnerSid = NULL;
1075 goto Quickie;
1076 }
1077
1078 /* Build the restricted SID */
1081 0, 0, 0, 0, 0, 0, 0,
1082 &RestrictedSid);
1083 if (!NT_SUCCESS(Status))
1084 {
1085 RestrictedSid = NULL;
1086 goto Quickie;
1087 }
1088
1089 /* Build the system SID */
1092 0, 0, 0, 0, 0, 0, 0,
1093 &SystemSid);
1094 if (!NT_SUCCESS(Status))
1095 {
1096 SystemSid = NULL;
1097 goto Quickie;
1098 }
1099
1100 /* Now check if we're creating the core descriptors */
1101 if (!InitialCall)
1102 {
1103 /* We're skipping NextAcl so we have to do this here */
1104 SidLength = RtlLengthSid(WorldSid) + RtlLengthSid(RestrictedSid) + RtlLengthSid(AdminSid);
1105 SidLength *= 2;
1106 goto NotInitial;
1107 }
1108
1109 /* Allocate an ACL with two ACEs with two SIDs each */
1110 SidLength = RtlLengthSid(SystemSid) + RtlLengthSid(AdminSid);
1111 AclLength = sizeof(ACL) + 2 * sizeof(ACCESS_ALLOWED_ACE) + SidLength;
1112 Acl = RtlAllocateHeap(RtlGetProcessHeap(), 0, AclLength);
1113 if (!Acl) Status = STATUS_NO_MEMORY;
1114 if (!NT_SUCCESS(Status)) goto NextAcl;
1115
1116 /* Now build the ACL and add the two ACEs */
1123
1124 /* Set this as the DACL */
1126 TRUE,
1127 Acl,
1128 FALSE);
1130
1131NextAcl:
1132 /* Allocate an ACL with 6 ACEs, two ACEs per SID */
1133 SidLength = RtlLengthSid(WorldSid) + RtlLengthSid(RestrictedSid) + RtlLengthSid(AdminSid);
1134 SidLength *= 2;
1135 AclLength = sizeof(ACL) + 6 * sizeof(ACCESS_ALLOWED_ACE) + SidLength;
1136 Acl = RtlAllocateHeap(RtlGetProcessHeap(), 0, AclLength);
1137 if (!Acl) Status = STATUS_NO_MEMORY;
1138 if (!NT_SUCCESS(Status)) goto NotInitial;
1139
1140 /* Now build the ACL and add the six ACEs */
1155
1156 /* Now edit the last three ACEs and make them inheritable */
1157 Status = RtlGetAce(Acl, 3, (PVOID)&Ace);
1160 Status = RtlGetAce(Acl, 4, (PVOID)&Ace);
1163 Status = RtlGetAce(Acl, 5, (PVOID)&Ace);
1166
1167 /* Set this as the DACL */
1169 TRUE,
1170 Acl,
1171 FALSE);
1173
1174NotInitial:
1175 /* The initial ACLs have been created, are we also protecting objects? */
1176 if (!ProtectionRequired) goto Quickie;
1177
1178 /* Allocate an ACL with 7 ACEs, two ACEs per SID, and one final owner ACE */
1179 SidLength += RtlLengthSid(OwnerSid);
1180 AclLength = sizeof(ACL) + 7 * sizeof (ACCESS_ALLOWED_ACE) + 2 * SidLength;
1181 Acl = RtlAllocateHeap(RtlGetProcessHeap(), 0, AclLength);
1182 if (!Acl) Status = STATUS_NO_MEMORY;
1183 if (!NT_SUCCESS(Status)) goto Quickie;
1184
1185 /* Build the ACL and add the seven ACEs */
1202
1203 /* Edit the last 4 ACEs to make then inheritable */
1204 Status = RtlGetAce(Acl, 3, (PVOID)&Ace);
1207 Status = RtlGetAce(Acl, 4, (PVOID)&Ace);
1210 Status = RtlGetAce(Acl, 5, (PVOID)&Ace);
1213 Status = RtlGetAce(Acl, 6, (PVOID)&Ace);
1216
1217 /* Set this as the DACL for the primary SD */
1219 TRUE,
1220 Acl,
1221 FALSE);
1223
1224 /* Allocate an ACL with 7 ACEs, two ACEs per SID, and one final owner ACE */
1225 AclLength = sizeof(ACL) + 7 * sizeof (ACCESS_ALLOWED_ACE) + 2 * SidLength;
1226 Acl = RtlAllocateHeap(RtlGetProcessHeap(), 0, AclLength);
1227 if (!Acl) Status = STATUS_NO_MEMORY;
1228 if (!NT_SUCCESS(Status)) goto Quickie;
1229
1230 /* Build the ACL and add the seven ACEs */
1247
1248 /* Edit the last 4 ACEs to make then inheritable */
1249 Status = RtlGetAce(Acl, 3, (PVOID)&Ace);
1252 Status = RtlGetAce(Acl, 4, (PVOID)&Ace);
1255 Status = RtlGetAce(Acl, 5, (PVOID)&Ace);
1258 Status = RtlGetAce(Acl, 6, (PVOID)&Ace);
1261
1262 /* Now set this as the DACL for the liberal SD */
1264 TRUE,
1265 Acl,
1266 FALSE);
1268
1269Quickie:
1270 /* Cleanup the SIDs */
1271 if (OwnerSid) RtlFreeHeap(RtlGetProcessHeap(), 0, OwnerSid);
1272 if (AdminSid) RtlFreeHeap(RtlGetProcessHeap(), 0, AdminSid);
1273 if (WorldSid) RtlFreeHeap(RtlGetProcessHeap(), 0, WorldSid);
1274 if (SystemSid) RtlFreeHeap(RtlGetProcessHeap(), 0, SystemSid);
1275 if (RestrictedSid) RtlFreeHeap(RtlGetProcessHeap(), 0, RestrictedSid);
1276 return Status;
1277}
unsigned char BOOLEAN
Definition: actypes.h:127
PSID WorldSid
Definition: globals.c:15
static SID_IDENTIFIER_AUTHORITY NtAuthority
Definition: security.c:40
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:634
@ Ace
Definition: card.h:12
#define GENERIC_READ
Definition: compat.h:135
static SID_IDENTIFIER_AUTHORITY WorldAuthority
Definition: security.c:14
#define ASSERT(a)
Definition: mode.c:44
struct _ACL ACL
static PSID AdminSid
Definition: msgina.c:39
NTSYSAPI NTSTATUS NTAPI RtlCreateAcl(PACL Acl, ULONG AclSize, ULONG AclRevision)
NTSYSAPI NTSTATUS NTAPI RtlGetAce(PACL Acl, ULONG AceIndex, PVOID *Ace)
NTSYSAPI ULONG NTAPI RtlLengthSid(IN PSID Sid)
Definition: sid.c:150
NTSYSAPI NTSTATUS NTAPI RtlCreateSecurityDescriptor(_Out_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ ULONG Revision)
#define GENERIC_ALL
Definition: nt_native.h:92
#define GENERIC_EXECUTE
Definition: nt_native.h:91
NTSYSAPI NTSTATUS NTAPI RtlAllocateAndInitializeSid(IN PSID_IDENTIFIER_AUTHORITY IdentifierAuthority, IN UCHAR SubAuthorityCount, IN ULONG SubAuthority0, IN ULONG SubAuthority1, IN ULONG SubAuthority2, IN ULONG SubAuthority3, IN ULONG SubAuthority4, IN ULONG SubAuthority5, IN ULONG SubAuthority6, IN ULONG SubAuthority7, OUT PSID *Sid)
Definition: sid.c:290
SECURITY_DESCRIPTOR SmpApiPortSDBody
Definition: sminit.c:37
SECURITY_DESCRIPTOR SmpLiberalSDBody
Definition: sminit.c:36
SECURITY_DESCRIPTOR SmpKnownDllsSDBody
Definition: sminit.c:36
PISECURITY_DESCRIPTOR SmpKnownDllsSecurityDescriptor
Definition: sminit.c:39
PISECURITY_DESCRIPTOR SmpApiPortSecurityDescriptor
Definition: sminit.c:39
SECURITY_DESCRIPTOR SmpPrimarySDBody
Definition: sminit.c:36
NTSYSAPI NTSTATUS WINAPI RtlAddAccessAllowedAce(PACL, DWORD, DWORD, PSID)
NTSYSAPI NTSTATUS WINAPI RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR, BOOLEAN, PACL, BOOLEAN)
_In_ ULONG AclLength
Definition: rtlfuncs.h:1859
#define CONTAINER_INHERIT_ACE
Definition: setypes.h:747
#define INHERIT_ONLY_ACE
Definition: setypes.h:749
#define SECURITY_BUILTIN_DOMAIN_RID
Definition: setypes.h:581
#define SECURITY_WORLD_SID_AUTHORITY
Definition: setypes.h:527
#define SECURITY_WORLD_RID
Definition: setypes.h:541
#define SECURITY_LOCAL_SYSTEM_RID
Definition: setypes.h:574
#define ACL_REVISION2
Definition: setypes.h:43
#define SECURITY_RESTRICTED_CODE_RID
Definition: setypes.h:569
#define SECURITY_NT_AUTHORITY
Definition: setypes.h:554
#define OBJECT_INHERIT_ACE
Definition: setypes.h:746
#define SECURITY_DESCRIPTOR_REVISION
Definition: setypes.h:58
#define SECURITY_CREATOR_OWNER_RID
Definition: setypes.h:545
#define DOMAIN_ALIAS_RID_ADMINS
Definition: setypes.h:652
#define SECURITY_CREATOR_SID_AUTHORITY
Definition: setypes.h:533

Referenced by SmpConfigureProtectionMode(), and SmpInit().

◆ SmpFindRegistryValue()

PSMP_REGISTRY_VALUE NTAPI SmpFindRegistryValue ( IN PLIST_ENTRY  List,
IN PWSTR  ValueName 
)

Definition at line 189 of file sminit.c.

191{
192 PSMP_REGISTRY_VALUE RegEntry;
193 UNICODE_STRING ValueString;
194 PLIST_ENTRY NextEntry;
195
196 /* Initialize the value name sting */
197 RtlInitUnicodeString(&ValueString, ValueName);
198
199 /* Loop the list */
200 NextEntry = List->Flink;
201 while (NextEntry != List)
202 {
203 /* Get each entry */
204 RegEntry = CONTAINING_RECORD(NextEntry, SMP_REGISTRY_VALUE, Entry);
205
206 /* Check if the value name matches */
207 if (!RtlCompareUnicodeString(&RegEntry->Name, &ValueString, TRUE)) break;
208
209 /* It doesn't, move on */
210 NextEntry = NextEntry->Flink;
211 }
212
213 /* If we looped back, return NULL, otherwise return the entry we found */
214 if (NextEntry == List) RegEntry = NULL;
215 return RegEntry;
216}
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
Entry
Definition: section.c:5210
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
UNICODE_STRING Name
Definition: smss.h:58
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550

Referenced by SmpConfigureSubSystems(), and SmpInitializeKnownDllsInternal().

◆ SmpInit()

NTSTATUS NTAPI SmpInit ( IN PUNICODE_STRING  InitialCommand,
OUT PHANDLE  ProcessHandle 
)

Definition at line 2451 of file sminit.c.

2453{
2454 NTSTATUS Status, Status2;
2456 UNICODE_STRING PortName, EventName;
2457 HANDLE EventHandle, PortHandle;
2458 ULONG HardErrorMode;
2459
2460 /* Create the SMSS Heap */
2461 SmBaseTag = RtlCreateTagHeap(RtlGetProcessHeap(),
2462 0,
2463 L"SMSS!",
2464 L"INIT");
2465 SmpHeap = RtlGetProcessHeap();
2466
2467 /* Enable hard errors */
2468 HardErrorMode = TRUE;
2471 &HardErrorMode,
2472 sizeof(HardErrorMode));
2473
2474 /* Initialize the subsystem list and the session list, plus their locks */
2479
2480 /* Initialize the process list */
2482
2483 /* Initialize session parameters */
2484 SmpNextSessionId = 1;
2487
2488 /* Create the initial security descriptors */
2490 if (!NT_SUCCESS(Status))
2491 {
2492 /* Fail */
2494 return Status;
2495 }
2496
2497 /* Initialize subsystem names */
2498 RtlInitUnicodeString(&SmpSubsystemName, L"NT-Session Manager");
2501
2502 /* Create the SM API Port */
2503 RtlInitUnicodeString(&PortName, L"\\SmApiPort");
2505 Status = NtCreatePort(&PortHandle,
2507 sizeof(SB_CONNECTION_INFO),
2508 sizeof(SM_API_MSG),
2509 sizeof(SB_API_MSG) * 32);
2511 SmpDebugPort = PortHandle;
2512
2513 /* Create two SM API threads */
2515 NULL,
2516 FALSE,
2517 0,
2518 0,
2519 0,
2520 SmpApiLoop,
2521 PortHandle,
2522 NULL,
2523 NULL);
2526 NULL,
2527 FALSE,
2528 0,
2529 0,
2530 0,
2531 SmpApiLoop,
2532 PortHandle,
2533 NULL,
2534 NULL);
2536
2537 /* Create the write event that autochk can set after running */
2538 RtlInitUnicodeString(&EventName, L"\\Device\\VolumesSafeForWriteAccess");
2540 &EventName,
2542 NULL,
2543 NULL);
2544 Status2 = NtCreateEvent(&EventHandle,
2547 0,
2548 0);
2549 if (!NT_SUCCESS(Status2))
2550 {
2551 /* Should never really fail */
2552 DPRINT1("SMSS: Unable to create %wZ event - Status == %lx\n",
2553 &EventName, Status2);
2554 ASSERT(NT_SUCCESS(Status2));
2555 }
2556
2557 /* Now initialize everything else based on the registry parameters */
2558 Status = SmpLoadDataFromRegistry(InitialCommand);
2559 if (NT_SUCCESS(Status))
2560 {
2561 /* Autochk should've run now. Set the event and save the CSRSS handle */
2565 }
2566
2567 /* All done */
2568 return Status;
2569}
static UNICODE_STRING PortName
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define EVENT_ALL_ACCESS
Definition: isotest.c:82
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:403
NTSYSAPI NTSTATUS NTAPI RtlCreateUserThread(_In_ PVOID ThreadContext, _Out_ HANDLE *OutThreadHandle, _Reserved_ PVOID Reserved1, _Reserved_ PVOID Reserved2, _Reserved_ PVOID Reserved3, _Reserved_ PVOID Reserved4, _Reserved_ PVOID Reserved5, _Reserved_ PVOID Reserved6, _Reserved_ PVOID Reserved7, _Reserved_ PVOID Reserved8)
NTSYSAPI NTSTATUS NTAPI RtlInitializeCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
#define NtCurrentProcess()
Definition: nt_native.h:1660
NTSTATUS NTAPI NtSetEvent(IN HANDLE EventHandle, OUT PLONG PreviousState OPTIONAL)
Definition: event.c:463
NTSTATUS NTAPI NtCreateEvent(OUT PHANDLE EventHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN EVENT_TYPE EventType, IN BOOLEAN InitialState)
Definition: event.c:96
NTSTATUS NTAPI NtCreatePort(OUT PHANDLE PortHandle, IN POBJECT_ATTRIBUTES ObjectAttributes, IN ULONG MaxConnectInfoLength, IN ULONG MaxDataLength, IN ULONG MaxPoolUsage)
Definition: create.c:222
NTSTATUS NTAPI NtSetInformationProcess(_In_ HANDLE ProcessHandle, _In_ PROCESSINFOCLASS ProcessInformationClass, _In_reads_bytes_(ProcessInformationLength) PVOID ProcessInformation, _In_ ULONG ProcessInformationLength)
Definition: query.c:1390
ULONG NTAPI RtlCreateTagHeap(_In_ HANDLE HeapHandle, _In_ ULONG Flags, _In_opt_ PWSTR TagName, _In_ PWSTR TagSubName)
Definition: heap.c:4037
PVOID SmpHeap
Definition: sminit.c:25
HANDLE SmpDebugPort
Definition: sminit.c:27
#define SMSS_CHECKPOINT(x, y)
Definition: sminit.c:44
UNICODE_STRING PosixName
Definition: sminit.c:18
UNICODE_STRING Os2Name
Definition: sminit.c:18
NTSTATUS NTAPI SmpLoadDataFromRegistry(OUT PUNICODE_STRING InitialCommand)
Definition: sminit.c:2245
UNICODE_STRING SmpSubsystemName
Definition: sminit.c:18
LIST_ENTRY NativeProcessList
Definition: sminit.c:23
ULONG NTAPI SmpApiLoop(IN PVOID Parameter)
Definition: smloop.c:423
LIST_ENTRY SmpSessionListHead
Definition: smsessn.c:27
RTL_CRITICAL_SECTION SmpSessionListLock
Definition: smsessn.c:26
BOOLEAN SmpNextSessionIdScanMode
Definition: smsessn.c:29
BOOLEAN SmpDbgSsLoaded
Definition: smsessn.c:30
ULONG SmpNextSessionId
Definition: smsessn.c:28
HANDLE SmpWindowsSubSysProcess
Definition: smsubsys.c:20
RTL_CRITICAL_SECTION SmpKnownSubSysLock
Definition: smsubsys.c:18
LIST_ENTRY SmpKnownSubSysHead
Definition: smsubsys.c:19
@ ProcessDefaultHardErrorMode
Definition: winternl.h:1894
_Out_ PHANDLE EventHandle
Definition: iofuncs.h:857

Referenced by _main().

◆ SmpInitializeDosDevices()

NTSTATUS NTAPI SmpInitializeDosDevices ( VOID  )

Definition at line 1281 of file sminit.c.

1282{
1284 PSMP_REGISTRY_VALUE RegEntry;
1285 SECURITY_DESCRIPTOR_CONTROL OldFlag = 0;
1287 UNICODE_STRING GlobalName;
1288 HANDLE DirHandle;
1289 PLIST_ENTRY NextEntry, Head;
1290
1291 /* Open the \GLOBAL?? directory */
1292 RtlInitUnicodeString(&GlobalName, L"\\??");
1294 &GlobalName,
1296 NULL,
1297 NULL);
1301 if (!NT_SUCCESS(Status))
1302 {
1303 DPRINT1("SMSS: Unable to open %wZ directory - Status == %lx\n",
1304 &GlobalName, Status);
1305 return Status;
1306 }
1307
1308 /* Loop the DOS devices */
1309 Head = &SmpDosDevicesList;
1310 while (!IsListEmpty(Head))
1311 {
1312 /* Get the entry and remove it */
1313 NextEntry = RemoveHeadList(Head);
1314 RegEntry = CONTAINING_RECORD(NextEntry, SMP_REGISTRY_VALUE, Entry);
1315
1316 /* Initialize the attributes, and see which descriptor is being used */
1318 &RegEntry->Name,
1323 {
1324 /* Save the old flag and set it while we create this link */
1327 }
1328
1329 /* Create the symbolic link */
1330 DPRINT("Creating symlink for %wZ to %wZ\n", &RegEntry->Name, &RegEntry->Value);
1334 &RegEntry->Value);
1336 {
1337 /* Make it temporary and get rid of the handle */
1338 NtMakeTemporaryObject(DirHandle);
1339 NtClose(DirHandle);
1340
1341 /* Treat this as success, and see if we got a name back */
1343 if (RegEntry->Value.Length)
1344 {
1345 /* Create it now with this name */
1346 ObjectAttributes.Attributes &= ~OBJ_OPENIF;
1350 &RegEntry->Value);
1351 }
1352 }
1353
1354 /* If we were using a security descriptor, restore the non-defaulted flag */
1355 if (ObjectAttributes.SecurityDescriptor)
1356 {
1358 }
1359
1360 /* Print a failure if we failed to create the symbolic link */
1361 if (!NT_SUCCESS(Status))
1362 {
1363 DPRINT1("SMSS: Unable to create %wZ => %wZ symbolic link object - Status == 0x%lx\n",
1364 &RegEntry->Name,
1365 &RegEntry->Value,
1366 Status);
1367 break;
1368 }
1369
1370 /* Close the handle */
1371 NtClose(DirHandle);
1372
1373 /* Free this entry */
1374 if (RegEntry->AnsiValue) RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry->AnsiValue);
1375 if (RegEntry->Value.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry->Value.Buffer);
1376 RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry);
1377 }
1378
1379 /* Return the status */
1380 return Status;
1381}
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
WORD SECURITY_DESCRIPTOR_CONTROL
Definition: lsa.idl:37
#define SYMBOLIC_LINK_ALL_ACCESS
Definition: nt_native.h:1270
#define STATUS_OBJECT_NAME_EXISTS
Definition: ntstatus.h:189
NTSTATUS NTAPI NtOpenDirectoryObject(OUT PHANDLE DirectoryHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: obdir.c:393
NTSTATUS NTAPI NtMakeTemporaryObject(IN HANDLE ObjectHandle)
Definition: oblife.c:1473
LIST_ENTRY SmpDosDevicesList
Definition: sminit.c:20
HANDLE SmpDosDevicesObjectDirectory
Definition: sminit.c:27
PCHAR AnsiValue
Definition: smss.h:60
UNICODE_STRING Value
Definition: smss.h:59
#define SE_DACL_DEFAULTED
Definition: setypes.h:834

Referenced by SmpLoadDataFromRegistry().

◆ SmpInitializeKnownDllPath()

NTSTATUS NTAPI SmpInitializeKnownDllPath ( IN PUNICODE_STRING  DllPath,
IN PWCHAR  Buffer,
IN ULONG  Length 
)

Definition at line 430 of file sminit.c.

433{
435
436 /* Allocate the buffer */
437 DllPath->Buffer = RtlAllocateHeap(RtlGetProcessHeap(), SmBaseTag, Length);
438 if (DllPath->Buffer)
439 {
440 /* Fill out the rest of the string */
441 DllPath->MaximumLength = (USHORT)Length;
442 DllPath->Length = (USHORT)Length - sizeof(UNICODE_NULL);
443
444 /* Copy the actual path and return success */
447 }
448 else
449 {
450 /* Fail with out of memory code */
452 }
453
454 /* Return result */
455 return Status;
456}
Definition: bufpool.h:45
static const char const char * DllPath
Definition: image.c:34
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102

Referenced by SmpConfigureKnownDlls().

◆ SmpInitializeKnownDlls()

NTSTATUS NTAPI SmpInitializeKnownDlls ( VOID  )

Definition at line 1654 of file sminit.c.

1655{
1657 PSMP_REGISTRY_VALUE RegEntry;
1658 UNICODE_STRING KnownDllsName;
1659 PLIST_ENTRY Head, NextEntry;
1660
1661 /* Call the internal function */
1662 RtlInitUnicodeString(&KnownDllsName, L"\\KnownDlls");
1664
1665 /* Wipe out the list regardless of success */
1666 Head = &SmpKnownDllsList;
1667 while (!IsListEmpty(Head))
1668 {
1669 /* Remove this entry */
1670 NextEntry = RemoveHeadList(Head);
1671
1672 /* Free it */
1673 RegEntry = CONTAINING_RECORD(NextEntry, SMP_REGISTRY_VALUE, Entry);
1674 RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry->AnsiValue);
1675 RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry->Value.Buffer);
1676 RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry);
1677 }
1678
1679 /* All done */
1680 return Status;
1681}
LIST_ENTRY SmpKnownDllsList
Definition: sminit.c:21
NTSTATUS NTAPI SmpInitializeKnownDllsInternal(IN PUNICODE_STRING Directory, IN PUNICODE_STRING Path)
Definition: sminit.c:1427

Referenced by SmpLoadDataFromRegistry().

◆ SmpInitializeKnownDllsInternal()

NTSTATUS NTAPI SmpInitializeKnownDllsInternal ( IN PUNICODE_STRING  Directory,
IN PUNICODE_STRING  Path 
)

Definition at line 1427 of file sminit.c.

1429{
1430 HANDLE DirFileHandle, DirHandle, SectionHandle, FileHandle, LinkHandle;
1431 UNICODE_STRING NtPath, SymLinkName;
1433 NTSTATUS Status, Status1;
1434 PLIST_ENTRY NextEntry;
1435 PSMP_REGISTRY_VALUE RegEntry;
1436 ULONG_PTR ErrorParameters[3];
1437 UNICODE_STRING ErrorResponse;
1439 SECURITY_DESCRIPTOR_CONTROL OldFlag = 0;
1440 USHORT ImageCharacteristics;
1441
1442 /* Initialize to NULL */
1443 DirFileHandle = NULL;
1444 DirHandle = NULL;
1445 NtPath.Buffer = NULL;
1446
1447 /* Create the \KnownDLLs directory */
1449 Directory,
1451 NULL,
1453 Status = NtCreateDirectoryObject(&DirHandle,
1456 if (!NT_SUCCESS(Status))
1457 {
1458 /* Handle failure */
1459 DPRINT1("SMSS: Unable to create %wZ directory - Status == %lx\n",
1460 Directory, Status);
1461 return Status;
1462 }
1463
1464 /* Convert the path to native format */
1465 if (!RtlDosPathNameToNtPathName_U(Path->Buffer, &NtPath, NULL, NULL))
1466 {
1467 /* Fail if this didn't work */
1468 DPRINT1("SMSS: Unable to to convert %wZ to an Nt path\n", Path);
1470 goto Quickie;
1471 }
1472
1473 /* Open the path that was specified, which should be a directory */
1475 &NtPath,
1477 NULL,
1478 NULL);
1479 Status = NtOpenFile(&DirFileHandle,
1485 if (!NT_SUCCESS(Status))
1486 {
1487 /* Fail if we couldn't open it */
1488 DPRINT1("SMSS: Unable to open a handle to the KnownDll directory (%wZ)"
1489 "- Status == %lx\n",
1490 Path,
1491 Status);
1492 FileHandle = NULL;
1493 goto Quickie;
1494 }
1495
1496 /* Temporarily hack the SD to use a default DACL for this symbolic link */
1498 {
1501 }
1502
1503 /* Create a symbolic link to the directory in the object manager */
1504 RtlInitUnicodeString(&SymLinkName, L"KnownDllPath");
1506 &SymLinkName,
1508 DirHandle,
1510 Status = NtCreateSymbolicLinkObject(&LinkHandle,
1513 Path);
1514
1515 /* Undo the hack */
1517
1518 /* Check if the symlink was created */
1519 if (!NT_SUCCESS(Status))
1520 {
1521 /* It wasn't, so bail out since the OS needs it to exist */
1522 DPRINT1("SMSS: Unable to create %wZ symbolic link - Status == %lx\n",
1523 &SymLinkName, Status);
1524 LinkHandle = NULL;
1525 goto Quickie;
1526 }
1527
1528 /* We created it permanent, we can go ahead and close the handle now */
1529 Status1 = NtClose(LinkHandle);
1530 ASSERT(NT_SUCCESS(Status1));
1531
1532 /* Now loop the known DLLs */
1533 NextEntry = SmpKnownDllsList.Flink;
1534 while (NextEntry != &SmpKnownDllsList)
1535 {
1536 /* Get the entry and move on */
1537 RegEntry = CONTAINING_RECORD(NextEntry, SMP_REGISTRY_VALUE, Entry);
1538 NextEntry = NextEntry->Flink;
1539
1540 DPRINT("Processing known DLL: %wZ-%wZ\n", &RegEntry->Name, &RegEntry->Value);
1541
1542 /* Skip the entry if it's in the excluded list */
1544 RegEntry->Name.Buffer)) ||
1546 RegEntry->Value.Buffer)))
1547 {
1548 continue;
1549 }
1550
1551 /* Open the actual file */
1553 &RegEntry->Value,
1555 DirFileHandle,
1556 NULL);
1557 Status1 = NtOpenFile(&FileHandle,
1564 /* If we failed, skip it */
1565 if (!NT_SUCCESS(Status1)) continue;
1566
1567 /* Checksum it */
1570 RegEntry,
1571 &ImageCharacteristics);
1572 if (!NT_SUCCESS(Status))
1573 {
1574 /* Checksum failed, so don't even try going further -- kill SMSS */
1575 RtlInitUnicodeString(&ErrorResponse,
1576 L"Verification of a KnownDLL failed.");
1577 ErrorParameters[0] = (ULONG_PTR)&ErrorResponse;
1578 ErrorParameters[1] = Status;
1579 ErrorParameters[2] = (ULONG_PTR)&RegEntry->Value;
1580 SmpTerminate(ErrorParameters, 5, RTL_NUMBER_OF(ErrorParameters));
1581 }
1582 else if (!(ImageCharacteristics & IMAGE_FILE_DLL))
1583 {
1584 /* An invalid known DLL entry will also kill SMSS */
1585 RtlInitUnicodeString(&ErrorResponse,
1586 L"Non-DLL file included in KnownDLL list.");
1587 ErrorParameters[0] = (ULONG_PTR)&ErrorResponse;
1588 ErrorParameters[1] = STATUS_INVALID_IMPORT_OF_NON_DLL;
1589 ErrorParameters[2] = (ULONG_PTR)&RegEntry->Value;
1590 SmpTerminate(ErrorParameters, 5, RTL_NUMBER_OF(ErrorParameters));
1591 }
1592
1593 /* Temporarily hack the SD to use a default DACL for this section */
1595 {
1598 }
1599
1600 /* Create the section for this known DLL */
1602 &RegEntry->Value,
1604 DirHandle,
1606 Status = NtCreateSection(&SectionHandle,
1609 0,
1611 SEC_IMAGE,
1612 FileHandle);
1613
1614 /* Undo the hack */
1616
1617 /* Check if we created the section okay */
1618 if (NT_SUCCESS(Status))
1619 {
1620 /* We can close it now, since it's marked permanent */
1621 Status1 = NtClose(SectionHandle);
1622 ASSERT(NT_SUCCESS(Status1));
1623 }
1624 else
1625 {
1626 /* If we couldn't make it "known", that's fine and keep going */
1627 DPRINT1("SMSS: CreateSection for KnownDll %wZ failed - Status == %lx\n",
1628 &RegEntry->Value, Status);
1629 }
1630
1631 /* Close the file since we can move on to the next one */
1632 Status1 = NtClose(FileHandle);
1633 ASSERT(NT_SUCCESS(Status1));
1634 }
1635
1636Quickie:
1637 /* Close both handles and free the NT path buffer */
1638 if (DirHandle)
1639 {
1640 Status1 = NtClose(DirHandle);
1641 ASSERT(NT_SUCCESS(Status1));
1642 }
1643 if (DirFileHandle)
1644 {
1645 Status1 = NtClose(DirFileHandle);
1646 ASSERT(NT_SUCCESS(Status1));
1647 }
1648 if (NtPath.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, NtPath.Buffer);
1649 return Status;
1650}
NTSTATUS NTAPI NtCreateSection(OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN PLARGE_INTEGER MaximumSize OPTIONAL, IN ULONG SectionPageProtection OPTIONAL, IN ULONG AllocationAttributes, IN HANDLE FileHandle OPTIONAL)
Definition: section.c:3078
PRTL_UNICODE_STRING_BUFFER Path
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
#define FILE_SHARE_READ
Definition: compat.h:136
#define ULONG_PTR
Definition: config.h:101
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
NTSTATUS NTAPI LdrVerifyImageMatchesChecksum(_In_ HANDLE FileHandle, _In_ PLDR_CALLBACK Callback, _In_ PVOID CallbackContext, _Out_ PUSHORT ImageCharacteristics)
Definition: ldrapi.c:804
#define SEC_IMAGE
Definition: mmtypes.h:97
_In_ BOOLEAN _In_ USHORT Directory
Definition: rtlfuncs.h:3942
NTSYSAPI BOOLEAN NTAPI RtlDosPathNameToNtPathName_U(_In_opt_z_ PCWSTR DosPathName, _Out_ PUNICODE_STRING NtPathName, _Out_opt_ PCWSTR *NtFileNamePart, _Out_opt_ PRTL_RELATIVE_NAME_U DirectoryInfo)
NTSYSAPI NTSTATUS NTAPI NtOpenFile(OUT PHANDLE phFile, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG ShareMode, IN ULONG OpenMode)
Definition: file.c:3950
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define SYNCHRONIZE
Definition: nt_native.h:61
#define SECTION_ALL_ACCESS
Definition: nt_native.h:1296
#define FILE_LIST_DIRECTORY
Definition: nt_native.h:629
#define PAGE_EXECUTE
Definition: nt_native.h:1309
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
#define FILE_EXECUTE
Definition: nt_native.h:642
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define STATUS_INVALID_IMPORT_OF_NON_DLL
Definition: ntstatus.h:1049
#define IMAGE_FILE_DLL
Definition: pedump.c:169
LIST_ENTRY SmpExcludeKnownDllsList
Definition: sminit.c:21
VOID NTAPI SmpProcessModuleImports(IN PVOID Unused, IN PCHAR ImportName)
Definition: sminit.c:1385
NTSTATUS NTAPI SmpTerminate(IN PULONG_PTR Parameters, IN ULONG ParameterMask, IN ULONG ParameterCount)
Definition: smss.c:374
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148

Referenced by SmpInitializeKnownDlls().

◆ SmpLoadDataFromRegistry()

NTSTATUS NTAPI SmpLoadDataFromRegistry ( OUT PUNICODE_STRING  InitialCommand)

Definition at line 2245 of file sminit.c.

2246{
2248 PLIST_ENTRY Head, NextEntry;
2249 PSMP_REGISTRY_VALUE RegEntry;
2250 PVOID OriginalEnvironment;
2251 ULONG MuSessionId = 0;
2255
2256 /* Initialize the keywords we'll be looking for */
2260
2261 /* Initialize all the registry-associated list heads */
2273
2275
2276 /* Initialize the SMSS environment */
2278 if (!NT_SUCCESS(Status))
2279 {
2280 /* Fail if there was a problem */
2281 DPRINT1("SMSS: Unable to allocate default environment - Status == %X\n",
2282 Status);
2284 return Status;
2285 }
2286
2287 /* Check if we were booted in PE mode (LiveCD should have this) */
2289 L"\\Registry\\Machine\\System\\CurrentControlSet\\"
2290 L"Control\\MiniNT");
2294 NULL,
2295 NULL);
2297 if (NT_SUCCESS(Status))
2298 {
2299 /* If the key exists, we were */
2301 MiniNTBoot = TRUE;
2302 }
2303
2304 /* Print out if this is the case */
2305 if (MiniNTBoot) DPRINT("SMSS: !!! MiniNT Boot !!!\n");
2306
2307 /* Open the environment key to see if we are booted in safe mode */
2309 L"\\Registry\\Machine\\System\\CurrentControlSet\\"
2310 L"Control\\Session Manager\\Environment");
2314 NULL,
2315 NULL);
2317 if (NT_SUCCESS(Status))
2318 {
2319 /* Delete the value if we found it */
2320 RtlInitUnicodeString(&DestinationString, L"SAFEBOOT_OPTION");
2323 }
2324
2325 /* Switch environments, then query the registry for all needed settings */
2326 OriginalEnvironment = NtCurrentPeb()->ProcessParameters->Environment;
2327 NtCurrentPeb()->ProcessParameters->Environment = SmpDefaultEnvironment;
2329 L"Session Manager",
2331 NULL,
2332 NULL);
2333 SmpDefaultEnvironment = NtCurrentPeb()->ProcessParameters->Environment;
2334 NtCurrentPeb()->ProcessParameters->Environment = OriginalEnvironment;
2335 if (!NT_SUCCESS(Status))
2336 {
2337 /* We failed somewhere in registry initialization, which is bad... */
2338 DPRINT1("SMSS: RtlQueryRegistryValues failed - Status == %lx\n", Status);
2340 return Status;
2341 }
2342
2343 /* Now we can start acting on the registry settings. First to DOS devices */
2345 if (!NT_SUCCESS(Status))
2346 {
2347 /* Failed */
2348 DPRINT1("SMSS: Unable to initialize DosDevices configuration - Status == %lx\n",
2349 Status);
2351 return Status;
2352 }
2353
2354 /* Next create the session directory... */
2359 NULL,
2364 if (!NT_SUCCESS(Status))
2365 {
2366 /* Fail */
2367 DPRINT1("SMSS: Unable to create %wZ object directory - Status == %lx\n",
2370 return Status;
2371 }
2372
2373 /* Next loop all the boot execute binaries */
2374 Head = &SmpBootExecuteList;
2375 while (!IsListEmpty(Head))
2376 {
2377 /* Remove each one from the list */
2378 NextEntry = RemoveHeadList(Head);
2379
2380 /* Execute it */
2381 RegEntry = CONTAINING_RECORD(NextEntry, SMP_REGISTRY_VALUE, Entry);
2382 SmpExecuteCommand(&RegEntry->Name, 0, NULL, 0);
2383
2384 /* And free it */
2385 if (RegEntry->AnsiValue) RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry->AnsiValue);
2386 if (RegEntry->Value.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry->Value.Buffer);
2387 RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry);
2388 }
2389
2390 /* Now do any pending file rename operations... */
2392
2393 /* And initialize known DLLs... */
2395 if (!NT_SUCCESS(Status))
2396 {
2397 /* Fail if that didn't work */
2398 DPRINT1("SMSS: Unable to initialize KnownDll configuration - Status == %lx\n",
2399 Status);
2401 return Status;
2402 }
2403
2404 /* Create the needed page files */
2405 if (!MiniNTBoot)
2406 {
2407 /* Loop every page file */
2408 Head = &SmpPagingFileList;
2409 while (!IsListEmpty(Head))
2410 {
2411 /* Remove each one from the list */
2412 NextEntry = RemoveHeadList(Head);
2413
2414 /* Create the descriptor for it */
2415 RegEntry = CONTAINING_RECORD(NextEntry, SMP_REGISTRY_VALUE, Entry);
2417
2418 /* And free it */
2419 if (RegEntry->AnsiValue) RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry->AnsiValue);
2420 if (RegEntry->Value.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry->Value.Buffer);
2421 RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry);
2422 }
2423
2424 /* Now create all the paging files for the descriptors that we have */
2426 }
2427
2428 /* Tell Cm it's now safe to fully enable write access to the registry */
2430
2431 /* Create all the system-based environment variables for later inheriting */
2433 if (!NT_SUCCESS(Status))
2434 {
2435 /* Handle failure */
2437 return Status;
2438 }
2439
2440 /* And finally load all the subsystems for our first session! */
2443 InitialCommand);
2444 ASSERT(MuSessionId == 0);
2446 return Status;
2447}
#define NtCurrentPeb()
Definition: FLS.c:22
VOID NTAPI SmpPagingFileInitialize(VOID)
Definition: pagefile.c:130
NTSTATUS NTAPI SmpCreatePagingFiles(VOID)
Definition: pagefile.c:1049
NTSTATUS NTAPI SmpCreatePagingFileDescriptor(IN PUNICODE_STRING PageFileToken)
Definition: pagefile.c:139
#define CM_BOOT_FLAG_SMSS
Definition: cmtypes.h:172
NTSYSAPI NTSTATUS NTAPI RtlCreateEnvironment(_In_ BOOLEAN Inherit, _Out_ PWSTR *Environment)
#define RTL_REGISTRY_CONTROL
Definition: nt_native.h:163
NTSYSAPI NTSTATUS NTAPI NtDeleteValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName)
Definition: ntapi.c:1014
NTSTATUS NTAPI NtInitializeRegistry(IN USHORT Flag)
Definition: ntapi.c:1318
LIST_ENTRY SmpBootExecuteList
Definition: sminit.c:19
LIST_ENTRY SmpSubSystemList
Definition: sminit.c:22
BOOLEAN MiniNTBoot
Definition: sminit.c:42
LIST_ENTRY SmpPagingFileList
Definition: sminit.c:20
LIST_ENTRY SmpExecuteList
Definition: sminit.c:23
NTSTATUS NTAPI SmpProcessFileRenames(VOID)
Definition: sminit.c:2030
LIST_ENTRY SmpFileRenameList
Definition: sminit.c:20
PWCHAR SmpDefaultEnvironment
Definition: sminit.c:28
NTSTATUS NTAPI SmpCreateDynamicEnvironmentVariables(VOID)
Definition: sminit.c:1685
NTSTATUS NTAPI SmpInitializeDosDevices(VOID)
Definition: sminit.c:1281
NTSTATUS NTAPI SmpInitializeKnownDlls(VOID)
Definition: sminit.c:1654
LIST_ENTRY SmpSetupExecuteList
Definition: sminit.c:19
RTL_QUERY_REGISTRY_TABLE SmpRegistryConfigurationTable[]
Definition: sminit.c:604
HANDLE SmpSessionsObjectDirectory
Definition: smsessn.c:31
NTSTATUS NTAPI SmpExecuteCommand(IN PUNICODE_STRING CommandLine, IN ULONG MuSessionId, OUT PHANDLE ProcessId, IN ULONG Flags)
Definition: smss.c:210
UNICODE_STRING SmpAutoChkKeyword
Definition: smss.h:90
NTSTATUS NTAPI SmpLoadSubSystemsForMuSession(IN PULONG MuSessionId, OUT PHANDLE ProcessId, IN PUNICODE_STRING InitialCommand)
Definition: smsubsys.c:510
UNICODE_STRING SmpDebugKeyword
Definition: smutil.c:34
HANDLE SmpWindowsSubSysProcessId
Definition: smsubsys.c:21
UNICODE_STRING SmpASyncKeyword
Definition: smss.h:90
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)

Referenced by SmpInit().

◆ SmpProcessFileRenames()

NTSTATUS NTAPI SmpProcessFileRenames ( VOID  )

Definition at line 2030 of file sminit.c.

2031{
2032 BOOLEAN OldState, HavePrivilege = FALSE;
2034 HANDLE FileHandle, OtherFileHandle;
2038 UNICODE_STRING FileString;
2039 FILE_BASIC_INFORMATION BasicInfo;
2040 FILE_DISPOSITION_INFORMATION DeleteInformation;
2042 PLIST_ENTRY Head, NextEntry;
2043 PSMP_REGISTRY_VALUE RegEntry;
2046
2047 /* Give us access to restore any files we want */
2049 if (NT_SUCCESS(Status)) HavePrivilege = TRUE;
2050
2051 // FIXME: Handle SFC-protected file renames!
2053 DPRINT1("SMSS: FIXME: Handle SFC-protected file renames!\n");
2054
2055 /* Process pending files to rename */
2056 Head = &SmpFileRenameList;
2057 while (!IsListEmpty(Head))
2058 {
2059 /* Get this entry */
2060 NextEntry = RemoveHeadList(Head);
2061 RegEntry = CONTAINING_RECORD(NextEntry, SMP_REGISTRY_VALUE, Entry);
2062 DPRINT("Processing PFRO: '%wZ' / '%wZ'\n", &RegEntry->Value, &RegEntry->Name);
2063
2064 /* Skip past the '@' marker */
2065 if (!(RegEntry->Value.Length) && (*RegEntry->Name.Buffer == L'@'))
2066 {
2067 RegEntry->Name.Length -= sizeof(UNICODE_NULL);
2068 RegEntry->Name.Buffer++;
2069 }
2070
2071 /* Open the file for delete access */
2073 &RegEntry->Name,
2075 NULL,
2076 NULL);
2077 Status = NtOpenFile(&OtherFileHandle,
2083 if (!NT_SUCCESS(Status)) goto Quickie;
2084
2085 /* Check if it's a rename or just a delete */
2086 ValueLength = RegEntry->Value.Length;
2087 if (!ValueLength)
2088 {
2089 /* Just a delete, set up the class, length and buffer */
2091 Length = sizeof(DeleteInformation);
2092 Buffer = (PFILE_RENAME_INFORMATION)&DeleteInformation;
2093
2094 /* Set the delete disposition */
2095 DeleteInformation.DeleteFile = TRUE;
2096 }
2097 else
2098 {
2099 /* This is a rename, setup the class and length */
2102
2103 /* Skip past the special markers */
2104 FileName = RegEntry->Value.Buffer;
2105 if ((*FileName == L'!') || (*FileName == L'@'))
2106 {
2107 FileName++;
2108 Length -= sizeof(UNICODE_NULL);
2109 }
2110
2111 /* Now allocate the buffer for the rename information */
2112 Buffer = RtlAllocateHeap(RtlGetProcessHeap(), SmBaseTag, Length);
2113 if (Buffer)
2114 {
2115 /* Setup the buffer to point to the filename, and copy it */
2116 Buffer->RootDirectory = NULL;
2117 Buffer->FileNameLength = Length - sizeof(FILE_RENAME_INFORMATION);
2118 Buffer->ReplaceIfExists = FileName != RegEntry->Value.Buffer;
2119 RtlCopyMemory(Buffer->FileName, FileName, Buffer->FileNameLength);
2120 }
2121 else
2122 {
2123 /* Fail */
2125 }
2126 }
2127
2128 /* Check if everything is okay till here */
2129 if (NT_SUCCESS(Status))
2130 {
2131 /* Now either rename or delete the file as requested */
2132 Status = NtSetInformationFile(OtherFileHandle,
2134 Buffer,
2135 Length,
2137
2138 /* Check if we seem to have failed because the file was readonly */
2139 if (!NT_SUCCESS(Status) &&
2142 Buffer->ReplaceIfExists)
2143 {
2144 /* Open the file for write attribute access this time... */
2145 DPRINT("\nSMSS: '%wZ' => '%wZ' failed - Status == %x, Possible readonly target\n",
2146 &RegEntry->Name,
2147 &RegEntry->Value,
2149 FileString.Length = RegEntry->Value.Length - sizeof(WCHAR);
2150 FileString.MaximumLength = RegEntry->Value.MaximumLength - sizeof(WCHAR);
2151 FileString.Buffer = FileName;
2153 &FileString,
2155 NULL,
2156 NULL);
2163 if (!NT_SUCCESS(Status))
2164 {
2165 /* That didn't work, so bail out */
2166 DPRINT1(" SMSS: Open Existing file Failed - Status == %x\n",
2167 Status);
2168 }
2169 else
2170 {
2171 /* Now remove the read-only attribute from the file */
2172 DPRINT(" SMSS: Open Existing Success\n");
2173 RtlZeroMemory(&BasicInfo, sizeof(BasicInfo));
2177 &BasicInfo,
2178 sizeof(BasicInfo),
2181 if (!NT_SUCCESS(Status))
2182 {
2183 /* That didn't work, bail out */
2184 DPRINT1(" SMSS: Set To NORMAL Failed - Status == %x\n",
2185 Status);
2186 }
2187 else
2188 {
2189 /* Now that the file is no longer read-only, delete! */
2190 DPRINT(" SMSS: Set To NORMAL OK\n");
2191 Status = NtSetInformationFile(OtherFileHandle,
2193 Buffer,
2194 Length,
2196 if (!NT_SUCCESS(Status))
2197 {
2198 /* That failed too! */
2199 DPRINT1(" SMSS: Re-Rename Failed - Status == %x\n",
2200 Status);
2201 }
2202 else
2203 {
2204 /* Everything ok */
2205 DPRINT(" SMSS: Re-Rename Worked OK\n");
2206 }
2207 }
2208 }
2209 }
2210 }
2211
2212 /* Close the file handle and check the operation result */
2213 NtClose(OtherFileHandle);
2214Quickie:
2215 if (!NT_SUCCESS(Status))
2216 {
2217 /* We totally failed */
2218 DPRINT1("SMSS: '%wZ' => '%wZ' failed - Status == %x\n",
2219 &RegEntry->Name, &RegEntry->Value, Status);
2220 }
2221 else if (RegEntry->Value.Length)
2222 {
2223 /* We succeed with a rename */
2224 DPRINT("SMSS: '%wZ' (renamed to) '%wZ'\n", &RegEntry->Name, &RegEntry->Value);
2225 }
2226 else
2227 {
2228 /* We succeeded with a delete */
2229 DPRINT("SMSS: '%wZ' (deleted)\n", &RegEntry->Name);
2230 }
2231
2232 /* Now free this entry and keep going */
2233 if (RegEntry->AnsiValue) RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry->AnsiValue);
2234 if (RegEntry->Value.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry->Value.Buffer);
2235 RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry);
2236 }
2237
2238 /* Put back the restore privilege if we had requested it, and return */
2239 if (HavePrivilege) RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, FALSE, FALSE, &OldState);
2240 return Status;
2241}
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
struct _FileName FileName
Definition: fatprocs.h:897
_In_ FILTER_INFORMATION_CLASS InformationClass
Definition: fltkernel.h:1713
@ FileRenameInformation
Definition: from_kernel.h:71
@ FileBasicInformation
Definition: from_kernel.h:65
@ FileDispositionInformation
Definition: from_kernel.h:74
enum _FILE_INFORMATION_CLASS FILE_INFORMATION_CLASS
Definition: directory.c:44
#define SE_RESTORE_PRIVILEGE
Definition: security.c:602
NTSYSAPI NTSTATUS NTAPI RtlAdjustPrivilege(_In_ ULONG Privilege, _In_ BOOLEAN NewValue, _In_ BOOLEAN ForThread, _Out_ PBOOLEAN OldValue)
NTSYSAPI NTSTATUS NTAPI NtSetInformationFile(IN HANDLE hFile, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN PVOID FileInformationBuffer, IN ULONG FileInformationBufferLength, IN FILE_INFORMATION_CLASS FileInfoClass)
Definition: iofunc.c:3096
#define FILE_WRITE_ATTRIBUTES
Definition: nt_native.h:649
#define DELETE
Definition: nt_native.h:57
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
struct _FILE_RENAME_INFORMATION * PFILE_RENAME_INFORMATION
struct _FILE_RENAME_INFORMATION FILE_RENAME_INFORMATION

Referenced by SmpLoadDataFromRegistry().

◆ SmpProcessModuleImports()

VOID NTAPI SmpProcessModuleImports ( IN PVOID  Unused,
IN PCHAR  ImportName 
)

Definition at line 1385 of file sminit.c.

1387{
1388 ULONG Length = 0;
1390 PWCHAR DllName, DllValue;
1391 ANSI_STRING ImportString;
1392 UNICODE_STRING ImportUnicodeString;
1394
1395 /* Skip NTDLL since it's already always mapped */
1396 if (!_stricmp(ImportName, "ntdll.dll")) return;
1397
1398 /* Initialize our strings */
1399 RtlInitAnsiString(&ImportString, ImportName);
1400 RtlInitEmptyUnicodeString(&ImportUnicodeString, Buffer, sizeof(Buffer));
1401 Status = RtlAnsiStringToUnicodeString(&ImportUnicodeString, &ImportString, FALSE);
1402 if (!NT_SUCCESS(Status)) return;
1403
1404 /* Loop to find the DLL file extension */
1405 while (Length < ImportUnicodeString.Length)
1406 {
1407 if (ImportUnicodeString.Buffer[Length / sizeof(WCHAR)] == L'.') break;
1408 Length += sizeof(WCHAR);
1409 }
1410
1411 /*
1412 * Break up the values as needed; the buffer acquires the form:
1413 * "dll_name.dll\0dll_name\0"
1414 */
1415 DllValue = ImportUnicodeString.Buffer;
1416 DllName = &ImportUnicodeString.Buffer[(ImportUnicodeString.Length + sizeof(UNICODE_NULL)) / sizeof(WCHAR)];
1417 RtlStringCbCopyNW(DllName,
1418 ImportUnicodeString.MaximumLength - (ImportUnicodeString.Length + sizeof(UNICODE_NULL)),
1419 ImportUnicodeString.Buffer, Length);
1420
1421 /* Add the DLL to the list */
1422 SmpSaveRegistryValue(&SmpKnownDllsList, DllName, DllValue, TRUE);
1423}
#define _stricmp
Definition: cat.c:22
#define MAX_PATH
Definition: compat.h:34
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
NTSTRSAFEAPI RtlStringCbCopyNW(_Out_writes_bytes_(cbDest) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_reads_bytes_(cbToCopy) STRSAFE_LPCWSTR pszSrc, _In_ size_t cbToCopy)
Definition: ntstrsafe.h:416

Referenced by SmpInitializeKnownDllsInternal().

◆ SmpSaveRegistryValue()

NTSTATUS NTAPI SmpSaveRegistryValue ( IN PLIST_ENTRY  ListAddress,
IN PWSTR  Name,
IN PWCHAR  Value,
IN BOOLEAN  Flags 
)

Definition at line 55 of file sminit.c.

59{
60 PSMP_REGISTRY_VALUE RegEntry;
61 UNICODE_STRING NameString, ValueString;
62 ANSI_STRING AnsiValueString;
63 PLIST_ENTRY NextEntry;
64
65 /* Convert to unicode strings */
66 RtlInitUnicodeString(&NameString, Name);
67 RtlInitUnicodeString(&ValueString, Value);
68
69 /* In case this is the first value, initialize a new list/structure */
70 RegEntry = NULL;
71
72 /* Check if we should do a duplicate check */
73 if (Flags)
74 {
75 /* Loop the current list */
76 NextEntry = ListAddress->Flink;
77 while (NextEntry != ListAddress)
78 {
79 /* Get each entry */
80 RegEntry = CONTAINING_RECORD(NextEntry, SMP_REGISTRY_VALUE, Entry);
81
82 /* Check if the value name matches */
83 if (!RtlCompareUnicodeString(&RegEntry->Name, &NameString, TRUE))
84 {
85 /* Check if the value is the exact same thing */
86 if (!RtlCompareUnicodeString(&RegEntry->Value, &ValueString, TRUE))
87 {
88 /* Fail -- the same setting is being set twice */
90 }
91
92 /* We found the list, and this isn't a duplicate value */
93 break;
94 }
95
96 /* This wasn't a match, keep going */
97 NextEntry = NextEntry->Flink;
98 RegEntry = NULL;
99 }
100 }
101
102 /* Are we adding on, or creating a new entry */
103 if (!RegEntry)
104 {
105 /* A new entry -- allocate it */
106 RegEntry = RtlAllocateHeap(RtlGetProcessHeap(),
107 SmBaseTag,
108 sizeof(SMP_REGISTRY_VALUE) +
109 NameString.MaximumLength);
110 if (!RegEntry) return STATUS_NO_MEMORY;
111
112 /* Initialize the list and set all values to NULL */
113 InitializeListHead(&RegEntry->Entry);
114 RegEntry->AnsiValue = NULL;
115 RegEntry->Value.Buffer = NULL;
116
117 /* Copy and initialize the value name */
118 RegEntry->Name.Buffer = (PWCHAR)(RegEntry + 1);
119 RegEntry->Name.Length = NameString.Length;
120 RegEntry->Name.MaximumLength = NameString.MaximumLength;
121 RtlCopyMemory(RegEntry->Name.Buffer,
122 NameString.Buffer,
123 NameString.MaximumLength);
124
125 /* Add this entry into the list */
126 InsertTailList(ListAddress, &RegEntry->Entry);
127 }
128
129 /* Did we have an old value buffer? */
130 if (RegEntry->Value.Buffer)
131 {
132 /* Free it */
133 ASSERT(RegEntry->Value.Length != 0);
134 RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry->Value.Buffer);
135 }
136
137 /* Is there no value associated? */
138 if (!Value)
139 {
140 /* We're done here */
141 RtlInitUnicodeString(&RegEntry->Value, NULL);
142 return STATUS_SUCCESS;
143 }
144
145 /* There is a value, so allocate a buffer for it */
146 RegEntry->Value.Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
147 SmBaseTag,
148 ValueString.MaximumLength);
149 if (!RegEntry->Value.Buffer)
150 {
151 /* Out of memory, undo */
152 RemoveEntryList(&RegEntry->Entry);
153 RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry);
154 return STATUS_NO_MEMORY;
155 }
156
157 /* Copy the value into the entry */
158 RegEntry->Value.Length = ValueString.Length;
159 RegEntry->Value.MaximumLength = ValueString.MaximumLength;
160 RtlCopyMemory(RegEntry->Value.Buffer,
161 ValueString.Buffer,
162 ValueString.MaximumLength);
163
164 /* Now allocate memory for an ANSI copy of it */
165 RegEntry->AnsiValue = RtlAllocateHeap(RtlGetProcessHeap(),
166 SmBaseTag,
167 (ValueString.Length / sizeof(WCHAR)) +
168 sizeof(ANSI_NULL));
169 if (!RegEntry->AnsiValue)
170 {
171 /* Out of memory, undo */
172 RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry->Value.Buffer);
173 RemoveEntryList(&RegEntry->Entry);
174 RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry);
175 return STATUS_NO_MEMORY;
176 }
177
178 /* Convert the Unicode value string and return success */
179 RtlInitEmptyAnsiString(&AnsiValueString,
180 RegEntry->AnsiValue,
181 (ValueString.Length / sizeof(WCHAR)) +
182 sizeof(ANSI_NULL));
183 RtlUnicodeStringToAnsiString(&AnsiValueString, &ValueString, FALSE);
184 return STATUS_SUCCESS;
185}
LPWSTR Name
Definition: desk.c:124
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
#define ANSI_NULL
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by SmpConfigureDosDevices(), SmpConfigureExcludeKnownDlls(), SmpConfigureFileRenames(), SmpConfigureKnownDlls(), SmpConfigureMemoryMgmt(), SmpConfigureSubSystems(), and SmpProcessModuleImports().

◆ SmpTranslateSystemPartitionInformation()

VOID NTAPI SmpTranslateSystemPartitionInformation ( VOID  )

Definition at line 811 of file sminit.c.

812{
816 HANDLE KeyHandle, LinkHandle;
818 size_t StrLength;
819 WCHAR LinkBuffer[MAX_PATH];
820 struct { KEY_VALUE_PARTIAL_INFORMATION; CHAR Buffer[512]; } ValueBuffer;
821 struct { OBJECT_DIRECTORY_INFORMATION; WCHAR Buffer[256]; } DirInfoBuffer;
822 PKEY_VALUE_PARTIAL_INFORMATION PartialInfo = (PVOID)&ValueBuffer;
823 POBJECT_DIRECTORY_INFORMATION DirInfo = (PVOID)&DirInfoBuffer;
824
825 /* Open the setup key */
826 RtlInitUnicodeString(&UnicodeString, L"\\Registry\\Machine\\System\\Setup");
830 NULL,
831 NULL);
833 if (!NT_SUCCESS(Status))
834 {
835 DPRINT1("SMSS: Cannot open system setup key for reading: 0x%x\n", Status);
836 return;
837 }
838
839 /* Query the system partition */
840 RtlInitUnicodeString(&UnicodeString, L"SystemPartition");
844 &ValueBuffer,
845 sizeof(ValueBuffer),
846 &Length);
848 if (!NT_SUCCESS(Status) ||
849 ((PartialInfo->Type != REG_SZ) && (PartialInfo->Type != REG_EXPAND_SZ)))
850 {
851 DPRINT1("SMSS: Cannot query SystemPartition value (Type %lu, Status 0x%x)\n",
852 PartialInfo->Type, Status);
853 return;
854 }
855
856 /* Initialize the system partition string */
857 RtlInitEmptyUnicodeString(&SystemPartition,
858 (PWCHAR)PartialInfo->Data,
859 PartialInfo->DataLength);
861 SystemPartition.MaximumLength,
862 &StrLength);
863 SystemPartition.Length = (USHORT)StrLength;
864
865 /* Enumerate the directory looking for the symbolic link string */
866 RtlInitUnicodeString(&SymLinkU, L"SymbolicLink");
867 RtlInitEmptyUnicodeString(&LinkTarget, LinkBuffer, sizeof(LinkBuffer));
869 &DirInfoBuffer,
870 sizeof(DirInfoBuffer),
871 TRUE,
872 TRUE,
873 &Context,
874 NULL);
875 /* Keep searching until we find it */
876 while (NT_SUCCESS(Status))
877 {
878 /* Is this it? */
879 if (RtlEqualUnicodeString(&DirInfo->TypeName, &SymLinkU, TRUE) &&
880 (DirInfo->Name.Length == 2 * sizeof(WCHAR)) &&
881 (DirInfo->Name.Buffer[1] == L':'))
882 {
883 /* Looks like we found it, open the link to get its target */
885 &DirInfo->Name,
888 NULL);
889 Status = NtOpenSymbolicLinkObject(&LinkHandle,
892 if (NT_SUCCESS(Status))
893 {
894 /* Open worked, query the target now */
896 &LinkTarget,
897 NULL);
898 NtClose(LinkHandle);
899
900 /* Check if it matches the string we had found earlier */
901 if (NT_SUCCESS(Status) &&
904 (LinkTarget.Buffer[SystemPartition.Length / sizeof(WCHAR)] == L'\\'))))
905 {
906 /* All done */
907 break;
908 }
909 }
910 }
911
912 /* Couldn't find it, try again */
914 &DirInfoBuffer,
915 sizeof(DirInfoBuffer),
916 TRUE,
917 FALSE,
918 &Context,
919 NULL);
920 }
921 if (!NT_SUCCESS(Status))
922 {
923 DPRINT1("SMSS: Cannot find drive letter for system partition: 0x%x\n", Status);
924#if (NTDDI_VERSION > NTDDI_WIN7SP1) || defined(__REACTOS__)
925 /* If we failed because no drive letter associated to the system
926 * volume was found (none was assigned to it), fall back to using
927 * the OS boot drive letter instead. Otherwise, fail altogether.
928 * NOTE: This has been introduced in a post-SP1 Windows 7 update. */
930 return;
931 DirInfo->Name.Buffer = DirInfoBuffer.Buffer;
932 DirInfo->Name.Buffer[0] = SharedUserData->NtSystemRoot[0];
933 DirInfo->Name.Buffer[1] = SharedUserData->NtSystemRoot[1]; // == L':';
934#else
935 return;
936#endif
937 }
938
939 /* Open the setup key again, for full access this time */
941 L"\\Registry\\Machine\\Software\\Microsoft\\Windows\\CurrentVersion\\Setup");
945 NULL,
946 NULL);
948 if (!NT_SUCCESS(Status))
949 {
950 DPRINT1("SMSS: Cannot open software setup key for writing: 0x%x\n", Status);
951 return;
952 }
953
954 /* Wrap up the end of the link buffer */
955 LinkBuffer[0] = DirInfo->Name.Buffer[0];
956 LinkBuffer[1] = DirInfo->Name.Buffer[1]; // == L':';
957 LinkBuffer[2] = L'\\';
958 LinkBuffer[3] = UNICODE_NULL;
959
960 /* Now set this as the "BootDir" */
964 0,
965 REG_SZ,
966 LinkBuffer,
967 4 * sizeof(WCHAR));
968 if (!NT_SUCCESS(Status))
969 {
970 DPRINT1("SMSS: couldn't write BootDir value: 0x%x\n", Status);
971 }
973}
PPARTENTRY SystemPartition
Definition: reactos.c:50
struct _OBJECT_DIRECTORY_INFORMATION OBJECT_DIRECTORY_INFORMATION
NTSYSAPI BOOLEAN NTAPI RtlPrefixUnicodeString(IN PUNICODE_STRING String1, IN PUNICODE_STRING String2, IN BOOLEAN CaseInSensitive)
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:285
NTSTATUS NTAPI NtQueryDirectoryObject(IN HANDLE DirectoryHandle, OUT PVOID Buffer, IN ULONG BufferLength, IN BOOLEAN ReturnSingleEntry, IN BOOLEAN RestartScan, IN OUT PULONG Context, OUT PULONG ReturnLength OPTIONAL)
Definition: obdir.c:490
char CHAR
Definition: pedump.c:57
#define SharedUserData
_In_ PVOID Context
Definition: storport.h:2269
UNICODE_STRING TypeName
Definition: obtypes.h:279
WDF_EXTERN_C_START typedef _Must_inspect_result_ _In_opt_ PCUNICODE_STRING UnicodeString
Definition: wdfstring.h:64
_Inout_ PUNICODE_STRING LinkTarget
Definition: zwfuncs.h:292

Referenced by SmpLoadSubSystemsForMuSession().

Variable Documentation

◆ MiniNTBoot

BOOLEAN MiniNTBoot = FALSE

Definition at line 42 of file sminit.c.

Referenced by SmpLoadDataFromRegistry().

◆ NativeProcessList

LIST_ENTRY NativeProcessList

Definition at line 23 of file sminit.c.

Referenced by SmpInit(), and SmpSbCreateSession().

◆ Os2Name

UNICODE_STRING Os2Name

Definition at line 18 of file sminit.c.

Referenced by SmpInit().

◆ PosixName

UNICODE_STRING PosixName

Definition at line 18 of file sminit.c.

Referenced by SmpInit().

◆ SmBaseTag

◆ SmpAllowProtectedRenames

ULONG SmpAllowProtectedRenames

Definition at line 41 of file sminit.c.

Referenced by SmpConfigureAllowProtectedRenames(), and SmpProcessFileRenames().

◆ SmpApiPortSDBody

SECURITY_DESCRIPTOR SmpApiPortSDBody

Definition at line 37 of file sminit.c.

Referenced by SmpCreateSecurityDescriptors().

◆ SmpApiPortSecurityDescriptor

PISECURITY_DESCRIPTOR SmpApiPortSecurityDescriptor

Definition at line 39 of file sminit.c.

Referenced by SmpCreateSecurityDescriptors(), and SmpInit().

◆ SmpBootExecuteList

LIST_ENTRY SmpBootExecuteList

Definition at line 19 of file sminit.c.

Referenced by SmpLoadDataFromRegistry().

◆ SmpCalledConfigEnv

ULONG SmpCalledConfigEnv

Definition at line 30 of file sminit.c.

Referenced by SmpConfigureEnvironment().

◆ SmpDebugPort

HANDLE SmpDebugPort

Definition at line 27 of file sminit.c.

Referenced by SmpInit(), and SmpSbCreateSession().

◆ SmpDefaultEnvironment

PWCHAR SmpDefaultEnvironment

◆ SmpDefaultLibPath

UNICODE_STRING SmpDefaultLibPath

◆ SmpDefaultLibPathBuffer

PWCHAR SmpDefaultLibPathBuffer

Definition at line 28 of file sminit.c.

Referenced by SmpConfigureEnvironment().

◆ SmpDosDevicesList

LIST_ENTRY SmpDosDevicesList

Definition at line 20 of file sminit.c.

Referenced by SmpInitializeDosDevices(), and SmpLoadDataFromRegistry().

◆ SmpDosDevicesObjectDirectory

HANDLE SmpDosDevicesObjectDirectory

Definition at line 27 of file sminit.c.

Referenced by SmpInitializeDosDevices(), and SmpTranslateSystemPartitionInformation().

◆ SmpExcludeKnownDllsList

LIST_ENTRY SmpExcludeKnownDllsList

Definition at line 21 of file sminit.c.

Referenced by SmpInitializeKnownDllsInternal(), and SmpLoadDataFromRegistry().

◆ SmpExecuteList

LIST_ENTRY SmpExecuteList

Definition at line 23 of file sminit.c.

Referenced by SmpLoadDataFromRegistry(), and SmpLoadSubSystemsForMuSession().

◆ SmpFileRenameList

LIST_ENTRY SmpFileRenameList

Definition at line 20 of file sminit.c.

Referenced by SmpLoadDataFromRegistry(), and SmpProcessFileRenames().

◆ SmpHeap

◆ SmpInitLastCall

PVOID SmpInitLastCall

Definition at line 34 of file sminit.c.

◆ SmpInitProgressByLine

ULONG SmpInitProgressByLine

Definition at line 32 of file sminit.c.

◆ SmpInitReturnStatus

NTSTATUS SmpInitReturnStatus

Definition at line 33 of file sminit.c.

◆ SmpKnownDllPath

UNICODE_STRING SmpKnownDllPath

Definition at line 29 of file sminit.c.

Referenced by SmpConfigureKnownDlls(), and SmpInitializeKnownDlls().

◆ SmpKnownDllsList

◆ SmpKnownDllsSDBody

SECURITY_DESCRIPTOR SmpKnownDllsSDBody

Definition at line 36 of file sminit.c.

Referenced by SmpCreateSecurityDescriptors().

◆ SmpKnownDllsSecurityDescriptor

PISECURITY_DESCRIPTOR SmpKnownDllsSecurityDescriptor

Definition at line 39 of file sminit.c.

Referenced by SmpCreateSecurityDescriptors(), and SmpInitializeKnownDllsInternal().

◆ SmpLiberalSDBody

SECURITY_DESCRIPTOR SmpLiberalSDBody

Definition at line 36 of file sminit.c.

Referenced by SmpCreateSecurityDescriptors().

◆ SmpLiberalSecurityDescriptor

PISECURITY_DESCRIPTOR SmpLiberalSecurityDescriptor

◆ SmpPagingFileList

LIST_ENTRY SmpPagingFileList

Definition at line 20 of file sminit.c.

Referenced by SmpLoadDataFromRegistry().

◆ SmpPrimarySDBody

SECURITY_DESCRIPTOR SmpPrimarySDBody

Definition at line 36 of file sminit.c.

Referenced by SmpCreateSecurityDescriptors().

◆ SmpPrimarySecurityDescriptor

◆ SmpProtectionMode

ULONG SmpProtectionMode = 1

Definition at line 41 of file sminit.c.

Referenced by SmpConfigureProtectionMode(), and SmpCreateSecurityDescriptors().

◆ SmpRegistryConfigurationTable

RTL_QUERY_REGISTRY_TABLE SmpRegistryConfigurationTable[]

Definition at line 604 of file sminit.c.

Referenced by SmpLoadDataFromRegistry().

◆ SmpSetupExecuteList

LIST_ENTRY SmpSetupExecuteList

Definition at line 19 of file sminit.c.

Referenced by SmpLoadDataFromRegistry(), and SmpLoadSubSystemsForMuSession().

◆ SmpSubSystemList

LIST_ENTRY SmpSubSystemList

Definition at line 22 of file sminit.c.

Referenced by SmpLoadDataFromRegistry(), and SmpLoadSubSystemsForMuSession().

◆ SmpSubsystemName

UNICODE_STRING SmpSubsystemName

Definition at line 18 of file sminit.c.

Referenced by SmpInit().

◆ SmpSubSystemsToDefer

LIST_ENTRY SmpSubSystemsToDefer

◆ SmpSubSystemsToLoad

LIST_ENTRY SmpSubSystemsToLoad