Blame winpr/libwinpr/shell/shell.c

Packit 1fb8d4
/**
Packit 1fb8d4
 * WinPR: Windows Portable Runtime
Packit 1fb8d4
 * Shell Functions
Packit 1fb8d4
 *
Packit 1fb8d4
 * Copyright 2015 Dell Software <Mike.McDonald@software.dell.com>
Packit 1fb8d4
 *
Packit 1fb8d4
 * Licensed under the Apache License, Version 2.0 (the "License");
Packit 1fb8d4
 * you may not use this file except in compliance with the License.
Packit 1fb8d4
 * You may obtain a copy of the License at
Packit 1fb8d4
 *
Packit 1fb8d4
 *     http://www.apache.org/licenses/LICENSE-2.0
Packit 1fb8d4
 *
Packit 1fb8d4
 * Unless required by applicable law or agreed to in writing, software
Packit 1fb8d4
 * distributed under the License is distributed on an "AS IS" BASIS,
Packit 1fb8d4
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Packit 1fb8d4
 * See the License for the specific language governing permissions and
Packit 1fb8d4
 * limitations under the License.
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
#ifdef HAVE_CONFIG_H
Packit 1fb8d4
#include "config.h"
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#include <winpr/shell.h>
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * shell32.dll:
Packit 1fb8d4
 *
Packit 1fb8d4
 * GetUserProfileDirectoryA
Packit 1fb8d4
 * GetUserProfileDirectoryW
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
#ifndef _WIN32
Packit 1fb8d4
Packit 1fb8d4
#include <winpr/crt.h>
Packit 1fb8d4
Packit 1fb8d4
#ifdef HAVE_UNISTD_H
Packit 1fb8d4
#include <unistd.h>
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#include <pwd.h>
Packit 1fb8d4
#include <grp.h>
Packit 1fb8d4
Packit 1fb8d4
#include "../handle/handle.h"
Packit 1fb8d4
Packit 1fb8d4
#include "../security/security.h"
Packit 1fb8d4
Packit 1fb8d4
BOOL GetUserProfileDirectoryA(HANDLE hToken, LPSTR lpProfileDir, LPDWORD lpcchSize)
Packit 1fb8d4
{
Packit 1fb8d4
	char* buf;
Packit 1fb8d4
	int buflen;
Packit 1fb8d4
	int status;
Packit 1fb8d4
	DWORD cchDirSize;
Packit 1fb8d4
	struct passwd pwd;
Packit 1fb8d4
	struct passwd* pw = NULL;
Packit 1fb8d4
	WINPR_ACCESS_TOKEN* token;
Packit Service 5a9772
	token = (WINPR_ACCESS_TOKEN*)hToken;
Packit 1fb8d4
Packit 1fb8d4
	if (!token || (token->Type != HANDLE_TYPE_ACCESS_TOKEN) || !lpcchSize)
Packit 1fb8d4
	{
Packit 1fb8d4
		SetLastError(ERROR_INVALID_PARAMETER);
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
Packit 1fb8d4
Packit 1fb8d4
	if (buflen == -1)
Packit 1fb8d4
		buflen = 8196;
Packit 1fb8d4
Packit Service 5a9772
	buf = (char*)malloc(buflen);
Packit 1fb8d4
Packit 1fb8d4
	if (!buf)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	status = getpwnam_r(token->Username, &pwd, buf, buflen, &pw;;
Packit 1fb8d4
Packit 1fb8d4
	if ((status != 0) || !pw)
Packit 1fb8d4
	{
Packit 1fb8d4
		SetLastError(ERROR_INVALID_PARAMETER);
Packit 1fb8d4
		free(buf);
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	cchDirSize = strlen(pw->pw_dir) + 1;
Packit 1fb8d4
Packit 1fb8d4
	if (!lpProfileDir || (*lpcchSize < cchDirSize))
Packit 1fb8d4
	{
Packit 1fb8d4
		*lpcchSize = cchDirSize;
Packit 1fb8d4
		SetLastError(ERROR_INSUFFICIENT_BUFFER);
Packit 1fb8d4
		free(buf);
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	ZeroMemory(lpProfileDir, *lpcchSize);
Packit 1fb8d4
	sprintf_s(lpProfileDir, *lpcchSize, "%s", pw->pw_dir);
Packit 1fb8d4
	*lpcchSize = cchDirSize;
Packit 1fb8d4
	free(buf);
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL GetUserProfileDirectoryW(HANDLE hToken, LPWSTR lpProfileDir, LPDWORD lpcchSize)
Packit 1fb8d4
{
Packit 1fb8d4
	BOOL bStatus;
Packit 1fb8d4
	DWORD cchSizeA;
Packit 1fb8d4
	LPSTR lpProfileDirA;
Packit 1fb8d4
Packit 1fb8d4
	if (!lpcchSize)
Packit 1fb8d4
	{
Packit 1fb8d4
		SetLastError(ERROR_INVALID_PARAMETER);
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	cchSizeA = *lpcchSize;
Packit 1fb8d4
	lpProfileDirA = NULL;
Packit 1fb8d4
Packit 1fb8d4
	if (lpProfileDir)
Packit 1fb8d4
	{
Packit Service 5a9772
		lpProfileDirA = (LPSTR)malloc(cchSizeA);
Packit 1fb8d4
Packit 1fb8d4
		if (lpProfileDirA == NULL)
Packit 1fb8d4
		{
Packit 1fb8d4
			SetLastError(ERROR_OUTOFMEMORY);
Packit 1fb8d4
			return FALSE;
Packit 1fb8d4
		}
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	bStatus = GetUserProfileDirectoryA(hToken, lpProfileDirA, &cchSizeA);
Packit 1fb8d4
Packit 1fb8d4
	if (bStatus)
Packit 1fb8d4
	{
Packit 1fb8d4
		MultiByteToWideChar(CP_ACP, 0, lpProfileDirA, cchSizeA, lpProfileDir, *lpcchSize);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (lpProfileDirA)
Packit 1fb8d4
	{
Packit 1fb8d4
		free(lpProfileDirA);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	*lpcchSize = cchSizeA;
Packit 1fb8d4
	return bStatus;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif