wfreerdp: merging with win32 integration branch

This commit is contained in:
Marc-André Moreau
2012-10-02 11:05:21 -04:00
23 changed files with 1054 additions and 78 deletions

3
.gitignore vendored
View File

@@ -27,9 +27,12 @@ client/X11/xfreerdp.1
# Windows
*.vcxproj
*.vcxproj.*
*.vcproj
*.vcproj.*
*.sdf
*.sln
*.suo
*.ncb
*.opensdf
ipch
Debug

View File

@@ -62,6 +62,10 @@ if(NOT DEFINED BUILD_SHARED_LIBS)
set(BUILD_SHARED_LIBS ON)
endif()
if(NOT BUILD_SHARED_LIBS AND WITH_MONOLITHIC_BUILD)
set(WITH_STATIC_PLUGINS ON)
endif()
# Configure MSVC Runtime
if(MSVC)
include(MSVCRuntime)
@@ -76,6 +80,7 @@ if(MSVC)
configure_msvc_runtime()
endif()
# Compiler-specific flags
if(CMAKE_COMPILER_IS_GNUCC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")

View File

@@ -40,9 +40,9 @@ endif()
install(TARGETS rdpdr DESTINATION ${FREERDP_PLUGIN_PATH})
add_subdirectory(disk)
add_subdirectory(printer)
if(NOT WIN32)
add_subdirectory(disk)
add_subdirectory(printer)
add_subdirectory(parallel)
add_subdirectory(serial)
endif()

View File

@@ -24,6 +24,13 @@ set(${MODULE_PREFIX}_SRCS
disk_file.c
disk_file.h
disk_main.c)
if(WIN32)
set(${MODULE_PREFIX}_SRCS
statvfs.c
statvfs.h
dirent.h)
endif()
include_directories(..)

View File

@@ -0,0 +1,374 @@
/*****************************************************************************
* dirent.h - dirent API for Microsoft Visual Studio
*
* Copyright (C) 2006 Toni Ronkko
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* ``Software''), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL TONI RONKKO BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Mar 15, 2011, Toni Ronkko
* Defined FILE_ATTRIBUTE_DEVICE for MSVC 6.0.
*
* Aug 11, 2010, Toni Ronkko
* Added d_type and d_namlen fields to dirent structure. The former is
* especially useful for determining whether directory entry represents a
* file or a directory. For more information, see
* http://www.delorie.com/gnu/docs/glibc/libc_270.html
*
* Aug 11, 2010, Toni Ronkko
* Improved conformance to the standards. For example, errno is now set
* properly on failure and assert() is never used. Thanks to Peter Brockam
* for suggestions.
*
* Aug 11, 2010, Toni Ronkko
* Fixed a bug in rewinddir(): when using relative directory names, change
* of working directory no longer causes rewinddir() to fail.
*
* Dec 15, 2009, John Cunningham
* Added rewinddir member function
*
* Jan 18, 2008, Toni Ronkko
* Using FindFirstFileA and WIN32_FIND_DATAA to avoid converting string
* between multi-byte and unicode representations. This makes the
* code simpler and also allows the code to be compiled under MingW. Thanks
* to Azriel Fasten for the suggestion.
*
* Mar 4, 2007, Toni Ronkko
* Bug fix: due to the strncpy_s() function this file only compiled in
* Visual Studio 2005. Using the new string functions only when the
* compiler version allows.
*
* Nov 2, 2006, Toni Ronkko
* Major update: removed support for Watcom C, MS-DOS and Turbo C to
* simplify the file, updated the code to compile cleanly on Visual
* Studio 2005 with both unicode and multi-byte character strings,
* removed rewinddir() as it had a bug.
*
* Aug 20, 2006, Toni Ronkko
* Removed all remarks about MSVC 1.0, which is antiqued now. Simplified
* comments by removing SGML tags.
*
* May 14 2002, Toni Ronkko
* Embedded the function definitions directly to the header so that no
* source modules need to be included in the Visual Studio project. Removed
* all the dependencies to other projects so that this very header can be
* used independently.
*
* May 28 1998, Toni Ronkko
* First version.
*****************************************************************************/
#ifndef DIRENT_H
#define DIRENT_H
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
/* Entries missing from MSVC 6.0 */
#if !defined(FILE_ATTRIBUTE_DEVICE)
# define FILE_ATTRIBUTE_DEVICE 0x40
#endif
/* File type and permission flags for stat() */
#if defined(_MSC_VER) && !defined(S_IREAD)
# define S_IFMT _S_IFMT /* file type mask */
# define S_IFDIR _S_IFDIR /* directory */
# define S_IFCHR _S_IFCHR /* character device */
# define S_IFFIFO _S_IFFIFO /* pipe */
# define S_IFREG _S_IFREG /* regular file */
# define S_IREAD _S_IREAD /* read permission */
# define S_IWRITE _S_IWRITE /* write permission */
# define S_IEXEC _S_IEXEC /* execute permission */
#endif
#define S_IFBLK 0 /* block device */
#define S_IFLNK 0 /* link */
#define S_IFSOCK 0 /* socket */
#if defined(_MSC_VER)
# define S_IRUSR S_IREAD /* read, user */
# define S_IWUSR S_IWRITE /* write, user */
# define S_IXUSR 0 /* execute, user */
# define S_IRGRP 0 /* read, group */
# define S_IWGRP 0 /* write, group */
# define S_IXGRP 0 /* execute, group */
# define S_IROTH 0 /* read, others */
# define S_IWOTH 0 /* write, others */
# define S_IXOTH 0 /* execute, others */
#endif
/* Indicates that d_type field is available in dirent structure */
#define _DIRENT_HAVE_D_TYPE
/* File type flags for d_type */
#define DT_UNKNOWN 0
#define DT_REG S_IFREG
#define DT_DIR S_IFDIR
#define DT_FIFO S_IFFIFO
#define DT_SOCK S_IFSOCK
#define DT_CHR S_IFCHR
#define DT_BLK S_IFBLK
/* Macros for converting between st_mode and d_type */
#define IFTODT(mode) ((mode) & S_IFMT)
#define DTTOIF(type) (type)
/*
* File type macros. Note that block devices, sockets and links cannot be
* distinguished on Windows and the macros S_ISBLK, S_ISSOCK and S_ISLNK are
* only defined for compatibility. These macros should always return false
* on Windows.
*/
#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFFIFO)
#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
#define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
#define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
#define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
#define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
#ifdef __cplusplus
extern "C" {
#endif
typedef struct dirent
{
char d_name[MAX_PATH + 1]; /* File name */
size_t d_namlen; /* Length of name without \0 */
int d_type; /* File type */
} dirent;
typedef struct DIR
{
dirent curentry; /* Current directory entry */
WIN32_FIND_DATAA find_data; /* Private file data */
int cached; /* True if data is valid */
HANDLE search_handle; /* Win32 search handle */
char patt[MAX_PATH + 3]; /* Initial directory name */
} DIR;
/* Forward declarations */
static DIR *opendir(const char *dirname);
static struct dirent *readdir(DIR *dirp);
static int closedir(DIR *dirp);
static void rewinddir(DIR* dirp);
/* Use the new safe string functions introduced in Visual Studio 2005 */
#if defined(_MSC_VER) && _MSC_VER >= 1400
# define DIRENT_STRNCPY(dest,src,size) strncpy_s((dest),(size),(src),_TRUNCATE)
#else
# define DIRENT_STRNCPY(dest,src,size) strncpy((dest),(src),(size))
#endif
/* Set errno variable */
#if defined(_MSC_VER)
#define DIRENT_SET_ERRNO(x) _set_errno (x)
#else
#define DIRENT_SET_ERRNO(x) (errno = (x))
#endif
/*****************************************************************************
* Open directory stream DIRNAME for read and return a pointer to the
* internal working area that is used to retrieve individual directory
* entries.
*/
static DIR *opendir(const char *dirname)
{
DIR *dirp;
/* ensure that the resulting search pattern will be a valid file name */
if (dirname == NULL) {
DIRENT_SET_ERRNO (ENOENT);
return NULL;
}
if (strlen (dirname) + 3 >= MAX_PATH) {
DIRENT_SET_ERRNO (ENAMETOOLONG);
return NULL;
}
/* construct new DIR structure */
dirp = (DIR*) malloc (sizeof (struct DIR));
if (dirp != NULL) {
int error;
/*
* Convert relative directory name to an absolute one. This
* allows rewinddir() to function correctly when the current working
* directory is changed between opendir() and rewinddir().
*/
if (GetFullPathNameA (dirname, MAX_PATH, dirp->patt, NULL)) {
char *p;
/* append the search pattern "\\*\0" to the directory name */
p = strchr (dirp->patt, '\0');
if (dirp->patt < p && *(p-1) != '\\' && *(p-1) != ':') {
*p++ = '\\';
}
*p++ = '*';
*p = '\0';
/* open directory stream and retrieve the first entry */
dirp->search_handle = FindFirstFileA (dirp->patt, &dirp->find_data);
if (dirp->search_handle != INVALID_HANDLE_VALUE) {
/* a directory entry is now waiting in memory */
dirp->cached = 1;
error = 0;
} else {
/* search pattern is not a directory name? */
DIRENT_SET_ERRNO (ENOENT);
error = 1;
}
} else {
/* buffer too small */
DIRENT_SET_ERRNO (ENOMEM);
error = 1;
}
if (error) {
free (dirp);
dirp = NULL;
}
}
return dirp;
}
/*****************************************************************************
* Read a directory entry, and return a pointer to a dirent structure
* containing the name of the entry in d_name field. Individual directory
* entries returned by this very function include regular files,
* sub-directories, pseudo-directories "." and "..", but also volume labels,
* hidden files and system files may be returned.
*/
static struct dirent *readdir(DIR *dirp)
{
DWORD attr;
if (dirp == NULL) {
/* directory stream did not open */
DIRENT_SET_ERRNO (EBADF);
return NULL;
}
/* get next directory entry */
if (dirp->cached != 0) {
/* a valid directory entry already in memory */
dirp->cached = 0;
} else {
/* get the next directory entry from stream */
if (dirp->search_handle == INVALID_HANDLE_VALUE) {
return NULL;
}
if (FindNextFileA (dirp->search_handle, &dirp->find_data) == FALSE) {
/* the very last entry has been processed or an error occured */
FindClose (dirp->search_handle);
dirp->search_handle = INVALID_HANDLE_VALUE;
return NULL;
}
}
/* copy as a multibyte character string */
DIRENT_STRNCPY ( dirp->curentry.d_name,
dirp->find_data.cFileName,
sizeof(dirp->curentry.d_name) );
dirp->curentry.d_name[MAX_PATH] = '\0';
/* compute the length of name */
dirp->curentry.d_namlen = strlen (dirp->curentry.d_name);
/* determine file type */
attr = dirp->find_data.dwFileAttributes;
if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
dirp->curentry.d_type = DT_CHR;
} else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
dirp->curentry.d_type = DT_DIR;
} else {
dirp->curentry.d_type = DT_REG;
}
return &dirp->curentry;
}
/*****************************************************************************
* Close directory stream opened by opendir() function. Close of the
* directory stream invalidates the DIR structure as well as any previously
* read directory entry.
*/
static int closedir(DIR *dirp)
{
if (dirp == NULL) {
/* invalid directory stream */
DIRENT_SET_ERRNO (EBADF);
return -1;
}
/* release search handle */
if (dirp->search_handle != INVALID_HANDLE_VALUE) {
FindClose (dirp->search_handle);
dirp->search_handle = INVALID_HANDLE_VALUE;
}
/* release directory structure */
free (dirp);
return 0;
}
/*****************************************************************************
* Resets the position of the directory stream to which dirp refers to the
* beginning of the directory. It also causes the directory stream to refer
* to the current state of the corresponding directory, as a call to opendir()
* would have done. If dirp does not refer to a directory stream, the effect
* is undefined.
*/
static void rewinddir(DIR* dirp)
{
if (dirp != NULL) {
/* release search handle */
if (dirp->search_handle != INVALID_HANDLE_VALUE) {
FindClose (dirp->search_handle);
}
/* open new search handle and retrieve the first entry */
dirp->search_handle = FindFirstFileA (dirp->patt, &dirp->find_data);
if (dirp->search_handle != INVALID_HANDLE_VALUE) {
/* a directory entry is now waiting in memory */
dirp->cached = 1;
} else {
/* failed to re-open directory: no directory entry in memory */
dirp->cached = 0;
}
}
}
#ifdef __cplusplus
}
#endif
#endif /*DIRENT_H*/

