ReactOS 0.4.15-dev-6068-g8061a6f
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:71
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:4196
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:588
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
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)
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define L(x)
Definition: ntvdm.h:50
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
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}
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define REG_SZ
Definition: layer.c:22
#define REG_MULTI_SZ
Definition: nt_native.h:1501
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 OBJ_OPENIF
Definition: winternl.h:229
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define OBJ_PERMANENT
Definition: winternl.h:226
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_Out_ _Inout_ POEM_STRING _In_ PCUNICODE_STRING SourceString
Definition: rtlfuncs.h:1910
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:1259
NTSTATUS NTAPI NtCreateDirectoryObject(OUT PHANDLE DirectoryHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: obdir.c:765
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:975

◆ 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{
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);
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 */
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:596
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
Entry(ENTRY_TYPE etype)
Definition: entries.cpp:35
Registry entry.
Definition: regfs.h:31

◆ SmpCreateDynamicEnvironmentVariables()

NTSTATUS NTAPI SmpCreateDynamicEnvironmentVariables ( VOID  )

Definition at line 1683 of file sminit.c.

1684{
1686 SYSTEM_BASIC_INFORMATION BasicInfo;
1687 SYSTEM_PROCESSOR_INFORMATION ProcessorInfo;
1690 HANDLE KeyHandle, KeyHandle2;
1693 size_t StrLength;
1694 WCHAR ValueBuffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 512];
1695 WCHAR ValueBuffer2[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 512];
1696 PKEY_VALUE_PARTIAL_INFORMATION PartialInfo = (PVOID)ValueBuffer;
1697 PKEY_VALUE_PARTIAL_INFORMATION PartialInfo2 = (PVOID)ValueBuffer2;
1698
1699 /* Get system basic information -- we'll need the CPU count */
1701 &BasicInfo,
1702 sizeof(BasicInfo),
1703 NULL);
1704 if (!NT_SUCCESS(Status))
1705 {
1706 /* Bail out on failure */
1707 DPRINT1("SMSS: Unable to query system basic information - %x\n", Status);
1708 return Status;
1709 }
1710
1711 /* Get the processor information, we'll query a bunch of revision info */
1713 &ProcessorInfo,
1714 sizeof(ProcessorInfo),
1715 NULL);
1716 if (!NT_SUCCESS(Status))
1717 {
1718 /* Bail out on failure */
1719 DPRINT1("SMSS: Unable to query system processor information - %x\n", Status);
1720 return Status;
1721 }
1722
1723 /* We'll be writing all these environment variables over here */
1725 L"\\Registry\\Machine\\System\\CurrentControlSet\\"
1726 L"Control\\Session Manager\\Environment");
1730 NULL,
1731 NULL);
1733 if (!NT_SUCCESS(Status))
1734 {
1735 /* Bail out on failure */
1736 DPRINT1("SMSS: Unable to open %wZ - %x\n", &DestinationString, Status);
1737 return Status;
1738 }
1739
1740 /* First let's write the OS variable */
1742 ValueData = L"Windows_NT";
1743 DPRINT("Setting %wZ to %S\n", &ValueName, ValueData);
1745 &ValueName,
1746 0,
1747 REG_SZ,
1748 ValueData,
1749 (ULONG)(wcslen(ValueData) + 1) * sizeof(WCHAR));
1750 if (!NT_SUCCESS(Status))
1751 {
1752 DPRINT1("SMSS: Failed writing %wZ environment variable - %x\n",
1753 &ValueName, Status);
1755 return Status;
1756 }
1757
1758 /* Next, let's write the CPU architecture variable */
1759 RtlInitUnicodeString(&ValueName, L"PROCESSOR_ARCHITECTURE");
1760 switch (ProcessorInfo.ProcessorArchitecture)
1761 {
1762 /* Pick the correct string that matches the architecture */
1764 ValueData = L"x86";
1765 break;
1766
1768 ValueData = L"AMD64";
1769 break;
1770
1772 ValueData = L"IA64";
1773 break;
1774
1775 default:
1776 ValueData = L"Unknown";
1777 break;
1778 }
1779
1780 /* Set it */
1781 DPRINT("Setting %wZ to %S\n", &ValueName, ValueData);
1783 &ValueName,
1784 0,
1785 REG_SZ,
1786 ValueData,
1787 (ULONG)(wcslen(ValueData) + 1) * sizeof(WCHAR));
1788 if (!NT_SUCCESS(Status))
1789 {
1790 DPRINT1("SMSS: Failed writing %wZ environment variable - %x\n",
1791 &ValueName, Status);
1793 return Status;
1794 }
1795
1796 /* And now let's write the processor level */
1797 RtlInitUnicodeString(&ValueName, L"PROCESSOR_LEVEL");
1798 swprintf(ValueBuffer, L"%u", ProcessorInfo.ProcessorLevel);
1799 DPRINT("Setting %wZ to %S\n", &ValueName, ValueBuffer);
1801 &ValueName,
1802 0,
1803 REG_SZ,
1804 ValueBuffer,
1805 (ULONG)(wcslen(ValueBuffer) + 1) * sizeof(WCHAR));
1806 if (!NT_SUCCESS(Status))
1807 {
1808 DPRINT1("SMSS: Failed writing %wZ environment variable - %x\n",
1809 &ValueName, Status);
1811 return Status;
1812 }
1813
1814 /* Now open the hardware CPU key */
1816 L"\\Registry\\Machine\\Hardware\\Description\\System\\"
1817 L"CentralProcessor\\0");
1821 NULL,
1822 NULL);
1823 Status = NtOpenKey(&KeyHandle2, KEY_READ, &ObjectAttributes);
1824 if (!NT_SUCCESS(Status))
1825 {
1826 DPRINT1("SMSS: Unable to open %wZ - %x\n", &DestinationString, Status);
1828 return Status;
1829 }
1830
1831 /* So that we can read the identifier out of it... */
1832 RtlInitUnicodeString(&ValueName, L"Identifier");
1833 Status = NtQueryValueKey(KeyHandle2,
1834 &ValueName,
1836 PartialInfo,
1837 sizeof(ValueBuffer),
1838 &ResultLength);
1839 if (!NT_SUCCESS(Status) ||
1840 ((PartialInfo->Type != REG_SZ) && (PartialInfo->Type != REG_EXPAND_SZ)))
1841 {
1842 NtClose(KeyHandle2);
1844 DPRINT1("SMSS: Unable to read %wZ\\%wZ (Type %lu, Status 0x%x)\n",
1845 &DestinationString, &ValueName, PartialInfo->Type, Status);
1846 return Status;
1847 }
1848
1849 /* Initialize the string so that it can be large enough
1850 * to contain both the identifier and the vendor strings. */
1851 RtlInitEmptyUnicodeString(&DestinationString,
1852 (PWCHAR)PartialInfo->Data,
1853 sizeof(ValueBuffer) -
1856 PartialInfo->DataLength,
1857 &StrLength);
1858 DestinationString.Length = (USHORT)StrLength;
1859
1860 /* As well as the vendor... */
1861 RtlInitUnicodeString(&ValueName, L"VendorIdentifier");
1862 Status = NtQueryValueKey(KeyHandle2,
1863 &ValueName,
1865 PartialInfo2,
1866 sizeof(ValueBuffer2),
1867 &ResultLength);
1868 NtClose(KeyHandle2);
1869 if (NT_SUCCESS(Status) &&
1870 ((PartialInfo2->Type == REG_SZ) || (PartialInfo2->Type == REG_EXPAND_SZ)))
1871 {
1872 /* To combine it into a single string */
1875 L", %.*s",
1876 PartialInfo2->DataLength / sizeof(WCHAR),
1877 (PWCHAR)PartialInfo2->Data);
1879 }
1880
1881 /* So that we can set this as the PROCESSOR_IDENTIFIER variable */
1882 RtlInitUnicodeString(&ValueName, L"PROCESSOR_IDENTIFIER");
1883 DPRINT("Setting %wZ to %wZ\n", &ValueName, &DestinationString);
1885 &ValueName,
1886 0,
1887 REG_SZ,
1890 if (!NT_SUCCESS(Status))
1891 {
1892 DPRINT1("SMSS: Failed writing %wZ environment variable - %x\n",
1893 &ValueName, Status);
1895 return Status;
1896 }
1897
1898 /* Now let's get the processor architecture */
1899 RtlInitUnicodeString(&ValueName, L"PROCESSOR_REVISION");
1900 switch (ProcessorInfo.ProcessorArchitecture)
1901 {
1902 /* Check if this is an older Intel CPU */
1904 if ((ProcessorInfo.ProcessorRevision >> 8) == 0xFF)
1905 {
1906 /* These guys used a revision + stepping, so get the rev only */
1907 swprintf(ValueBuffer, L"%02x", ProcessorInfo.ProcessorRevision & 0xFF);
1908 _wcsupr(ValueBuffer);
1909 break;
1910 }
1911
1912 /* Modern Intel, as well as 64-bit CPUs use a revision without stepping */
1915 swprintf(ValueBuffer, L"%04x", ProcessorInfo.ProcessorRevision);
1916 break;
1917
1918 /* And anything else we'll just read the whole revision identifier */
1919 default:
1920 swprintf(ValueBuffer, L"%u", ProcessorInfo.ProcessorRevision);
1921 break;
1922 }
1923
1924 /* Write the revision to the registry */
1925 DPRINT("Setting %wZ to %S\n", &ValueName, ValueBuffer);
1927 &ValueName,
1928 0,
1929 REG_SZ,
1930 ValueBuffer,
1931 (ULONG)(wcslen(ValueBuffer) + 1) * sizeof(WCHAR));
1932 if (!NT_SUCCESS(Status))
1933 {
1934 DPRINT1("SMSS: Failed writing %wZ environment variable - %x\n",
1935 &ValueName, Status);
1937 return Status;
1938 }
1939
1940 /* And finally, write the number of CPUs */
1941 RtlInitUnicodeString(&ValueName, L"NUMBER_OF_PROCESSORS");
1942 swprintf(ValueBuffer, L"%d", BasicInfo.NumberOfProcessors);
1943 DPRINT("Setting %wZ to %S\n", &ValueName, ValueBuffer);
1945 &ValueName,
1946 0,
1947 REG_SZ,
1948 ValueBuffer,
1949 (ULONG)(wcslen(ValueBuffer) + 1) * sizeof(WCHAR));
1950 if (!NT_SUCCESS(Status))
1951 {
1952 DPRINT1("SMSS: Failed writing %wZ environment variable - %x\n",
1953 &ValueName, Status);
1955 return Status;
1956 }
1957
1958 /* Now we need to write the safeboot option key in a different format */
1960 L"\\Registry\\Machine\\System\\CurrentControlSet\\"
1961 L"Control\\Safeboot\\Option");
1965 NULL,
1966 NULL);
1968 if (NT_SUCCESS(Status))
1969 {
1970 /* This was indeed a safeboot, so check what kind of safeboot it was */
1971 RtlInitUnicodeString(&ValueName, L"OptionValue");
1972 Status = NtQueryValueKey(KeyHandle2,
1973 &ValueName,
1975 PartialInfo,
1976 sizeof(ValueBuffer),
1977 &ResultLength);
1978 NtClose(KeyHandle2);
1979 if (NT_SUCCESS(Status) &&
1980 (PartialInfo->Type == REG_DWORD) &&
1981 (PartialInfo->DataLength >= sizeof(ULONG)))
1982 {
1983 /* Convert from the integer value to the correct specifier */
1984 RtlInitUnicodeString(&ValueName, L"SAFEBOOT_OPTION");
1985 switch (*(PULONG)PartialInfo->Data)
1986 {
1987 case 1:
1988 wcscpy(ValueBuffer, L"MINIMAL");
1989 break;
1990 case 2:
1991 wcscpy(ValueBuffer, L"NETWORK");
1992 break;
1993 case 3:
1994 wcscpy(ValueBuffer, L"DSREPAIR");
1995 break;
1996 }
1997
1998 /* And write it in the environment! */
1999 DPRINT("Setting %wZ to %S\n", &ValueName, ValueBuffer);
2001 &ValueName,
2002 0,
2003 REG_SZ,
2004 ValueBuffer,
2005 (ULONG)(wcslen(ValueBuffer) + 1) * sizeof(WCHAR));
2006 if (!NT_SUCCESS(Status))
2007 {
2008 DPRINT1("SMSS: Failed writing %wZ environment variable - %x\n",
2009 &ValueName, Status);
2011 return Status;
2012 }
2013 }
2014 else
2015 {
2016 DPRINT1("SMSS: Failed to query SAFEBOOT option (Type %lu, Status 0x%x)\n",
2017 PartialInfo->Type, Status);
2018 }
2019 }
2020
2021 /* We are all done now */
2023 return STATUS_SUCCESS;
2024}
#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:1909
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:1182
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define KEY_READ
Definition: nt_native.h:1023
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:1494
#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
unsigned short USHORT
Definition: pedump.c:61
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
_CRTIMP wchar_t *__cdecl _wcsupr(_Inout_z_ wchar_t *_String)
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:3776
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by SmpLoadDataFromRegistry().

