mirror of
https://github.com/reactos/reactos.git
synced 2024-09-30 14:37:45 +00:00
[SMSS2]: Implement KnownDLL and DOSDevice initialization now that the kernel bugs are gone. Compared to SMSS, SMSS2 is smarter and uses a Ldr callback to manually add any imported DLLs of KnownDLLs to the KnownDLL list, which helps with long-term app launch performance. Next up will be environment and page file.
svn path=/trunk/; revision=55324
This commit is contained in:
parent
864a1bc6ae
commit
9f51b3ff35
|
@ -30,7 +30,7 @@ LIST_ENTRY SmpExcludeKnownDllsList, SmpSubSystemList, SmpSubSystemsToLoad;
|
||||||
LIST_ENTRY SmpSubSystemsToDefer, SmpExecuteList, NativeProcessList;
|
LIST_ENTRY SmpSubSystemsToDefer, SmpExecuteList, NativeProcessList;
|
||||||
|
|
||||||
ULONG SmBaseTag;
|
ULONG SmBaseTag;
|
||||||
HANDLE SmpDebugPort;
|
HANDLE SmpDebugPort, SmpDosDevicesObjectDirectory;
|
||||||
PVOID SmpHeap;
|
PVOID SmpHeap;
|
||||||
PWCHAR SmpDefaultEnvironment, SmpDefaultLibPathBuffer;
|
PWCHAR SmpDefaultEnvironment, SmpDefaultLibPathBuffer;
|
||||||
UNICODE_STRING SmpKnownDllPath, SmpDefaultLibPath;
|
UNICODE_STRING SmpKnownDllPath, SmpDefaultLibPath;
|
||||||
|
@ -42,8 +42,8 @@ PVOID SmpInitLastCall;
|
||||||
|
|
||||||
SECURITY_DESCRIPTOR SmpPrimarySDBody, SmpLiberalSDBody, SmpKnownDllsSDBody;
|
SECURITY_DESCRIPTOR SmpPrimarySDBody, SmpLiberalSDBody, SmpKnownDllsSDBody;
|
||||||
SECURITY_DESCRIPTOR SmpApiPortSDBody;
|
SECURITY_DESCRIPTOR SmpApiPortSDBody;
|
||||||
PSECURITY_DESCRIPTOR SmpPrimarySecurityDescriptor, SmpLiberalSecurityDescriptor;
|
PISECURITY_DESCRIPTOR SmpPrimarySecurityDescriptor, SmpLiberalSecurityDescriptor;
|
||||||
PSECURITY_DESCRIPTOR SmpKnownDllsSecurityDescriptor, SmpApiPortSecurityDescriptor;
|
PISECURITY_DESCRIPTOR SmpKnownDllsSecurityDescriptor, SmpApiPortSecurityDescriptor;
|
||||||
|
|
||||||
ULONG SmpAllowProtectedRenames, SmpProtectionMode = 1;
|
ULONG SmpAllowProtectedRenames, SmpProtectionMode = 1;
|
||||||
BOOLEAN MiniNTBoot;
|
BOOLEAN MiniNTBoot;
|
||||||
|
@ -353,7 +353,6 @@ SmpConfigureMemoryMgmt(IN PWSTR ValueName,
|
||||||
IN PVOID EntryContext)
|
IN PVOID EntryContext)
|
||||||
{
|
{
|
||||||
/* Save this is into a list */
|
/* Save this is into a list */
|
||||||
DPRINT1("PageFile or Execute Entry: %S-%S\n", ValueName, ValueData);
|
|
||||||
return SmpSaveRegistryValue(EntryContext, ValueData, NULL, TRUE);
|
return SmpSaveRegistryValue(EntryContext, ValueData, NULL, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -433,7 +432,6 @@ SmpConfigureDosDevices(IN PWSTR ValueName,
|
||||||
IN PVOID EntryContext)
|
IN PVOID EntryContext)
|
||||||
{
|
{
|
||||||
/* Save into linked list */
|
/* Save into linked list */
|
||||||
DPRINT1("DOS Device: %S-%S\n", ValueName, ValueData);
|
|
||||||
return SmpSaveRegistryValue(EntryContext, ValueName, ValueData, TRUE);
|
return SmpSaveRegistryValue(EntryContext, ValueName, ValueData, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -480,7 +478,6 @@ SmpConfigureKnownDlls(IN PWSTR ValueName,
|
||||||
if (_wcsicmp(ValueName, L"DllDirectory"))
|
if (_wcsicmp(ValueName, L"DllDirectory"))
|
||||||
{
|
{
|
||||||
/* Add to the linked list -- this is a file */
|
/* Add to the linked list -- this is a file */
|
||||||
DPRINT1("KnownDll: %S-%S\n", ValueName, ValueData);
|
|
||||||
return SmpSaveRegistryValue(EntryContext, ValueName, ValueData, TRUE);
|
return SmpSaveRegistryValue(EntryContext, ValueName, ValueData, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1101,14 +1098,400 @@ NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
SmpInitializeDosDevices(VOID)
|
SmpInitializeDosDevices(VOID)
|
||||||
{
|
{
|
||||||
return STATUS_SUCCESS;
|
NTSTATUS Status;
|
||||||
|
PSMP_REGISTRY_VALUE RegEntry;
|
||||||
|
SECURITY_DESCRIPTOR_CONTROL OldFlag = 0;
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
UNICODE_STRING DestinationString;
|
||||||
|
HANDLE DirHandle;
|
||||||
|
PLIST_ENTRY NextEntry, Head;
|
||||||
|
|
||||||
|
/* Open the GLOBAL?? directory */
|
||||||
|
RtlInitUnicodeString(&DestinationString, L"\\??");
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
&DestinationString,
|
||||||
|
OBJ_CASE_INSENSITIVE | OBJ_OPENIF | OBJ_PERMANENT,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
Status = NtOpenDirectoryObject(&SmpDosDevicesObjectDirectory,
|
||||||
|
DIRECTORY_ALL_ACCESS,
|
||||||
|
&ObjectAttributes);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("SMSS: Unable to open %wZ directory - Status == %lx\n",
|
||||||
|
&DestinationString, Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Loop the DOS devices */
|
||||||
|
Head = &SmpDosDevicesList;
|
||||||
|
while (!IsListEmpty(Head))
|
||||||
|
{
|
||||||
|
/* Get the entry and remove it */
|
||||||
|
NextEntry = RemoveHeadList(Head);
|
||||||
|
RegEntry = CONTAINING_RECORD(NextEntry, SMP_REGISTRY_VALUE, Entry);
|
||||||
|
|
||||||
|
/* Initialize the attributes, and see which descriptor is being used */
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
&RegEntry->Name,
|
||||||
|
OBJ_CASE_INSENSITIVE | OBJ_OPENIF | OBJ_PERMANENT,
|
||||||
|
SmpDosDevicesObjectDirectory,
|
||||||
|
SmpPrimarySecurityDescriptor);
|
||||||
|
if (SmpPrimarySecurityDescriptor)
|
||||||
|
{
|
||||||
|
/* Save the old flag and set it while we create this link */
|
||||||
|
OldFlag = SmpPrimarySecurityDescriptor->Control;
|
||||||
|
SmpPrimarySecurityDescriptor->Control |= SE_DACL_DEFAULTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create the symbolic link */
|
||||||
|
DPRINT1("Creating symlink for %wZ to %wZ\n", &RegEntry->Name, &RegEntry->Value);
|
||||||
|
Status = NtCreateSymbolicLinkObject(&DirHandle,
|
||||||
|
SYMBOLIC_LINK_ALL_ACCESS,
|
||||||
|
&ObjectAttributes,
|
||||||
|
&RegEntry->Value);
|
||||||
|
if (Status == STATUS_OBJECT_NAME_EXISTS)
|
||||||
|
{
|
||||||
|
/* Make it temporary and get rid of the handle */
|
||||||
|
NtMakeTemporaryObject(DirHandle);
|
||||||
|
NtClose(DirHandle);
|
||||||
|
|
||||||
|
/* Treat this as success, and see if we got a name back */
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
if (RegEntry->Value.Length)
|
||||||
|
{
|
||||||
|
/* Create it now with this name */
|
||||||
|
ObjectAttributes.Attributes &= ~OBJ_OPENIF;
|
||||||
|
Status = NtCreateSymbolicLinkObject(&DirHandle,
|
||||||
|
SYMBOLIC_LINK_ALL_ACCESS,
|
||||||
|
&ObjectAttributes,
|
||||||
|
&RegEntry->Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we were using a security descriptor, restore the non-defaulted flag */
|
||||||
|
if (ObjectAttributes.SecurityDescriptor)
|
||||||
|
{
|
||||||
|
SmpPrimarySecurityDescriptor->Control = OldFlag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print a failure if we failed to create the symbolic link */
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("SMSS: Unable to create %wZ => %wZ symbolic link object - Status == 0x%lx\n",
|
||||||
|
&RegEntry->Name,
|
||||||
|
&RegEntry->Value,
|
||||||
|
Status);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close the handle */
|
||||||
|
NtClose(DirHandle);
|
||||||
|
|
||||||
|
/* Free this entry */
|
||||||
|
if (RegEntry->AnsiValue) RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry->AnsiValue);
|
||||||
|
if (RegEntry->Value.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry->Value.Buffer);
|
||||||
|
RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the status */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
SmpProcessModuleImports(IN PVOID Unused,
|
||||||
|
IN PCHAR ImportName)
|
||||||
|
{
|
||||||
|
ULONG Length = 0, Chars;
|
||||||
|
WCHAR Buffer[MAX_PATH];
|
||||||
|
PWCHAR DllName, DllValue;
|
||||||
|
ANSI_STRING ImportString;
|
||||||
|
UNICODE_STRING ImportUnicodeString;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
/* Skip NTDLL since it's already always mapped */
|
||||||
|
if (!_stricmp(ImportName, "ntdll.dll")) return;
|
||||||
|
|
||||||
|
/* Initialize our strings */
|
||||||
|
RtlInitAnsiString(&ImportString, ImportName);
|
||||||
|
RtlInitEmptyUnicodeString(&ImportUnicodeString, Buffer, sizeof(Buffer));
|
||||||
|
Status = RtlAnsiStringToUnicodeString(&ImportUnicodeString, &ImportString, FALSE);
|
||||||
|
if (!NT_SUCCESS(Status)) return;
|
||||||
|
|
||||||
|
/* Loop in case we find a forwarder */
|
||||||
|
ImportUnicodeString.MaximumLength = ImportUnicodeString.Length + sizeof(UNICODE_NULL);
|
||||||
|
while (Length < ImportUnicodeString.Length)
|
||||||
|
{
|
||||||
|
if (ImportUnicodeString.Buffer[Length / sizeof(WCHAR)] == L'.') break;
|
||||||
|
Length += sizeof(WCHAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Break up the values as needed */
|
||||||
|
DllValue = ImportUnicodeString.Buffer;
|
||||||
|
DllName = &ImportUnicodeString.Buffer[ImportUnicodeString.MaximumLength / sizeof(WCHAR)];
|
||||||
|
Chars = Length >> 1;
|
||||||
|
wcsncpy(DllName, ImportUnicodeString.Buffer, Chars);
|
||||||
|
DllName[Chars] = 0;
|
||||||
|
|
||||||
|
/* Add the DLL to the list */
|
||||||
|
SmpSaveRegistryValue(&SmpKnownDllsList, DllName, DllValue, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
SmpInitializeKnownDllsInternal(IN PUNICODE_STRING Directory,
|
||||||
|
IN PUNICODE_STRING Path)
|
||||||
|
{
|
||||||
|
HANDLE DirFileHandle, DirHandle, SectionHandle, FileHandle, LinkHandle;
|
||||||
|
UNICODE_STRING NtPath, DestinationString;
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
NTSTATUS Status, Status1;
|
||||||
|
PLIST_ENTRY NextEntry;
|
||||||
|
PSMP_REGISTRY_VALUE RegEntry;
|
||||||
|
ULONG_PTR ErrorParameters[3];
|
||||||
|
UNICODE_STRING ErrorResponse;
|
||||||
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
|
ULONG OldFlag = 0;
|
||||||
|
USHORT ImageCharacteristics;
|
||||||
|
|
||||||
|
/* Initialize to NULL */
|
||||||
|
DirFileHandle = NULL;
|
||||||
|
DirHandle = NULL;
|
||||||
|
NtPath.Buffer = NULL;
|
||||||
|
|
||||||
|
/* Create the \KnownDLLs directory */
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
Directory,
|
||||||
|
OBJ_CASE_INSENSITIVE | OBJ_OPENIF | OBJ_PERMANENT,
|
||||||
|
NULL,
|
||||||
|
SmpKnownDllsSecurityDescriptor);
|
||||||
|
Status = NtCreateDirectoryObject(&DirHandle,
|
||||||
|
DIRECTORY_ALL_ACCESS,
|
||||||
|
&ObjectAttributes);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Handle failure */
|
||||||
|
DPRINT1("SMSS: Unable to create %wZ directory - Status == %lx\n",
|
||||||
|
Directory, Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert the path to native format */
|
||||||
|
if (!RtlDosPathNameToNtPathName_U(Path->Buffer, &NtPath, NULL, NULL))
|
||||||
|
{
|
||||||
|
/* Fail if this didn't work */
|
||||||
|
DPRINT1("SMSS: Unable to to convert %wZ to an Nt path\n", Path);
|
||||||
|
Status = STATUS_OBJECT_NAME_INVALID;
|
||||||
|
goto Quickie;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open the path that was specified, which should be a directory */
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
&NtPath,
|
||||||
|
OBJ_CASE_INSENSITIVE,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
Status = NtOpenFile(&DirFileHandle,
|
||||||
|
FILE_LIST_DIRECTORY | SYNCHRONIZE,
|
||||||
|
&ObjectAttributes,
|
||||||
|
&IoStatusBlock,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
|
FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Fail if we couldn't open it */
|
||||||
|
DPRINT1("SMSS: Unable to open a handle to the KnownDll directory (%wZ)"
|
||||||
|
"- Status == %lx\n",
|
||||||
|
Path,
|
||||||
|
Status);
|
||||||
|
FileHandle = NULL;
|
||||||
|
goto Quickie;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Temporarily hack the SD to use a default DACL for this symbolic link */
|
||||||
|
if (SmpPrimarySecurityDescriptor)
|
||||||
|
{
|
||||||
|
OldFlag = SmpPrimarySecurityDescriptor->Control;
|
||||||
|
SmpPrimarySecurityDescriptor->Control |= SE_DACL_DEFAULTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create a symbolic link to the directory in the object manager */
|
||||||
|
RtlInitUnicodeString(&DestinationString, L"KnownDllPath");
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
&DestinationString,
|
||||||
|
OBJ_CASE_INSENSITIVE | OBJ_OPENIF | OBJ_PERMANENT,
|
||||||
|
DirHandle,
|
||||||
|
SmpPrimarySecurityDescriptor);
|
||||||
|
Status = NtCreateSymbolicLinkObject(&LinkHandle,
|
||||||
|
SYMBOLIC_LINK_ALL_ACCESS,
|
||||||
|
&ObjectAttributes,
|
||||||
|
Path);
|
||||||
|
|
||||||
|
/* Undo the hack */
|
||||||
|
if (SmpPrimarySecurityDescriptor) SmpPrimarySecurityDescriptor->Control = OldFlag;
|
||||||
|
|
||||||
|
/* Check if the symlink was created */
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* It wasn't, so bail out since the OS needs it to exist */
|
||||||
|
DPRINT1("SMSS: Unable to create %wZ symbolic link - Status == %lx\n",
|
||||||
|
&DestinationString, Status);
|
||||||
|
LinkHandle = NULL;
|
||||||
|
goto Quickie;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We created it permanent, we can go ahead and close the handle now */
|
||||||
|
Status1 = NtClose(LinkHandle);
|
||||||
|
ASSERT(NT_SUCCESS(Status1));
|
||||||
|
|
||||||
|
/* Now loop the known DLLs */
|
||||||
|
NextEntry = SmpKnownDllsList.Flink;
|
||||||
|
while (NextEntry != &SmpKnownDllsList)
|
||||||
|
{
|
||||||
|
/* Get the entry and skip it if it's in the exluded list */
|
||||||
|
RegEntry = CONTAINING_RECORD(NextEntry, SMP_REGISTRY_VALUE, Entry);
|
||||||
|
DPRINT1("Processing known DLL: %wZ-%wZ\n", &RegEntry->Name, &RegEntry->Value);
|
||||||
|
if ((SmpFindRegistryValue(&SmpExcludeKnownDllsList,
|
||||||
|
RegEntry->Name.Buffer)) ||
|
||||||
|
(SmpFindRegistryValue(&SmpExcludeKnownDllsList,
|
||||||
|
RegEntry->Value.Buffer)))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open the actual file */
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
&RegEntry->Value,
|
||||||
|
OBJ_CASE_INSENSITIVE,
|
||||||
|
DirFileHandle,
|
||||||
|
NULL);
|
||||||
|
Status = NtOpenFile(&FileHandle,
|
||||||
|
SYNCHRONIZE | FILE_EXECUTE,
|
||||||
|
&ObjectAttributes,
|
||||||
|
&IoStatusBlock,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_DELETE,
|
||||||
|
FILE_NON_DIRECTORY_FILE |
|
||||||
|
FILE_SYNCHRONOUS_IO_NONALERT);
|
||||||
|
if (!NT_SUCCESS(Status)) break;
|
||||||
|
|
||||||
|
/* Checksum it */
|
||||||
|
Status = LdrVerifyImageMatchesChecksum((HANDLE)((ULONG_PTR)FileHandle | 1),
|
||||||
|
SmpProcessModuleImports,
|
||||||
|
RegEntry,
|
||||||
|
&ImageCharacteristics);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Checksum failed, so don't even try going further -- kill SMSS */
|
||||||
|
RtlInitUnicodeString(&ErrorResponse,
|
||||||
|
L"Verification of a KnownDLL failed.");
|
||||||
|
ErrorParameters[0] = (ULONG)&ErrorResponse;
|
||||||
|
ErrorParameters[1] = Status;
|
||||||
|
ErrorParameters[2] = (ULONG)&RegEntry->Value;
|
||||||
|
SmpTerminate(ErrorParameters, 5, RTL_NUMBER_OF(ErrorParameters));
|
||||||
|
}
|
||||||
|
else if (!(ImageCharacteristics & IMAGE_FILE_DLL))
|
||||||
|
{
|
||||||
|
/* An invalid known DLL entry will also kill SMSS */
|
||||||
|
RtlInitUnicodeString(&ErrorResponse,
|
||||||
|
L"Non-DLL file included in KnownDLL list.");
|
||||||
|
ErrorParameters[0] = (ULONG)&ErrorResponse;
|
||||||
|
ErrorParameters[1] = STATUS_INVALID_IMPORT_OF_NON_DLL;
|
||||||
|
ErrorParameters[2] = (ULONG)&RegEntry->Value;
|
||||||
|
SmpTerminate(ErrorParameters, 5, RTL_NUMBER_OF(ErrorParameters));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Temporarily hack the SD to use a default DACL for this section */
|
||||||
|
if (SmpLiberalSecurityDescriptor)
|
||||||
|
{
|
||||||
|
OldFlag = SmpLiberalSecurityDescriptor->Control;
|
||||||
|
SmpLiberalSecurityDescriptor->Control |= SE_DACL_DEFAULTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create the section for this known DLL */
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
&RegEntry->Value,
|
||||||
|
OBJ_PERMANENT,
|
||||||
|
DirHandle,
|
||||||
|
SmpLiberalSecurityDescriptor)
|
||||||
|
Status = NtCreateSection(&SectionHandle,
|
||||||
|
SECTION_ALL_ACCESS,
|
||||||
|
&ObjectAttributes,
|
||||||
|
0,
|
||||||
|
PAGE_EXECUTE,
|
||||||
|
SEC_IMAGE,
|
||||||
|
FileHandle);
|
||||||
|
|
||||||
|
/* Undo the hack */
|
||||||
|
if (SmpLiberalSecurityDescriptor) SmpLiberalSecurityDescriptor->Control = OldFlag;
|
||||||
|
|
||||||
|
/* Check if we created the section okay */
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* We can close it now, since it's marked permanent */
|
||||||
|
Status1 = NtClose(SectionHandle);
|
||||||
|
ASSERT(NT_SUCCESS(Status1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* If we couldn't make it "known", that's fine and keep going */
|
||||||
|
DPRINT1("SMSS: CreateSection for KnownDll %wZ failed - Status == %lx\n",
|
||||||
|
&RegEntry->Value, Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close the file since we can move on to the next one */
|
||||||
|
Status1 = NtClose(FileHandle);
|
||||||
|
ASSERT(NT_SUCCESS(Status1));
|
||||||
|
|
||||||
|
/* Go to the next entry */
|
||||||
|
NextEntry = NextEntry->Flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
Quickie:
|
||||||
|
/* Close both handles and free the NT path buffer */
|
||||||
|
if (DirHandle)
|
||||||
|
{
|
||||||
|
Status1 = NtClose(DirHandle);
|
||||||
|
ASSERT(NT_SUCCESS(Status1));
|
||||||
|
}
|
||||||
|
if (DirFileHandle)
|
||||||
|
{
|
||||||
|
Status1 = NtClose(DirFileHandle);
|
||||||
|
ASSERT(NT_SUCCESS(Status1));
|
||||||
|
}
|
||||||
|
if (NtPath.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, NtPath.Buffer);
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
SmpInitializeKnownDlls(VOID)
|
SmpInitializeKnownDlls(VOID)
|
||||||
{
|
{
|
||||||
return STATUS_SUCCESS;
|
NTSTATUS Status;
|
||||||
|
PSMP_REGISTRY_VALUE RegEntry;
|
||||||
|
UNICODE_STRING DestinationString;
|
||||||
|
PLIST_ENTRY Head, NextEntry;
|
||||||
|
|
||||||
|
/* Call the internal function */
|
||||||
|
RtlInitUnicodeString(&DestinationString, L"\\KnownDlls");
|
||||||
|
Status = SmpInitializeKnownDllsInternal(&DestinationString, &SmpKnownDllPath);
|
||||||
|
|
||||||
|
/* Wipe out the list regardless of success */
|
||||||
|
Head = &SmpKnownDllsList;
|
||||||
|
while (!IsListEmpty(Head))
|
||||||
|
{
|
||||||
|
/* Remove this entry */
|
||||||
|
NextEntry = RemoveHeadList(Head);
|
||||||
|
|
||||||
|
/* Free it */
|
||||||
|
RegEntry = CONTAINING_RECORD(NextEntry, SMP_REGISTRY_VALUE, Entry);
|
||||||
|
RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry->AnsiValue);
|
||||||
|
RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry->Value.Buffer);
|
||||||
|
RtlFreeHeap(RtlGetProcessHeap(), 0, RegEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* All done */
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
|
|
@ -46,6 +46,14 @@ extern BOOLEAN RegPosixSingleInstance;
|
||||||
|
|
||||||
/* FUNCTIONS ******************************************************************/
|
/* FUNCTIONS ******************************************************************/
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
SmpTerminate(
|
||||||
|
IN PULONG_PTR Parameters,
|
||||||
|
IN ULONG ParameterMask,
|
||||||
|
IN ULONG ParameterCount
|
||||||
|
);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
SmpCreateSecurityDescriptors(
|
SmpCreateSecurityDescriptors(
|
||||||
|
|
Loading…
Reference in a new issue