View File

@@ -4,6 +4,7 @@
*
* Copyright 2010-2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* Copyright 2010-2011 Vic Lee
* Copyright 2012 Gerald Richter
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -118,10 +119,12 @@ static boolean disk_file_remove_dir(const char* path)
boolean ret = true;
dir = opendir(path);
if (dir == NULL)
return false;
pdirent = readdir(dir);
while (pdirent)
{
if (strcmp(pdirent->d_name, ".") == 0 || strcmp(pdirent->d_name, "..") == 0)
@@ -174,6 +177,7 @@ static void disk_file_set_fullpath(DISK_FILE* file, char* fullpath)
xfree(file->fullpath);
file->fullpath = fullpath;
file->filename = strrchr(file->fullpath, '/');
if (file->filename == NULL)
file->filename = file->fullpath;
else
@@ -182,10 +186,12 @@ static void disk_file_set_fullpath(DISK_FILE* file, char* fullpath)
static boolean disk_file_init(DISK_FILE* file, uint32 DesiredAccess, uint32 CreateDisposition, uint32 CreateOptions)
{
const static int mode = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH;
struct STAT st;
boolean exists;
#ifndef WIN32
#ifdef WIN32
const static int mode = _S_IREAD | _S_IWRITE ;
#else
const static int mode = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH;
boolean largeFile = false;
#endif
int oflag = 0;
@@ -423,7 +429,8 @@ boolean disk_file_query_information(DISK_FILE* file, uint32 FsInformationClass,
boolean disk_file_set_information(DISK_FILE* file, uint32 FsInformationClass, uint32 Length, STREAM* input)
{
char* s;
mode_t m;
mode_t m;
uint64 size;
char* fullpath;
struct STAT st;
@@ -449,7 +456,9 @@ boolean disk_file_set_information(DISK_FILE* file, uint32 FsInformationClass, ui
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;
futimes(file->fd, tv);
#ifndef WIN32
/* TODO on win32 */
futimes(file->fd, tv);
if (FileAttributes > 0)
{
@@ -461,7 +470,8 @@ boolean disk_file_set_information(DISK_FILE* file, uint32 FsInformationClass, ui
if (m != st.st_mode)
fchmod(file->fd, st.st_mode);
}
break;
#endif
break;
case FileEndOfFileInformation:
/* http://msdn.microsoft.com/en-us/library/cc232067.aspx */
@@ -492,14 +502,15 @@ boolean disk_file_set_information(DISK_FILE* file, uint32 FsInformationClass, ui
fullpath = disk_file_combine_fullpath(file->basepath, s);
xfree(s);
if (rename(file->fullpath, fullpath) == 0)
/* TODO rename does not work on win32 */
if (rename(file->fullpath, fullpath) == 0)
{
DEBUG_SVC("renamed %s to %s", file->fullpath, fullpath);
disk_file_set_fullpath(file, fullpath);
}
else
{
DEBUG_WARN("rename %s to %s failed", file->fullpath, fullpath);
DEBUG_WARN("rename %s to %s failed, errno = %d", file->fullpath, fullpath, errno);
free(fullpath);
return false;
}

View File

@@ -4,6 +4,7 @@
*
* Copyright 2010-2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* Copyright 2010-2011 Vic Lee
* Copyright 2012 Gerald Richter
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,17 +25,33 @@
#include <sys/types.h>
#include <sys/stat.h>
#ifndef _WIN32
#ifdef _WIN32
#include <direct.h>
#include <io.h>
#include "dirent.h"
#include "statvfs.h"
#else
#include <dirent.h>
#include <sys/statvfs.h>
#endif
#ifdef _WIN32
#define STAT stat
#define OPEN open
#define LSEEK lseek
#define OPEN _open
#define close _close
#define read _read
#define write _write
#define LSEEK _lseek
#define FSTAT fstat
#define STATVFS statvfs
#define mkdir(a,b) _mkdir(a)
#define rmdir _rmdir
#define unlink(a) _unlink(a)
#define ftruncate(a,b) _chsize(a,b)
typedef uint32 ssize_t ;
typedef uint32 mode_t ;
#elif defined(__APPLE__) || defined(__FreeBSD__)
#define STAT stat
#define OPEN open

View File

@@ -263,7 +263,7 @@ static void disk_process_irp_read(DISK_DEVICE* disk, IRP* irp)
if (Length > 0)
{
stream_check_size(irp->output, Length);
stream_check_size(irp->output, (int)Length);
stream_write(irp->output, buffer, Length);
}
@@ -647,15 +647,23 @@ static void disk_free(DEVICE* device)
xfree(disk);
}
int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
{
char* name;
char* path;
int i, length;
DISK_DEVICE* disk;
name = (char*) pEntryPoints->plugin_data->data[1];
path = (char*) pEntryPoints->plugin_data->data[2];
void disk_register_disk_path(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, char *name, char *path)
{
DISK_DEVICE* disk;
int i, length ;
#ifdef WIN32
// We cannot enter pathes like c:\ because : is an arg separator
// thus, pathes are entered as c+\ and the + is substitutet here
if ( path[1] == '+' )
{
if ( (path[0]>='a' && path[0]<='z') || (path[0]>='A' && path[0]<='Z') )
{
path[1] = ':';
}
}
#endif
if (name[0] && path[0])
{
@@ -683,8 +691,66 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*) disk);
ResumeThread(disk->thread);
ResumeThread(disk->thread);
}
return 0;
}
#ifdef WITH_STATIC_PLUGINS
int disk_entry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
#else
int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
#endif
{
char* name;
char* path;
int i ;
#ifdef WIN32
char devlist[512], buf[512];
char *dev;
int len ;
#endif
name = (char*) pEntryPoints->plugin_data->data[1];
path = (char*) pEntryPoints->plugin_data->data[2];
#ifndef WIN32
disk_register_disk_path(pEntryPoints, name, path);
#else
// Special case: path[0] == '*' -> export all drives
// Special case: path[0] == '%' -> user home dir
if( path[0] == '%' )
{
_snprintf(buf, sizeof(buf), "%s\\", getenv("USERPROFILE"));
disk_register_disk_path(pEntryPoints, name, xstrdup(buf));
}
else if( path[0] == '*' )
{
// Enumerate all devices:
GetLogicalDriveStringsA(sizeof(devlist)-1, devlist);
for(dev=devlist, i=0; *dev; dev += 4, i++ )
{
if( *dev > 'B')
{ // Supress disk drives A and B to avoid pesty messages
_snprintf(buf, sizeof(buf)-4, "%s", name);
len=strlen(buf);
buf[len] = '_';
buf[len+1] = dev[0];
buf[len+2] = 0;
buf[len+3] = 0;
disk_register_disk_path(pEntryPoints, xstrdup(buf), xstrdup(dev));
}
}
}
else
{
disk_register_disk_path(pEntryPoints, name, path);
}
#endif
return 0;
}

View File

@@ -0,0 +1,57 @@
/**
* FreeRDP: A Remote Desktop Protocol client.
* statvfs emulation für windows
*
* Copyright 2012 Gerald Richter
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <string.h>
#include <malloc.h>
#include <winpr/crt.h>
#include <winpr/windows.h>
#include "statvfs.h"
int statvfs(const char *path, struct statvfs *buf)
{
BOOL res;
int len;
LPWSTR unicodestr;
DWORD lpSectorsPerCluster;
DWORD lpBytesPerSector;
DWORD lpNumberOfFreeClusters;
DWORD lpTotalNumberOfClusters;
len = MultiByteToWideChar(CP_ACP, 0, path, -1, NULL, 0);
unicodestr = (LPWSTR) malloc(len);
MultiByteToWideChar(CP_ACP, 0, path, -1, unicodestr, len);
res = GetDiskFreeSpace(unicodestr, &lpSectorsPerCluster, &lpBytesPerSector, &lpNumberOfFreeClusters, &lpTotalNumberOfClusters);
buf->f_bsize = lpBytesPerSector; /* file system block size */
buf->f_frsize = 0; /* fragment size */
buf->f_blocks = lpTotalNumberOfClusters; /* size of fs in f_frsize units */
buf->f_bfree = lpNumberOfFreeClusters; /* # free blocks */
buf->f_bavail = lpNumberOfFreeClusters; /* # free blocks for unprivileged users */
buf->f_files = 0; /* # inodes */
buf->f_ffree = 0; /* # free inodes */
buf->f_favail = 0; /* # free inodes for unprivileged users */
buf->f_fsid = lpNumberOfFreeClusters & 0xffff; /* file system ID */
buf->f_flag = 0; /* mount flags */
buf->f_namemax = 250; /* maximum filename length */
return res;
}

View File

@@ -0,0 +1,50 @@
/**
* FreeRDP: A Remote Desktop Protocol client.
* statvfs emulation for windows
*
* Copyright 2012 Gerald Richter
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef RDPDR_DISK_STATVFS_H
#define RDPDR_DISK_STATVFS_H
#ifdef __cplusplus
extern "C" {
#endif
typedef unsigned long long fsblkcnt_t;
typedef unsigned long long fsfilcnt_t;
struct statvfs {
unsigned long f_bsize; /* file system block size */
unsigned long f_frsize; /* fragment size */
fsblkcnt_t f_blocks; /* size of fs in f_frsize units */
fsblkcnt_t f_bfree; /* # free blocks */
fsblkcnt_t f_bavail; /* # free blocks for unprivileged users */
fsfilcnt_t f_files; /* # inodes */
fsfilcnt_t f_ffree; /* # free inodes */
fsfilcnt_t f_favail; /* # free inodes for unprivileged users */
unsigned long f_fsid; /* file system ID */
unsigned long f_flag; /* mount flags */
unsigned long f_namemax; /* maximum filename length */
};
int statvfs(const char *path, struct statvfs *buf);
#ifdef __cplusplus
}
#endif
#endif /* RDPDR_DISK_STATVFS_H */

View File

@@ -31,6 +31,13 @@ if(WITH_CUPS)
add_definitions(-DWITH_CUPS)
endif()
if(WIN32)
set(PRINTER_SRCS
${PRINTER_SRCS}
printer_win.c
printer_win.h)
endif()
include_directories(..)
add_library(printer ${PRINTER_SRCS})

View File

@@ -40,6 +40,10 @@
#include "printer_main.h"
#ifdef WIN32
#include "printer_win.h"
#endif
typedef struct _PRINTER_DEVICE PRINTER_DEVICE;
struct _PRINTER_DEVICE
{
@@ -294,7 +298,11 @@ void printer_register(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, rdpPrinter* pri
freerdp_thread_start(printer_dev->thread, printer_thread_func, printer_dev);
}
#ifdef WITH_STATIC_PLUGINS
int printer_entry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
#else
int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
#endif
{
rdpPrinterDriver* driver = NULL;
rdpPrinter** printers;
@@ -305,6 +313,9 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
#ifdef WITH_CUPS
driver = printer_cups_get_driver();
#endif
#ifdef WIN32
driver = printer_win_get_driver();
#endif
if (driver == NULL)
{

View File

@@ -0,0 +1,283 @@
/**
* FreeRDP: A Remote Desktop Protocol client.
* Print Virtual Channel - WIN driver
*
* Copyright 2012 Gerald Richter
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <windows.h>
#include <winspool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "config.h"
#include <freerdp/utils/memory.h>
#include <freerdp/utils/svc_plugin.h>
#include "rdpdr_types.h"
#include "printer_main.h"
#include "printer_win.h"
typedef struct rdp_win_printer_driver rdpWinPrinterDriver;
typedef struct rdp_win_printer rdpWinPrinter;
typedef struct rdp_win_print_job rdpWinPrintJob;
struct rdp_win_printer_driver
{
rdpPrinterDriver driver;
int id_sequence;
};
struct rdp_win_printer
{
rdpPrinter printer;
HANDLE hPrinter;
rdpWinPrintJob* printjob;
};
struct rdp_win_print_job
{
rdpPrintJob printjob;
DOC_INFO_1 di;
DWORD handle;
void* printjob_object;
int printjob_id;
};
static void printer_win_get_printjob_name(char* buf, int size)
{
time_t tt;
struct tm* t;
DEBUG_WINPR("");
tt = time(NULL);
t = localtime(&tt);
snprintf(buf, size - 1, "FreeRDP Print Job %d%02d%02d%02d%02d%02d",
t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
t->tm_hour, t->tm_min, t->tm_sec);
DEBUG_WINPR("buf: %s", buf);
}
static void printer_win_write_printjob(rdpPrintJob* printjob, uint8* data, int size)
{
rdpWinPrintJob* win_printjob = (rdpWinPrintJob*)printjob;
LPVOID pBuf = data;
DWORD cbBuf = size;
DWORD pcWritten;
if( ! WritePrinter( ((rdpWinPrinter*)printjob->printer)->hPrinter, pBuf, cbBuf, &pcWritten ) )
DEBUG_WINPR("WritePrinter failed");
;
}
static void printer_win_close_printjob(rdpPrintJob* printjob)
{
rdpWinPrintJob* win_printjob = (rdpWinPrintJob*)printjob;
DEBUG_WINPR("");
if ( ! EndPagePrinter( ((rdpWinPrinter*)printjob->printer)->hPrinter ) )
DEBUG_WINPR("EndPagePrinter failed");;
if ( ! ClosePrinter( ((rdpWinPrinter*)printjob->printer)->hPrinter ) )
DEBUG_WINPR("ClosePrinter failed");;
((rdpWinPrinter*)printjob->printer)->printjob = NULL;
xfree(win_printjob) ;
}
static rdpPrintJob* printer_win_create_printjob(rdpPrinter* printer, uint32 id)
{
rdpWinPrinter* win_printer = (rdpWinPrinter*)printer;
rdpWinPrintJob* win_printjob;
DEBUG_WINPR("");
if (win_printer->printjob != NULL)
return NULL;
win_printjob = xnew(rdpWinPrintJob);
win_printjob->printjob.id = id;
win_printjob->printjob.printer = printer;
win_printjob->di.pDocName = L"FREERDPjob";
win_printjob->di.pDatatype= NULL;
win_printjob->di.pOutputFile = NULL;
win_printjob->handle = StartDocPrinter(win_printer->hPrinter, 1, (LPBYTE)&(win_printjob->di) );
if(! win_printjob->handle) DEBUG_WINPR("StartDocPrinter failed");
if ( ! StartPagePrinter(win_printer->hPrinter) )
DEBUG_WINPR("ClosePrinter failed");
win_printjob->printjob.Write = printer_win_write_printjob;
win_printjob->printjob.Close = printer_win_close_printjob;
win_printer->printjob = win_printjob;
return (rdpPrintJob*)win_printjob;
}
static rdpPrintJob* printer_win_find_printjob(rdpPrinter* printer, uint32 id)
{
rdpWinPrinter* win_printer = (rdpWinPrinter*)printer;
DEBUG_WINPR("");
if (win_printer->printjob == NULL)
return NULL;
if (win_printer->printjob->printjob.id != id)
return NULL;
return (rdpPrintJob*)win_printer->printjob;
}
static void printer_win_free_printer(rdpPrinter* printer)
{
rdpWinPrinter* win_printer = (rdpWinPrinter*)printer;
DEBUG_WINPR("");
if (win_printer->printjob)
win_printer->printjob->printjob.Close((rdpPrintJob*)win_printer->printjob);
xfree(printer->name);
xfree(printer);
}
static rdpPrinter* printer_win_new_printer(rdpWinPrinterDriver* win_driver, const char* name, const wchar_t* drivername, boolean is_default)
{
rdpWinPrinter* win_printer;
wchar_t wname[256];
DWORD needed;
PRINTER_INFO_2 *prninfo=NULL;
size_t charsConverted;
DEBUG_WINPR("");
win_printer = xnew(rdpWinPrinter);
win_printer->printer.id = win_driver->id_sequence++;
win_printer->printer.name = xstrdup(name);
win_printer->printer.is_default = is_default;
win_printer->printer.CreatePrintJob = printer_win_create_printjob;
win_printer->printer.FindPrintJob = printer_win_find_printjob;
win_printer->printer.Free = printer_win_free_printer;
swprintf(wname, 256, L"%hs", name);
OpenPrinter(wname, &(win_printer->hPrinter), NULL);
DEBUG_WINPR("handle: 0x%08X", win_printer->hPrinter);
GetPrinter(win_printer->hPrinter, 2, (LPBYTE) prninfo, 0, &needed);
prninfo = (PRINTER_INFO_2*) GlobalAlloc(GPTR,needed);
GetPrinter(win_printer->hPrinter, 2, (LPBYTE) prninfo, needed, &needed);
win_printer->printer.driver = xmalloc(1000);
wcstombs_s(&charsConverted, win_printer->printer.driver, 1000, prninfo->pDriverName, _TRUNCATE);
return (rdpPrinter*)win_printer;
}
static rdpPrinter** printer_win_enum_printers(rdpPrinterDriver* driver)
{
rdpPrinter** printers;
int num_printers;
int i;
char pname[1000];
size_t charsConverted;
PRINTER_INFO_2 *prninfo=NULL;
DWORD needed, returned;
DEBUG_WINPR("");
//find required size for the buffer
EnumPrinters(PRINTER_ENUM_LOCAL|PRINTER_ENUM_CONNECTIONS, NULL, 2, NULL, 0, &needed, &returned);
//allocate array of PRINTER_INFO structures
prninfo = (PRINTER_INFO_2*) GlobalAlloc(GPTR,needed);
//call again
if ( !EnumPrinters(PRINTER_ENUM_LOCAL|PRINTER_ENUM_CONNECTIONS, NULL, 2, (LPBYTE) prninfo, needed, &needed, &returned) ) {
DEBUG_WINPR("EnumPrinters failed");
} ; /* eRROR... */
DEBUG_WINPR("printers found: %d", returned);
printers = (rdpPrinter**)xzalloc(sizeof(rdpPrinter*) * (returned + 1));
num_printers = 0;
for (i = 0; i < (int)returned; i++)
{
wcstombs_s(&charsConverted, pname, 1000, prninfo[i].pPrinterName, _TRUNCATE);
printers[num_printers++] = printer_win_new_printer((rdpWinPrinterDriver*)driver,
pname, prninfo[i].pDriverName, 0);
}
GlobalFree(prninfo);
return printers;
}
static rdpPrinter* printer_win_get_printer(rdpPrinterDriver* driver, const char* name)
{
rdpWinPrinterDriver* win_driver = (rdpWinPrinterDriver*)driver;
rdpPrinter *myPrinter = NULL;
DEBUG_WINPR("printer %s", name);
myPrinter = printer_win_new_printer(win_driver, name, L"", win_driver->id_sequence == 1 ? true : false);
return myPrinter;
}
static rdpWinPrinterDriver* win_driver = NULL;
rdpPrinterDriver* printer_win_get_driver(void)
{
DEBUG_WINPR("");
if (win_driver == NULL)
{
win_driver = xnew(rdpWinPrinterDriver);
win_driver->driver.EnumPrinters = printer_win_enum_printers;
win_driver->driver.GetPrinter = printer_win_get_printer;
win_driver->id_sequence = 1;
//#ifdef _win_API_1_4
// DEBUG_SVC("using win API 1.4");
//#else
// DEBUG_SVC("using win API 1.2");
//#endif
}
return (rdpPrinterDriver*)win_driver;
}

View File

@@ -0,0 +1,37 @@
/**
* FreeRDP: A Remote Desktop Protocol client.
* Print Virtual Channel - win driver
*
* Copyright 2012 Gerald Richter
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __PRINTER_WIN_H
#define __PRINTER_WIN_H
rdpPrinterDriver* printer_win_get_driver(void);
#ifdef WITH_DEBUG_WINPR
#define DEBUG_WINPR(fmt, ...) DEBUG_CLASS(WINPR, fmt, ## __VA_ARGS__)
#else
#define DEBUG_WINPR(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__)
#endif
#endif
#ifdef WIN32
#define snprintf _snprintf
#endif

View File

@@ -1,53 +1,58 @@
# FreeRDP: A Remote Desktop Protocol Client
# FreeRDP Windows cmake build script
#
# Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set(MODULE_NAME "wfreerdp")
set(MODULE_PREFIX "FREERDP_CLIENT_WINDOWS")
set(${MODULE_PREFIX}_SRCS
wf_gdi.c
wf_gdi.h
wf_event.c
wf_event.h
wf_graphics.c
wf_graphics.h
wf_cliprdr.c
wf_cliprdr.h
wf_window.c
wf_window.h
wf_rail.c
wf_rail.h
wfreerdp.c
wfreerdp.h)
add_executable(${MODULE_NAME} WIN32 ${${MODULE_PREFIX}_SRCS})
if(WITH_MONOLITHIC_BUILD)
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} freerdp)
else()
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS}
freerdp-core
freerdp-gdi
freerdp-codec
freerdp-channels
freerdp-utils)
endif()
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR})
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Client/Windows")
# FreeRDP: A Remote Desktop Protocol Client
# FreeRDP Windows cmake build script
#
# Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set(MODULE_NAME "wfreerdp")
set(MODULE_PREFIX "FREERDP_CLIENT_WINDOWS")
set(${MODULE_PREFIX}_SRCS
wf_gdi.c
wf_gdi.h
wf_event.c
wf_event.h
wf_graphics.c
wf_graphics.h
wf_cliprdr.c
wf_cliprdr.h
wf_window.c
wf_window.h
wf_rail.c
wf_rail.h
wfreerdp.c
wfreerdp.h)
add_executable(${MODULE_NAME} WIN32 ${${MODULE_PREFIX}_SRCS})
if(WITH_MONOLITHIC_BUILD)
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} freerdp)
if(WITH_RDPDR)
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} rdpdr disk printer)
endif()
else()
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS}
freerdp-core
freerdp-gdi
freerdp-codec
freerdp-channels
freerdp-utils)
endif()
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR})
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Client/Windows")

View File

@@ -56,6 +56,8 @@ LRESULT CALLBACK wf_ll_kbd_proc(int nCode, WPARAM wParam, LPARAM lParam)
case WM_SYSKEYUP:
wfi = (wfInfo*) GetWindowLongPtr(g_focus_hWnd, GWLP_USERDATA);
p = (PKBDLLHOOKSTRUCT) lParam;
if (!wfi || !p)
return 1;
input = wfi->instance->input;
rdp_scancode = MAKE_RDP_SCANCODE((uint8) p->scanCode, p->flags & LLKHF_EXTENDED);

View File

@@ -41,6 +41,8 @@
#include <freerdp/utils/args.h>
#include <freerdp/utils/event.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/load_plugin.h>
#include <freerdp/utils/svc_plugin.h>
#include <freerdp/channels/channels.h>
#include "wf_gdi.h"
@@ -537,6 +539,10 @@ int wfreerdp_run(freerdp* instance)
printf("Failed to check FreeRDP file descriptor\n");
break;
}
if (freerdp_shall_disconnect(instance))
{
break;
}
if (wf_check_fds(instance) != TRUE)
{
printf("Failed to check wfreerdp file descriptor\n");
@@ -631,6 +637,13 @@ static DWORD WINAPI kbd_thread_func(LPVOID lpParam)
return (DWORD) NULL;
}
#ifdef WITH_RDPDR
DEFINE_SVC_PLUGIN_ENTRY(rdpdr) ;
DEFINE_DEV_PLUGIN_ENTRY(disk) ;
DEFINE_DEV_PLUGIN_ENTRY(printer) ;
#endif
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
freerdp* instance;
@@ -688,7 +701,13 @@ INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
instance->context->argc = __argc;
instance->context->argv = __argv;
if (!CreateThread(NULL, 0, kbd_thread_func, NULL, 0, NULL))
#ifdef WITH_RDPDR
REGISTER_SVC_PLUGIN_ENTRY(rdpdr) ;
REGISTER_DEV_PLUGIN_ENTRY(disk) ;
REGISTER_DEV_PLUGIN_ENTRY(printer) ;
#endif
if (!CreateThread(NULL, 0, kbd_thread_func, NULL, 0, NULL))
printf("error creating keyboard handler thread");
//while (1)

View File

@@ -27,6 +27,7 @@
#cmakedefine HAVE_TM_GMTOFF
/* Options */
#cmakedefine WITH_PROFILER
#cmakedefine WITH_SSE2
@@ -35,6 +36,11 @@
#cmakedefine WITH_JPEG
#cmakedefine WITH_WIN8
/* Plugins */
#cmakedefine WITH_STATIC_PLUGINS
#cmakedefine WITH_RDPDR
/* Debug */
#cmakedefine WITH_DEBUG_CERTIFICATE
#cmakedefine WITH_DEBUG_CHANNELS

View File

@@ -62,7 +62,13 @@ FREERDP_API int svc_plugin_send_event(rdpSvcPlugin* plugin, RDP_EVENT* event);
#ifdef WITH_STATIC_PLUGINS
#define DEFINE_SVC_PLUGIN_ENTRY(_prefix) int _prefix##_entry(PCHANNEL_ENTRY_POINTS pEntryPoints)
#define DEFINE_DEV_PLUGIN_ENTRY(_prefix) int _prefix##_entry(PCHANNEL_ENTRY_POINTS pEntryPoints)
#define REGISTER_SVC_PLUGIN_ENTRY(_prefix) freerdp_register_static_plugin(#_prefix, "VirtualChannelEntry", _prefix##_entry)
#define REGISTER_DEV_PLUGIN_ENTRY(_prefix) freerdp_register_static_plugin(#_prefix, "DeviceServiceEntry", _prefix##_entry)
#else
#define REGISTER_DEV_PLUGIN_ENTRY(_prefix)
#define REGISTER_SVC_PLUGIN_ENTRY(_prefix)
#define DEFINE_DEV_PLUGIN_ENTRY(_prefix)
#define DEFINE_SVC_PLUGIN_ENTRY(_prefix) int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
#endif

View File

@@ -25,7 +25,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#include <freerdp/codec/nsc.h>
#include <freerdp/utils/memory.h>

View File

@@ -24,7 +24,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#include <freerdp/codec/nsc.h>
#include <freerdp/utils/memory.h>

View File

@@ -24,7 +24,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#include <freerdp/codec/rfx.h>
#include <freerdp/utils/memory.h>

View File

@@ -228,8 +228,12 @@ boolean rdp_read_header(rdpRdp* rdp, STREAM* s, uint16* length, uint16* channel_
enum DomainMCSPDU MCSPDU;
MCSPDU = (rdp->settings->server_mode) ? DomainMCSPDU_SendDataRequest : DomainMCSPDU_SendDataIndication;
if (!mcs_read_domain_mcspdu_header(s, &MCSPDU, length))
return false ;
{
if (MCSPDU != DomainMCSPDU_DisconnectProviderUltimatum)
return false;
}
if (*length - 8 > stream_get_left(s))
return false;