◆ SmpCreateSecurityDescriptors()

NTSTATUS NTAPI SmpCreateSecurityDescriptors ( IN BOOLEAN  InitialCall)

Definition at line 975 of file sminit.c.

976{
978 PSID WorldSid = NULL, AdminSid = NULL, SystemSid = NULL;
979 PSID RestrictedSid = NULL, OwnerSid = NULL;
983 ULONG AclLength, SidLength;
984 PACL Acl;
986 BOOLEAN ProtectionRequired = FALSE;
987
988 /* Check if this is the first call */
989 if (InitialCall)
990 {
991 /* Create and set the primary descriptor */
997 TRUE,
998 NULL,
999 FALSE);
1001
1002 /* Create and set the liberal descriptor */
1008 TRUE,
1009 NULL,
1010 FALSE);
1012
1013 /* Create and set the \KnownDlls descriptor */
1019 TRUE,
1020 NULL,
1021 FALSE);
1023
1024 /* Create and Set the \ApiPort descriptor */
1030 TRUE,
1031 NULL,
1032 FALSE);
1034 }
1035
1036 /* Check if protection was requested in the registry (on by default) */
1037 if (SmpProtectionMode & 1) ProtectionRequired = TRUE;
1038
1039 /* Exit if there's nothing to do */
1040 if (!(InitialCall || ProtectionRequired)) return STATUS_SUCCESS;
1041
1042 /* Build the world SID */
1045 0, 0, 0, 0, 0, 0, 0,
1046 &WorldSid);
1047 if (!NT_SUCCESS(Status))
1048 {
1049 WorldSid = NULL;
1050 goto Quickie;
1051 }
1052
1053 /* Build the admin SID */
1057 0, 0, 0, 0, 0, 0,
1058 &AdminSid);
1059 if (!NT_SUCCESS(Status))
1060 {
1061 AdminSid = NULL;
1062 goto Quickie;
1063 }
1064
1065 /* Build the owner SID */
1066 Status = RtlAllocateAndInitializeSid(&CreatorAuthority, 1,
1068 0, 0, 0, 0, 0, 0, 0,
1069 &OwnerSid);
1070 if (!NT_SUCCESS(Status))
1071 {
1072 OwnerSid = NULL;
1073 goto Quickie;
1074 }
1075
1076 /* Build the restricted SID */
1079 0, 0, 0, 0, 0, 0, 0,
1080 &RestrictedSid);
1081 if (!NT_SUCCESS(Status))
1082 {
1083 RestrictedSid = NULL;
1084 goto Quickie;
1085 }
1086
1087 /* Build the system SID */
1090 0, 0, 0, 0, 0, 0, 0,
1091 &SystemSid);
1092 if (!NT_SUCCESS(Status))
1093 {
1094 SystemSid = NULL;
1095 goto Quickie;
1096 }
1097
1098 /* Now check if we're creating the core descriptors */
1099 if (!InitialCall)
1100 {
1101 /* We're skipping NextAcl so we have to do this here */
1102 SidLength = RtlLengthSid(WorldSid) + RtlLengthSid(RestrictedSid) + RtlLengthSid(AdminSid);
1103 SidLength *= 2;
1104 goto NotInitial;
1105 }
1106
1107 /* Allocate an ACL with two ACEs with two SIDs each */
1108 SidLength = RtlLengthSid(SystemSid) + RtlLengthSid(AdminSid);
1109 AclLength = sizeof(ACL) + 2 * sizeof(ACCESS_ALLOWED_ACE) + SidLength;
1110 Acl = RtlAllocateHeap(RtlGetProcessHeap(), 0, AclLength);
1111 if (!Acl) Status = STATUS_NO_MEMORY;
1112 if (!NT_SUCCESS(Status)) goto NextAcl;
1113
1114 /* Now build the ACL and add the two ACEs */
1121
1122 /* Set this as the DACL */
1124 TRUE,
1125 Acl,
1126 FALSE);
1128
1129NextAcl:
1130 /* Allocate an ACL with 6 ACEs, two ACEs per SID */
1131 SidLength = RtlLengthSid(WorldSid) + RtlLengthSid(RestrictedSid) + RtlLengthSid(AdminSid);
1132 SidLength *= 2;
1133 AclLength = sizeof(ACL) + 6 * sizeof(ACCESS_ALLOWED_ACE) + SidLength;
1134 Acl = RtlAllocateHeap(RtlGetProcessHeap(), 0, AclLength);
1135 if (!Acl) Status = STATUS_NO_MEMORY;
1136 if (!NT_SUCCESS(Status)) goto NotInitial;
1137
1138 /* Now build the ACL and add the six ACEs */
1153
1154 /* Now edit the last three ACEs and make them inheritable */
1155 Status = RtlGetAce(Acl, 3, (PVOID)&Ace);
1158 Status = RtlGetAce(Acl, 4, (PVOID)&Ace);
1161 Status = RtlGetAce(Acl, 5, (PVOID)&Ace);
1164
1165 /* Set this as the DACL */
1167 TRUE,
1168 Acl,
1169 FALSE);
1171
1172NotInitial:
1173 /* The initial ACLs have been created, are we also protecting objects? */
1174 if (!ProtectionRequired) goto Quickie;
1175
1176 /* Allocate an ACL with 7 ACEs, two ACEs per SID, and one final owner ACE */
1177 SidLength += RtlLengthSid(OwnerSid);
1178 AclLength = sizeof(ACL) + 7 * sizeof (ACCESS_ALLOWED_ACE) + 2 * SidLength;
1179 Acl = RtlAllocateHeap(RtlGetProcessHeap(), 0, AclLength);
1180 if (!Acl) Status = STATUS_NO_MEMORY;
1181 if (!NT_SUCCESS(Status)) goto Quickie;
1182
1183 /* Build the ACL and add the seven ACEs */
1200
1201 /* Edit the last 4 ACEs to make then inheritable */
1202 Status = RtlGetAce(Acl, 3, (PVOID)&Ace);
1205 Status = RtlGetAce(Acl, 4, (PVOID)&Ace);
1208 Status = RtlGetAce(Acl, 5, (PVOID)&Ace);
1211 Status = RtlGetAce(Acl, 6, (PVOID)&Ace);
1214
1215 /* Set this as the DACL for the primary SD */
1217 TRUE,
1218 Acl,
1219 FALSE);
1221
1222 /* Allocate an ACL with 7 ACEs, two ACEs per SID, and one final owner ACE */
1223 AclLength = sizeof(ACL) + 7 * sizeof (ACCESS_ALLOWED_ACE) + 2 * SidLength;
1224 Acl = RtlAllocateHeap(RtlGetProcessHeap(), 0, AclLength);
1225 if (!Acl) Status = STATUS_NO_MEMORY;
1226 if (!NT_SUCCESS(Status)) goto Quickie;
1227
1228 /* Build the ACL and add the seven ACEs */
1245
1246 /* Edit the last 4 ACEs to make then inheritable */
1247 Status = RtlGetAce(Acl, 3, (PVOID)&Ace);
1250 Status = RtlGetAce(Acl, 4, (PVOID)&Ace);
1253 Status = RtlGetAce(Acl, 5, (PVOID)&Ace);
1256 Status = RtlGetAce(Acl, 6, (PVOID)&Ace);
1259
1260 /* Now set this as the DACL for the liberal SD */
1262 TRUE,
1263 Acl,
1264 FALSE);
1266
1267Quickie:
1268 /* Cleanup the SIDs */
1269 if (OwnerSid) RtlFreeHeap(RtlGetProcessHeap(), 0, OwnerSid);
1270 if (AdminSid) RtlFreeHeap(RtlGetProcessHeap(), 0, AdminSid);
1271 if (WorldSid) RtlFreeHeap(RtlGetProcessHeap(), 0, WorldSid);
1272 if (SystemSid) RtlFreeHeap(RtlGetProcessHeap(), 0, SystemSid);
1273 if (RestrictedSid) RtlFreeHeap(RtlGetProcessHeap(), 0, RestrictedSid);
1274 return Status;
1275}
unsigned char BOOLEAN
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:606
@ Ace
Definition: card.h:12
#define GENERIC_READ
Definition: compat.h:135
static SID_IDENTIFIER_AUTHORITY WorldAuthority
Definition: security.c:14
NTSYSAPI NTSTATUS WINAPI RtlAddAccessAllowedAce(PACL, DWORD, DWORD, PSID)
NTSYSAPI NTSTATUS WINAPI RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR, BOOLEAN, PACL, BOOLEAN)
#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
_In_ ULONG AclLength
Definition: rtlfuncs.h:1842
#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{
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 */
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
base of all file and directory entries
Definition: entries.h:83
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#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 2449 of file sminit.c.

