ReactOS 0.4.17-dev-694-g606b2e9
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 SmpConfigureExecute (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 SmpConfigureMemoryMgmt (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 438 of file sminit.c.

444{
445 /* Save the data into the list */
447}
#define TRUE
Definition: types.h:120
_In_ PCWSTR _Inout_ _At_ QueryTable EntryContext
Definition: rtlfuncs.h:4230
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 510 of file sminit.c.

516{
518 UNICODE_STRING ValueString, DataString;
519
520 /* Convert the strings into UNICODE_STRING and set the variable defined */
521 RtlInitUnicodeString(&ValueString, ValueName);
522 RtlInitUnicodeString(&DataString, ValueData);
523 DPRINT("Setting %wZ = %wZ\n", &ValueString, &DataString);
524 Status = RtlSetEnvironmentVariable(NULL, &ValueString, &DataString);
525 if (!NT_SUCCESS(Status))
526 {
527 DPRINT1("SMSS: 'SET %wZ = %wZ' failed - Status == %lx\n",
528 &ValueString, &DataString, Status);
529 return Status;
530 }
531
532 /* Check if the path is being set, and wait for the second instantiation */
533 if ((_wcsicmp(ValueName, L"Path") == 0) && (++SmpCalledConfigEnv == 2))
534 {
535 /* Allocate the path buffer */
536 SmpDefaultLibPathBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
537 SmBaseTag,
540
541 /* Copy the data into it and create the UNICODE_STRING to hold it */
544 }
545
546 /* All good */
547 return STATUS_SUCCESS;
548}
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:164
#define L(x)
Definition: resources.c:13
Status
Definition: gdiplustypes.h:24
NTSYSAPI NTSTATUS NTAPI RtlSetEnvironmentVariable(_In_z_ PWSTR *Environment, _In_ PUNICODE_STRING Name, _In_ PUNICODE_STRING Value)
Definition: env.c:338
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 390 of file sminit.c.

396{
397 PWCHAR DllName;
399
400 /* Make sure the value type is valid */
401 if ((ValueType == REG_MULTI_SZ) || (ValueType == REG_SZ))
402 {
403 /* Keep going for each DLL in the list */
404 DllName = ValueData;
405 while (*DllName)
406 {
407 /* Add this to the linked list */
408 DPRINT("Excluded DLL: %S\n", DllName);
410
411 /* Bail out on failure or if only one DLL name was present */
412 if (!(NT_SUCCESS(Status)) || (ValueType == REG_SZ)) return Status;
413
414 /* Otherwise, move to the next DLL name */
415 DllName += wcslen(DllName) + 1;
416 }
417 }
418
419 /* All done */
420 return STATUS_SUCCESS;
421}
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2988
#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

◆ SmpConfigureExecute()

NTSTATUS NTAPI SmpConfigureExecute ( 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{
346 size_t StrLength;
347
348 /* If the value is invalid or empty, skip it */
350 if (!NT_SUCCESS(Status) || (StrLength < sizeof(WCHAR)))
351 return STATUS_SUCCESS;
352
353 /* Save the value into the list */
355}
_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
short WCHAR
Definition: pedump.c:58

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

365{
367 static PWCHAR Canary = NULL;
368
369 /* Check if this is the second call */
370 if (Canary)
371 {
372 /* Save the data into the list */
373 DPRINT("Renamed file: '%S' - '%S'\n", Canary, ValueData);
375 Canary = NULL;
376 }
377 else
378 {
379 /* This it the first call, do nothing until we get the second call */
380 Canary = ValueData;
382 }
383
384 /* Return the status */
385 return Status;
386}
#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 481 of file sminit.c.

487{
488 /* Check which value is being set */
489 if (_wcsicmp(ValueName, L"DllDirectory") == 0)
490 {
491 /* This is the directory, initialize it */
492 DPRINT("KnownDll Path: %S\n", ValueData);
494 }
495 else
496 {
497 /* Add to the linked list -- this is a file */
499 }
500}
UNICODE_STRING SmpKnownDllPath
Definition: sminit.c:29
NTSTATUS NTAPI SmpInitializeKnownDllPath(IN PUNICODE_STRING DllPath, IN PWCHAR Buffer, IN ULONG Length)
Definition: sminit.c:451

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

431{
432 /* Save the value into the list */
434}

◆ 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:115
_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:3429
#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:998

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

558{
559 PSMP_REGISTRY_VALUE RegEntry;
560 PWCHAR SubsystemName;
561
562 /* Is this a required or optional subsystem? */
563 if ((_wcsicmp(ValueName, L"Required") != 0) &&
564 (_wcsicmp(ValueName, L"Optional") != 0))
565 {
566 /* It isn't, is this the PSI flag? */
567 if ((_wcsicmp(ValueName, L"PosixSingleInstance") != 0) ||
568 (ValueType != REG_DWORD))
569 {
570 /* It isn't, must be a subsystem entry, add it to the list */
571 DPRINT("Subsystem entry: %S-%S\n", ValueName, ValueData);
573 }
574
575 /* This was the PSI flag, save it and exit */
577 return STATUS_SUCCESS;
578 }
579
580 /* This should be one of the required/optional lists. Is the type valid? */
581 if (ValueType == REG_MULTI_SZ)
582 {
583 /* It is, get the first subsystem */
584 SubsystemName = ValueData;
585 while (*SubsystemName)
586 {
587 /* We should have already put it into the list when we found it */
588 DPRINT("Found subsystem: %S\n", SubsystemName);
589 RegEntry = SmpFindRegistryValue(EntryContext, SubsystemName);
590 if (!RegEntry)
591 {
592 /* This subsystem doesn't exist, so skip it */
593 DPRINT1("SMSS: Invalid subsystem name - %ws\n", SubsystemName);
594 }
595 else
596 {
597 /* Found it -- remove it from the main list */
598 RemoveEntryList(&RegEntry->Entry);
599
600 /* Figure out which list to put it in */
601 if (_wcsicmp(ValueName, L"Required") == 0)
602 {
603 /* Put it into the required list */
604 DPRINT("Required\n");
606 }
607 else
608 {
609 /* Put it into the optional list */
610 DPRINT("Optional\n");
612 }
613 }
614
615 /* Move to the next name */
616 SubsystemName += wcslen(SubsystemName) + 1;
617 }
618 }
619
620 /* All done! */
621 return STATUS_SUCCESS;
622}
#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 1706 of file sminit.c.

1707{
1709 SYSTEM_BASIC_INFORMATION BasicInfo;
1710 SYSTEM_PROCESSOR_INFORMATION ProcessorInfo;
1713 HANDLE KeyHandle, KeyHandle2;
1716 size_t StrLength;
1717 WCHAR ValueBuffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 512];
1718 WCHAR ValueBuffer2[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 512];
1719 PKEY_VALUE_PARTIAL_INFORMATION PartialInfo = (PVOID)ValueBuffer;
1720 PKEY_VALUE_PARTIAL_INFORMATION PartialInfo2 = (PVOID)ValueBuffer2;
1721
1722 /* Get system basic information -- we'll need the CPU count */
1724 &BasicInfo,
1725 sizeof(BasicInfo),
1726 NULL);
1727 if (!NT_SUCCESS(Status))
1728 {
1729 /* Bail out on failure */
1730 DPRINT1("SMSS: Unable to query system basic information - %x\n", Status);
1731 return Status;
1732 }
1733
1734 /* Get the processor information, we'll query a bunch of revision info */
1736 &ProcessorInfo,
1737 sizeof(ProcessorInfo),
1738 NULL);
1739 if (!NT_SUCCESS(Status))
1740 {
1741 /* Bail out on failure */
1742 DPRINT1("SMSS: Unable to query system processor information - %x\n", Status);
1743 return Status;
1744 }
1745
1746 /* We'll be writing all these environment variables over here */
1748 L"\\Registry\\Machine\\System\\CurrentControlSet\\"
1749 L"Control\\Session Manager\\Environment");
1753 NULL,
1754 NULL);
1756 if (!NT_SUCCESS(Status))
1757 {
1758 /* Bail out on failure */
1759 DPRINT1("SMSS: Unable to open %wZ - %x\n", &DestinationString, Status);
1760 return Status;
1761 }
1762
1763 /* First let's write the OS variable */
1765 ValueData = L"Windows_NT";
1766 DPRINT("Setting %wZ to %S\n", &ValueName, ValueData);
1768 &ValueName,
1769 0,
1770 REG_SZ,
1771 ValueData,
1772 (ULONG)(wcslen(ValueData) + 1) * sizeof(WCHAR));
1773 if (!NT_SUCCESS(Status))
1774 {
1775 DPRINT1("SMSS: Failed writing %wZ environment variable - %x\n",
1776 &ValueName, Status);
1778 return Status;
1779 }
1780
1781 /* Next, let's write the CPU architecture variable */
1782 RtlInitUnicodeString(&ValueName, L"PROCESSOR_ARCHITECTURE");
1783 switch (ProcessorInfo.ProcessorArchitecture)
1784 {
1785 /* Pick the correct string that matches the architecture */
1787 ValueData = L"x86";
1788 break;
1789
1791 ValueData = L"AMD64";
1792 break;
1793
1795 ValueData = L"IA64";
1796 break;
1797
1798 default:
1799 ValueData = L"Unknown";
1800 break;
1801 }
1802
1803 /* Set it */
1804 DPRINT("Setting %wZ to %S\n", &ValueName, ValueData);
1806 &ValueName,
1807 0,
1808 REG_SZ,
1809 ValueData,
1810 (ULONG)(wcslen(ValueData) + 1) * sizeof(WCHAR));
1811 if (!NT_SUCCESS(Status))
1812 {
1813 DPRINT1("SMSS: Failed writing %wZ environment variable - %x\n",
1814 &ValueName, Status);
1816 return Status;
1817 }
1818
1819 /* And now let's write the processor level */
1820 RtlInitUnicodeString(&ValueName, L"PROCESSOR_LEVEL");
1821 _swprintf(ValueBuffer, L"%u", ProcessorInfo.ProcessorLevel);
1822 DPRINT("Setting %wZ to %S\n", &ValueName, ValueBuffer);
1824 &ValueName,
1825 0,
1826 REG_SZ,
1827 ValueBuffer,
1828 (ULONG)(wcslen(ValueBuffer) + 1) * sizeof(WCHAR));
1829 if (!NT_SUCCESS(Status))
1830 {
1831 DPRINT1("SMSS: Failed writing %wZ environment variable - %x\n",
1832 &ValueName, Status);
1834 return Status;
1835 }
1836
1837 /* Now open the hardware CPU key */
1839 L"\\Registry\\Machine\\Hardware\\Description\\System\\"
1840 L"CentralProcessor\\0");
1844 NULL,
1845 NULL);
1846 Status = NtOpenKey(&KeyHandle2, KEY_READ, &ObjectAttributes);
1847 if (!NT_SUCCESS(Status))
1848 {
1849 DPRINT1("SMSS: Unable to open %wZ - %x\n", &DestinationString, Status);
1851 return Status;
1852 }
1853
1854 /* So that we can read the identifier out of it... */
1855 RtlInitUnicodeString(&ValueName, L"Identifier");
1856 Status = NtQueryValueKey(KeyHandle2,
1857 &ValueName,
1859 ValueBuffer,
1860 sizeof(ValueBuffer),
1861 &ResultLength);
1862 if (!NT_SUCCESS(Status) ||
1863 ((PartialInfo->Type != REG_SZ) && (PartialInfo->Type != REG_EXPAND_SZ)))
1864 {
1865 NtClose(KeyHandle2);
1867 DPRINT1("SMSS: Unable to read %wZ\\%wZ (Type %lu, Status 0x%x)\n",
1869 (NT_SUCCESS(Status) ? PartialInfo->Type : REG_NONE), Status);
1870 return Status;
1871 }
1872
1873 /* Initialize the string so that it can be large enough
1874 * to contain both the identifier and the vendor strings. */
1875 RtlInitEmptyUnicodeString(&DestinationString,
1876 (PWCHAR)PartialInfo->Data,
1877 sizeof(ValueBuffer) -
1880 PartialInfo->DataLength,
1881 &StrLength);
1882 DestinationString.Length = (USHORT)StrLength;
1883
1884 /* As well as the vendor... */
1885 RtlInitUnicodeString(&ValueName, L"VendorIdentifier");
1886 Status = NtQueryValueKey(KeyHandle2,
1887 &ValueName,
1889 ValueBuffer2,
1890 sizeof(ValueBuffer2),
1891 &ResultLength);
1892 NtClose(KeyHandle2);
1893 if (NT_SUCCESS(Status) &&
1894 ((PartialInfo2->Type == REG_SZ) || (PartialInfo2->Type == REG_EXPAND_SZ)))
1895 {
1896 /* To combine it into a single string */
1899 L", %.*s",
1900 PartialInfo2->DataLength / sizeof(WCHAR),
1901 (PWCHAR)PartialInfo2->Data);
1903 }
1904
1905 /* So that we can set this as the PROCESSOR_IDENTIFIER variable */
1906 RtlInitUnicodeString(&ValueName, L"PROCESSOR_IDENTIFIER");
1907 DPRINT("Setting %wZ to %wZ\n", &ValueName, &DestinationString);
1909 &ValueName,
1910 0,
1911 REG_SZ,
1914 if (!NT_SUCCESS(Status))
1915 {
1916 DPRINT1("SMSS: Failed writing %wZ environment variable - %x\n",
1917 &ValueName, Status);
1919 return Status;
1920 }
1921
1922 /* Now let's get the processor architecture */
1923 RtlInitUnicodeString(&ValueName, L"PROCESSOR_REVISION");
1924 switch (ProcessorInfo.ProcessorArchitecture)
1925 {
1926 /* Check if this is an older Intel CPU */
1928 if ((ProcessorInfo.ProcessorRevision >> 8) == 0xFF)
1929 {
1930 /* These guys used a revision + stepping, so get the rev only */
1931 _swprintf(ValueBuffer, L"%02x", ProcessorInfo.ProcessorRevision & 0xFF);
1932 _wcsupr(ValueBuffer);
1933 break;
1934 }
1935
1936 /* Modern Intel, as well as 64-bit CPUs use a revision without stepping */
1939 _swprintf(ValueBuffer, L"%04x", ProcessorInfo.ProcessorRevision);
1940 break;
1941
1942 /* And anything else we'll just read the whole revision identifier */
1943 default:
1944 _swprintf(ValueBuffer, L"%u", ProcessorInfo.ProcessorRevision);
1945 break;
1946 }
1947
1948 /* Write the revision to the registry */
1949 DPRINT("Setting %wZ to %S\n", &ValueName, ValueBuffer);
1951 &ValueName,
1952 0,
1953 REG_SZ,
1954 ValueBuffer,
1955 (ULONG)(wcslen(ValueBuffer) + 1) * sizeof(WCHAR));
1956 if (!NT_SUCCESS(Status))
1957 {
1958 DPRINT1("SMSS: Failed writing %wZ environment variable - %x\n",
1959 &ValueName, Status);
1961 return Status;
1962 }
1963
1964 /* And finally, write the number of CPUs */
1965 RtlInitUnicodeString(&ValueName, L"NUMBER_OF_PROCESSORS");
1966 _swprintf(ValueBuffer, L"%d", BasicInfo.NumberOfProcessors);
1967 DPRINT("Setting %wZ to %S\n", &ValueName, ValueBuffer);
1969 &ValueName,
1970 0,
1971 REG_SZ,
1972 ValueBuffer,
1973 (ULONG)(wcslen(ValueBuffer) + 1) * sizeof(WCHAR));
1974 if (!NT_SUCCESS(Status))
1975 {
1976 DPRINT1("SMSS: Failed writing %wZ environment variable - %x\n",
1977 &ValueName, Status);
1979 return Status;
1980 }
1981
1982 /* Now we need to write the safeboot option key in a different format */
1984 L"\\Registry\\Machine\\System\\CurrentControlSet\\"
1985 L"Control\\Safeboot\\Option");
1989 NULL,
1990 NULL);
1992 if (NT_SUCCESS(Status))
1993 {
1994 /* This was indeed a safeboot, so check what kind of safeboot it was */
1995 RtlInitUnicodeString(&ValueName, L"OptionValue");
1996 Status = NtQueryValueKey(KeyHandle2,
1997 &ValueName,
1999 ValueBuffer,
2000 sizeof(ValueBuffer),
2001 &ResultLength);
2002 NtClose(KeyHandle2);
2003 if (NT_SUCCESS(Status) &&
2004 (PartialInfo->Type == REG_DWORD) &&
2005 (PartialInfo->DataLength >= sizeof(ULONG)))
2006 {
2007 /* Convert from the integer value to the correct specifier */
2008 RtlInitUnicodeString(&ValueName, L"SAFEBOOT_OPTION");
2009 switch (*(PULONG)PartialInfo->Data)
2010 {
2011 case 1:
2012 wcscpy(ValueBuffer, L"MINIMAL");
2013 break;
2014 case 2:
2015 wcscpy(ValueBuffer, L"NETWORK");
2016 break;
2017 case 3:
2018 wcscpy(ValueBuffer, L"DSREPAIR");
2019 break;
2020 }
2021
2022 /* And write it in the environment! */
2023 DPRINT("Setting %wZ to %S\n", &ValueName, ValueBuffer);
2025 &ValueName,
2026 0,
2027 REG_SZ,
2028 ValueBuffer,
2029 (ULONG)(wcslen(ValueBuffer) + 1) * sizeof(WCHAR));
2030 if (!NT_SUCCESS(Status))
2031 {
2032 DPRINT1("SMSS: Failed writing %wZ environment variable - %x\n",
2033 &ValueName, Status);
2035 return Status;
2036 }
2037 }
2038 else
2039 {
2040 DPRINT1("SMSS: Failed to query SAFEBOOT option (Type %lu, Status 0x%x)\n",
2041 (NT_SUCCESS(Status) ? PartialInfo->Type : REG_NONE), Status);
2042 }
2043 }
2044
2045 /* We are all done now */
2047 return STATUS_SUCCESS;
2048}
@ SystemProcessorInformation
Definition: ntddk_ex.h:12
@ SystemBasicInformation
Definition: ntddk_ex.h:11
#define _swprintf(buf, format,...)
Definition: sprintf.c:56
_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 REG_NONE
Definition: nt_native.h:1495
#define GENERIC_WRITE
Definition: nt_native.h:90
#define REG_EXPAND_SZ
Definition: nt_native.h:1497
#define UNICODE_NULL
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
_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 998 of file sminit.c.

