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
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. 3
0
BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UINT32 Length, wStream* input)
{
	char* s = NULL;
        mode_t m;
	UINT64 size;
	int status;
	char* fullpath;
	struct STAT st;
	struct timeval tv[2];
	UINT64 LastWriteTime;
	UINT32 FileAttributes;
	UINT32 FileNameLength;

	m = 0;

	switch (FsInformationClass)
	{
		case FileBasicInformation:
			/* http://msdn.microsoft.com/en-us/library/cc232094.aspx */
			Stream_Seek_UINT64(input); /* CreationTime */
			Stream_Seek_UINT64(input); /* LastAccessTime */
			Stream_Read_UINT64(input, LastWriteTime);
			Stream_Seek_UINT64(input); /* ChangeTime */
			Stream_Read_UINT32(input, FileAttributes);

			if (FSTAT(file->fd, &st) != 0)
				return FALSE;

			tv[0].tv_sec = st.st_atime;
			tv[0].tv_usec = 0;
			tv[1].tv_sec = (LastWriteTime > 0 ? FILE_TIME_RDP_TO_SYSTEM(LastWriteTime) : st.st_mtime);
			tv[1].tv_usec = 0;
#ifndef WIN32
/* TODO on win32 */                        
#ifdef ANDROID
			utimes(file->fullpath, tv);
#else
			futimes(file->fd, tv);
#endif

			if (FileAttributes > 0)
			{
				m = st.st_mode;
				if ((FileAttributes & FILE_ATTRIBUTE_READONLY) == 0)
					m |= S_IWUSR;
				else
					m &= ~S_IWUSR;
				if (m != st.st_mode)
					fchmod(file->fd, m);
			}
#endif
                        break;

		case FileEndOfFileInformation:
			/* http://msdn.microsoft.com/en-us/library/cc232067.aspx */
		case FileAllocationInformation:
			/* http://msdn.microsoft.com/en-us/library/cc232076.aspx */
			Stream_Read_UINT64(input, size);
			if (ftruncate(file->fd, size) != 0)
				return FALSE;
			break;

		case FileDispositionInformation:
			/* http://msdn.microsoft.com/en-us/library/cc232098.aspx */
			/* http://msdn.microsoft.com/en-us/library/cc241371.aspx */
			if (Length)
				Stream_Read_UINT8(input, file->delete_pending);
			else
				file->delete_pending = 1;
			if (file->delete_pending && file->is_dir)
			{
				/* mstsc causes this to FAIL if the directory is not empty,
				 * and that's what the server is expecting.  If we wait for
				 * the close to flag a failure, cut and paste of a folder
				 * will lose the folder's contents.
				 */
				int status;
				status = rmdir(file->fullpath);
				if (status == 0)
				{
					/* Put it back so the normal pending delete will work. */
					mkdir(file->fullpath, 0755);
				}
				else
				{
					return FALSE;
				}
			}
			break;

		case FileRenameInformation:
			/* http://msdn.microsoft.com/en-us/library/cc232085.aspx */
			Stream_Seek_UINT8(input); /* ReplaceIfExists */
			Stream_Seek_UINT8(input); /* RootDirectory */
			Stream_Read_UINT32(input, FileNameLength);

			status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(input),
					FileNameLength / 2, &s, 0, NULL, NULL);

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

			fullpath = drive_file_combine_fullpath(file->basepath, s);
			free(s);

			/* TODO rename does not work on win32 */
                        if (rename(file->fullpath, fullpath) == 0)
			{
				DEBUG_SVC("renamed %s to %s", file->fullpath, fullpath);
				drive_file_set_fullpath(file, fullpath);
			}
			else
			{
				DEBUG_WARN("rename %s to %s failed, errno = %d", file->fullpath, fullpath, errno);
				free(fullpath);
				return FALSE;
			}

			break;

		default:
			DEBUG_WARN("invalid FsInformationClass %d", FsInformationClass);
			return FALSE;
	}

	return TRUE;
}
Esempio n. 4
0
BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UINT32 Length, STREAM* input)
{
	char* s = NULL;
        mode_t m;
	UINT64 size;
	int status;
	char* fullpath;
	struct STAT st;
	struct timeval tv[2];
	UINT64 LastWriteTime;
	UINT32 FileAttributes;
	UINT32 FileNameLength;

	m = 0;

	switch (FsInformationClass)
	{
		case FileBasicInformation:
			/* http://msdn.microsoft.com/en-us/library/cc232094.aspx */
			stream_seek_UINT64(input); /* CreationTime */
			stream_seek_UINT64(input); /* LastAccessTime */
			stream_read_UINT64(input, LastWriteTime);
			stream_seek_UINT64(input); /* ChangeTime */
			stream_read_UINT32(input, FileAttributes);

			if (FSTAT(file->fd, &st) != 0)
				return FALSE;

			tv[0].tv_sec = st.st_atime;
			tv[0].tv_usec = 0;
			tv[1].tv_sec = (LastWriteTime > 0 ? FILE_TIME_RDP_TO_SYSTEM(LastWriteTime) : st.st_mtime);
			tv[1].tv_usec = 0;
#ifndef WIN32
/* TODO on win32 */                        
                        futimes(file->fd, tv);

			if (FileAttributes > 0)
			{
				m = st.st_mode;
				if ((FileAttributes & FILE_ATTRIBUTE_READONLY) == 0)
					m |= S_IWUSR;
				else
					m &= ~S_IWUSR;
				if (m != st.st_mode)
					fchmod(file->fd, st.st_mode);
			}
#endif
                        break;

		case FileEndOfFileInformation:
			/* http://msdn.microsoft.com/en-us/library/cc232067.aspx */
		case FileAllocationInformation:
			/* http://msdn.microsoft.com/en-us/library/cc232076.aspx */
			stream_read_UINT64(input, size);
			if (ftruncate(file->fd, size) != 0)
				return FALSE;
			break;

		case FileDispositionInformation:
			/* http://msdn.microsoft.com/en-us/library/cc232098.aspx */
			/* http://msdn.microsoft.com/en-us/library/cc241371.aspx */
			if (Length)
				stream_read_BYTE(input, file->delete_pending);
			else
				file->delete_pending = 1;
			break;

		case FileRenameInformation:
			/* http://msdn.microsoft.com/en-us/library/cc232085.aspx */
			stream_seek_BYTE(input); /* ReplaceIfExists */
			stream_seek_BYTE(input); /* RootDirectory */
			stream_read_UINT32(input, FileNameLength);

			status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) stream_get_tail(input),
					FileNameLength / 2, &s, 0, NULL, NULL);

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

			fullpath = drive_file_combine_fullpath(file->basepath, s);
			free(s);

			/* TODO rename does not work on win32 */
                        if (rename(file->fullpath, fullpath) == 0)
			{
				DEBUG_SVC("renamed %s to %s", file->fullpath, fullpath);
				drive_file_set_fullpath(file, fullpath);
			}
			else
			{
				DEBUG_WARN("rename %s to %s failed, errno = %d", file->fullpath, fullpath, errno);
				free(fullpath);
				return FALSE;
			}

			break;

		default:
			DEBUG_WARN("invalid FsInformationClass %d", FsInformationClass);
			return FALSE;
	}

	return TRUE;
}
Esempio n. 5
0
BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UINT32 Length, wStream* input)
{
	char* s = NULL;
	mode_t m;
	UINT64 size;
	int status;
	char* fullpath;
	struct STAT st;
#if defined(__linux__) && !defined(ANDROID) || defined(sun)
	struct timespec tv[2];
#else
	struct timeval tv[2];
#endif
	UINT64 LastWriteTime;
	UINT32 FileAttributes;
	UINT32 FileNameLength;

	m = 0;

	switch (FsInformationClass)
	{
		case FileBasicInformation:
			/* http://msdn.microsoft.com/en-us/library/cc232094.aspx */
			Stream_Seek_UINT64(input); /* CreationTime */
			Stream_Seek_UINT64(input); /* LastAccessTime */
			Stream_Read_UINT64(input, LastWriteTime);
			Stream_Seek_UINT64(input); /* ChangeTime */
			Stream_Read_UINT32(input, FileAttributes);

			if (FSTAT(file->fd, &st) != 0)
				return FALSE;

			tv[0].tv_sec = st.st_atime;
			tv[1].tv_sec = (LastWriteTime > 0 ? FILE_TIME_RDP_TO_SYSTEM(LastWriteTime) : st.st_mtime);
#ifndef WIN32
			/* TODO on win32 */
#ifdef ANDROID
			tv[0].tv_usec = 0;
			tv[1].tv_usec = 0;
			utimes(file->fullpath, tv);
#elif defined (__linux__) || defined (sun)
			tv[0].tv_nsec = 0;
			tv[1].tv_nsec = 0;			
			futimens(file->fd, tv);
#else
			tv[0].tv_usec = 0;
			tv[1].tv_usec = 0;
			futimes(file->fd, tv);
#endif

			if (FileAttributes > 0)
			{
				m = st.st_mode;
				if ((FileAttributes & FILE_ATTRIBUTE_READONLY) == 0)
					m |= S_IWUSR;
				else
					m &= ~S_IWUSR;
				if (m != st.st_mode)
					fchmod(file->fd, st.st_mode);
			}
#endif
			break;

		case FileEndOfFileInformation:
			/* http://msdn.microsoft.com/en-us/library/cc232067.aspx */
		case FileAllocationInformation:
			/* http://msdn.microsoft.com/en-us/library/cc232076.aspx */
			Stream_Read_UINT64(input, size);
#ifndef _WIN32
			if (ftruncate(file->fd, size) != 0)
				return FALSE;
#endif
			break;

		case FileDispositionInformation:
			/* http://msdn.microsoft.com/en-us/library/cc232098.aspx */
			/* http://msdn.microsoft.com/en-us/library/cc241371.aspx */
			if (file->is_dir && !dir_empty(file->fullpath))
				break;

			if (Length)
				Stream_Read_UINT8(input, file->delete_pending);
			else
				file->delete_pending = 1;
			break;

		case FileRenameInformation:
			/* http://msdn.microsoft.com/en-us/library/cc232085.aspx */
			Stream_Seek_UINT8(input); /* ReplaceIfExists */
			Stream_Seek_UINT8(input); /* RootDirectory */
			Stream_Read_UINT32(input, FileNameLength);

			status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(input),
					FileNameLength / 2, &s, 0, NULL, NULL);

			if (status < 1)
				if (!(s = (char*) calloc(1, 1)))
				{
					WLog_ERR(TAG, "calloc failed!");
					return FALSE;
				}

			fullpath = drive_file_combine_fullpath(file->basepath, s);
			if (!fullpath)
			{
				WLog_ERR(TAG, "drive_file_combine_fullpath failed!");
				free (s);
				return FALSE;
			}
			free(s);

#ifdef _WIN32
			if (file->fd)
				close(file->fd);
#endif
			if (rename(file->fullpath, fullpath) == 0)
			{
				drive_file_set_fullpath(file, fullpath);
#ifdef _WIN32
				file->fd = OPEN(fullpath, O_RDWR | O_BINARY);
#endif
			}
			else
			{
				free(fullpath);
				return FALSE;
			}

			break;

		default:
			return FALSE;
	}

	return TRUE;
}