2451{
2452 NTSTATUS Status, Status2;
2454 UNICODE_STRING PortName, EventName;
2455 HANDLE EventHandle, PortHandle;
2456 ULONG HardErrorMode;
2457
2458 /* Create the SMSS Heap */
2459 SmBaseTag = RtlCreateTagHeap(RtlGetProcessHeap(),
2460 0,
2461 L"SMSS!",
2462 L"INIT");
2463 SmpHeap = RtlGetProcessHeap();
2464
2465 /* Enable hard errors */
2466 HardErrorMode = TRUE;
2469 &HardErrorMode,
2470 sizeof(HardErrorMode));
2471
2472 /* Initialize the subsystem list and the session list, plus their locks */
2477
2478 /* Initialize the process list */
2480
2481 /* Initialize session parameters */
2482 SmpNextSessionId = 1;
2485
2486 /* Create the initial security descriptors */
2488 if (!NT_SUCCESS(Status))
2489 {
2490 /* Fail */
2492 return Status;
2493 }
2494
2495 /* Initialize subsystem names */
2496 RtlInitUnicodeString(&SmpSubsystemName, L"NT-Session Manager");
2499
2500 /* Create the SM API Port */
2501 RtlInitUnicodeString(&PortName, L"\\SmApiPort");
2503 Status = NtCreatePort(&PortHandle,
2505 sizeof(SB_CONNECTION_INFO),
2506 sizeof(SM_API_MSG),
2507 sizeof(SB_API_MSG) * 32);
2509 SmpDebugPort = PortHandle;
2510
2511 /* Create two SM API threads */
2513 NULL,
2514 FALSE,
2515 0,
2516 0,
2517 0,
2518 SmpApiLoop,
2519 PortHandle,
2520 NULL,
2521 NULL);
2524 NULL,
2525 FALSE,
2526 0,
2527 0,
2528 0,
2529 SmpApiLoop,
2530 PortHandle,
2531 NULL,
2532 NULL);
2534
2535 /* Create the write event that autochk can set after running */
2536 RtlInitUnicodeString(&EventName, L"\\Device\\VolumesSafeForWriteAccess");
2538 &EventName,
2540 NULL,
2541 NULL);
2542 Status2 = NtCreateEvent(&EventHandle,
2545 0,
2546 0);
2547 if (!NT_SUCCESS(Status2))
2548 {
2549 /* Should never really fail */
2550 DPRINT1("SMSS: Unable to create %wZ event - Status == %lx\n",
2551 &EventName, Status2);
2552 ASSERT(NT_SUCCESS(Status2));
2553 }
2554
2555 /* Now initialize everything else based on the registry parameters */
2556 Status = SmpLoadDataFromRegistry(InitialCommand);
2557 if (NT_SUCCESS(Status))
2558 {
2559 /* Autochk should've run now. Set the event and save the CSRSS handle */
2563 }
2564
2565 /* All done */
2566 return Status;
2567}
static UNICODE_STRING PortName
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
@ ProcessDefaultHardErrorMode
Definition: winternl.h:868
#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:1657
NTSTATUS NTAPI NtSetEvent(IN HANDLE EventHandle, OUT PLONG PreviousState OPTIONAL)
Definition: event.c:455
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:221
NTSTATUS NTAPI NtSetInformationProcess(IN HANDLE ProcessHandle, IN PROCESSINFOCLASS ProcessInformationClass, IN PVOID ProcessInformation, IN ULONG ProcessInformationLength)
Definition: query.c:1105
ULONG NTAPI RtlCreateTagHeap(_In_ HANDLE HeapHandle, _In_ ULONG Flags, _In_opt_ PWSTR TagName, _In_ PWSTR TagSubName)
Definition: heap.c:4031
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:2243
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
_Out_ PHANDLE EventHandle
Definition: iofuncs.h:857

