Jump to content
IGNORED

Need help with raw access


mizapf
 Share

Recommended Posts

So I got back for another time to the issue of accessing raw devices via Java, but I must admit that I ran out of options now. I don't have a clue how to get it working. :(

 

Accessing raw devices is required for TIImageTool to get read/write access to CF cards. This would make it possible to support CF7+ cards in TIImageTool.

 

If I don't get this raw access there won't be a CF7+ support for TIImageTool in Windows; you'd have to use Linux.

 

As things turned out, the already used java.io.RandomAccessFile works perfectly for reading and writing CF cards in Linux (using the device file /dev/sdX where X is the number by which it is registered in your system); should also work in OSX, I suppose. In Windows, however, you can only get read access to the CF device (using a path like \\.\h:); when trying to write you will get a FileNotFoundException. This problem was also reported by other people.

 

So I did some research and found the NIO package of Java, and people recommending to use this instead of RandomAccessFile. The idea is to open a FileChannel and do the read/write operation on it.

 

This is my test code. Note that you can run it with a regular file (e.g. use some disk image like test.dsk) as well as with device files.

import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.File;
import java.nio.ByteBuffer;
import java.nio.file.Path;
import java.nio.channels.FileChannel;
import java.nio.file.StandardOpenOption;

public class RawAccess {
   Path m_path;

   public static void main(String[] arg)
   {
     System.out.print("Enter device: ");
     BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
     try {
         String input = br.readLine();
         System.out.println(input);
         RawAccess ra = new RawAccess(input);
         ra.go();
     }
     catch (IOException iox) {
        iox.printStackTrace();
     }
   }

   RawAccess(String dev) {
      File fl = new File(dev);
      m_path = fl.toPath();
   }

   void go() throws IOException {
      FileChannel fc = FileChannel.open(m_path, StandardOpenOption.READ, StandardOpenOption.WRITE);
      ByteBuffer bb = ByteBuffer.allocate(256);
      fc.position(0);
      fc.read(bb);
      byte[] sect0 = bb.array();
 
      System.out.print("Ready to write (enter WRITE): ");
      BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
      String input = br.readLine();
      if (input.equals("WRITE")) {
         if (sect0[0xe0] == 0x00) {
            sect0[0xe0] = (byte)'M';
            sect0[0xe1] = (byte)'Z';
         }
         else {
            sect0[0xe0] = (byte)0x00;
            sect0[0xe1] = (byte)0x00;
         } 
         sect0[0xe2] = (byte)((sect0[0xe2]+1) & 0xff);
         fc.position(0);
         int number = 0;
         bb.rewind();
  
         while (bb.remaining()>0) {
            number += fc.write(bb);
            System.out.println("Wrote " + number + " bytes");
         }  
      } 
      fc.close();
   }
}

This works flawlessly in Linux when run as root, but does fail yet another time in Windows. :mad:

C:\Users\michael\Anwendungen>java RawAccess
Enter device: \\.\h:
\\.\h:
Exception in thread "main" java.nio.file.InvalidPathException: Illegal character
[:] in path at index 5: \\.\h:
        at sun.nio.fs.WindowsPathParser.nextSlash(Unknown Source)
        at sun.nio.fs.WindowsPathParser.parse(Unknown Source)
        at sun.nio.fs.WindowsPathParser.parse(Unknown Source)
        at sun.nio.fs.WindowsPath.parse(Unknown Source)
        at sun.nio.fs.WindowsFileSystem.getPath(Unknown Source)
        at java.io.File.toPath(Unknown Source)
        at RawAccess.<init>(RawAccess.java:54)
        at RawAccess.main(RawAccess.java:44)

So I tried again with another drive naming:

C:\Users\michael\Anwendungen>java RawAccess
Enter device: \\.\PHYSICALDRIVE2
\\.\PHYSICALDRIVE2
java.nio.file.FileSystemException: \\.\PHYSICALDRIVE2\: Ein an das System angesc
hlossenes Gerät funktioniert nicht.
        at sun.nio.fs.WindowsException.translateToIOException(Unknown Source)
        at sun.nio.fs.WindowsException.rethrowAsIOException(Unknown Source)
        at sun.nio.fs.WindowsException.rethrowAsIOException(Unknown Source)
        at sun.nio.fs.WindowsFileSystemProvider.newFileChannel(Unknown Source)
        at java.nio.channels.FileChannel.open(Unknown Source)
        at java.nio.channels.FileChannel.open(Unknown Source)
        at RawAccess.go(RawAccess.java:58)
        at RawAccess.main(RawAccess.java:45)

The error message translates to "A device which is connected to the system does not work."

 

