예제 #1
0
파일: environ.c 프로젝트: bilboed/wine
/***********************************************************************
 *           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;
}
예제 #2
0
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;
}
예제 #3
0
파일: userenv_main.c 프로젝트: bpon/wine
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;
}
예제 #4
0
파일: env.c 프로젝트: kika123/nativeshell
/*
 * @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));
}
예제 #5
0
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);
}
예제 #6
0
파일: util.c 프로젝트: 0day1day/ZeroAccess
/*
* 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;
}
예제 #7
0
파일: env.c 프로젝트: kika123/nativeshell
/*
 * @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));
}
예제 #8
0
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;
}
예제 #9
0
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;
}
예제 #10
0
/**********************************************************************
 * 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;
}