Referenced by _main().

◆ SmpInitializeDosDevices()

NTSTATUS NTAPI SmpInitializeDosDevices ( VOID  )

Definition at line 1279 of file sminit.c.

1280{
1283 SECURITY_DESCRIPTOR_CONTROL OldFlag = 0;
1285 UNICODE_STRING GlobalName;
1286 HANDLE DirHandle;
1287 PLIST_ENTRY NextEntry, Head;
1288
1289 /* Open the \GLOBAL?? directory */
1290 RtlInitUnicodeString(&GlobalName, L"\\??");
1292 &GlobalName,
1294 NULL,
1295 NULL);
1299 if (!NT_SUCCESS(Status))
1300 {
1301 DPRINT1("SMSS: Unable to open %wZ directory - Status == %lx\n",
1302 &GlobalName, Status);
1303 return Status;
1304 }
1305
1306 /* Loop the DOS devices */
1307 Head = &SmpDosDevicesList;
1308 while (!IsListEmpty(Head))
1309 {
1310 /* Get the entry and remove it */
1311 NextEntry = RemoveHeadList(Head);
1313
1314 /* Initialize the attributes, and see which descriptor is being used */
1316 &RegEntry->Name,
1321 {
1322 /* Save the old flag and set it while we create this link */
1325 }
1326
1327 /* Create the symbolic link */
1328 DPRINT("Creating symlink for %wZ to %wZ\n", &RegEntry->Name, &RegEntry->Value);
1332 &RegEntry->Value);
1334 {
1335 /* Make it temporary and get rid of the handle */
1336 NtMakeTemporaryObject(DirHandle);
1337 NtClose(DirHandle);
1338
1339 /* Treat this as success, and see if we got a name back */
1341 if (RegEntry->Value.Length)
1342 {
1343 /* Create it now with this name */
1344 ObjectAttributes.Attributes &= ~OBJ_OPENIF;
1348 &RegEntry->Value);
1349 }
1350 }
1351
1352 /* If we were using a security descriptor, restore the non-defaulted flag */
1353 if (ObjectAttributes.SecurityDescriptor)
1354 {
1356 }
1357
1358 /* Print a failure if we failed to create the symbolic link */
1359 if (!NT_SUCCESS(Status))
1360 {
1361 DPRINT1("SMSS: Unable to create %wZ => %wZ symbolic link object - Status == 0x%lx\n",
1362 &RegEntry->Name,
1363 &RegEntry->Value,
1364 Status);
1365 break;
1366 }
1367
1368 /* Close the handle */
1369 NtClose(DirHandle);
1370
1371 /* Free this entry */
1372 if (RegEntry->AnsiValue) RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry->AnsiValue);
1373 if (RegEntry->Value.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry->Value.Buffer);
1374 RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry);
1375 }
1376
1377 /* Return the status */
1378 return Status;
1379}
#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:1267
#define STATUS_OBJECT_NAME_EXISTS
Definition: ntstatus.h:114
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
#define SE_DACL_DEFAULTED
Definition: setypes.h:818

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 1652 of file sminit.c.

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