I double-checked that it is indeed PHYSICALDRIVE2 (using wmic). It seems as if it tries to instantiate a file system which is not available since we want to use a CF card from our TI system.

 

Maybe someone here has an idea what to do ...

 

If you want to try, please make sure you do not overwrite your system hard disk.

Edited by mizapf
Link to comment
Share on other sites

The following site might be of some assistance about writing to other drives in windows, http://www.chrysocome.net/dd. I am interested in trying to create a Geneve only emulator with the ability to mount, read, and write to TI drives: DSHD and DSDD drives, physical and image on newer computers and to SSSD, DSDD, and DSHD on older systems that have a floppy controller that will format single density as well as double and higher.

Link to comment
Share on other sites

Hi,

 

as Java tells you "thread "main" java.nio.file.InvalidPathException: Illegal character" - just a guess:

 

Maybe you can try some other type of descriptor. This " \\.\h: " sounds a bit strange to me,

but of course maybe it is typically for Java that I don´t know.

 

Maybe something that sounds more like Windows:

 

/H:/

H:/

\\Computername\H$

H:

\H:

 

 

or maybe something like " \device\ide\IAAStoragedevice-8 "

 

(Check this correct name for your card-device here in the Windows-DeviceManager:)

 

post-41141-0-58527500-1438979094_thumb.jpg

 

 

or something like this:

 

post-41141-0-17469600-1438979307_thumb.jpg

 

 

 

...and I found this here: "\\H:\\" needs to be "H:\\"

Link to comment
Share on other sites

@RickyDean: If there is ultimately no way to write to the device in Windows, I could possibly recommend to use dd to copy to/from the flash card and then use TIImageTool on that image - that is, delegate the external access away from Java.

 

@schmitzi: The notation "\\.\DriveLetter:" is indeed Windows style and refers to accessing the device directly, without file system. This is not from Java.

 

It actually works in the current release of TIImageTool when I use RandomAccessFile. But as I said, you can only open the device for reading this way. My hope was to use FileChannel as an alternative that was said to work for writing. But FileChannel seems to require a file system...

Link to comment
Share on other sites

OK, there's something wrong, but more profoundly. I just tried to access physical devices like FAT-formatted or NTFS-formatted USB sticks, but this also fails.

 

See also http://stackoverflow.com/questions/22161967/accessing-windows-disks-directly-with-java-nio

 

(The doubled backslashes are only required when writing them inside a string. This is different in my program where I use input from the console.)

 

I tried the hint with the block size, but in my case, it is the FileChannel.open that already fails, when I did not yet attempt any read operation.

Link to comment
Share on other sites

Is your Java code running with Administrator privileges? You can't write directly to devices without it. Note that just being logged in as an administrator does not automatically grant the application the needed rights.

 

There are restrictions if your OS is later than XP: https://support.microsoft.com/en-us/kb/942448 (although all this basically says is you can not directly write to a mounted volume without first locking it - are you trying to write to mounted volumes?)

 

CreateFile notes the following rules:

  • The caller must have administrative privileges. For more information, see Running with Special Privileges.
  • The dwCreationDisposition parameter must have the OPEN_EXISTINGflag.
  • When opening a volume or floppy disk, the dwShareMode parameter must have the FILE_SHARE_WRITEflag.

There IS a note that \\.\X: is the preferred syntax for removable drives (not PhysicalDrive), so that makes figuring out which one it is easier. ;)

 

Here's a discussion about creating a manifest to run Java as administrator.. but that seems like a security problem to me since it affects all Java apps: http://stackoverflow.com/questions/1385866/java-run-as-administrator

 

This answer from that page is simple and clean, though -- and would at least allow you to test whether that is in fact the problem:

 

 

 

I use the command line on windows for this purpose. From the Start menu, type cmd in the textbox and when the program cmd.exe appears, right click on it and select Run as Administrator. Now when ytou execute java -jar itwill run with Admin rights.
  • Like 1
Link to comment
Share on other sites

Hi Tursi,

 

yes, adminstrative privileges are required, I'm running cmd.exe as Administrator. In Linux I need root privileges as well, so I assumed that under Windows (7) this should also be needed.

 

The point with the manifest in the jar file is good ... I'll try that. Until now I had to start TIImageTool from a batch file when I wanted to be granted Administrator privileges.

 

Also, the flags for CreateFile seem very promising to me. Must be something like this because I did not get the chance to do a read operation. As I said, it's happening for reading, and also for a known file system. I'm going for the flags now first.

Link to comment
Share on other sites

Yes, I tried that, but it did not work. I thought that the buffer size could have been wrong (somewhere I read that the size must exactly match the block size of the device), but the open call is already failing. I'll continue to try, anyway.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...