999{
1001 PSID WorldSid = NULL, AdminSid = NULL, SystemSid = NULL;
1002 PSID RestrictedSid = NULL, OwnerSid = NULL;
1006 ULONG AclLength, SidLength;
1007 PACL Acl;
1009 BOOLEAN ProtectionRequired = FALSE;
1010
1011 /* Check if this is the first call */
1012 if (InitialCall)
1013 {
1014 /* Create and set the primary descriptor */
1020 TRUE,
1021 NULL,
1022 FALSE);
1024
1025 /* Create and set the liberal descriptor */
1031 TRUE,
1032 NULL,
1033 FALSE);
1035
1036 /* Create and set the \KnownDlls descriptor */
1042 TRUE,
1043 NULL,
1044 FALSE);
1046
1047 /* Create and Set the \ApiPort descriptor */
1053 TRUE,
1054 NULL,
1055 FALSE);
1057 }
1058
1059 /* Check if protection was requested in the registry (on by default) */
1060 if (SmpProtectionMode & 1) ProtectionRequired = TRUE;
1061
1062 /* Exit if there's nothing to do */
1063 if (!(InitialCall || ProtectionRequired)) return STATUS_SUCCESS;
1064
1065 /* Build the world SID */
1068 0, 0, 0, 0, 0, 0, 0,
1069 &WorldSid);
1070 if (!NT_SUCCESS(Status))
1071 {
1072 WorldSid = NULL;
1073 goto Quickie;
1074 }
1075
1076 /* Build the admin SID */
1080 0, 0, 0, 0, 0, 0,
1081 &AdminSid);
1082 if (!NT_SUCCESS(Status))
1083 {
1084 AdminSid = NULL;
1085 goto Quickie;
1086 }
1087
1088 /* Build the owner SID */
1089 Status = RtlAllocateAndInitializeSid(&CreatorAuthority, 1,
1091 0, 0, 0, 0, 0, 0, 0,
1092 &OwnerSid);
1093 if (!NT_SUCCESS(Status))
1094 {
1095 OwnerSid = NULL;
1096 goto Quickie;
1097 }
1098
1099 /* Build the restricted SID */
1102 0, 0, 0, 0, 0, 0, 0,
1103 &RestrictedSid);
1104 if (!NT_SUCCESS(Status))
1105 {
1106 RestrictedSid = NULL;
1107 goto Quickie;
1108 }
1109
1110 /* Build the system SID */
1113 0, 0, 0, 0, 0, 0, 0,
1114 &SystemSid);
1115 if (!NT_SUCCESS(Status))
1116 {
1117 SystemSid = NULL;
1118 goto Quickie;
1119 }
1120
1121 /* Now check if we're creating the core descriptors */
1122 if (!InitialCall)
1123 {
1124 /* We're skipping NextAcl so we have to do this here */
1125 SidLength = RtlLengthSid(WorldSid) + RtlLengthSid(RestrictedSid) + RtlLengthSid(AdminSid);
1126 SidLength *= 2;
1127 goto NotInitial;
1128 }
1129
1130 /* Allocate an ACL with two ACEs with two SIDs each */
1131 SidLength = RtlLengthSid(SystemSid) + RtlLengthSid(AdminSid);
1132 AclLength = sizeof(ACL) + 2 * sizeof(ACCESS_ALLOWED_ACE) + SidLength;
1133 Acl = RtlAllocateHeap(RtlGetProcessHeap(), 0, AclLength);
1134 if (!Acl) Status = STATUS_NO_MEMORY;
1135 if (!NT_SUCCESS(Status)) goto NextAcl;
1136
1137 /* Now build the ACL and add the two ACEs */
1144
1145 /* Set this as the DACL */
1147 TRUE,
1148 Acl,
1149 FALSE);
1151
1152NextAcl:
1153 /* Allocate an ACL with 6 ACEs, two ACEs per SID */
1154 SidLength = RtlLengthSid(WorldSid) + RtlLengthSid(RestrictedSid) + RtlLengthSid(AdminSid);
1155 SidLength *= 2;
1156 AclLength = sizeof(ACL) + 6 * sizeof(ACCESS_ALLOWED_ACE) + SidLength;
1157 Acl = RtlAllocateHeap(RtlGetProcessHeap(), 0, AclLength);
1158 if (!Acl) Status = STATUS_NO_MEMORY;
1159 if (!NT_SUCCESS(Status)) goto NotInitial;
1160
1161 /* Now build the ACL and add the six ACEs */
1176
1177 /* Now edit the last three ACEs and make them inheritable */
1178 Status = RtlGetAce(Acl, 3, (PVOID)&Ace);
1181 Status = RtlGetAce(Acl, 4, (PVOID)&Ace);
1184 Status = RtlGetAce(Acl, 5, (PVOID)&Ace);
1187
1188 /* Set this as the DACL */
1190 TRUE,
1191 Acl,
1192 FALSE);
1194
1195NotInitial:
1196 /* The initial ACLs have been created, are we also protecting objects? */
1197 if (!ProtectionRequired) goto Quickie;
1198
1199 /* Allocate an ACL with 7 ACEs, two ACEs per SID, and one final owner ACE */
1200 SidLength += RtlLengthSid(OwnerSid);
1201 AclLength = sizeof(ACL) + 7 * sizeof (ACCESS_ALLOWED_ACE) + 2 * SidLength;
1202 Acl = RtlAllocateHeap(RtlGetProcessHeap(), 0, AclLength);
1203 if (!Acl) Status = STATUS_NO_MEMORY;
1204 if (!NT_SUCCESS(Status)) goto Quickie;
1205
1206 /* Build the ACL and add the seven ACEs */
1223
1224 /* Edit the last 4 ACEs to make then inheritable */
1225 Status = RtlGetAce(Acl, 3, (PVOID)&Ace);
1228 Status = RtlGetAce(Acl, 4, (PVOID)&Ace);
1231 Status = RtlGetAce(Acl, 5, (PVOID)&Ace);
1234 Status = RtlGetAce(Acl, 6, (PVOID)&Ace);
1237
1238 /* Set this as the DACL for the primary SD */
1240 TRUE,
1241 Acl,
1242 FALSE);
1244
1245 /* Allocate an ACL with 7 ACEs, two ACEs per SID, and one final owner ACE */
1246 AclLength = sizeof(ACL) + 7 * sizeof (ACCESS_ALLOWED_ACE) + 2 * SidLength;
1247 Acl = RtlAllocateHeap(RtlGetProcessHeap(), 0, AclLength);
1248 if (!Acl) Status = STATUS_NO_MEMORY;
1249 if (!NT_SUCCESS(Status)) goto Quickie;
1250
1251 /* Build the ACL and add the seven ACEs */
1268
1269 /* Edit the last 4 ACEs to make then inheritable */
1270 Status = RtlGetAce(Acl, 3, (PVOID)&Ace);
1273 Status = RtlGetAce(Acl, 4, (PVOID)&Ace);
1276 Status = RtlGetAce(Acl, 5, (PVOID)&Ace);
1279 Status = RtlGetAce(Acl, 6, (PVOID)&Ace);
1282
1283 /* Now set this as the DACL for the liberal SD */
1285 TRUE,
1286 Acl,
1287 FALSE);
1289
1290Quickie:
1291 /* Cleanup the SIDs */
1292 if (OwnerSid) RtlFreeHeap(RtlGetProcessHeap(), 0, OwnerSid);
1293 if (AdminSid) RtlFreeHeap(RtlGetProcessHeap(), 0, AdminSid);
1294 if (WorldSid) RtlFreeHeap(RtlGetProcessHeap(), 0, WorldSid);
1295 if (SystemSid) RtlFreeHeap(RtlGetProcessHeap(), 0, SystemSid);
1296 if (RestrictedSid) RtlFreeHeap(RtlGetProcessHeap(), 0, RestrictedSid);
1297 return Status;
1298}
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:5216
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 2473 of file sminit.c.