Referenced by SmpLoadDataFromRegistry().

◆ SmpInitializeKnownDllsInternal()

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

Definition at line 1425 of file sminit.c.

1427{
1428 HANDLE DirFileHandle, DirHandle, SectionHandle, FileHandle, LinkHandle;
1429 UNICODE_STRING NtPath, SymLinkName;
1431 NTSTATUS Status, Status1;
1432 PLIST_ENTRY NextEntry;
1434 ULONG_PTR ErrorParameters[3];
1435 UNICODE_STRING ErrorResponse;
1437 SECURITY_DESCRIPTOR_CONTROL OldFlag = 0;
1438 USHORT ImageCharacteristics;
1439
1440 /* Initialize to NULL */
1441 DirFileHandle = NULL;
1442 DirHandle = NULL;
1443 NtPath.Buffer = NULL;
1444
1445 /* Create the \KnownDLLs directory */
1447 Directory,
1449 NULL,
1451 Status = NtCreateDirectoryObject(&DirHandle,
1454 if (!NT_SUCCESS(Status))
1455 {
1456 /* Handle failure */
1457 DPRINT1("SMSS: Unable to create %wZ directory - Status == %lx\n",
1458 Directory, Status);
1459 return Status;
1460 }
1461
1462 /* Convert the path to native format */
1463 if (!RtlDosPathNameToNtPathName_U(Path->Buffer, &NtPath, NULL, NULL))
1464 {
1465 /* Fail if this didn't work */
1466 DPRINT1("SMSS: Unable to to convert %wZ to an Nt path\n", Path);
1468 goto Quickie;
1469 }
1470
1471 /* Open the path that was specified, which should be a directory */
1473 &NtPath,
1475 NULL,
1476 NULL);
1477 Status = NtOpenFile(&DirFileHandle,
1483 if (!NT_SUCCESS(Status))
1484 {
1485 /* Fail if we couldn't open it */
1486 DPRINT1("SMSS: Unable to open a handle to the KnownDll directory (%wZ)"
1487 "- Status == %lx\n",
1488 Path,
1489 Status);
1490 FileHandle = NULL;
1491 goto Quickie;
1492 }
1493
1494 /* Temporarily hack the SD to use a default DACL for this symbolic link */
1496 {
1499 }
1500
1501 /* Create a symbolic link to the directory in the object manager */
1502 RtlInitUnicodeString(&SymLinkName, L"KnownDllPath");
1504 &SymLinkName,
1506 DirHandle,
1508 Status = NtCreateSymbolicLinkObject(&LinkHandle,
1511 Path);
1512
1513 /* Undo the hack */
1515
1516 /* Check if the symlink was created */
1517 if (!NT_SUCCESS(Status))
1518 {
1519 /* It wasn't, so bail out since the OS needs it to exist */
1520 DPRINT1("SMSS: Unable to create %wZ symbolic link - Status == %lx\n",
1521 &SymLinkName, Status);
1522 LinkHandle = NULL;
1523 goto Quickie;
1524 }
1525
1526 /* We created it permanent, we can go ahead and close the handle now */
1527 Status1 = NtClose(LinkHandle);
1528 ASSERT(NT_SUCCESS(Status1));
1529
1530 /* Now loop the known DLLs */
1531 NextEntry = SmpKnownDllsList.Flink;
1532 while (NextEntry != &SmpKnownDllsList)
1533 {
1534 /* Get the entry and move on */
1536 NextEntry = NextEntry->Flink;
1537
1538 DPRINT("Processing known DLL: %wZ-%wZ\n", &RegEntry->Name, &RegEntry->Value);
1539
1540 /* Skip the entry if it's in the excluded list */
1542 RegEntry->Name.Buffer)) ||
1544 RegEntry->Value.Buffer)))
1545 {
1546 continue;
1547 }
1548
1549 /* Open the actual file */
1551 &RegEntry->Value,
1553 DirFileHandle,
1554 NULL);
1555 Status1 = NtOpenFile(&FileHandle,
1562 /* If we failed, skip it */
1563 if (!NT_SUCCESS(Status1)) continue;
1564
1565 /* Checksum it */
1568 RegEntry,
1569 &ImageCharacteristics);
1570 if (!NT_SUCCESS(Status))
1571 {
1572 /* Checksum failed, so don't even try going further -- kill SMSS */
1573 RtlInitUnicodeString(&ErrorResponse,
1574 L"Verification of a KnownDLL failed.");
1575 ErrorParameters[0] = (ULONG_PTR)&ErrorResponse;
1576 ErrorParameters[1] = Status;
1577 ErrorParameters[2] = (ULONG_PTR)&RegEntry->Value;
1578 SmpTerminate(ErrorParameters, 5, RTL_NUMBER_OF(ErrorParameters));
1579 }
1580 else if (!(ImageCharacteristics & IMAGE_FILE_DLL))
1581 {
1582 /* An invalid known DLL entry will also kill SMSS */
1583 RtlInitUnicodeString(&ErrorResponse,
1584 L"Non-DLL file included in KnownDLL list.");
1585 ErrorParameters[0] = (ULONG_PTR)&ErrorResponse;
1586 ErrorParameters[1] = STATUS_INVALID_IMPORT_OF_NON_DLL;
1587 ErrorParameters[2] = (ULONG_PTR)&RegEntry->Value;
1588 SmpTerminate(ErrorParameters, 5, RTL_NUMBER_OF(ErrorParameters));
1589 }
1590
1591 /* Temporarily hack the SD to use a default DACL for this section */
1593 {
1596 }
1597
1598 /* Create the section for this known DLL */
1600 &RegEntry->Value,
1602 DirHandle,
1604 Status = NtCreateSection(&SectionHandle,
1607 0,
1609 SEC_IMAGE,
1610 FileHandle);
1611
1612 /* Undo the hack */
1614
1615 /* Check if we created the section okay */
1616 if (NT_SUCCESS(Status))
1617 {
1618 /* We can close it now, since it's marked permanent */
1619 Status1 = NtClose(SectionHandle);
1620 ASSERT(NT_SUCCESS(Status1));
1621 }
1622 else
1623 {
1624 /* If we couldn't make it "known", that's fine and keep going */
1625 DPRINT1("SMSS: CreateSection for KnownDll %wZ failed - Status == %lx\n",
1626 &RegEntry->Value, Status);
1627 }
1628
1629 /* Close the file since we can move on to the next one */
1630 Status1 = NtClose(FileHandle);
1631 ASSERT(NT_SUCCESS(Status1));
1632 }
1633
1634Quickie:
1635 /* Close both handles and free the NT path buffer */
1636 if (DirHandle)
1637 {
1638 Status1 = NtClose(DirHandle);
1639 ASSERT(NT_SUCCESS(Status1));
1640 }
1641 if (DirFileHandle)
1642 {
1643 Status1 = NtClose(DirFileHandle);
1644 ASSERT(NT_SUCCESS(Status1));
1645 }
1646 if (NtPath.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, NtPath.Buffer);
1647 return Status;
1648}
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:3441
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:837
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define SEC_IMAGE
Definition: mmtypes.h:96
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:3952
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define SYNCHRONIZE
Definition: nt_native.h:61
#define SECTION_ALL_ACCESS
Definition: nt_native.h:1293
#define FILE_LIST_DIRECTORY
Definition: nt_native.h:629
#define PAGE_EXECUTE
Definition: nt_native.h:1306
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
#define FILE_EXECUTE
Definition: nt_native.h:642
#define STATUS_INVALID_IMPORT_OF_NON_DLL
Definition: ntstatus.h:921
#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:1383
NTSTATUS NTAPI SmpTerminate(IN PULONG_PTR Parameters, IN ULONG ParameterMask, IN ULONG ParameterCount)
Definition: smss.c:374
base for all directory entries
Definition: entries.h:138
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 2243 of file sminit.c.

