rdpdr/disk: add read/write irp processing.

This commit is contained in:
Vic Lee 2011-08-07 13:11:52 +08:00
parent 49458e7363
commit 419a8163d6
3 changed files with 145 additions and 0 deletions

View File

@ -233,3 +233,49 @@ void disk_file_free(DISK_FILE* file)
xfree(file->pattern);
xfree(file);
}
boolean disk_file_seek(DISK_FILE* file, uint64 Offset)
{
if (file->is_dir || file->fd == -1)
return False;
if (lseek(file->fd, Offset, SEEK_SET) == (off_t)-1)
return False;
return True;
}
boolean disk_file_read(DISK_FILE* file, uint8* buffer, uint32* Length)
{
ssize_t r;
if (file->is_dir || file->fd == -1)
return False;
r = read(file->fd, buffer, *Length);
if (r < 0)
return False;
*Length = (uint32)r;
return True;
}
boolean disk_file_write(DISK_FILE* file, uint8* buffer, uint32 Length)
{
ssize_t r;
if (file->is_dir || file->fd == -1)
return False;
while (Length > 0)
{
r = write(file->fd, buffer, Length);
if (r == -1)
return False;
Length -= r;
buffer += r;
}
return True;
}

View File

@ -42,4 +42,8 @@ DISK_FILE* disk_file_new(const char* base_path, const char* path, uint32 id,
uint32 DesiredAccess, uint32 CreateDisposition, uint32 CreateOptions);
void disk_file_free(DISK_FILE* file);
boolean disk_file_seek(DISK_FILE* file, uint64 Offset);
boolean disk_file_read(DISK_FILE* file, uint8* buffer, uint32* Length);
boolean disk_file_write(DISK_FILE* file, uint8* buffer, uint32 Length);
#endif /* __DISK_FILE_H */

View File

@ -149,6 +149,93 @@ static void disk_process_irp_close(DISK_DEVICE* disk, IRP* irp)
stream_write(irp->output, "\0\0\0\0\0", 5); /* Padding(5) */
}
static void disk_process_irp_read(DISK_DEVICE* disk, IRP* irp)
{
DISK_FILE* file;
uint32 Length;
uint64 Offset;
uint8* buffer = NULL;
stream_read_uint32(irp->input, Length);
stream_read_uint64(irp->input, Offset);
file = disk_get_file_by_id(disk, irp->FileId);
if (file == NULL)
{
irp->IoStatus = STATUS_UNSUCCESSFUL;
Length = 0;
DEBUG_WARN("FileId %d not valid.", irp->FileId);
}
else if (!disk_file_seek(file, Offset))
{
irp->IoStatus = STATUS_UNSUCCESSFUL;
Length = 0;
DEBUG_WARN("seek %s(%d) failed.", file->fullpath, file->id);
}
else
{
buffer = (uint8*)xmalloc(Length);
if (!disk_file_read(file, buffer, &Length))
{
irp->IoStatus = STATUS_UNSUCCESSFUL;
xfree(buffer);
buffer = NULL;
Length = 0;
DEBUG_WARN("read %s(%d) failed.", file->fullpath, file->id);
}
}
stream_write_uint32(irp->output, Length);
if (Length > 0)
{
stream_check_size(irp->output, Length);
stream_write(irp->output, buffer, Length);
}
xfree(buffer);
}
static void disk_process_irp_write(DISK_DEVICE* disk, IRP* irp)
{
DISK_FILE* file;
uint32 Length;
uint64 Offset;
stream_read_uint32(irp->input, Length);
stream_read_uint64(irp->input, Offset);
stream_seek(irp->input, 20); /* Padding */
file = disk_get_file_by_id(disk, irp->FileId);
if (file == NULL)
{
irp->IoStatus = STATUS_UNSUCCESSFUL;
Length = 0;
DEBUG_WARN("FileId %d not valid.", irp->FileId);
}
else if (!disk_file_seek(file, Offset))
{
irp->IoStatus = STATUS_UNSUCCESSFUL;
Length = 0;
DEBUG_WARN("seek %s(%d) failed.", file->fullpath, file->id);
}
else if (!disk_file_write(file, stream_get_tail(irp->input), Length))
{
irp->IoStatus = STATUS_UNSUCCESSFUL;
Length = 0;
DEBUG_WARN("write %s(%d) failed.", file->fullpath, file->id);
}
stream_write_uint32(irp->output, Length);
stream_write_uint8(irp->output, 0); /* Padding */
}
static void disk_process_irp(DISK_DEVICE* disk, IRP* irp)
{
switch (irp->MajorFunction)
@ -161,6 +248,14 @@ static void disk_process_irp(DISK_DEVICE* disk, IRP* irp)
disk_process_irp_close(disk, irp);
break;
case IRP_MJ_READ:
disk_process_irp_read(disk, irp);
break;
case IRP_MJ_WRITE:
disk_process_irp_write(disk, irp);
break;
default:
DEBUG_WARN("MajorFunction 0x%X not supported", irp->MajorFunction);
irp->IoStatus = STATUS_NOT_SUPPORTED;