2475{
2476 NTSTATUS Status, Status2;
2478 UNICODE_STRING PortName, EventName;
2479 HANDLE EventHandle, PortHandle;
2480 ULONG HardErrorMode;
2481
2482 /* Create the SMSS Heap */
2483 SmBaseTag = RtlCreateTagHeap(RtlGetProcessHeap(),
2484 0,
2485 L"SMSS!",
2486 L"INIT");
2487 SmpHeap = RtlGetProcessHeap();
2488
2489 /* Enable hard errors */
2490 HardErrorMode = TRUE;
2493 &HardErrorMode,
2494 sizeof(HardErrorMode));
2495
2496 /* Initialize the subsystem list and the session list, plus their locks */
2501
2502 /* Initialize the process list */
2504
2505 /* Initialize session parameters */
2506 SmpNextSessionId = 1;
2509
2510 /* Create the initial security descriptors */
2512 if (!NT_SUCCESS(Status))
2513 {
2514 /* Fail */
2516 return Status;
2517 }
2518
2519 /* Initialize subsystem names */
2520 RtlInitUnicodeString(&SmpSubsystemName, L"NT-Session Manager");
2523
2524 /* Create the SM API Port */
2525 RtlInitUnicodeString(&PortName, L"\\SmApiPort");
2527 Status = NtCreatePort(&PortHandle,
2529 sizeof(SB_CONNECTION_INFO),
2530 sizeof(SM_API_MSG),
2531 sizeof(SB_API_MSG) * 32);
2533 SmpDebugPort = PortHandle;
2534
2535 /* Create two SM API threads */
2537 NULL,
2538 FALSE,
2539 0,
2540 0,
2541 0,
2542 SmpApiLoop,
2543 PortHandle,
2544 NULL,
2545 NULL);
2548 NULL,
2549 FALSE,
2550 0,
2551 0,
2552 0,
2553 SmpApiLoop,
2554 PortHandle,
2555 NULL,
2556 NULL);
2558
2559 /* Create the write event that autochk can set after running */
2560 RtlInitUnicodeString(&EventName, L"\\Device\\VolumesSafeForWriteAccess");
2562 &EventName,
2564 NULL,
2565 NULL);
2566 Status2 = NtCreateEvent(&EventHandle,
2569 0,
2570 0);
2571 if (!NT_SUCCESS(Status2))
2572 {
2573 /* Should never really fail */
2574 DPRINT1("SMSS: Unable to create %wZ event - Status == %lx\n",
2575 &EventName, Status2);
2576 ASSERT(NT_SUCCESS(Status2));
2577 }
2578
2579 /* Now initialize everything else based on the registry parameters */
2580 Status = SmpLoadDataFromRegistry(InitialCommand);
2581 if (NT_SUCCESS(Status))
2582 {
2583 /* Autochk should've run now. Set the event and save the CSRSS handle */
2587 }
2588
2589 /* All done */
2590 return Status;
2591}
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:407
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:1422
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:2267
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 1302 of file sminit.c.