2244{
2246 PLIST_ENTRY Head, NextEntry;
2248 PVOID OriginalEnvironment;
2249 ULONG MuSessionId = 0;
2253
2254 /* Initialize the keywords we'll be looking for */
2258
2259 /* Initialize all the registry-associated list heads */
2271
2273
2274 /* Initialize the SMSS environment */
2276 if (!NT_SUCCESS(Status))
2277 {
2278 /* Fail if there was a problem */
2279 DPRINT1("SMSS: Unable to allocate default environment - Status == %X\n",
2280 Status);
2282 return Status;
2283 }
2284
2285 /* Check if we were booted in PE mode (LiveCD should have this) */
2287 L"\\Registry\\Machine\\System\\CurrentControlSet\\"
2288 L"Control\\MiniNT");
2292 NULL,
2293 NULL);
2295 if (NT_SUCCESS(Status))
2296 {
2297 /* If the key exists, we were */
2299 MiniNTBoot = TRUE;
2300 }
2301
2302 /* Print out if this is the case */
2303 if (MiniNTBoot) DPRINT("SMSS: !!! MiniNT Boot !!!\n");
2304
2305 /* Open the environment key to see if we are booted in safe mode */
2307 L"\\Registry\\Machine\\System\\CurrentControlSet\\"
2308 L"Control\\Session Manager\\Environment");
2312 NULL,
2313 NULL);
2315 if (NT_SUCCESS(Status))
2316 {
2317 /* Delete the value if we found it */
2318 RtlInitUnicodeString(&DestinationString, L"SAFEBOOT_OPTION");
2321 }
2322
2323 /* Switch environments, then query the registry for all needed settings */
2324 OriginalEnvironment = NtCurrentPeb()->ProcessParameters->Environment;
2325 NtCurrentPeb()->ProcessParameters->Environment = SmpDefaultEnvironment;
2327 L"Session Manager",
2329 NULL,
2330 NULL);
2331 SmpDefaultEnvironment = NtCurrentPeb()->ProcessParameters->Environment;
2332 NtCurrentPeb()->ProcessParameters->Environment = OriginalEnvironment;
2333 if (!NT_SUCCESS(Status))
2334 {
2335 /* We failed somewhere in registry initialization, which is bad... */
2336 DPRINT1("SMSS: RtlQueryRegistryValues failed - Status == %lx\n", Status);
2338 return Status;
2339 }
2340
2341 /* Now we can start acting on the registry settings. First to DOS devices */
2343 if (!NT_SUCCESS(Status))
2344 {
2345 /* Failed */
2346 DPRINT1("SMSS: Unable to initialize DosDevices configuration - Status == %lx\n",
2347 Status);
2349 return Status;
2350 }
2351
2352 /* Next create the session directory... */
2357 NULL,
2362 if (!NT_SUCCESS(Status))
2363 {
2364 /* Fail */
2365 DPRINT1("SMSS: Unable to create %wZ object directory - Status == %lx\n",
2368 return Status;
2369 }
2370
2371 /* Next loop all the boot execute binaries */
2372 Head = &SmpBootExecuteList;
2373 while (!IsListEmpty(Head))
2374 {
2375 /* Remove each one from the list */
2376 NextEntry = RemoveHeadList(Head);
2377
2378 /* Execute it */
2380 SmpExecuteCommand(&RegEntry->Name, 0, NULL, 0);
2381
2382 /* And free it */
2383 if (RegEntry->AnsiValue) RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry->AnsiValue);
2384 if (RegEntry->Value.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry->Value.Buffer);
2385 RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry);
2386 }
2387
2388 /* Now do any pending file rename operations... */
2390
2391 /* And initialize known DLLs... */
2393 if (!NT_SUCCESS(Status))
2394 {
2395 /* Fail if that didn't work */
2396 DPRINT1("SMSS: Unable to initialize KnownDll configuration - Status == %lx\n",
2397 Status);
2399 return Status;
2400 }
2401
2402 /* Create the needed page files */
2403 if (!MiniNTBoot)
2404 {
2405 /* Loop every page file */
2406 Head = &SmpPagingFileList;
2407 while (!IsListEmpty(Head))
2408 {
2409 /* Remove each one from the list */
2410 NextEntry = RemoveHeadList(Head);
2411
2412 /* Create the descriptor for it */
2415
2416 /* And free it */
2417 if (RegEntry->AnsiValue) RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry->AnsiValue);
2418 if (RegEntry->Value.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry->Value.Buffer);
2419 RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry);
2420 }
2421
2422 /* Now create all the paging files for the descriptors that we have */
2424 }
2425
2426 /* Tell Cm it's now safe to fully enable write access to the registry */
2428
2429 /* Create all the system-based environment variables for later inheriting */
2431 if (!NT_SUCCESS(Status))
2432 {
2433 /* Handle failure */
2435 return Status;
2436 }
2437
2438 /* And finally load all the subsystems for our first session! */
2441 InitialCommand);
2442 ASSERT(MuSessionId == 0);
2444 return Status;
2445}
#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
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
#define CM_BOOT_FLAG_SMSS
Definition: cmtypes.h:158
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:2028
LIST_ENTRY SmpFileRenameList
Definition: sminit.c:20
PWCHAR SmpDefaultEnvironment
Definition: sminit.c:28
NTSTATUS NTAPI SmpCreateDynamicEnvironmentVariables(VOID)
Definition: sminit.c:1683
NTSTATUS NTAPI SmpInitializeDosDevices(VOID)
Definition: sminit.c:1279
NTSTATUS NTAPI SmpInitializeKnownDlls(VOID)
Definition: sminit.c:1652
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

Referenced by SmpInit().

◆ SmpProcessFileRenames()

NTSTATUS NTAPI SmpProcessFileRenames ( VOID  )

Definition at line 2028 of file sminit.c.

2029{
2030 BOOLEAN OldState, HavePrivilege = FALSE;
2032 HANDLE FileHandle, OtherFileHandle;
2036 UNICODE_STRING FileString;
2037 FILE_BASIC_INFORMATION BasicInfo;
2038 FILE_DISPOSITION_INFORMATION DeleteInformation;
2040 PLIST_ENTRY Head, NextEntry;
2044
2045 /* Give us access to restore any files we want */
2047 if (NT_SUCCESS(Status)) HavePrivilege = TRUE;
2048
2049 // FIXME: Handle SFC-protected file renames!
2051 DPRINT1("SMSS: FIXME: Handle SFC-protected file renames!\n");
2052
2053 /* Process pending files to rename */
2054 Head = &SmpFileRenameList;
2055 while (!IsListEmpty(Head))
2056 {
2057 /* Get this entry */
2058 NextEntry = RemoveHeadList(Head);
2060 DPRINT("Processing PFRO: '%wZ' / '%wZ'\n", &RegEntry->Value, &RegEntry->Name);
2061
2062 /* Skip past the '@' marker */
2063 if (!(RegEntry->Value.Length) && (*RegEntry->Name.Buffer == L'@'))
2064 {
2065 RegEntry->Name.Length -= sizeof(UNICODE_NULL);
2066 RegEntry->Name.Buffer++;
2067 }
2068
2069 /* Open the file for delete access */
2071 &RegEntry->Name,
2073 NULL,
2074 NULL);
2075 Status = NtOpenFile(&OtherFileHandle,
2081 if (!NT_SUCCESS(Status)) goto Quickie;
2082
2083 /* Check if it's a rename or just a delete */
2084 ValueLength = RegEntry->Value.Length;
2085 if (!ValueLength)
2086 {
2087 /* Just a delete, set up the class, length and buffer */
2089 Length = sizeof(DeleteInformation);
2090 Buffer = (PFILE_RENAME_INFORMATION)&DeleteInformation;
2091
2092 /* Set the delete disposition */
2093 DeleteInformation.DeleteFile = TRUE;
2094 }
2095 else
2096 {
2097 /* This is a rename, setup the class and length */
2100
2101 /* Skip past the special markers */
2102 FileName = RegEntry->Value.Buffer;
2103 if ((*FileName == L'!') || (*FileName == L'@'))
2104 {
2105 FileName++;
2106 Length -= sizeof(UNICODE_NULL);
2107 }
2108
2109 /* Now allocate the buffer for the rename information */
2110 Buffer = RtlAllocateHeap(RtlGetProcessHeap(), SmBaseTag, Length);
2111 if (Buffer)
2112 {
2113 /* Setup the buffer to point to the filename, and copy it */
2114 Buffer->RootDirectory = NULL;
2115 Buffer->FileNameLength = Length - sizeof(FILE_RENAME_INFORMATION);
2116 Buffer->ReplaceIfExists = FileName != RegEntry->Value.Buffer;
2117 RtlCopyMemory(Buffer->FileName, FileName, Buffer->FileNameLength);
2118 }
2119 else
2120 {
2121 /* Fail */
2123 }
2124 }
2125
2126 /* Check if everything is okay till here */
2127 if (NT_SUCCESS(Status))
2128 {
2129 /* Now either rename or delete the file as requested */
2130 Status = NtSetInformationFile(OtherFileHandle,
2132 Buffer,
2133 Length,
2135
2136 /* Check if we seem to have failed because the file was readonly */
2137 if (!NT_SUCCESS(Status) &&
2140 Buffer->ReplaceIfExists)
2141 {
2142 /* Open the file for write attribute access this time... */
2143 DPRINT("\nSMSS: '%wZ' => '%wZ' failed - Status == %x, Possible readonly target\n",
2144 &RegEntry->Name,
2145 &RegEntry->Value,
2147 FileString.Length = RegEntry->Value.Length - sizeof(WCHAR);
2148 FileString.MaximumLength = RegEntry->Value.MaximumLength - sizeof(WCHAR);
2149 FileString.Buffer = FileName;
2151 &FileString,
2153 NULL,
2154 NULL);
2161 if (!NT_SUCCESS(Status))
2162 {
2163 /* That didn't work, so bail out */
2164 DPRINT1(" SMSS: Open Existing file Failed - Status == %x\n",
2165 Status);
2166 }
2167 else
2168 {
2169 /* Now remove the read-only attribute from the file */
2170 DPRINT(" SMSS: Open Existing Success\n");
2171 RtlZeroMemory(&BasicInfo, sizeof(BasicInfo));
2175 &BasicInfo,
2176 sizeof(BasicInfo),
2179 if (!NT_SUCCESS(Status))
2180 {
2181 /* That didn't work, bail out */
2182 DPRINT1(" SMSS: Set To NORMAL Failed - Status == %x\n",
2183 Status);
2184 }
2185 else
2186 {
2187 /* Now that the file is no longer read-only, delete! */
2188 DPRINT(" SMSS: Set To NORMAL OK\n");
2189 Status = NtSetInformationFile(OtherFileHandle,
2191 Buffer,
2192 Length,
2194 if (!NT_SUCCESS(Status))
2195 {
2196 /* That failed too! */
2197 DPRINT1(" SMSS: Re-Rename Failed - Status == %x\n",
2198 Status);
2199 }
2200 else
2201 {
2202 /* Everything ok */
2203 DPRINT(" SMSS: Re-Rename Worked OK\n");
2204 }
2205 }
2206 }
2207 }
2208 }
2209
2210 /* Close the file handle and check the operation result */
2211 NtClose(OtherFileHandle);
2212Quickie:
2213 if (!NT_SUCCESS(Status))
2214 {
2215 /* We totally failed */
2216 DPRINT1("SMSS: '%wZ' => '%wZ' failed - Status == %x\n",
2217 &RegEntry->Name, &RegEntry->Value, Status);
2218 }
2219 else if (RegEntry->Value.Length)
2220 {
2221 /* We succeed with a rename */
2222 DPRINT("SMSS: '%wZ' (renamed to) '%wZ'\n", &RegEntry->Name, &RegEntry->Value);
2223 }
2224 else
2225 {
2226 /* We succeeded with a delete */
2227 DPRINT("SMSS: '%wZ' (deleted)\n", &RegEntry->Name);
2228 }
2229
2230 /* Now free this entry and keep going */
2231 if (RegEntry->AnsiValue) RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry->AnsiValue);
2232 if (RegEntry->Value.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry->Value.Buffer);
2233 RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry);
2234 }
2235
2236 /* Put back the restore privilege if we had requested it, and return */
2237 if (HavePrivilege) RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, FALSE, FALSE, &OldState);
2238 return Status;
2239}
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
struct _FileName FileName
Definition: fatprocs.h:896
_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
struct _FILE_RENAME_INFORMATION * PFILE_RENAME_INFORMATION
struct _FILE_RENAME_INFORMATION FILE_RENAME_INFORMATION
#define SE_RESTORE_PRIVILEGE
Definition: security.c:672
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

