iPod Work

I started working on a generic iPod device class that provides lots of information about the iPod and will work with Snorp’s ipod-sharp. It provides things like the name of the iPod (not the volume name, but the assigned name), the model/type (shuffle, regular, mini, photo), version info, serial numbers, capacity, used space, etc. It also supports safe ejection of the iPod. Initially I was doing this by just calling ‘eject’ on the device.

However, I decided I’d try doing this by making an ioctl call on the device. Not giving much thought to it, I came up with a few lines of code to eject a CD-ROM drive. It didn’t dawn on me until after the CD ejection code was working that the iPod is not a CD-ROM drive (it’s okay, you can smack me). It needs to be ejected as a SCSI device. The ioctl call[s] for this task are much more complicated (a structure must be passed to the device instead of a plain integer), and I’m not sure how to do this easily in C#. I’m not sure that it’s even worth it, and will probably go back to just execing ‘eject.’

Anyway, if anyone wants to eject a CD-ROM drive in C#, here you go. This may be useful for making basic ioctls in C# for other reasons. I’ve never seen an example of ioctl from C#, so maybe this is new.

<br /> using System;<br /> using System.Runtime.InteropServices;<br /> using Mono.Unix;</p> <p>public class SimpleEject<br /> {<br /> public static void Main(string [] args)<br /> {<br /> if(args.Length &lt;= 0) {<br /> Console.WriteLine(&#8220;Usage: mono-eject.exe [-t] <device>&#8220;);<br /> return;<br /> }</p> <p> string device = args[0];<br /> bool open = true;</p> <p> if(args.Length > 1 &#038;&#038; args[0].Equals(&#8220;-t&#8221;)) {<br /> device = args[1];<br /> open = false;<br /> }</p> <p> Console.WriteLine(Eject(device, open)<br /> ? String.Format(&#8220;Device {0} {1} successfully&#8221;, device,<br /> open ? &#8220;opened&#8221; : &#8220;closed&#8221;)<br /> : &#8220;Error ejecting device &#8221; + device);<br /> }</p> <p> [DllImport(&#8220;libc&#8221;)]<br /> static extern int ioctl(int device, EjectOperation request); </p> <p> private enum EjectOperation {<br /> Open = 0x5309,<br /> Close = 0x5319<br /> }</p> <p> public static bool Eject(string devicePath, bool open)<br /> {<br /> try {<br /> using(UnixStream stream = UnixFile.Open(devicePath,<br /> OpenFlags.O_RDONLY | OpenFlags.O_NONBLOCK)) {<br /> return ioctl(stream.Handle, open<br /> ? EjectOperation.Open<br /> : EjectOperation.Close) == 0;<br /> }<br /> } catch {<br /> return false;<br /> }<br /> }<br /> }<br /> </device>

And with that we have a simple Mono eject replacement for basic opening/closing CD-ROM trays. Woo-hoo!

3 Replies to “iPod Work”

  1. Mono.Unix.UnixStream implements IDisposable, so your Eject function could instead be:

    public static bool Eject(string devicePath, bool open)
    {
    try {
    using (UnixStream stream =
    UnixFile.Open(devicePath,
    OpenFlags.O_RDONLY |
    OpenFlags.O_NONBLOCK)) {
    return ioctl(stream.Handle, open
    ? EjectOperation.Open
    : EjectOperation.Close) == 0;
    }
    } catch {
    return false;
    }
    }

    – Jon

  2. Thanks! I hadn’t even looked into UnixStream that closely. First time I’ve ever used it. I’ll update the post to reflect the optimization. Best, Aaron.

  3. Hi Aaron,

    your article is very useful, I’m trying to write a lib for DVD access in c# (porting dvdcss and libdvdread), but I can’t find IOCTL codes. Where did you get the open/close codes?

    thank you, keep up the good work :)
    andrea – tek (italy)

Comments are closed.