1303{
1305 PSMP_REGISTRY_VALUE RegEntry;
1306 SECURITY_DESCRIPTOR_CONTROL OldFlag = 0;
1308 UNICODE_STRING GlobalName;
1309 HANDLE DirHandle;
1310 PLIST_ENTRY NextEntry, Head;
1311
1312 /* Open the \GLOBAL?? directory */
1313 RtlInitUnicodeString(&GlobalName, L"\\??");
1315 &GlobalName,
1317 NULL,
1318 NULL);
1322 if (!NT_SUCCESS(Status))
1323 {
1324 DPRINT1("SMSS: Unable to open %wZ directory - Status == %lx\n",
1325 &GlobalName, Status);
1326 return Status;
1327 }
1328
1329 /* Loop the DOS devices */
1330 Head = &SmpDosDevicesList;
1331 while (!IsListEmpty(Head))
1332 {
1333 /* Get the entry and remove it */
1334 NextEntry = RemoveHeadList(Head);
1335 RegEntry = CONTAINING_RECORD(NextEntry, SMP_REGISTRY_VALUE, Entry);
1336
1337 /* Initialize the attributes, and see which descriptor is being used */
1339 &RegEntry->Name,
1344 {
1345 /* Save the old flag and set it while we create this link */
1348 }
1349
1350 /* Create the symbolic link */
1351 DPRINT("Creating symlink for %wZ to %wZ\n", &RegEntry->Name, &RegEntry->Value);
1355 &RegEntry->Value);
1357 {
1358 /* Make it temporary and get rid of the handle */
1359 NtMakeTemporaryObject(DirHandle);
1360 NtClose(DirHandle);
1361
1362 /* Treat this as success, and see if we got a name back */
1364 if (RegEntry->Value.Length)
1365 {
1366 /* Create it now with this name */
1367 ObjectAttributes.Attributes &= ~OBJ_OPENIF;
1371 &RegEntry->Value);
1372 }
1373 }
1374
1375 /* If we were using a security descriptor, restore the non-defaulted flag */
1376 if (ObjectAttributes.SecurityDescriptor)
1377 {
1379 }
1380
1381 /* Print a failure if we failed to create the symbolic link */
1382 if (!NT_SUCCESS(Status))
1383 {
1384 DPRINT1("SMSS: Unable to create %wZ => %wZ symbolic link object - Status == 0x%lx\n",
1385 &RegEntry->Name,
1386 &RegEntry->Value,
1387 Status);
1388 break;
1389 }
1390
1391 /* Close the handle */
1392 NtClose(DirHandle);
1393
1394 /* Free this entry */
1395 if (RegEntry->AnsiValue) RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry->AnsiValue);
1396 if (RegEntry->Value.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry->Value.Buffer);
1397 RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry);
1398 }
1399
1400 /* Return the status */
1401 return Status;
1402}
#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:1474
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 451 of file sminit.c.