Referenced by SmpLoadDataFromRegistry().

◆ SmpProcessModuleImports()

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

Definition at line 1383 of file sminit.c.

1385{
1386 ULONG Length = 0;
1388 PWCHAR DllName, DllValue;
1389 ANSI_STRING ImportString;
1390 UNICODE_STRING ImportUnicodeString;
1392
1393 /* Skip NTDLL since it's already always mapped */
1394 if (!_stricmp(ImportName, "ntdll.dll")) return;
1395
1396 /* Initialize our strings */
1397 RtlInitAnsiString(&ImportString, ImportName);
1398 RtlInitEmptyUnicodeString(&ImportUnicodeString, Buffer, sizeof(Buffer));
1399 Status = RtlAnsiStringToUnicodeString(&ImportUnicodeString, &ImportString, FALSE);
1400 if (!NT_SUCCESS(Status)) return;
1401
1402 /* Loop to find the DLL file extension */
1403 while (Length < ImportUnicodeString.Length)
1404 {
1405 if (ImportUnicodeString.Buffer[Length / sizeof(WCHAR)] == L'.') break;
1406 Length += sizeof(WCHAR);
1407 }
1408
1409 /*
1410 * Break up the values as needed; the buffer acquires the form:
1411 * "dll_name.dll\0dll_name\0"
1412 */
1413 DllValue = ImportUnicodeString.Buffer;
1414 DllName = &ImportUnicodeString.Buffer[(ImportUnicodeString.Length + sizeof(UNICODE_NULL)) / sizeof(WCHAR)];
1415 RtlStringCbCopyNW(DllName,
1416 ImportUnicodeString.MaximumLength - (ImportUnicodeString.Length + sizeof(UNICODE_NULL)),
1417 ImportUnicodeString.Buffer, Length);
1418
1419 /* Add the DLL to the list */
1420 SmpSaveRegistryValue(&SmpKnownDllsList, DllName, DllValue, TRUE);
1421}
#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{
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 */
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 */
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 */
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 */
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);
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}
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 CHAR ValueBuffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 512];
821 PKEY_VALUE_PARTIAL_INFORMATION PartialInfo = (PVOID)ValueBuffer;
822 CHAR DirInfoBuffer[sizeof(OBJECT_DIRECTORY_INFORMATION) + 512];
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 PartialInfo,
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(&SearchString, L"SymbolicLink");
867 RtlInitEmptyUnicodeString(&LinkTarget, LinkBuffer, sizeof(LinkBuffer));
869 DirInfo,
870 sizeof(DirInfoBuffer),
871 TRUE,
872 TRUE,
873 &Context,
874 NULL);
875 if (!NT_SUCCESS(Status))
876 {
877 DPRINT1("SMSS: Cannot find drive letter for system partition\n");
878 return;
879 }
880
881 /* Keep searching until we find it */
882 do
883 {
884 /* Is this it? */
885 if ((RtlEqualUnicodeString(&DirInfo->TypeName, &SearchString, TRUE)) &&
886 (DirInfo->Name.Length == 2 * sizeof(WCHAR)) &&
887 (DirInfo->Name.Buffer[1] == L':'))
888 {
889 /* Looks like we found it, open the link to get its target */
891 &DirInfo->Name,
894 NULL);
895 Status = NtOpenSymbolicLinkObject(&LinkHandle,
898 if (NT_SUCCESS(Status))
899 {
900 /* Open worked, query the target now */
902 &LinkTarget,
903 NULL);
904 NtClose(LinkHandle);
905
906 /* Check if it matches the string we had found earlier */
907 if ((NT_SUCCESS(Status)) &&
909 &LinkTarget,
910 TRUE)) ||
912 &LinkTarget,
913 TRUE)) &&
914 (LinkTarget.Buffer[SystemPartition.Length / sizeof(WCHAR)] == L'\\'))))
915 {
916 /* All done */
917 break;
918 }
919 }
920 }
921
922 /* Couldn't find it, try again */
924 DirInfo,
925 sizeof(DirInfoBuffer),
926 TRUE,
927 FALSE,
928 &Context,
929 NULL);
930 } while (NT_SUCCESS(Status));
931 if (!NT_SUCCESS(Status))
932 {
933 DPRINT1("SMSS: Cannot find drive letter for system partition\n");
934 return;
935 }
936
937 /* Open the setup key again, for full access this time */
939 L"\\Registry\\Machine\\Software\\Microsoft\\Windows\\CurrentVersion\\Setup");
943 NULL,
944 NULL);
946 if (!NT_SUCCESS(Status))
947 {
948 DPRINT1("SMSS: Cannot open software setup key for writing: 0x%x\n",
949 Status);
950 return;
951 }
952
953 /* Wrap up the end of the link buffer */
954 wcsncpy(LinkBuffer, DirInfo->Name.Buffer, 2);
955 LinkBuffer[2] = L'\\';
956 LinkBuffer[3] = L'\0';
957
958 /* Now set this as the "BootDir" */
962 0,
963 REG_SZ,
964 LinkBuffer,
965 4 * sizeof(WCHAR));
966 if (!NT_SUCCESS(Status))
967 {
968 DPRINT1("SMSS: couldn't write BootDir value: 0x%x\n", Status);
969 }
971}
struct _OBJECT_DIRECTORY_INFORMATION OBJECT_DIRECTORY_INFORMATION
NTSYSAPI BOOLEAN NTAPI RtlPrefixUnicodeString(IN PUNICODE_STRING String1, IN PUNICODE_STRING String2, IN BOOLEAN CaseInSensitive)
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
_CRTIMP wchar_t *__cdecl wcsncpy(wchar_t *_Dest, const wchar_t *_Source, size_t _Count)
static PPARTENTRY SystemPartition
Definition: usetup.c:61
char CHAR
Definition: xmlstorage.h:175
_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