home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC-Online 1998 February
/
PCOnline_02_1998.iso
/
filesbbs
/
win95
/
ext2tool.exe
/
SRC
/
MSDOS_IO.C
< prev
next >
Wrap
C/C++ Source or Header
|
1995-05-10
|
5KB
|
212 lines
/***************************************************************************
* msdos_io.c --- This is the MS-DOS I/O interface to the I/O manager.
*
* Copyright (C) 1995 Claus Tondering, ct@login.dknet.dk
*
* Based on unix_io.c, which is copyright (C) 1993 Theodore Ts'o.
*
* This file may be redistributed under the terms of the GNU Public License.
***************************************************************************/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <time.h>
#include <sys/stat.h>
#include <errno.h>
#include <sys/types.h>
#include "ext2fs/com_err.h"
#include "ext2fs/ext2_err.h"
#include "ext2fs/io.h"
#include "diskio.h"
#include "ldisk.h"
/*
* For checking structure magic numbers...
*/
#define EXT2_CHECK_MAGIC(struct, code) \
if ((struct)->magic != (code)) return (code)
struct msdos_private_data {
long magic;
int diskno;
long offset;
long length;
int flags;
char *buf;
int buf_block_nr;
};
static errcode_t msdos_open(const char *name, int flags, io_channel *channel);
static errcode_t msdos_close(io_channel channel);
static errcode_t msdos_set_blksize(io_channel channel, int blksize);
static errcode_t msdos_read_blk(io_channel channel, unsigned long block,
int count, void *data);
static errcode_t msdos_write_blk(io_channel channel, unsigned long block,
int count, const void *data);
static errcode_t msdos_flush(io_channel channel);
static struct struct_io_manager struct_msdos_manager = {
EXT2_ET_MAGIC_IO_MANAGER,
"MS-DOS I/O Manager",
msdos_open,
msdos_close,
msdos_set_blksize,
msdos_read_blk,
msdos_write_blk,
msdos_flush
};
io_manager msdos_io_manager = &struct_msdos_manager;
static errcode_t msdos_open(const char *name, int flags, io_channel *channel)
{
io_channel io = NULL;
struct msdos_private_data *data = NULL;
errcode_t retval;
io = (io_channel) malloc(sizeof(struct struct_io_channel));
if (!io)
return ENOMEM;
io->magic = EXT2_ET_MAGIC_IO_CHANNEL;
data = (struct msdos_private_data *)
malloc(sizeof(struct msdos_private_data));
if (!data) {
retval = ENOMEM;
goto cleanup;
}
io->manager = msdos_io_manager;
io->private_data = data;
io->block_size = 1024;
memset(data, 0, sizeof(struct msdos_private_data));
data->magic = EXT2_ET_MAGIC_MSDOS_IO_CHANNEL;
data->buf = malloc(io->block_size);
data->buf_block_nr = -1;
if (!data->buf) {
retval = ENOMEM;
goto cleanup;
}
retval=nametodisk(&data->diskno, &data->offset, &data->length);
if (retval)
goto cleanup;
if (flags&IO_FLAG_RW) {
retval = EACCES;
goto cleanup;
}
*channel = io;
return 0;
cleanup:
if (io)
free(io);
if (data) {
if (data->buf)
free(data->buf);
free(data);
}
return retval;
}
static errcode_t msdos_close(io_channel channel)
{
struct msdos_private_data *data;
errcode_t retval = 0;
EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
data = (struct msdos_private_data *) channel->private_data;
EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_MSDOS_IO_CHANNEL);
if (data->buf)
free(data->buf);
if (channel->private_data)
free(channel->private_data);
if (channel->name)
free(channel->name);
free(channel);
return retval;
}
static errcode_t msdos_set_blksize(io_channel channel, int blksize)
{
struct msdos_private_data *data;
EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
data = (struct msdos_private_data *) channel->private_data;
EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_MSDOS_IO_CHANNEL);
if (channel->block_size != blksize) {
channel->block_size = blksize;
free(data->buf);
data->buf = malloc(blksize);
if (!data->buf)
return ENOMEM;
data->buf_block_nr = -1;
}
return 0;
}
static errcode_t msdos_read_blk(io_channel channel, unsigned long block,
int count, void *buf)
{
struct msdos_private_data *data;
errcode_t retval;
size_t size;
ext2_loff_t location;
int actual = 0;
EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
data = (struct msdos_private_data *) channel->private_data;
EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_MSDOS_IO_CHANNEL);
/*
* If it's in the cache, use it!
*/
if ((count == 1) && (block == data->buf_block_nr)) {
memcpy(buf, data->buf, channel->block_size);
return 0;
}
size = (count < 0) ? -count : count * channel->block_size;
location = (ext2_loff_t) block * channel->block_size;
retval = readdisk(data->diskno, data->offset + location/512, size/512, buf);
if (retval)
goto error_out;
if (count == 1) {
data->buf_block_nr = block;
memcpy(data->buf, buf, size); /* Update the cache */
}
return 0;
error_out:
memset((char *) buf+actual, 0, size-actual);
if (channel->read_error)
retval = (channel->read_error)(channel, block, count, buf,
size, actual, retval);
return retval;
}
static errcode_t msdos_write_blk(io_channel channel, unsigned long block,
int count, const void *buf)
{
return EACCES;
}
/*
* Flush data buffers to disk.
* This is a no-op.
*/
static errcode_t msdos_flush(io_channel channel)
{
return 0;
}