rdpdr: implement irp.

This commit is contained in:
Vic Lee 2011-08-06 01:54:40 +08:00
parent 4c5ad80033
commit 5ce3e4deac
8 changed files with 173 additions and 12 deletions

View File

@ -24,6 +24,8 @@ set(RDPDR_SRCS
rdpdr_capabilities.h
devman.c
devman.h
irp.c
irp.h
rdpdr_main.c
rdpdr_main.h
)

View File

@ -87,3 +87,17 @@ boolean devman_load_device_service(DEVMAN* devman, FRDP_PLUGIN_DATA* plugin_data
return True;
}
DEVICE* devman_get_device_by_id(DEVMAN* devman, uint32 id)
{
LIST_ITEM* item;
DEVICE* device;
for (item = devman->devices->head; item; item = item->next)
{
device = (DEVICE*)item->data;
if (device->id == id)
return device;
}
return NULL;
}

View File

@ -24,5 +24,6 @@
DEVMAN* devman_new(rdpSvcPlugin* plugin);
void devman_free(DEVMAN* devman);
boolean devman_load_device_service(DEVMAN* devman, FRDP_PLUGIN_DATA* plugin_data);
DEVICE* devman_get_device_by_id(DEVMAN* devman, uint32 id);
#endif /* __DEVMAN_H */

View File

@ -26,8 +26,6 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <fnmatch.h>
#include <utime.h>
@ -37,6 +35,13 @@
#include <freerdp/utils/list.h>
#include <freerdp/utils/svc_plugin.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#include "rdpdr_constants.h"
#include "rdpdr_types.h"
@ -66,7 +71,7 @@ void disk_irp_request(DEVICE* device, IRP* irp)
{
DISK_DEVICE* disk = (DISK_DEVICE*)device;
irp->Discard(irp);
IFCALL(irp->Complete, irp);
}
void disk_free(DEVICE* device)

97
channels/rdpdr/irp.c Normal file
View File

@ -0,0 +1,97 @@
/**
* FreeRDP: A Remote Desktop Protocol client.
* File System Virtual Channel
*
* Copyright 2010-2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* Copyright 2010-2011 Vic Lee
*
* 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 "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <freerdp/utils/memory.h>
#include <freerdp/utils/stream.h>
#include <freerdp/utils/svc_plugin.h>
#include "rdpdr_types.h"
#include "rdpdr_constants.h"
#include "devman.h"
#include "irp.h"
static void irp_free(IRP* irp)
{
DEBUG_SVC("DeviceId %d FileId %d CompletionId %d", irp->device->id, irp->FileId, irp->CompletionId);
stream_free(irp->input);
stream_free(irp->output);
xfree(irp);
}
static void irp_complete(IRP* irp)
{
int pos;
DEBUG_SVC("DeviceId %d FileId %d CompletionId %d", irp->device->id, irp->FileId, irp->CompletionId);
pos = stream_get_pos(irp->output);
stream_set_pos(irp->output, 12);
stream_write_uint32(irp->output, irp->IoStatus);
stream_set_pos(irp->output, pos);
svc_plugin_send(irp->devman->plugin, irp->output);
irp->output = NULL;
irp_free(irp);
}
IRP* irp_new(DEVMAN* devman, STREAM* data_in)
{
IRP* irp;
uint32 DeviceId;
DEVICE* device;
stream_read_uint32(data_in, DeviceId);
device = devman_get_device_by_id(devman, DeviceId);
if (device == NULL)
{
DEBUG_WARN("unknown DeviceId %d", DeviceId);
return NULL;
}
irp = xnew(IRP);
irp->device = device;
irp->devman = devman;
stream_read_uint32(data_in, irp->FileId);
stream_read_uint32(data_in, irp->CompletionId);
stream_read_uint32(data_in, irp->MajorFunction);
stream_read_uint32(data_in, irp->MinorFunction);
irp->input = data_in;
irp->output = stream_new(256);
stream_write_uint16(irp->output, RDPDR_CTYP_CORE);
stream_write_uint16(irp->output, PAKID_CORE_DEVICE_IOCOMPLETION);
stream_write_uint32(irp->output, DeviceId);
stream_write_uint32(irp->output, irp->CompletionId);
stream_seek_uint32(irp->output); /* IoStatus */
irp->Complete = irp_complete;
irp->Discard = irp_free;
DEBUG_SVC("DeviceId %d FileId %d CompletionId %d MajorFunction 0x%X MinorFunction 0x%x",
irp->device->id, irp->FileId, irp->CompletionId, irp->MajorFunction, irp->MinorFunction);
return irp;
}

28
channels/rdpdr/irp.h Normal file
View File

@ -0,0 +1,28 @@
/**
* FreeRDP: A Remote Desktop Protocol client.
* File System Virtual Channel
*
* Copyright 2010-2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* Copyright 2010-2011 Vic Lee
*
* 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 __IRP_H
#define __IRP_H
#include "rdpdr_types.h"
IRP* irp_new(DEVMAN* devman, STREAM* data_in);
#endif /* __IRP_H */

View File

@ -35,8 +35,9 @@
#include "rdpdr_types.h"
#include "rdpdr_constants.h"
#include "devman.h"
#include "rdpdr_capabilities.h"
#include "devman.h"
#include "irp.h"
#include "rdpdr_main.h"
static void rdpdr_process_connect(rdpSvcPlugin* plugin)
@ -207,6 +208,19 @@ static void rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, boolean
svc_plugin_send((rdpSvcPlugin*)rdpdr, data_out);
}
static boolean rdpdr_process_irp(rdpdrPlugin* rdpdr, STREAM* data_in)
{
IRP* irp;
irp = irp_new(rdpdr->devman, data_in);
if (irp == NULL)
return False;
IFCALL(irp->device->IRPRequest, irp->device, irp);
return True;
}
static void rdpdr_process_receive(rdpSvcPlugin* plugin, STREAM* data_in)
{
rdpdrPlugin* rdpdr = (rdpdrPlugin*)plugin;
@ -255,6 +269,8 @@ static void rdpdr_process_receive(rdpSvcPlugin* plugin, STREAM* data_in)
case PAKID_CORE_DEVICE_IOREQUEST:
DEBUG_SVC("RDPDR_CTYP_CORE / PAKID_CORE_DEVICE_IOREQUEST");
if (rdpdr_process_irp(rdpdr, data_in))
data_in = NULL;
break;
default:

View File

@ -49,17 +49,15 @@ typedef void (*pcIRPResponse)(IRP* irp);
struct _IRP
{
DEVICE* dev;
DEVICE* device;
DEVMAN* devman;
uint32 packetID;
uint32 fileID;
uint32 completionID;
uint32 majorFunction;
uint32 minorFunction;
uint32 FileId;
uint32 CompletionId;
uint32 MajorFunction;
uint32 MinorFunction;
STREAM* input;
uint32 ioStatus;
uint32 outputResult;
uint32 IoStatus;
STREAM* output;
pcIRPResponse Complete;