All of lore.kernel.org
 help / color / mirror / Atom feed
From: "lode leroy" <lode_leroy@hotmail.com>
To: grub-devel@gnu.org
Subject: problems compiling NTFS on GRUB2
Date: Thu, 12 Aug 2004 14:43:46 +0200	[thread overview]
Message-ID: <BAY22-F39kBfMPAFcdn000332e0@hotmail.com> (raw)

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	other threads:[~2004-08-12 12:48 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-08-12 12:43 lode leroy [this message]
2004-08-12 13:02 ` problems compiling NTFS on GRUB2 Marco Gerards
  -- strict thread matches above, loose matches on Subject: below --
2004-08-13  6:59 lode leroy
2004-08-13 10:25 ` Marco Gerards
2004-08-16  9:22 lode leroy
2004-08-16  9:44 ` Marco Gerards
2004-08-16 10:35   ` Yoshinori K. Okuji

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=BAY22-F39kBfMPAFcdn000332e0@hotmail.com \
    --to=lode_leroy@hotmail.com \
    --cc=grub-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.