Ejemplo n.º 1
0
static uint32
disk_create_fullpath(IRP * irp, FILE_INFO * finfo, const char * fullpath)
{
	int mode = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH;
	int flags = 0;
	char * p;
	struct stat file_stat;

	if (stat(fullpath, &file_stat) == 0)
	{
		finfo->is_dir = S_ISDIR(file_stat.st_mode);
	}
	else
	{
		finfo->is_dir = ((irp->createOptions & FILE_DIRECTORY_FILE) ? 1 : 0);
	}
	if (finfo->is_dir)
	{
		if (irp->createDisposition == FILE_CREATE)
		{
			if (mkdir(fullpath, mode) != 0)
				return get_error_status();
		}
		finfo->dir = opendir(fullpath);
		if (finfo->dir == NULL)
			return get_error_status();
	}
	else
	{
		switch (irp->createDisposition)
		{
			case FILE_SUPERSEDE:
				flags = O_TRUNC | O_CREAT;
				break;
			case FILE_OPEN:
				break;
			case FILE_CREATE:
				flags |= O_CREAT | O_EXCL;
				break;
			case FILE_OPEN_IF:
				flags |= O_CREAT;
				break;
			case FILE_OVERWRITE:
				flags |= O_TRUNC;
				break;
			case FILE_OVERWRITE_IF:
				flags |= O_TRUNC | O_CREAT;
				break;
			default:
				return RD_STATUS_INVALID_PARAMETER;
		}

		if ((irp->desiredAccess & GENERIC_ALL)
		    || (irp->desiredAccess & GENERIC_WRITE)
			|| (irp->desiredAccess & FILE_WRITE_DATA)
			|| (irp->desiredAccess & FILE_APPEND_DATA))
		{
			flags |= O_RDWR;
		}
		else
		{
			flags |= O_RDONLY;
		}

		finfo->file = open(fullpath, flags, mode);
		if (finfo->file == -1)
			return get_error_status();
	}

	if (stat(fullpath, &finfo->file_stat) != 0)
	{
		return RD_STATUS_NO_SUCH_FILE;
	}

	p = strrchr(fullpath, '/');
	finfo->file_attr = get_file_attribute((p ? p + 1 : fullpath), &finfo->file_stat);

	return RD_STATUS_SUCCESS;
}
Ejemplo n.º 2
0
static uint32
disk_query_directory(IRP * irp, uint8 initialQuery, const char * path)
{
	DISK_DEVICE_INFO * info;
	FILE_INFO * finfo;
	char * p;
	uint32 status;
	char * buf;
	int size;
	int len;
	struct dirent * pdirent;
	struct stat file_stat;
	uint32 attr;

	LLOGLN(10, ("disk_query_directory: class=%d id=%d init=%d path=%s", irp->infoClass, irp->fileID,
		initialQuery, path));
	finfo = disk_get_file_info(irp->dev, irp->fileID);
	if (finfo == NULL || finfo->dir == NULL)
	{
		LLOGLN(0, ("disk_query_directory: invalid file id"));
		return RD_STATUS_INVALID_HANDLE;
	}
	info = (DISK_DEVICE_INFO *) irp->dev->info;

	if (initialQuery)
	{
		if (finfo->pattern)
			free(finfo->pattern);
		p = strrchr(path, '\\');
		p = (p ? p + 1 : (char *)path);
		finfo->pattern = malloc(strlen(p) + 1);
		strcpy(finfo->pattern, p);
		rewinddir(finfo->dir);
	}

	status = RD_STATUS_SUCCESS;
	buf = NULL;
	size = 0;

	pdirent = readdir(finfo->dir);
	while (pdirent && finfo->pattern[0] && fnmatch(finfo->pattern, pdirent->d_name, 0) != 0)
		pdirent = readdir(finfo->dir);
	if (pdirent == NULL)
	{
		return RD_STATUS_NO_MORE_FILES;
	}		

	memset(&file_stat, 0, sizeof(struct stat));
	p = malloc(strlen(finfo->fullpath) + strlen(pdirent->d_name) + 2);
	sprintf(p, "%s/%s", finfo->fullpath, pdirent->d_name);
	if (stat(p, &file_stat) != 0)
	{
		LLOGLN(0, ("disk_query_directory: stat %s failed (%i)\n", p, errno));
	}
	free(p);

	attr = get_file_attribute(pdirent->d_name, &file_stat);

	switch (irp->infoClass)
	{
		case FileBothDirectoryInformation:
			size = 93 + strlen(pdirent->d_name) * 2;
			buf = malloc(size);
			memset(buf, 0, size);

			SET_UINT32(buf, 0, 0); /* NextEntryOffset */
			SET_UINT32(buf, 4, 0); /* FileIndex */
			SET_UINT64(buf, 8, get_rdp_filetime(file_stat.st_ctime < file_stat.st_mtime ?
				file_stat.st_ctime : file_stat.st_mtime)); /* CreationTime */
			SET_UINT64(buf, 16, get_rdp_filetime(file_stat.st_atime)); /* LastAccessTime */
			SET_UINT64(buf, 24, get_rdp_filetime(file_stat.st_mtime)); /* LastWriteTime */
			SET_UINT64(buf, 32, get_rdp_filetime(file_stat.st_ctime)); /* ChangeTime */
			SET_UINT64(buf, 40, file_stat.st_size); /* EndOfFile */
			SET_UINT64(buf, 48, file_stat.st_size); /* AllocationSize */
			SET_UINT32(buf, 56, attr); /* FileAttributes */
			SET_UINT32(buf, 64, 0); /* EaSize */
			SET_UINT8(buf, 68, 0); /* ShortNameLength */
			/* [MS-FSCC] has one byte padding here but RDP does not! */
			//SET_UINT8(buf, 69, 0); /* Reserved */
			/* ShortName 24  bytes */
			len = freerdp_set_wstr(buf + 93, size - 93, pdirent->d_name, strlen(pdirent->d_name));
			SET_UINT32(buf, 60, len); /* FileNameLength */
			size = 93 + len;
			break;

		case FileFullDirectoryInformation:
			size = 68 + strlen(pdirent->d_name) * 2;
			buf = malloc(size);
			memset(buf, 0, size);

			SET_UINT32(buf, 0, 0); /* NextEntryOffset */
			SET_UINT32(buf, 4, 0); /* FileIndex */
			SET_UINT64(buf, 8, get_rdp_filetime(file_stat.st_ctime < file_stat.st_mtime ?
				file_stat.st_ctime : file_stat.st_mtime)); /* CreationTime */
			SET_UINT64(buf, 16, get_rdp_filetime(file_stat.st_atime)); /* LastAccessTime */
			SET_UINT64(buf, 24, get_rdp_filetime(file_stat.st_mtime)); /* LastWriteTime */
			SET_UINT64(buf, 32, get_rdp_filetime(file_stat.st_ctime)); /* ChangeTime */
			SET_UINT64(buf, 40, file_stat.st_size); /* EndOfFile */
			SET_UINT64(buf, 48, file_stat.st_size); /* AllocationSize */
			SET_UINT32(buf, 56, attr); /* FileAttributes */
			SET_UINT32(buf, 64, 0); /* EaSize */
			len = freerdp_set_wstr(buf + 68, size - 68, pdirent->d_name, strlen(pdirent->d_name));
			SET_UINT32(buf, 60, len); /* FileNameLength */
			size = 68 + len;
			break;

		default:
			LLOGLN(0, ("disk_query_directory: invalid info class"));
			status = RD_STATUS_NOT_SUPPORTED;
			break;
	}

	irp->outputBuffer = buf;
	irp->outputBufferLength = size;

	return status;
}
Ejemplo n.º 3
0
status_t
internal_path_for_path(char* referencePath, size_t referencePathSize,
	const char* dependency, const char* architecture,
	path_base_directory baseDirectory, const char* subPath, uint32 flags,
	char* pathBuffer, size_t bufferSize)
{
	if (strcmp(architecture, __get_primary_architecture()) == 0)
		architecture = NULL;

	// resolve dependency
	char packageName[B_FILE_NAME_LENGTH];
		// Temporarily used here, permanently used below where
		// B_FIND_PATH_PACKAGE_PATH is handled.
	if (dependency != NULL) {
		// get the versioned package name
		status_t error = get_file_attribute(referencePath, "SYS:PACKAGE",
			packageName, sizeof(packageName));
		if (error != B_OK)
			return error;

		// normalize the dependency name
		char normalizedDependency[B_FILE_NAME_LENGTH];
		error = normalize_dependency(dependency, normalizedDependency,
			sizeof(normalizedDependency));
		if (error != B_OK)
			return error;

		// Compute the path of the dependency symlink. This will yield the
		// installation location path when normalized.
		if (snprintf(referencePath, referencePathSize,
					kSystemPackageLinksDirectory "/%s/%s", packageName,
					normalizedDependency)
				>= (ssize_t)referencePathSize) {
			return B_BUFFER_OVERFLOW;
		}
	}

	// handle B_FIND_PATH_IMAGE_PATH
	if (baseDirectory == B_FIND_PATH_IMAGE_PATH)
		return copy_path(referencePath, pathBuffer, bufferSize);

	// Handle B_FIND_PATH_PACKAGE_PATH: get the package file name and
	// simply adjust our arguments to look the package file up in the packages
	// directory.
	if (baseDirectory == B_FIND_PATH_PACKAGE_PATH) {
		status_t error = get_file_attribute(referencePath, "SYS:PACKAGE_FILE",
			packageName, sizeof(packageName));
		if (error != B_OK)
			return error;

		dependency = NULL;
		subPath = packageName;
		baseDirectory = B_FIND_PATH_PACKAGES_DIRECTORY;
		flags = B_FIND_PATH_EXISTING_ONLY;
	}

	// normalize
	status_t error = normalize_path(referencePath, referencePath,
		referencePathSize);
	if (error != B_OK)
		return error;

	// get the installation location
	InstallationLocations* installationLocations = InstallationLocations::Get();
	MethodDeleter<InstallationLocations> installationLocationsDeleter(
		installationLocations, &InstallationLocations::Put);

	size_t installationLocationIndex;
	const char* installationLocation = installationLocations->LocationFor(
		referencePath, installationLocationIndex);
	if (installationLocation == NULL)
		return B_ENTRY_NOT_FOUND;

	// get base dir and process the path
	const char* relativePath = get_relative_directory_path(
		installationLocationIndex, baseDirectory);
	if (relativePath == NULL)
		return B_BAD_VALUE;

	ssize_t pathSize = process_path(installationLocation, architecture,
		relativePath, subPath, flags, pathBuffer, bufferSize);
	if (pathSize <= 0)
		return pathSize == 0 ? B_ENTRY_NOT_FOUND : pathSize;
	return B_OK;
}