454{
456
457 /* Allocate the buffer */
458 DllPath->Buffer = RtlAllocateHeap(RtlGetProcessHeap(), SmBaseTag, Length);
459 if (DllPath->Buffer)
460 {
461 /* Fill out the rest of the string */
462 DllPath->MaximumLength = (USHORT)Length;
463 DllPath->Length = (USHORT)Length - sizeof(UNICODE_NULL);
464
465 /* Copy the actual path and return success */
468 }
469 else
470 {
471 /* Fail with out of memory code */
473 }
474
475 /* Return result */
476 return Status;
477}
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 1675 of file sminit.c.

1676{
1678 PSMP_REGISTRY_VALUE RegEntry;
1679 UNICODE_STRING KnownDllsName;
1680 PLIST_ENTRY Head, NextEntry;
1681
1682 /* Call the internal function */
1683 RtlInitUnicodeString(&KnownDllsName, L"\\KnownDlls");
1685
1686 /* Wipe out the list regardless of success */
1687 Head = &SmpKnownDllsList;
1688 while (!IsListEmpty(Head))
1689 {
1690 /* Remove this entry */
1691 NextEntry = RemoveHeadList(Head);
1692
1693 /* Free it */
1694 RegEntry = CONTAINING_RECORD(NextEntry, SMP_REGISTRY_VALUE, Entry);
1695 RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry->AnsiValue);
1696 RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry->Value.Buffer);
1697 RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry);
1698 }
1699
1700 /* All done */
1701 return Status;
1702}
LIST_ENTRY SmpKnownDllsList
Definition: sminit.c:21
NTSTATUS NTAPI SmpInitializeKnownDllsInternal(IN PUNICODE_STRING Directory, IN PUNICODE_STRING Path)
Definition: sminit.c:1448

Referenced by SmpLoadDataFromRegistry().

◆ SmpInitializeKnownDllsInternal()

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

Definition at line 1448 of file sminit.c.

1450{
1451 HANDLE DirFileHandle, DirHandle, SectionHandle, FileHandle, LinkHandle;
1452 UNICODE_STRING NtPath, SymLinkName;
1454 NTSTATUS Status, Status1;
1455 PLIST_ENTRY NextEntry;
1456 PSMP_REGISTRY_VALUE RegEntry;
1457 ULONG_PTR ErrorParameters[3];
1458 UNICODE_STRING ErrorResponse;
1460 SECURITY_DESCRIPTOR_CONTROL OldFlag = 0;
1461 USHORT ImageCharacteristics;
1462
1463 /* Initialize to NULL */
1464 DirFileHandle = NULL;
1465 DirHandle = NULL;
1466 NtPath.Buffer = NULL;
1467
1468 /* Create the \KnownDLLs directory */
1470 Directory,
1472 NULL,
1474 Status = NtCreateDirectoryObject(&DirHandle,
1477 if (!NT_SUCCESS(Status))
1478 {
1479 /* Handle failure */
1480 DPRINT1("SMSS: Unable to create %wZ directory - Status == %lx\n",
1481 Directory, Status);
1482 return Status;
1483 }
1484
1485 /* Convert the path to native format */
1486 if (!RtlDosPathNameToNtPathName_U(Path->Buffer, &NtPath, NULL, NULL))
1487 {
1488 /* Fail if this didn't work */
1489 DPRINT1("SMSS: Unable to to convert %wZ to an Nt path\n", Path);
1491 goto Quickie;
1492 }
1493
1494 /* Open the path that was specified, which should be a directory */
1496 &NtPath,
1498 NULL,
1499 NULL);
1500 Status = NtOpenFile(&DirFileHandle,
1506 if (!NT_SUCCESS(Status))
1507 {
1508 /* Fail if we couldn't open it */
1509 DPRINT1("SMSS: Unable to open a handle to the KnownDll directory (%wZ)"
1510 "- Status == %lx\n",
1511 Path,
1512 Status);
1513 FileHandle = NULL;
1514 goto Quickie;
1515 }
1516
1517 /* Temporarily hack the SD to use a default DACL for this symbolic link */
1519 {
1522 }
1523
1524 /* Create a symbolic link to the directory in the object manager */
1525 RtlInitUnicodeString(&SymLinkName, L"KnownDllPath");
1527 &SymLinkName,
1529 DirHandle,
1531 Status = NtCreateSymbolicLinkObject(&LinkHandle,
1534 Path);
1535
1536 /* Undo the hack */
1538
1539 /* Check if the symlink was created */
1540 if (!NT_SUCCESS(Status))
1541 {
1542 /* It wasn't, so bail out since the OS needs it to exist */
1543 DPRINT1("SMSS: Unable to create %wZ symbolic link - Status == %lx\n",
1544 &SymLinkName, Status);
1545 LinkHandle = NULL;
1546 goto Quickie;
1547 }
1548
1549 /* We created it permanent, we can go ahead and close the handle now */
1550 Status1 = NtClose(LinkHandle);
1551 ASSERT(NT_SUCCESS(Status1));
1552
1553 /* Now loop the known DLLs */
1554 NextEntry = SmpKnownDllsList.Flink;
1555 while (NextEntry != &SmpKnownDllsList)
1556 {
1557 /* Get the entry and move on */
1558 RegEntry = CONTAINING_RECORD(NextEntry, SMP_REGISTRY_VALUE, Entry);
1559 NextEntry = NextEntry->Flink;
1560
1561 DPRINT("Processing known DLL: %wZ-%wZ\n", &RegEntry->Name, &RegEntry->Value);
1562
1563 /* Skip the entry if it's in the excluded list */
1565 RegEntry->Name.Buffer)) ||
1567 RegEntry->Value.Buffer)))
1568 {
1569 continue;
1570 }
1571
1572 /* Open the actual file */
1574 &RegEntry->Value,
1576 DirFileHandle,
1577 NULL);
1578 Status1 = NtOpenFile(&FileHandle,
1585 /* If we failed, skip it */
1586 if (!NT_SUCCESS(Status1)) continue;
1587
1588 /* Checksum it */
1591 RegEntry,
1592 &ImageCharacteristics);
1593 if (!NT_SUCCESS(Status))
1594 {
1595 /* Checksum failed, so don't even try going further -- kill SMSS */
1596 RtlInitUnicodeString(&ErrorResponse,
1597 L"Verification of a KnownDLL failed.");
1598 ErrorParameters[0] = (ULONG_PTR)&ErrorResponse;
1599 ErrorParameters[1] = Status;
1600 ErrorParameters[2] = (ULONG_PTR)&RegEntry->Value;
1601 SmpTerminate(ErrorParameters, 5, RTL_NUMBER_OF(ErrorParameters));
1602 }
1603 else if (!(ImageCharacteristics & IMAGE_FILE_DLL))
1604 {
1605 /* An invalid known DLL entry will also kill SMSS */
1606 RtlInitUnicodeString(&ErrorResponse,
1607 L"Non-DLL file included in KnownDLL list.");
1608 ErrorParameters[0] = (ULONG_PTR)&ErrorResponse;
1609 ErrorParameters[1] = STATUS_INVALID_IMPORT_OF_NON_DLL;
1610 ErrorParameters[2] = (ULONG_PTR)&RegEntry->Value;
1611 SmpTerminate(ErrorParameters, 5, RTL_NUMBER_OF(ErrorParameters));
1612 }
1613
1614 /* Temporarily hack the SD to use a default DACL for this section */
1616 {
1619 }
1620
1621 /* Create the section for this known DLL */
1623 &RegEntry->Value,
1625 DirHandle,
1627 Status = NtCreateSection(&SectionHandle,
1630 0,
1632 SEC_IMAGE,
1633 FileHandle);
1634
1635 /* Undo the hack */
1637
1638 /* Check if we created the section okay */
1639 if (NT_SUCCESS(Status))
1640 {
1641 /* We can close it now, since it's marked permanent */
1642 Status1 = NtClose(SectionHandle);
1643 ASSERT(NT_SUCCESS(Status1));
1644 }
1645 else
1646 {
1647 /* If we couldn't make it "known", that's fine and keep going */
1648 DPRINT1("SMSS: CreateSection for KnownDll %wZ failed - Status == %lx\n",
1649 &RegEntry->Value, Status);
1650 }
1651
1652 /* Close the file since we can move on to the next one */
1653 Status1 = NtClose(FileHandle);
1654 ASSERT(NT_SUCCESS(Status1));
1655 }
1656
1657Quickie:
1658 /* Close both handles and free the NT path buffer */
1659 if (DirHandle)
1660 {
1661 Status1 = NtClose(DirHandle);
1662 ASSERT(NT_SUCCESS(Status1));
1663 }
1664 if (DirFileHandle)
1665 {
1666 Status1 = NtClose(DirFileHandle);
1667 ASSERT(NT_SUCCESS(Status1));
1668 }
1669 if (NtPath.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, NtPath.Buffer);
1670 return Status;
1671}
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:3090
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:818
#define SEC_IMAGE
Definition: mmtypes.h:97
_In_ BOOLEAN _In_ USHORT Directory
Definition: rtlfuncs.h:3962
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:3951
#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:100
#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:1406
NTSTATUS NTAPI SmpTerminate(IN PULONG_PTR Parameters, IN ULONG ParameterMask, IN ULONG ParameterCount)
Definition: smss.c:371
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 2267 of file sminit.c.

