/*********************************************************************** * ExpandEnvironmentStringsW (KERNEL32.@) * * Replaces references to environment variables of the form '%EnvVar%' * by their value. If the environment variable does not exist, then the * reference is left as is. * * PARAMS * src [I] The string to be expanded. * dst [O] The buffer in which to put the expanded string. * len [I] The buffer size, in characters. * * RETURNS * The number of characters copied into the buffer. If the buffer is * too small, then the required buffer size, in characters including the * trailing '\0', is returned. * If the function fails for some other reason, then it returns 0. */ DWORD WINAPI ExpandEnvironmentStringsW( LPCWSTR src, LPWSTR dst, DWORD len ) { UNICODE_STRING us_src; UNICODE_STRING us_dst; NTSTATUS status; DWORD res; TRACE("(%s %p %u)\n", debugstr_w(src), dst, len); RtlInitUnicodeString(&us_src, src); /* make sure we don't overflow the maximum UNICODE_STRING size */ if (len > UNICODE_STRING_MAX_CHARS) len = UNICODE_STRING_MAX_CHARS; us_dst.Length = 0; us_dst.MaximumLength = len * sizeof(WCHAR); us_dst.Buffer = dst; res = 0; status = RtlExpandEnvironmentStrings_U(NULL, &us_src, &us_dst, &res); res /= sizeof(WCHAR); if (status != STATUS_SUCCESS) { SetLastError( RtlNtStatusToDosError(status) ); if (status != STATUS_BUFFER_TOO_SMALL) return 0; if (len && dst) dst[len - 1] = '\0'; } return res; }
BOOL WINAPI ExpandEnvironmentStringsForUserW(IN HANDLE hToken, IN LPCWSTR lpSrc, OUT LPWSTR lpDest, IN DWORD dwSize) { BOOL Ret = FALSE; PVOID lpEnvironment; if (lpSrc == NULL || lpDest == NULL || dwSize == 0) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } if (CreateEnvironmentBlock(&lpEnvironment, hToken, FALSE)) { UNICODE_STRING SrcU, DestU; NTSTATUS Status; /* Initialize the strings */ RtlInitUnicodeString(&SrcU, lpSrc); DestU.Length = 0; DestU.MaximumLength = dwSize * sizeof(WCHAR); DestU.Buffer = lpDest; /* Expand the strings */ Status = RtlExpandEnvironmentStrings_U((PWSTR)lpEnvironment, &SrcU, &DestU, NULL); DestroyEnvironmentBlock(lpEnvironment); if (NT_SUCCESS(Status)) { Ret = TRUE; } else { SetLastError(RtlNtStatusToDosError(Status)); } } return Ret; }
static BOOL get_reg_value(WCHAR *env, HKEY hkey, const WCHAR *name, WCHAR *val, DWORD size) { DWORD type, res_size=0; if (RegQueryValueExW(hkey, name, 0, &type, NULL, &res_size) != ERROR_SUCCESS) return FALSE; if (type == REG_SZ) { if (res_size > size) return FALSE; return RegQueryValueExW(hkey, name, 0, NULL, (BYTE*)val, &size) == ERROR_SUCCESS; } else if (type == REG_EXPAND_SZ) { UNICODE_STRING us_buf, us_expanded; WCHAR *buf = HeapAlloc(GetProcessHeap(), 0, res_size); if (!buf) return FALSE; if (RegQueryValueExW(hkey, name, 0, NULL, (BYTE*)buf, &res_size) != ERROR_SUCCESS) { HeapFree(GetProcessHeap(), 0, buf); return FALSE; } RtlInitUnicodeString(&us_buf, buf); us_expanded.Buffer = val; us_expanded.MaximumLength = size; if (RtlExpandEnvironmentStrings_U(env, &us_buf, &us_expanded, &size) != STATUS_SUCCESS) { HeapFree(GetProcessHeap(), 0, buf); return FALSE; } HeapFree(GetProcessHeap(), 0, buf); return TRUE; } return FALSE; }
/* * @implemented */ DWORD WINAPI ExpandEnvironmentStringsW ( LPCWSTR lpSrc, LPWSTR lpDst, DWORD nSize ) { UNICODE_STRING Source; UNICODE_STRING Destination; NTSTATUS Status; ULONG Length = 0; RtlInitUnicodeString (&Source, (LPWSTR)lpSrc); /* make sure we don't overflow the maximum UNICODE_STRING size */ if (nSize > 0x7fff) nSize = 0x7fff; Destination.Length = 0; Destination.MaximumLength = (USHORT)nSize * sizeof(WCHAR); Destination.Buffer = lpDst; Status = RtlExpandEnvironmentStrings_U (NULL, &Source, &Destination, &Length); if (!NT_SUCCESS(Status)) { SetLastErrorByStatus (Status); if (Status != STATUS_BUFFER_TOO_SMALL) return 0; } return (Length / sizeof(WCHAR)); }
VOID AppendPackage() { PLDR_MODULE Self; UNICODE_STRING SelfPath; static WCHAR PythonZip[] = L"python.zip"; ml::MlInitialize(); //Py_IgnoreEnvironmentFlag = TRUE; //Py_NoSiteFlag = TRUE; Py_DontWriteBytecodeFlag = TRUE; //Py_NoUserSiteDirectory = TRUE; Self = FindLdrModuleByHandle(nullptr); SelfPath = Self->FullDllName; SelfPath.Length -= Self->BaseDllName.Length; Py_SetPath(ml::String::Format( L"%wZ;%wZ%s;%wZ%s\\site-packages;%wZlib;%wZDLLs;%wZUserSite", &SelfPath, // exe path &SelfPath, PythonZip, // ./python.zip &SelfPath, PythonZip, // ./python.zip/site-packages &SelfPath, // ./lib &SelfPath, // ./DLLs &SelfPath // ./UserSite )); ml::String PathEnv, UserSite; PWSTR EnvBuffer; ULONG Length; UNICODE_STRING Path; RtlInitEmptyString(&Path); RtlExpandEnvironmentStrings_U(nullptr, &USTR(L"%Path%"), &Path, &Length); EnvBuffer = (PWSTR)AllocStack(Length); RtlInitEmptyString(&Path, EnvBuffer, Length); RtlExpandEnvironmentStrings_U(nullptr, &USTR(L"%Path%"), &Path, nullptr); UserSite = SelfPath; UserSite += L"UserSite"; PathEnv = SelfPath; PathEnv += L"DLLs;"; EnumDirectoryFiles( nullptr, L"*.*", 0, UserSite, nullptr, [] (PVOID Buffer, PWIN32_FIND_DATAW FindData, ULONG_PTR Context) -> LONG { ml::String *PathEnv = (ml::String *)Context; if (FLAG_OFF(FindData->dwFileAttributes, FILE_ATTRIBUTE_DIRECTORY)) return 0; (*PathEnv) += FindData->cFileName; (*PathEnv) += ';'; return 0; }, (ULONG_PTR)&PathEnv, EDF_PROCDIR | EDF_BEFORE ); PathEnv += Path; PathEnv += ';'; RtlSetEnvironmentVariable(nullptr, &USTR(L"Path"), PathEnv); }
/* * SfuBuildBotPath * * Purpose: * * Return full path to bot in both variants. * */ BOOL SfuBuildBotPath( _Inout_ PZA_BOT_PATH Context ) { BOOL cond = FALSE, bResult = FALSE; OBJECT_ATTRIBUTES obja; UNICODE_STRING ustr1, ustr2; WCHAR szRegBuffer[MAX_PATH + 1]; HANDLE ProcessHeap; HANDLE hKey = NULL; NTSTATUS status; KEY_VALUE_PARTIAL_INFORMATION *pki = NULL; LPWSTR lpEnv; ULONG memIO = 0; LPWSTR lpLocalBotName, lpPFilesBotName; PVOID Wow64Information = NULL; GUID sfGUID; if (Context == NULL) return bResult; ProcessHeap = RtlGetCurrentPeb()->ProcessHeap; RtlSecureZeroMemory(&ustr1, sizeof(ustr1)); do { if (!SfInitMD5()) break; RtlSecureZeroMemory(&sfGUID, sizeof(sfGUID)); SfuCalcVolumeMD5((BYTE*)&sfGUID); status = NtQueryInformationProcess(NtCurrentProcess(), ProcessWow64Information, &Wow64Information, sizeof(PVOID), NULL); if (!NT_SUCCESS(status)) break; //query current user registry string if (!NT_SUCCESS(RtlFormatCurrentUserKeyPath(&ustr1))) break; lpLocalBotName = Context->szBotPathLocal; lpPFilesBotName = Context->szBotPathPFiles; RtlSecureZeroMemory(&szRegBuffer, sizeof(szRegBuffer)); wsprintf(szRegBuffer, T_SHELL_FOLDERS_KEY, ustr1.Buffer); RtlFreeUnicodeString(&ustr1); //open User Shell Folders key to query Local AppData value RtlSecureZeroMemory(&ustr2, sizeof(ustr2)); RtlInitUnicodeString(&ustr2, szRegBuffer); InitializeObjectAttributes(&obja, &ustr2, OBJ_CASE_INSENSITIVE, NULL, NULL); status = NtOpenKey(&hKey, KEY_READ, &obja); if (!NT_SUCCESS(status)) break; //query value size RtlInitUnicodeString(&ustr2, T_LOCAL_APPDATA_VALUE); NtQueryValueKey(hKey, &ustr2, KeyValuePartialInformation, NULL, 0, &memIO); if (memIO == 0) break; pki = RtlAllocateHeap(ProcessHeap, HEAP_ZERO_MEMORY, memIO); if (pki == NULL) break; //query value status = NtQueryValueKey(hKey, &ustr2, KeyValuePartialInformation, pki, memIO, &memIO); if (!NT_SUCCESS(status)) break; RtlInitUnicodeString(&ustr2, (WCHAR*)pki->Data); memIO = 0; //expand environment variable inside value RtlSecureZeroMemory(&szRegBuffer, sizeof(szRegBuffer)); ustr1.Buffer = szRegBuffer; ustr1.Length = 0; ustr1.MaximumLength = sizeof(szRegBuffer); status = RtlExpandEnvironmentStrings_U(NULL, &ustr2, &ustr1, &memIO); if (!NT_SUCCESS(status)) { ustr1.Buffer = NULL; break; } //build result string _strcpy(lpLocalBotName, T_GLOBAL_LINK); _strcat(lpLocalBotName, szRegBuffer); wsprintf(_strend(lpLocalBotName), T_SIREFEF_DIRECTORY, sfGUID.Data1, sfGUID.Data2, sfGUID.Data3, sfGUID.Data4[0], sfGUID.Data4[1], sfGUID.Data4[2], sfGUID.Data4[3], sfGUID.Data4[4], sfGUID.Data4[5], sfGUID.Data4[6], sfGUID.Data4[7]); ustr1.Buffer = NULL; _strcpy(lpPFilesBotName, T_GLOBAL_LINK); if (Wow64Information == NULL) { lpEnv = L"ProgramFiles="; } else { lpEnv = L"ProgramFiles(x86)="; } RtlInitUnicodeString(&ustr2, lpEnv); lpEnv = SfuQueryEnvironmentVariableOffset(&ustr2); if (lpEnv) { _strcat(lpPFilesBotName, lpEnv); wsprintf(_strend(lpPFilesBotName), T_SIREFEF_DIRECTORY, sfGUID.Data1, sfGUID.Data2, sfGUID.Data3, sfGUID.Data4[0], sfGUID.Data4[1], sfGUID.Data4[2], sfGUID.Data4[3], sfGUID.Data4[4], sfGUID.Data4[5], sfGUID.Data4[6], sfGUID.Data4[7]); } bResult = TRUE; } while (cond); if (hKey != NULL) { NtClose(hKey); } if (ustr1.Buffer != NULL) { RtlFreeUnicodeString(&ustr1); } if (pki != NULL) { RtlFreeHeap(ProcessHeap, 0, pki); } return bResult; }
/* * @implemented */ DWORD WINAPI ExpandEnvironmentStringsA ( LPCSTR lpSrc, LPSTR lpDst, DWORD nSize ) { ANSI_STRING Source; ANSI_STRING Destination; UNICODE_STRING SourceU; UNICODE_STRING DestinationU; NTSTATUS Status; ULONG Length = 0; RtlInitAnsiString (&Source, (LPSTR)lpSrc); Status = RtlAnsiStringToUnicodeString (&SourceU, &Source, TRUE); if (!NT_SUCCESS(Status)) { SetLastErrorByStatus (Status); return 0; } /* make sure we don't overflow the maximum ANSI_STRING size */ if (nSize > 0x7fff) nSize = 0x7fff; Destination.Length = 0; Destination.MaximumLength = (USHORT)nSize; Destination.Buffer = lpDst; DestinationU.Length = 0; DestinationU.MaximumLength = (USHORT)nSize * sizeof(WCHAR); DestinationU.Buffer = RtlAllocateHeap (RtlGetProcessHeap (), 0, DestinationU.MaximumLength); if (DestinationU.Buffer == NULL) { RtlFreeUnicodeString(&SourceU); SetLastError(ERROR_NOT_ENOUGH_MEMORY); return 0; } Status = RtlExpandEnvironmentStrings_U (NULL, &SourceU, &DestinationU, &Length); RtlFreeUnicodeString (&SourceU); if (!NT_SUCCESS(Status)) { SetLastErrorByStatus (Status); if (Status != STATUS_BUFFER_TOO_SMALL) { RtlFreeHeap (RtlGetProcessHeap (), 0, DestinationU.Buffer); return 0; } } RtlUnicodeStringToAnsiString (&Destination, &DestinationU, FALSE); RtlFreeHeap (RtlGetProcessHeap (), 0, DestinationU.Buffer); return (Length / sizeof(WCHAR)); }
static BOOL SetUserEnvironmentVariable(PWSTR* Environment, LPWSTR lpName, LPWSTR lpValue, BOOL bExpand) { NTSTATUS Status; UNICODE_STRING Name; UNICODE_STRING SrcValue, DstValue; ULONG Length; PVOID Buffer = NULL; WCHAR ShortName[MAX_PATH]; if (bExpand) { RtlInitUnicodeString(&SrcValue, lpValue); Length = 2 * MAX_PATH * sizeof(WCHAR); DstValue.Length = 0; DstValue.MaximumLength = Length; DstValue.Buffer = Buffer = LocalAlloc(LPTR, Length); if (DstValue.Buffer == NULL) { DPRINT1("LocalAlloc() failed\n"); return FALSE; } Status = RtlExpandEnvironmentStrings_U(*Environment, &SrcValue, &DstValue, &Length); if (!NT_SUCCESS(Status)) { DPRINT1("RtlExpandEnvironmentStrings_U() failed (Status %lx)\n", Status); DPRINT1("Length %lu\n", Length); if (Buffer) LocalFree(Buffer); return FALSE; } } else { RtlInitUnicodeString(&DstValue, lpValue); } if (!_wcsicmp(lpName, L"TEMP") || !_wcsicmp(lpName, L"TMP")) { if (GetShortPathNameW(DstValue.Buffer, ShortName, ARRAYSIZE(ShortName))) { RtlInitUnicodeString(&DstValue, ShortName); } else { DPRINT("GetShortPathNameW() failed for %S (Error %lu)\n", DstValue.Buffer, GetLastError()); } DPRINT("Buffer: %S\n", ShortName); } RtlInitUnicodeString(&Name, lpName); DPRINT("Value: %wZ\n", &DstValue); Status = RtlSetEnvironmentVariable(Environment, &Name, &DstValue); if (Buffer) LocalFree(Buffer); if (!NT_SUCCESS(Status)) { DPRINT1("RtlSetEnvironmentVariable() failed (Status %lx)\n", Status); return FALSE; } return TRUE; }
VOID NTAPI BaseInitializeStaticServerData(IN PCSR_SERVER_DLL LoadedServerDll) { NTSTATUS Status; BOOLEAN Success; WCHAR Buffer[MAX_PATH]; PWCHAR HeapBuffer; UNICODE_STRING SystemRootString; UNICODE_STRING UnexpandedSystemRootString = RTL_CONSTANT_STRING(L"%SystemRoot%"); UNICODE_STRING BaseSrvCSDString; UNICODE_STRING BaseSrvWindowsDirectory; UNICODE_STRING BaseSrvWindowsSystemDirectory; UNICODE_STRING BnoString; OBJECT_ATTRIBUTES ObjectAttributes; ULONG SessionId; HANDLE BaseSrvNamedObjectDirectory; HANDLE BaseSrvRestrictedObjectDirectory; PACL BnoDacl, BnoRestrictedDacl; PSECURITY_DESCRIPTOR BnoSd; HANDLE SymHandle; UNICODE_STRING DirectoryName, SymlinkName; ULONG LuidEnabled; RTL_QUERY_REGISTRY_TABLE BaseServerRegistryConfigurationTable[2] = { { NULL, RTL_QUERY_REGISTRY_DIRECT, L"CSDVersion", &BaseSrvCSDString, REG_NONE, NULL, 0 }, {0} }; /* Initialize the memory */ BaseSrvHeap = RtlGetProcessHeap(); // Initialize our own heap. BaseSrvSharedHeap = LoadedServerDll->SharedSection; // Get the CSR shared heap. /* Get the session ID */ SessionId = NtCurrentPeb()->SessionId; /* Get the Windows directory */ RtlInitEmptyUnicodeString(&SystemRootString, Buffer, sizeof(Buffer)); Status = RtlExpandEnvironmentStrings_U(NULL, &UnexpandedSystemRootString, &SystemRootString, NULL); ASSERT(NT_SUCCESS(Status)); /* Create the base directory */ Buffer[SystemRootString.Length / sizeof(WCHAR)] = UNICODE_NULL; Success = RtlCreateUnicodeString(&BaseSrvWindowsDirectory, SystemRootString.Buffer); ASSERT(Success); /* Create the system directory */ wcscat(SystemRootString.Buffer, L"\\System32"); Success = RtlCreateUnicodeString(&BaseSrvWindowsSystemDirectory, SystemRootString.Buffer); ASSERT(Success); /* Create the kernel32 path */ wcscat(SystemRootString.Buffer, L"\\kernel32.dll"); Success = RtlCreateUnicodeString(&BaseSrvKernel32DllPath, SystemRootString.Buffer); ASSERT(Success); /* FIXME: Check Session ID */ wcscpy(Buffer, L"\\BaseNamedObjects"); RtlInitUnicodeString(&BnoString, Buffer); /* Allocate the server data */ BaseStaticServerData = RtlAllocateHeap(BaseSrvSharedHeap, HEAP_ZERO_MEMORY, sizeof(BASE_STATIC_SERVER_DATA)); ASSERT(BaseStaticServerData != NULL); /* Process timezone information */ BaseStaticServerData->TermsrvClientTimeZoneId = TIME_ZONE_ID_INVALID; BaseStaticServerData->TermsrvClientTimeZoneChangeNum = 0; Status = NtQuerySystemInformation(SystemTimeOfDayInformation, &BaseStaticServerData->TimeOfDay, sizeof(BaseStaticServerData->TimeOfDay), NULL); ASSERT(NT_SUCCESS(Status)); /* Make a shared heap copy of the Windows directory */ BaseStaticServerData->WindowsDirectory = BaseSrvWindowsDirectory; HeapBuffer = RtlAllocateHeap(BaseSrvSharedHeap, 0, BaseSrvWindowsDirectory.MaximumLength); ASSERT(HeapBuffer); RtlCopyMemory(HeapBuffer, BaseStaticServerData->WindowsDirectory.Buffer, BaseSrvWindowsDirectory.MaximumLength); BaseStaticServerData->WindowsDirectory.Buffer = HeapBuffer; /* Make a shared heap copy of the System directory */ BaseStaticServerData->WindowsSystemDirectory = BaseSrvWindowsSystemDirectory; HeapBuffer = RtlAllocateHeap(BaseSrvSharedHeap, 0, BaseSrvWindowsSystemDirectory.MaximumLength); ASSERT(HeapBuffer); RtlCopyMemory(HeapBuffer, BaseStaticServerData->WindowsSystemDirectory.Buffer, BaseSrvWindowsSystemDirectory.MaximumLength); BaseStaticServerData->WindowsSystemDirectory.Buffer = HeapBuffer; /* This string is not used */ RtlInitEmptyUnicodeString(&BaseStaticServerData->WindowsSys32x86Directory, NULL, 0); /* Make a shared heap copy of the BNO directory */ BaseStaticServerData->NamedObjectDirectory = BnoString; BaseStaticServerData->NamedObjectDirectory.MaximumLength = BnoString.Length + sizeof(UNICODE_NULL); HeapBuffer = RtlAllocateHeap(BaseSrvSharedHeap, 0, BaseStaticServerData->NamedObjectDirectory.MaximumLength); ASSERT(HeapBuffer); RtlCopyMemory(HeapBuffer, BaseStaticServerData->NamedObjectDirectory.Buffer, BaseStaticServerData->NamedObjectDirectory.MaximumLength); BaseStaticServerData->NamedObjectDirectory.Buffer = HeapBuffer; /* * Confirmed that in Windows, CSDNumber and RCNumber are actually Length * and MaximumLength of the CSD String, since the same UNICODE_STRING is * being queried twice, the first time as a ULONG! * * Somehow, in Windows this doesn't cause a buffer overflow, but it might * in ReactOS, so this code is disabled until someone figures out WTF. */ BaseStaticServerData->CSDNumber = 0; BaseStaticServerData->RCNumber = 0; /* Initialize the CSD string and query its value from the registry */ RtlInitEmptyUnicodeString(&BaseSrvCSDString, Buffer, sizeof(Buffer)); Status = RtlQueryRegistryValues(RTL_REGISTRY_WINDOWS_NT, L"", BaseServerRegistryConfigurationTable, NULL, NULL); if (NT_SUCCESS(Status)) { /* Copy into the shared buffer */ wcsncpy(BaseStaticServerData->CSDVersion, BaseSrvCSDString.Buffer, BaseSrvCSDString.Length / sizeof(WCHAR)); } else { /* NULL-terminate to indicate nothing is there */ BaseStaticServerData->CSDVersion[0] = UNICODE_NULL; } /* Cache the system information */ Status = NtQuerySystemInformation(SystemBasicInformation, &BaseStaticServerData->SysInfo, sizeof(BaseStaticServerData->SysInfo), NULL); ASSERT(NT_SUCCESS(Status)); /* Setup the ini file mappings */ Status = BaseSrvInitializeIniFileMappings(BaseStaticServerData); ASSERT(NT_SUCCESS(Status)); /* FIXME: Should query the registry for these */ BaseStaticServerData->DefaultSeparateVDM = FALSE; BaseStaticServerData->IsWowTaskReady = FALSE; /* Allocate a security descriptor and create it */ BnoSd = RtlAllocateHeap(BaseSrvHeap, 0, 1024); ASSERT(BnoSd); Status = RtlCreateSecurityDescriptor(BnoSd, SECURITY_DESCRIPTOR_REVISION); ASSERT(NT_SUCCESS(Status)); /* Create the BNO and \Restricted DACLs */ Status = CreateBaseAcls(&BnoDacl, &BnoRestrictedDacl); ASSERT(NT_SUCCESS(Status)); /* Set the BNO DACL as active for now */ Status = RtlSetDaclSecurityDescriptor(BnoSd, TRUE, BnoDacl, FALSE); ASSERT(NT_SUCCESS(Status)); /* Create the BNO directory */ RtlInitUnicodeString(&BnoString, L"\\BaseNamedObjects"); InitializeObjectAttributes(&ObjectAttributes, &BnoString, OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE, NULL, BnoSd); Status = NtCreateDirectoryObject(&BaseSrvNamedObjectDirectory, DIRECTORY_ALL_ACCESS, &ObjectAttributes); ASSERT(NT_SUCCESS(Status)); /* Check if we are session 0 */ if (SessionId == 0) { /* Mark this as a session 0 directory */ Status = NtSetInformationObject(BaseSrvNamedObjectDirectory, ObjectSessionInformation, NULL, 0); ASSERT(NT_SUCCESS(Status)); } /* Check if LUID device maps are enabled */ Status = NtQueryInformationProcess(NtCurrentProcess(), ProcessLUIDDeviceMapsEnabled, &LuidEnabled, sizeof(LuidEnabled), NULL); ASSERT(NT_SUCCESS(Status)); BaseStaticServerData->LUIDDeviceMapsEnabled = (BOOLEAN)LuidEnabled; if (!BaseStaticServerData->LUIDDeviceMapsEnabled) { /* Make Global point back to BNO */ RtlInitUnicodeString(&DirectoryName, L"Global"); RtlInitUnicodeString(&SymlinkName, L"\\BaseNamedObjects"); InitializeObjectAttributes(&ObjectAttributes, &DirectoryName, OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE, BaseSrvNamedObjectDirectory, BnoSd); Status = NtCreateSymbolicLinkObject(&SymHandle, SYMBOLIC_LINK_ALL_ACCESS, &ObjectAttributes, &SymlinkName); if ((NT_SUCCESS(Status)) && SessionId == 0) NtClose(SymHandle); /* Make local point back to \Sessions\x\BNO */ RtlInitUnicodeString(&DirectoryName, L"Local"); ASSERT(SessionId == 0); InitializeObjectAttributes(&ObjectAttributes, &DirectoryName, OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE, BaseSrvNamedObjectDirectory, BnoSd); Status = NtCreateSymbolicLinkObject(&SymHandle, SYMBOLIC_LINK_ALL_ACCESS, &ObjectAttributes, &SymlinkName); if ((NT_SUCCESS(Status)) && SessionId == 0) NtClose(SymHandle); /* Make Session point back to BNOLINKS */ RtlInitUnicodeString(&DirectoryName, L"Session"); RtlInitUnicodeString(&SymlinkName, L"\\Sessions\\BNOLINKS"); InitializeObjectAttributes(&ObjectAttributes, &DirectoryName, OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE, BaseSrvNamedObjectDirectory, BnoSd); Status = NtCreateSymbolicLinkObject(&SymHandle, SYMBOLIC_LINK_ALL_ACCESS, &ObjectAttributes, &SymlinkName); if ((NT_SUCCESS(Status)) && SessionId == 0) NtClose(SymHandle); /* Create the BNO\Restricted directory and set the restricted DACL */ RtlInitUnicodeString(&DirectoryName, L"Restricted"); Status = RtlSetDaclSecurityDescriptor(BnoSd, TRUE, BnoRestrictedDacl, FALSE); ASSERT(NT_SUCCESS(Status)); InitializeObjectAttributes(&ObjectAttributes, &DirectoryName, OBJ_OPENIF | OBJ_PERMANENT | OBJ_CASE_INSENSITIVE, BaseSrvNamedObjectDirectory, BnoSd); Status = NtCreateDirectoryObject(&BaseSrvRestrictedObjectDirectory, DIRECTORY_ALL_ACCESS, &ObjectAttributes); ASSERT(NT_SUCCESS(Status)); } /* Initialize NLS */ BaseSrvNLSInit(BaseStaticServerData); /* Finally, set the pointer */ LoadedServerDll->SharedSection = BaseStaticServerData; }
/********************************************************************** * NAME EXPORTED * SmLookupSubsystem/6 * * DESCRIPTION * Read from the registry key * \Registry\SYSTEM\CurrentControlSet\Control\Session Manager\Subsystems * the value which name is Name. * * ARGUMENTS * Name: name of the program to run, that is a value's name in * the SM registry key Subsystems; * Data: what the registry gave back for Name; * DataLength: how much Data the registry returns; * DataType: what is Data? * Environment: set it if you want this function to use it * to possibly expand Data before giving it back; if set * to NULL, no expansion will be performed. */ NTSTATUS WINAPI SmLookupSubsystem (IN PWSTR Name, IN OUT PWSTR Data, IN OUT PULONG DataLength, IN OUT PULONG DataType, IN PVOID Environment OPTIONAL) { NTSTATUS Status = STATUS_SUCCESS; UNICODE_STRING usKeyName = { 0, 0, NULL }; OBJECT_ATTRIBUTES Oa = {0}; HANDLE hKey = (HANDLE) 0; DPRINT("SM: %s(Name='%S') called\n", __FUNCTION__, Name); /* * Prepare the key name to scan and * related object attributes. */ RtlInitUnicodeString (& usKeyName, L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\SubSystems"); InitializeObjectAttributes (& Oa, & usKeyName, OBJ_CASE_INSENSITIVE, NULL, NULL); /* * Open the key. This MUST NOT fail, if the * request is for a legitimate subsystem. */ Status = NtOpenKey (& hKey, MAXIMUM_ALLOWED, & Oa); if(NT_SUCCESS(Status)) { UNICODE_STRING usValueName = { 0, 0, NULL }; PWCHAR KeyValueInformation = NULL; ULONG KeyValueInformationLength = 1024; ULONG ResultLength = 0L; PKEY_VALUE_PARTIAL_INFORMATION kvpi = NULL; KeyValueInformation = RtlAllocateHeap (RtlGetProcessHeap(), 0, KeyValueInformationLength); if (NULL == KeyValueInformation) { return STATUS_NO_MEMORY; } kvpi = (PKEY_VALUE_PARTIAL_INFORMATION) KeyValueInformation; RtlInitUnicodeString (& usValueName, Name); Status = NtQueryValueKey (hKey, & usValueName, KeyValuePartialInformation, KeyValueInformation, KeyValueInformationLength, & ResultLength); if(NT_SUCCESS(Status)) { DPRINT("nkvpi.TitleIndex = %ld\n", kvpi->TitleIndex); DPRINT("kvpi.Type = %ld\n", kvpi->Type); DPRINT("kvpi.DataLength = %ld\n", kvpi->DataLength); if((NULL != Data) && (NULL != DataLength) && (NULL != DataType)) { *DataType = kvpi->Type; if((NULL != Environment) && (REG_EXPAND_SZ == *DataType)) { UNICODE_STRING Source; PWCHAR DestinationBuffer = NULL; UNICODE_STRING Destination; ULONG Length = 0; DPRINT("SM: %s: value will be expanded\n", __FUNCTION__); DestinationBuffer = RtlAllocateHeap (RtlGetProcessHeap(), 0, (2 * KeyValueInformationLength)); if (NULL == DestinationBuffer) { Status = STATUS_NO_MEMORY; } else { Source.Length = kvpi->DataLength; Source.MaximumLength = kvpi->DataLength; Source.Buffer = (PWCHAR) & kvpi->Data; Destination.Length = 0; Destination.MaximumLength = (2 * KeyValueInformationLength); Destination.Buffer = DestinationBuffer; Status = RtlExpandEnvironmentStrings_U (Environment, & Source, & Destination, & Length); if(NT_SUCCESS(Status)) { *DataLength = min(*DataLength, Destination.Length); RtlCopyMemory (Data, Destination.Buffer, *DataLength); } RtlFreeHeap (RtlGetProcessHeap(), 0, DestinationBuffer); } }else{ DPRINT("SM: %s: value won't be expanded\n", __FUNCTION__); *DataLength = min(*DataLength, kvpi->DataLength); RtlCopyMemory (Data, & kvpi->Data, *DataLength); } *DataType = kvpi->Type; }else{ DPRINT1("SM: %s: Data or DataLength or DataType is NULL!\n", __FUNCTION__); Status = STATUS_INVALID_PARAMETER; } }else{ DPRINT1("%s: NtQueryValueKey failed (Status=0x%08lx)\n", __FUNCTION__, Status); } RtlFreeHeap (RtlGetProcessHeap(), 0, KeyValueInformation); NtClose (hKey); }else{ DPRINT1("%s: NtOpenKey failed (Status=0x%08lx)\n", __FUNCTION__, Status); } return Status; }