Esempio n. 1
0
DRIVE_FILE* drive_file_new(const char* base_path, const char* path, UINT32 id,
	UINT32 DesiredAccess, UINT32 CreateDisposition, UINT32 CreateOptions)
{
	DRIVE_FILE* file;

	file = (DRIVE_FILE*) calloc(1, sizeof(DRIVE_FILE));
	if (!file)
	{
		WLog_ERR(TAG, "calloc failed!");
		return NULL;
	}

	file->id = id;
	file->basepath = (char*) base_path;
	drive_file_set_fullpath(file, drive_file_combine_fullpath(base_path, path));
	file->fd = -1;

	if (!drive_file_init(file, DesiredAccess, CreateDisposition, CreateOptions))
	{
		drive_file_free(file);
		return NULL;
	}

#if defined(__linux__) && defined(O_PATH)
	if (file->fd < 0 && file->err == EACCES)
	{
		/**
		 * We have no access permissions for the file or directory but if the
		 * peer is only interested in reading the object's attributes we can try
		 * to obtain a file descriptor who's only purpose is to perform
		 * operations that act purely at the file descriptor level.
		 * See open(2)
		 **/
		 {
			if ((file->fd = OPEN(file->fullpath, O_PATH)) >= 0)
			{
				file->err = 0;
			}
		 }
	}
#endif

	return file;
}
Esempio n. 2
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT drive_process_irp_close(DRIVE_DEVICE* drive, IRP* irp)
{
	void* key;
	DRIVE_FILE* file;
	file = drive_get_file_by_id(drive, irp->FileId);
	key = (void*)(size_t) irp->FileId;

	if (!file)
	{
		irp->IoStatus = STATUS_UNSUCCESSFUL;
	}
	else
	{
		ListDictionary_Remove(drive->files, key);
		drive_file_free(file);
	}

	Stream_Zero(irp->output, 5); /* Padding(5) */
	return irp->Complete(irp);
}
Esempio n. 3
0
DRIVE_FILE* drive_file_new(const char* base_path, const char* path, UINT32 id,
	UINT32 DesiredAccess, UINT32 CreateDisposition, UINT32 CreateOptions)
{
	DRIVE_FILE* file;

	file = (DRIVE_FILE*) malloc(sizeof(DRIVE_FILE));
	ZeroMemory(file, sizeof(DRIVE_FILE));

	file->id = id;
	file->basepath = (char*) base_path;
	drive_file_set_fullpath(file, drive_file_combine_fullpath(base_path, path));
	file->fd = -1;

	if (!drive_file_init(file, DesiredAccess, CreateDisposition, CreateOptions))
	{
		(void) drive_file_free(file, TRUE);
		return NULL;
	}

	return file;
}
Esempio n. 4
0
static void drive_free(DEVICE* device)
{
	IRP* irp;
	DRIVE_FILE* file;
	DRIVE_DEVICE* disk = (DRIVE_DEVICE*) device;

	SetEvent(disk->stopEvent);
	CloseHandle(disk->thread);
	CloseHandle(disk->irpEvent);

	while ((irp = (IRP*) InterlockedPopEntrySList(disk->pIrpList)) != NULL)
		irp->Discard(irp);

	_aligned_free(disk->pIrpList);

	while ((file = (DRIVE_FILE*) list_dequeue(disk->files)) != NULL)
		drive_file_free(file);

	list_free(disk->files);

	free(disk);
}
Esempio n. 5
0
static void drive_process_irp_close(DRIVE_DEVICE* disk, IRP* irp)
{
	DRIVE_FILE* file;

	file = drive_get_file_by_id(disk, irp->FileId);

	if (file == NULL)
	{
		irp->IoStatus = STATUS_UNSUCCESSFUL;

		DEBUG_WARN("FileId %d not valid.", irp->FileId);
	}
	else
	{
		DEBUG_SVC("%s(%d) closed.", file->fullpath, file->id);

		list_remove(disk->files, file);
		drive_file_free(file);
	}

	stream_write_zero(irp->output, 5); /* Padding(5) */

	irp->Complete(irp);
}
Esempio n. 6
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT drive_process_irp_create(DRIVE_DEVICE* drive, IRP* irp)
{
	int status;
	void* key;
	UINT32 FileId;
	DRIVE_FILE* file;
	BYTE Information;
	UINT32 DesiredAccess;
	UINT32 CreateDisposition;
	UINT32 CreateOptions;
	UINT32 PathLength;
	char* path = NULL;
	Stream_Read_UINT32(irp->input, DesiredAccess);
	Stream_Seek(irp->input,
	            16); /* AllocationSize(8), FileAttributes(4), SharedAccess(4) */
	Stream_Read_UINT32(irp->input, CreateDisposition);
	Stream_Read_UINT32(irp->input, CreateOptions);
	Stream_Read_UINT32(irp->input, PathLength);
	status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(irp->input),
	                            PathLength / 2, &path, 0, NULL, NULL);

	if (status < 1)
	{
		path = (char*) calloc(1, 1);

		if (!path)
		{
			WLog_ERR(TAG, "calloc failed!");
			return CHANNEL_RC_NO_MEMORY;
		}
	}

	FileId = irp->devman->id_sequence++;
	file = drive_file_new(drive->path, path, FileId,
	                      DesiredAccess, CreateDisposition, CreateOptions);

	if (!file)
	{
		irp->IoStatus = STATUS_UNSUCCESSFUL;
		FileId = 0;
		Information = 0;
	}
	else if (file->err)
	{
		FileId = 0;
		Information = 0;
		/* map errno to windows result */
		irp->IoStatus = drive_map_posix_err(file->err);
		drive_file_free(file);
	}
	else
	{
		key = (void*)(size_t) file->id;

		if (!ListDictionary_Add(drive->files, key, file))
		{
			WLog_ERR(TAG, "ListDictionary_Add failed!");
			free(path);
			return ERROR_INTERNAL_ERROR;
		}

		switch (CreateDisposition)
		{
			case FILE_SUPERSEDE:
			case FILE_OPEN:
			case FILE_CREATE:
			case FILE_OVERWRITE:
				Information = FILE_SUPERSEDED;
				break;

			case FILE_OPEN_IF:
				Information = FILE_OPENED;
				break;

			case FILE_OVERWRITE_IF:
				Information = FILE_OVERWRITTEN;
				break;

			default:
				Information = 0;
				break;
		}
	}

	Stream_Write_UINT32(irp->output, FileId);
	Stream_Write_UINT8(irp->output, Information);
	free(path);
	return irp->Complete(irp);
}
Esempio n. 7
0
static void drive_process_irp_create(DRIVE_DEVICE* disk, IRP* irp)
{
	char* path;
	int status;
	UINT32 FileId;
	DRIVE_FILE* file;
	BYTE Information;
	UINT32 DesiredAccess;
	UINT32 CreateDisposition;
	UINT32 CreateOptions;
	UINT32 PathLength;

	stream_read_UINT32(irp->input, DesiredAccess);
	stream_seek(irp->input, 16); /* AllocationSize(8), FileAttributes(4), SharedAccess(4) */
	stream_read_UINT32(irp->input, CreateDisposition);
	stream_read_UINT32(irp->input, CreateOptions);
	stream_read_UINT32(irp->input, PathLength);

	status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) stream_get_tail(irp->input),
			PathLength / 2, &path, 0, NULL, NULL);

	if (status < 1)
		path = (char*) calloc(1, 1);

	FileId = irp->devman->id_sequence++;

	file = drive_file_new(disk->path, path, FileId,
		DesiredAccess, CreateDisposition, CreateOptions);

	if (file == NULL)
	{
		irp->IoStatus = STATUS_UNSUCCESSFUL;
		FileId = 0;
		Information = 0;

		DEBUG_WARN("failed to create %s.", path);
	}
	else if (file->err)
	{
		FileId = 0;
		Information = 0;

		/* map errno to windows result */
		irp->IoStatus = drive_map_posix_err(file->err);
		drive_file_free(file);
	}
	else
	{
		list_enqueue(disk->files, file);

		switch (CreateDisposition)
		{
			case FILE_SUPERSEDE:
			case FILE_OPEN:
			case FILE_CREATE:
			case FILE_OVERWRITE:
				Information = FILE_SUPERSEDED;
				break;
			case FILE_OPEN_IF:
				Information = FILE_OPENED;
				break;
			case FILE_OVERWRITE_IF:
				Information = FILE_OVERWRITTEN;
				break;
			default:
				Information = 0;
				break;
		}
		DEBUG_SVC("%s(%d) created.", file->fullpath, file->id);
	}

	stream_write_UINT32(irp->output, FileId);
	stream_write_BYTE(irp->output, Information);

	free(path);

	irp->Complete(irp);
}