2268{
2270 PLIST_ENTRY Head, NextEntry;
2271 PSMP_REGISTRY_VALUE RegEntry;
2272 PVOID OriginalEnvironment;
2273 ULONG MuSessionId = 0;
2277
2278 /* Initialize the keywords we'll be looking for */
2282
2283 /* Initialize all the registry-associated list heads */
2295
2297
2298 /* Initialize the SMSS environment */
2300 if (!NT_SUCCESS(Status))
2301 {
2302 /* Fail if there was a problem */
2303 DPRINT1("SMSS: Unable to allocate default environment - Status == %X\n",
2304 Status);
2306 return Status;
2307 }
2308
2309 /* Check if we were booted in PE mode (LiveCD should have this) */
2311 L"\\Registry\\Machine\\System\\CurrentControlSet\\"
2312 L"Control\\MiniNT");
2316 NULL,
2317 NULL);
2319 if (NT_SUCCESS(Status))
2320 {
2321 /* If the key exists, we were */
2323 MiniNTBoot = TRUE;
2324 }
2325
2326 /* Print out if this is the case */
2327 if (MiniNTBoot) DPRINT("SMSS: !!! MiniNT Boot !!!\n");
2328
2329 /* Open the environment key to see if we are booted in safe mode */
2331 L"\\Registry\\Machine\\System\\CurrentControlSet\\"
2332 L"Control\\Session Manager\\Environment");
2336 NULL,
2337 NULL);
2339 if (NT_SUCCESS(Status))
2340 {
2341 /* Delete the value if we found it */
2342 RtlInitUnicodeString(&DestinationString, L"SAFEBOOT_OPTION");
2345 }
2346
2347 /* Switch environments, then query the registry for all needed settings */
2348 OriginalEnvironment = NtCurrentPeb()->ProcessParameters->Environment;
2349 NtCurrentPeb()->ProcessParameters->Environment = SmpDefaultEnvironment;
2351 L"Session Manager",
2353 NULL,
2354 NULL);
2355 SmpDefaultEnvironment = NtCurrentPeb()->ProcessParameters->Environment;
2356 NtCurrentPeb()->ProcessParameters->Environment = OriginalEnvironment;
2357 if (!NT_SUCCESS(Status))
2358 {
2359 /* We failed somewhere in registry initialization, which is bad... */
2360 DPRINT1("SMSS: RtlQueryRegistryValues failed - Status == %lx\n", Status);
2362 return Status;
2363 }
2364
2365 /* Now we can start acting on the registry settings. First to DOS devices */
2367 if (!NT_SUCCESS(Status))
2368 {
2369 /* Failed */
2370 DPRINT1("SMSS: Unable to initialize DosDevices configuration - Status == %lx\n",
2371 Status);
2373 return Status;
2374 }
2375
2376 /* Next create the session directory... */
2381 NULL,
2386 if (!NT_SUCCESS(Status))
2387 {
2388 /* Fail */
2389 DPRINT1("SMSS: Unable to create %wZ object directory - Status == %lx\n",
2392 return Status;
2393 }
2394
2395 /* Next loop all the boot execute binaries */
2396 Head = &SmpBootExecuteList;
2397 while (!IsListEmpty(Head))
2398 {
2399 /* Remove each one from the list */
2400 NextEntry = RemoveHeadList(Head);
2401
2402 /* Execute it */
2403 RegEntry = CONTAINING_RECORD(NextEntry, SMP_REGISTRY_VALUE, Entry);
2404 SmpExecuteCommand(&RegEntry->Name, 0, NULL, 0);
2405
2406 /* And free it */
2407 if (RegEntry->AnsiValue) RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry->AnsiValue);
2408 if (RegEntry->Value.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry->Value.Buffer);
2409 RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry);
2410 }
2411
2412 /* Now do any pending file rename operations... */
2414
2415 /* And initialize known DLLs... */
2417 if (!NT_SUCCESS(Status))
2418 {
2419 /* Fail if that didn't work */
2420 DPRINT1("SMSS: Unable to initialize KnownDll configuration - Status == %lx\n",
2421 Status);
2423 return Status;
2424 }
2425
2426 /* Create the needed page files */
2427 if (!MiniNTBoot)
2428 {
2429 /* Loop every page file */
2430 Head = &SmpPagingFileList;
2431 while (!IsListEmpty(Head))
2432 {
2433 /* Remove each one from the list */
2434 NextEntry = RemoveHeadList(Head);
2435
2436 /* Create the descriptor for it */
2437 RegEntry = CONTAINING_RECORD(NextEntry, SMP_REGISTRY_VALUE, Entry);
2439
2440 /* And free it */
2441 if (RegEntry->AnsiValue) RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry->AnsiValue);
2442 if (RegEntry->Value.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry->Value.Buffer);
2443 RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry);
2444 }
2445
2446 /* Now create all the paging files for the descriptors that we have */
2448 }
2449
2450 /* Tell Cm it's now safe to fully enable write access to the registry */
2452
2453 /* Create all the system-based environment variables for later inheriting */
2455 if (!NT_SUCCESS(Status))
2456 {
2457 /* Handle failure */
2459 return Status;
2460 }
2461
2462 /* And finally load all the subsystems for our first session! */
2465 InitialCommand);
2466 ASSERT(MuSessionId == 0);
2468 return Status;
2469}
#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)
Definition: env.c:31
#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:2052
LIST_ENTRY SmpFileRenameList
Definition: sminit.c:20
PWCHAR SmpDefaultEnvironment
Definition: sminit.c:28
NTSTATUS NTAPI SmpCreateDynamicEnvironmentVariables(VOID)
Definition: sminit.c:1706
NTSTATUS NTAPI SmpInitializeDosDevices(VOID)
Definition: sminit.c:1302
NTSTATUS NTAPI SmpInitializeKnownDlls(VOID)
Definition: sminit.c:1675
LIST_ENTRY SmpSetupExecuteList
Definition: sminit.c:19
RTL_QUERY_REGISTRY_TABLE SmpRegistryConfigurationTable[]
Definition: sminit.c:625
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:207
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:29
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 2052 of file sminit.c.

2053{
2054 BOOLEAN OldState, HavePrivilege = FALSE;
2056 HANDLE FileHandle, OtherFileHandle;
2060 UNICODE_STRING FileString;
2061 FILE_BASIC_INFORMATION BasicInfo;
2062 FILE_DISPOSITION_INFORMATION DeleteInformation;
2064 PLIST_ENTRY Head, NextEntry;
2065 PSMP_REGISTRY_VALUE RegEntry;
2068
2069 /* Give us access to restore any files we want */
2071 if (NT_SUCCESS(Status)) HavePrivilege = TRUE;
2072
2073 // FIXME: Handle SFC-protected file renames!
2075 DPRINT1("SMSS: FIXME: Handle SFC-protected file renames!\n");
2076
2077 /* Process pending files to rename */
2078 Head = &SmpFileRenameList;
2079 while (!IsListEmpty(Head))
2080 {
2081 /* Get this entry */
2082 NextEntry = RemoveHeadList(Head);
2083 RegEntry = CONTAINING_RECORD(NextEntry, SMP_REGISTRY_VALUE, Entry);
2084 DPRINT("Processing PFRO: '%wZ' / '%wZ'\n", &RegEntry->Value, &RegEntry->Name);
2085
2086 /* Skip past the '@' marker */
2087 if (!(RegEntry->Value.Length) && (*RegEntry->Name.Buffer == L'@'))
2088 {
2089 RegEntry->Name.Length -= sizeof(UNICODE_NULL);
2090 RegEntry->Name.Buffer++;
2091 }
2092
2093 /* Open the file for delete access */
2095 &RegEntry->Name,
2097 NULL,
2098 NULL);
2099 Status = NtOpenFile(&OtherFileHandle,
2105 if (!NT_SUCCESS(Status)) goto Quickie;
2106
2107 /* Check if it's a rename or just a delete */
2108 ValueLength = RegEntry->Value.Length;
2109 if (!ValueLength)
2110 {
2111 /* Just a delete, set up the class, length and buffer */
2113 Length = sizeof(DeleteInformation);
2114 Buffer = (PFILE_RENAME_INFORMATION)&DeleteInformation;
2115
2116 /* Set the delete disposition */
2117 DeleteInformation.DeleteFile = TRUE;
2118 }
2119 else
2120 {
2121 /* This is a rename, setup the class and length */
2124
2125 /* Skip past the special markers */
2126 FileName = RegEntry->Value.Buffer;
2127 if ((*FileName == L'!') || (*FileName == L'@'))
2128 {
2129 FileName++;
2130 Length -= sizeof(UNICODE_NULL);
2131 }
2132
2133 /* Now allocate the buffer for the rename information */
2134 Buffer = RtlAllocateHeap(RtlGetProcessHeap(), SmBaseTag, Length);
2135 if (Buffer)
2136 {
2137 /* Setup the buffer to point to the filename, and copy it */
2138 Buffer->RootDirectory = NULL;
2139 Buffer->FileNameLength = Length - sizeof(FILE_RENAME_INFORMATION);
2140 Buffer->ReplaceIfExists = FileName != RegEntry->Value.Buffer;
2141 RtlCopyMemory(Buffer->FileName, FileName, Buffer->FileNameLength);
2142 }
2143 else
2144 {
2145 /* Fail */
2147 }
2148 }
2149
2150 /* Check if everything is okay till here */
2151 if (NT_SUCCESS(Status))
2152 {
2153 /* Now either rename or delete the file as requested */
2154 Status = NtSetInformationFile(OtherFileHandle,
2156 Buffer,
2157 Length,
2159
2160 /* Check if we seem to have failed because the file was readonly */
2161 if (!NT_SUCCESS(Status) &&
2164 Buffer->ReplaceIfExists)
2165 {
2166 /* Open the file for write attribute access this time... */
2167 DPRINT("\nSMSS: '%wZ' => '%wZ' failed - Status == %x, Possible readonly target\n",
2168 &RegEntry->Name,
2169 &RegEntry->Value,
2171 FileString.Length = RegEntry->Value.Length - sizeof(WCHAR);
2172 FileString.MaximumLength = RegEntry->Value.MaximumLength - sizeof(WCHAR);
2173 FileString.Buffer = FileName;
2175 &FileString,
2177 NULL,
2178 NULL);
2185 if (!NT_SUCCESS(Status))
2186 {
2187 /* That didn't work, so bail out */
2188 DPRINT1(" SMSS: Open Existing file Failed - Status == %x\n",
2189 Status);
2190 }
2191 else
2192 {
2193 /* Now remove the read-only attribute from the file */
2194 DPRINT(" SMSS: Open Existing Success\n");
2195 RtlZeroMemory(&BasicInfo, sizeof(BasicInfo));
2199 &BasicInfo,
2200 sizeof(BasicInfo),
2203 if (!NT_SUCCESS(Status))
2204 {
2205 /* That didn't work, bail out */
2206 DPRINT1(" SMSS: Set To NORMAL Failed - Status == %x\n",
2207 Status);
2208 }
2209 else
2210 {
2211 /* Now that the file is no longer read-only, delete! */
2212 DPRINT(" SMSS: Set To NORMAL OK\n");
2213 Status = NtSetInformationFile(OtherFileHandle,
2215 Buffer,
2216 Length,
2218 if (!NT_SUCCESS(Status))
2219 {
2220 /* That failed too! */
2221 DPRINT1(" SMSS: Re-Rename Failed - Status == %x\n",
2222 Status);
2223 }
2224 else
2225 {
2226 /* Everything ok */
2227 DPRINT(" SMSS: Re-Rename Worked OK\n");
2228 }
2229 }
2230 }
2231 }
2232 }
2233
2234 /* Close the file handle and check the operation result */
2235 NtClose(OtherFileHandle);
2236Quickie:
2237 if (!NT_SUCCESS(Status))
2238 {
2239 /* We totally failed */
2240 DPRINT1("SMSS: '%wZ' => '%wZ' failed - Status == %x\n",
2241 &RegEntry->Name, &RegEntry->Value, Status);
2242 }
2243 else if (RegEntry->Value.Length)
2244 {
2245 /* We succeed with a rename */
2246 DPRINT("SMSS: '%wZ' (renamed to) '%wZ'\n", &RegEntry->Name, &RegEntry->Value);
2247 }
2248 else
2249 {
2250 /* We succeeded with a delete */
2251 DPRINT("SMSS: '%wZ' (deleted)\n", &RegEntry->Name);
2252 }
2253
2254 /* Now free this entry and keep going */
2255 if (RegEntry->AnsiValue) RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry->AnsiValue);
2256 if (RegEntry->Value.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry->Value.Buffer);
2257 RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry);
2258 }
2259
2260 /* Put back the restore privilege if we had requested it, and return */
2261 if (HavePrivilege) RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, FALSE, FALSE, &OldState);
2262 return Status;
2263}
#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:572
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 1406 of file sminit.c.

