grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

problems compiling NTFS on GRUB2


From: lode leroy
Subject: problems compiling NTFS on GRUB2
Date: Thu, 12 Aug 2004 14:43:46 +0200

Hello grub,

I'm trying to compile the attached file, to provide
NTFS support for GRUB2. It's supposed to use libntfs
(http://linux-ntfs.sourceforge.net/).

to compile libntfs, I used
./configure --disable-default-device-io-ops
               --disable-gnome-vfs
               --enable-really-static

the in config.h, I added
#define printf grub_printf
#undef errno

then "make" in libntfs, which gives me a libntfs.a

Then I tried to compile fs/ntfs.c, which works,
but I then get a crash in
./grub-mkinage -d . -o core.img _chain ntfs ls terminal normal vga

Can anyone advise on this?

-- lode

#include <grub/fs.h>
#include <grub/disk.h>
#include <grub/file.h>
#include <grub/types.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/err.h>
#include <grub/dl.h>

#include <ntfs/types.h>
#include <ntfs/inode.h>
#include <ntfs/dir.h>

#ifndef GRUB_UTIL
static grub_dl_t my_mod;
#endif

#define PATH_SEP '/'

struct grub_ntfs_data
{
 struct ntfs_device *dev;
 ntfs_volume *vol;
 ntfs_inode *ino;

 grub_disk_t disk;
 grub_uint32_t current_pos;

 int (*hook) (const char *filename, int dir);
};

static int ntfs_device_grub_open(struct ntfs_device *dev, int flags)
{
 struct grub_ntfs_data* data = (struct grub_ntfs_data*)dev->d_private;
 data->current_pos = 0;
 return 0;
}

static s64 ntfs_device_grub_seek(struct ntfs_device *dev, s64 offset,
                                 int whence)
{
 struct grub_ntfs_data* data = (struct grub_ntfs_data*)dev->d_private;

 switch (whence) {
 case SEEK_SET:
   data->current_pos = offset;
   break;
 case SEEK_CUR:
   data->current_pos += offset;
   break;
 case SEEK_END:
   grub_errno = ENOTSUP;
   return -1;
   break;
 default:
   grub_printf("grub_seek() wrong mode %d\n", whence);
   grub_errno = EINVAL;
   return -1;
 }

 return data->current_pos;
}

static s64 ntfs_device_grub_read(struct ntfs_device *dev, void *buf, s64 count)
{
 struct grub_ntfs_data* data = (struct grub_ntfs_data*)dev->d_private;
 s64 sector = data->current_pos / 512;
 s64 offset = data->current_pos % 512;
 s64 size = count;
 s64 numread = grub_disk_read(data->disk, sector, offset, size, buf);
 data->current_pos += numread;
 return numread;
}

static int ntfs_device_grub_close(struct ntfs_device *dev)
{
 struct grub_ntfs_data* data = (struct grub_ntfs_data*)dev->d_private;
 grub_free (data);
 dev->d_private = NULL;
 return 0;
}

static int ntfs_device_grub_sync(struct ntfs_device *dev)
{
 grub_printf("grub_fsync() unimplemented\n");
 errno = ENOTSUP;
 return -1;
}

static s64 ntfs_device_grub_write(struct ntfs_device *dev, const void *buffer,
                                  s64 count)
{
 grub_printf("grub_write() unimplemented\n");
 errno = ENOTSUP;
 return -1;
}

static int ntfs_device_grub_stat(struct ntfs_device *dev, struct stat *buf)
{
 grub_printf("grub_fstat() unimplemented\n");
 errno = ENOTSUP;
 return -1;
}

static int ntfs_device_grub_ioctl(struct ntfs_device *dev, int request,
                                  void *argp)
{
 grub_printf("grub_ioctl() unimplemented\n");
 errno = ENOTSUP;
 return -1;
}

static s64 ntfs_device_grub_pread(struct ntfs_device *dev, void *buf,
                                  s64 count, s64 offset)
{
 return ntfs_pread(dev, offset, count, buf);
}

static s64 ntfs_device_grub_pwrite(struct ntfs_device *dev, const void *buf,
                                   s64 count, s64 offset)
{
 grub_printf("grub_pwrite() unimplemented\n");
 errno = ENOTSUP;
 return -1;
}

struct ntfs_device_operations ntfs_device_grub_io_ops = {
 .open   = ntfs_device_grub_open,
 .close  = ntfs_device_grub_close,
 .seek   = ntfs_device_grub_seek,
 .read   = ntfs_device_grub_read,
 .write  = ntfs_device_grub_write,
 .pread  = ntfs_device_grub_pread,
 .pwrite = ntfs_device_grub_pwrite,
 .sync   = ntfs_device_grub_sync,
 .stat   = ntfs_device_grub_stat,
 .ioctl  = ntfs_device_grub_ioctl
};


static struct grub_ntfs_data *
grub_ntfs_mount(grub_disk_t disk)
{
 struct grub_ntfs_data *data = 0;

 if (!disk)
   goto fail;

 data = (struct grub_ntfs_data *) grub_malloc (sizeof (*data));
 if (!data)
   goto fail;

data->dev = ntfs_device_alloc (disk->name, 0, &ntfs_device_grub_io_ops, disk);
 if (! data->dev)
   goto fail;

 data->vol = ntfs_device_mount (data->dev, MS_RDONLY);
 if (! data->vol)
   goto fail;

 data->disk = disk;

 return data;

fail:

 if (data && data->vol)
   ntfs_device_umount (data->vol, FALSE);
 if (data && data->dev)
   ntfs_device_free (data->dev);
 grub_free (data);
 grub_error (GRUB_ERR_BAD_FS, "not a ntfs filesystem");
 return 0;
}

static int
grub_ntfs_umount(struct grub_ntfs_data *data)
{
 int rvl = 0;

 if (! data)
   goto fail;

 if (data->vol)
   ntfs_device_umount (data->vol, FALSE);
 if (data->dev)
   rvl = ntfs_device_free (data->dev);
 grub_free (data);
 return rvl;

fail:
 return 0;
}

ntfs_inode*
grub_ntfs_pathname_to_inode(ntfs_volume *vol, ntfs_inode *parent, const char* pathname)
{
 char *p = 0;
 char *q = 0;
 uchar_t *unicode = 0;
 int max_path = 0;
 int name_len = 0;
 char *ascii = 0;
 ntfs_inode *ni = 0;
 s64 inum = 0;

 ni = ntfs_inode_open (vol, FILE_root);
 if (! ni)
   goto fail;

 ascii = grub_strdup (pathname);
 if (! ascii)
   goto fail;

 max_path = grub_strlen(pathname)+1;
 unicode = grub_malloc (max_path);
 if (! unicode)
   goto fail;

 p = ascii;
 while (p && *p && *p == PATH_SEP) // Remove leading /'s
   p++;

 while (p && *p)
   {
     q = grub_strrchr (p, PATH_SEP);

     if (q != NULL) {
        *q = '\0';
        q++;
     }

     name_len = ntfs_mbstoucs (p, &unicode, max_path);
     if (name_len < 0)
        goto fail;

     inum = ntfs_inode_lookup_by_name (ni, unicode, name_len);
     if (inum == -1) {
        grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
        goto fail;
     }

     ntfs_inode_close(ni);

     ni = ntfs_inode_open (vol, inum);
     if (! ni) {
        grub_error (GRUB_ERR_FILE_NOT_FOUND, "open inode failed");
        goto fail;
     }

     p = q;
     while (p && *p && *p == PATH_SEP)
        p++;
   }
 grub_free (unicode);
 grub_free (ascii);
 return ni;

fail:
 grub_free (unicode);
 grub_free (ascii);
 return 0;
}

static int
grub_ntfs_filldir(void *dirent, const uchar_t *unicode,
                  const int name_len, const int name_type, const s64 pos,
                  const MFT_REF mref, const unsigned dt_type)
{
 struct grub_ntfs_data *data = (struct grub_ntfs_data*) dirent;
 char *filename = 0;
 int max_path = name_len + 1;

 filename = grub_malloc (max_path);
 if (! filename)
   goto fail;

 if (ntfs_ucstombs (unicode, name_len, &filename, max_path) <0)
   goto fail;

 if (filename[0] == '$')
   goto fail;

 if ((name_type & FILE_NAME_WIN32_AND_DOS) == FILE_NAME_WIN32)
   data->hook(filename, dt_type == NTFS_DT_DIR);

fail:
 grub_free (filename);
 return 0;
}

static grub_err_t
grub_ntfs_dir (grub_device_t device, const char* path,
              int (*hook) (const char *filename, int dir))
{
 struct grub_ntfs_data *data = 0;
 grub_disk_t disk = device->disk;
 s64 pos = 0;
 ntfs_inode *ni = 0;

#ifndef GRUB_UTIL
 grub_dl_ref (my_mod);
#endif

 data = grub_ntfs_mount (disk);
 if (! data)
   goto fail;

 ni = grub_ntfs_pathname_to_inode(data->vol, 0, path);
 if (! ni)
   goto fail;

 if (! (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY))
   {
     grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
     return 0;
   }
 data->hook = hook;
 ntfs_readdir (ni, &pos, data, grub_ntfs_filldir);
 data->hook = 0;

fail:
 ntfs_inode_close (ni);
 grub_ntfs_umount (data);

#ifndef GRUB_UTIL
 grub_dl_ref (my_mod);
#endif

 return grub_errno;
}

static grub_err_t
grub_ntfs_open (grub_file_t file, const char* name)
{
 struct grub_ntfs_data *data = 0;

#ifndef GRUB_UTIL
 grub_dl_ref (my_mod);
#endif

 data = grub_ntfs_mount (file->device->disk);
 if (! data)
   goto fail;

 data->ino = grub_ntfs_pathname_to_inode(data->vol, 0, name);
 file->size = 42; //TODO: get actual file size

 file->data = data;
 return GRUB_ERR_NONE;

fail:
 if (data->ino)
   ntfs_inode_close (data->ino);
 grub_ntfs_umount (data);
 grub_free (data);

#ifndef GRUB_UTIL
 grub_dl_unref (my_mod);
#endif

 return grub_errno;
}

static grub_ssize_t
grub_ntfs_read (grub_file_t file, char* buf, grub_ssize_t len)
{
 return -1;
}

static grub_err_t
grub_ntfs_close (grub_file_t file)
{
 struct grub_ntfs_data *data = 0;
 data = (struct grub_ntfs_data*) file->data;
 if (data->ino)
   ntfs_inode_close (data->ino);
 if (data->vol)
   grub_ntfs_umount (data);
 grub_free (file->data);

#ifndef GRUB_UTIL
 grub_dl_unref (my_mod);
#endif

 return grub_errno;
}

static grub_err_t
grub_ntfs_label (grub_device_t device, char **label)
{
 *label = grub_strndup("ntfs_label", 11);
 return GRUB_ERR_NONE;
}


static struct grub_fs grub_ntfs_fs =
 {
   .name = "ntfs",
   .dir = grub_ntfs_dir,
   .open = grub_ntfs_open,
   .read = grub_ntfs_read,
   .close = grub_ntfs_close,
   .label = grub_ntfs_label,
   .next = 0
 };

#ifdef GRUB_UTIL
void
grub_ntfs_init (void)
{
 grub_fs_register (&grub_ntfs_fs);
}

void
grub_ntfs_fini (void)
{
 grub_fs_unregister (&grub_ntfs_fs);
}
#else /* ! GRUB_UTIL */
GRUB_MOD_INIT
{
 grub_fs_register (&grub_ntfs_fs);
 my_mod = mod;
}

GRUB_MOD_FINI
{
 grub_fs_unregister (&grub_ntfs_fs);
}
#endif /* ! GRUB_UTIL */

_________________________________________________________________
Try before you buy http://linkstat.neckermann.de/go.mb1?benl_10044





reply via email to

[Prev in Thread] Current Thread [Next in Thread]