1408{
1409 ULONG Length = 0;
1411 PWCHAR DllName, DllValue;
1412 ANSI_STRING ImportString;
1413 UNICODE_STRING ImportUnicodeString;
1415
1416 /* Skip NTDLL since it's already always mapped */
1417 if (!_stricmp(ImportName, "ntdll.dll")) return;
1418
1419 /* Initialize our strings */
1420 RtlInitAnsiString(&ImportString, ImportName);
1421 RtlInitEmptyUnicodeString(&ImportUnicodeString, Buffer, sizeof(Buffer));
1422 Status = RtlAnsiStringToUnicodeString(&ImportUnicodeString, &ImportString, FALSE);
1423 if (!NT_SUCCESS(Status)) return;
1424
1425 /* Loop to find the DLL file extension */
1426 while (Length < ImportUnicodeString.Length)
1427 {
1428 if (ImportUnicodeString.Buffer[Length / sizeof(WCHAR)] == L'.') break;
1429 Length += sizeof(WCHAR);
1430 }
1431
1432 /*
1433 * Break up the values as needed; the buffer acquires the form:
1434 * "dll_name.dll\0dll_name\0"
1435 */
1436 DllValue = ImportUnicodeString.Buffer;
1437 DllName = &ImportUnicodeString.Buffer[(ImportUnicodeString.Length + sizeof(UNICODE_NULL)) / sizeof(WCHAR)];
1438 RtlStringCbCopyNW(DllName,
1439 ImportUnicodeString.MaximumLength - (ImportUnicodeString.Length + sizeof(UNICODE_NULL)),
1440 ImportUnicodeString.Buffer, Length);
1441
1442 /* Add the DLL to the list */
1443 SmpSaveRegistryValue(&SmpKnownDllsList, DllName, DllValue, TRUE);
1444}
#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(), SmpConfigureExecute(), SmpConfigureFileRenames(), SmpConfigureKnownDlls(), SmpConfigureMemoryMgmt(), SmpConfigureSubSystems(), and SmpProcessModuleImports().

◆ SmpTranslateSystemPartitionInformation()

VOID NTAPI SmpTranslateSystemPartitionInformation ( VOID  )

Definition at line 832 of file sminit.c.

833{
837 HANDLE KeyHandle, LinkHandle;
839 size_t StrLength;
840 WCHAR LinkBuffer[MAX_PATH];
841 struct { KEY_VALUE_PARTIAL_INFORMATION; CHAR Buffer[512]; } ValueBuffer;
842 struct { OBJECT_DIRECTORY_INFORMATION; WCHAR Buffer[256]; } DirInfoBuffer;
843 PKEY_VALUE_PARTIAL_INFORMATION PartialInfo = (PVOID)&ValueBuffer;
844 POBJECT_DIRECTORY_INFORMATION DirInfo = (PVOID)&DirInfoBuffer;
845
846 /* Open the setup key */
847 RtlInitUnicodeString(&UnicodeString, L"\\Registry\\Machine\\System\\Setup");
851 NULL,
852 NULL);
854 if (!NT_SUCCESS(Status))
855 {
856 DPRINT1("SMSS: Cannot open system setup key for reading: 0x%x\n", Status);
857 return;
858 }
859
860 /* Query the system partition */
861 RtlInitUnicodeString(&UnicodeString, L"SystemPartition");
865 &ValueBuffer,
866 sizeof(ValueBuffer),
867 &Length);
869 if (!NT_SUCCESS(Status) ||
870 ((PartialInfo->Type != REG_SZ) && (PartialInfo->Type != REG_EXPAND_SZ)))
871 {
872 DPRINT1("SMSS: Cannot query SystemPartition value (Type %lu, Status 0x%x)\n",
873 (NT_SUCCESS(Status) ? PartialInfo->Type : REG_NONE), Status);
874 return;
875 }
876
877 /* Initialize the system partition string */
878 RtlInitEmptyUnicodeString(&SystemPartition,
879 (PWCHAR)PartialInfo->Data,
880 PartialInfo->DataLength);
882 SystemPartition.MaximumLength,
883 &StrLength);
884 SystemPartition.Length = (USHORT)StrLength;
885
886 /* Enumerate the directory looking for the symbolic link string */
887 RtlInitUnicodeString(&SymLinkU, L"SymbolicLink");
888 RtlInitEmptyUnicodeString(&LinkTarget, LinkBuffer, sizeof(LinkBuffer));
890 &DirInfoBuffer,
891 sizeof(DirInfoBuffer),
892 TRUE,
893 TRUE,
894 &Context,
895 NULL);
896 /* Keep searching until we find it */
897 while (NT_SUCCESS(Status))
898 {
899 /* Is this it? */
900 if (RtlEqualUnicodeString(&DirInfo->TypeName, &SymLinkU, TRUE) &&
901 (DirInfo->Name.Length == 2 * sizeof(WCHAR)) &&
902 (DirInfo->Name.Buffer[1] == L':'))
903 {
904 /* Looks like we found it, open the link to get its target */
906 &DirInfo->Name,
909 NULL);
910 Status = NtOpenSymbolicLinkObject(&LinkHandle,
913 if (NT_SUCCESS(Status))
914 {
915 /* Open worked, query the target now */
917 &LinkTarget,
918 NULL);
919 NtClose(LinkHandle);
920
921 /* Check if it matches the string we had found earlier */
922 if (NT_SUCCESS(Status) &&
925 (LinkTarget.Buffer[SystemPartition.Length / sizeof(WCHAR)] == L'\\'))))
926 {
927 /* All done */
928 break;
929 }
930 }
931 }
932
933 /* Couldn't find it, try again */
935 &DirInfoBuffer,
936 sizeof(DirInfoBuffer),
937 TRUE,
938 FALSE,
939 &Context,
940 NULL);
941 }
942 if (!NT_SUCCESS(Status))
943 {
944 DPRINT1("SMSS: Cannot find drive letter for system partition: 0x%x\n", Status);
945#if (NTDDI_VERSION > NTDDI_WIN7SP1) || defined(__REACTOS__)
946 /* If we failed because no drive letter associated to the system
947 * volume was found (none was assigned to it), fall back to using
948 * the OS boot drive letter instead. Otherwise, fail altogether.
949 * NOTE: This has been introduced in a post-SP1 Windows 7 update. */
951 return;
952 DirInfo->Name.Buffer = DirInfoBuffer.Buffer;
953 DirInfo->Name.Buffer[0] = SharedUserData->NtSystemRoot[0];
954 DirInfo->Name.Buffer[1] = SharedUserData->NtSystemRoot[1]; // == L':';
955#else
956 return;
957#endif
958 }
959
960 /* Open the setup key again, for full access this time */
962 L"\\Registry\\Machine\\Software\\Microsoft\\Windows\\CurrentVersion\\Setup");
966 NULL,
967 NULL);
969 if (!NT_SUCCESS(Status))
970 {
971 DPRINT1("SMSS: Cannot open software setup key for writing: 0x%x\n", Status);
972 return;
973 }
974
975 /* Wrap up the end of the link buffer */
976 LinkBuffer[0] = DirInfo->Name.Buffer[0];
977 LinkBuffer[1] = DirInfo->Name.Buffer[1]; // == L':';
978 LinkBuffer[2] = L'\\';
979 LinkBuffer[3] = UNICODE_NULL;
980
981 /* Now set this as the "BootDir" */
985 0,
986 REG_SZ,
987 LinkBuffer,
988 4 * sizeof(WCHAR));
989 if (!NT_SUCCESS(Status))
990 {
991 DPRINT1("SMSS: couldn't write BootDir value: 0x%x\n", Status);
992 }
994}
PPARTENTRY SystemPartition
Definition: reactos.c:32
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:254
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 625 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