不点 发表于 2018-1-25 12:06:46

imdisk支持sector map扇区映射

在 http://reboot.pro/topic/20450-mounting-split-image/ 的 7 楼,imdisk 的开发者本人透露:

This is rather easy nowadays with ImDisk.
Simply specify a physical drive object as "image file"
and specify offset and size as -b and -s switches.
Example:

imdisk -a -f \\?\physicaldrive1 -b 200000 -s 300000 -m #:

-f \\?\physicaldrive1 - path to physical drive object

-b 200000 = offset in bytes

-s 300000 = size in bytes (length to use after offset)

For first experiments add -o ro for read-only operation, so that ImDisk does not overwrite anything until you know that it works and you have got the right offsets and lengths.

And yes, I use this method now and then to mount secondary partitions on USB thumb drives that are not directly visible in Windows. :)

在 http://diddy.boot-land.net/firadisk/files/imdisk.htm 有个 imdisk 的教程。

在命令窗口执行 imdisk/? 命令,可以获得如下的帮助信息:


Control program for the ImDisk Virtual Disk Driver.
For copyrights and credits, type imdisk --version

Syntax:
imdisk -a -t type -m mountpoint [-n] [-o opt1[,opt2 ...]] [-f|-F file]
       [-s size] [-b offset] [-v partition] [-S sectorsize] [-u unit]
       [-x sectors/track] [-y tracks/cylinder] [-p "format-parameters"]
imdisk -d|-D [-u unit | -m mountpoint]
imdisk -l [-u unit | -m mountpoint]
imdisk -e [-s size] [-o opt1[,opt2 ...]] [-u unit | -m mountpoint]

-a      Attach a virtual disk. This will configure and attach a virtual disk
      with the parameters specified and attach it to the system.

-d      Detach a virtual disk from the system and release all resources.
      Use -D to force removal even if the device is in use.

-e      Edit an existing virtual disk.

      Along with the -s parameter extends the size of an existing virtual
      disk. Note that even if the disk can be extended successfully, the
      existing filesystem on it can only be extended to fill the new size
      without re-formatting if you are running Windows 2000 or later and the
      current filesystem is NTFS.

      Along with the -o parameter changes media characteristics for an
      existing virtual disk. Options that can be changed on existing virtual
      disks are those specifying wether or not the media of the virtual disk
      should be writable and/or removable.

-t type
      Select the backingstore for the virtual disk.

vm      Storage for this type of virtual disk is allocated from virtual memory
      in the system process. If a file is specified with -f that file is
      is loaded into the memory allocated for the disk image.

file    A file specified with -f file becomes the backingstore for this
      virtual disk.

proxy   The actual backingstore for this type of virtual disk is controlled by
      an ImDisk storage server accessed by the driver on this machine by
      sending storage I/O request through a named pipe specified with -f.

-f file or -F file
      Filename to use as backingstore for the file type virtual disk, to
      initialize a vm type virtual disk or name of a named pipe for I/O
      client/server communication for proxy type virtual disks. For proxy
      type virtual disks "file" may be a COM port or a remote server
      address if the -o options includes "ip" or "comm".

      Instead of using -f to specify 'DOS-style' paths, such as
      C:\dir\image.bin or \\server\share\image.bin, you can use -F to
      specify 'NT-style' native paths, such as
      \Device\Harddisk0\Partition1\image.bin. This makes it possible to
      specify files on disks or communication devices that currently have no
      drive letters assigned.

-l      List configured devices. If given with -u or -m, display details about
      that particular device.

-n      When printing ImDisk device names, print only the unit number without
      the \Device\ImDisk prefix.

-s size
      Size of the virtual disk. Size is number of bytes unless suffixed with
      a b, k, m, g, t, K, M, G or T which denotes number of 512-byte blocks,
      thousand bytes, million bytes, billion bytes, trillion bytes,
      kilobytes, megabytes, gigabytes and terabytes respectively. The suffix
      can also be % to indicate percentage of free physical memory which
      could be useful when creating vm type virtual disks. It is optional to
      specify a size unless the file to use for a file type virtual disk does
      not already exist or when a vm type virtual disk is created without
      specifying an initialization image file using the -f or -F. If size is
      specified when creating a file type virtual disk, the size of the file
      used as backingstore for the virtual disk is adjusted to the new size
      specified with this size option.

      The size can be a negative value to indicate the size of free physical
      memory minus this size. If you e.g. type -400M the size of the virtual
      disk will be the amount of free physical memory minus 400 MB.

-b offset
      Specifies an offset in an image file where the virtual disk begins. All
      offsets of I/O operations on the virtual disk will be relative to this
      offset. This parameter is particularily useful when mounting a specific
      partition in an image file that contains an image of a complete hard
      disk, not just one partition. This parameter has no effect when
      creating a blank vm type virtual disk. When creating a vm type virtual
      disk with a pre-load image file specified with -f or -F paramters, the
      -b parameter specifies an offset in the image file where the image to
      be loaded into the vm type virtual disk begins.

      Specify auto as offset to automatically select offset for a few known
      non-raw disk image file formats. Currently auto-selection is supported
      for Nero .nrg and Microsoft .sdi image files.

-v partition
      Specifies which partition to mount when mounting a raw hard disk image
      file containing a master boot record and partitions.

      Specify number 1-4 to mount a partition from the primary partition
      table and 5-8 to mount a partition from an extended partition table.

-S sectorsize
      Sectorsize to use for the virtual disk device. Default value is 512
      bytes except for CD-ROM/DVD-ROM style devices where 2048 bytes is used
      by default.

-x sectors/track
      See the description of the -y option below.

-y tracks/cylinder
      The -x and -y options can be used to specify a synthetic geometry.
      This is useful for constructing bootable images for later download to
      physical devices. Default values depends on the device-type specified
      with the -o option. If the 'fd' option is specified the default values
      are based on the virtual disk size, e.g. a 1440K image gets 2
      tracks/cylinder and 18 sectors/track.

-p "format-parameters"
      If -p is specified the 'format' command is invoked to create a
      filesystem when the new virtual disk has been created.
      "format-parameters" must be a parameter string enclosed within
      double-quotes. The string is added to the command line that starts
      'format'. You usually specify something like "/fs:ntfs /q /y", that
      is, create an NTFS filesystem with quick formatting and without user
      interaction.

-o option
      Set or reset options.

ro      Creates a read-only virtual disk. For vm type virtual disks, this
      option can only be used if the -f option is also specified.

rw      Specifies that the virtual disk should be read/writable. This is the
      default setting. It can be used with the -e parameter to set an
      existing read-only virtual disk writable.

rem   Specifies that the device should be created with removable media
      characteristics. This changes the device properties returned by the
      driver to the system. For example, this changes how some filesystems
      cache write operations.

fix   Specifies that the media characteristics of the virtual disk should be
      fixed media, as opposed to removable media specified with the rem
      option. Fixed media is the default setting. The fix option can be used
      with the -e parameter to set an existing removable virtual disk as
      fixed.

saved   Clears the 'image modified' flag from an existing virtual disk. This
      flag is set by the driver when an image is modified and is displayed
      in the -l output for a virtual disk. The 'saved' option is only valid
      with the -e parameter.

      Note that virtual floppy or CD/DVD-ROM drives are always read-only and
      removable devices and that cannot be changed.

cd      Creates a virtual CD-ROM/DVD-ROM. This is the default if the file
      name specified with the -f option ends with either .iso, .nrg or .bin
      extensions.

fd      Creates a virtual floppy disk. This is the default if the size of the
      virtual disk is any of 160K, 180K, 320K, 360K, 640K, 720K, 820K, 1200K,
      1440K, 1680K, 1722K, 2880K, 123264K or 234752K.

hd      Creates a virtual fixed disk partition. This is the default unless
      file extension or size match the criterias for defaulting to the cd or
      fd options.

ip      Can only be used with proxy-type virtual disks. With this option, the
      user-mode service component is initialized to connect to an ImDisk
      storage server using TCP/IP. With this option, the -f switch specifies
      the remote host optionally followed by a colon and a port number to
      connect to.

comm    Can only be used with proxy-type virtual disks. With this option, the
      user-mode service component is initialized to connect to an ImDisk
      storage server through a COM port. With this option, the -f switch
      specifies the COM port to connect to, optionally followed by a colon,
      a space, and then a device settings string with the same syntax as the
      MODE command.

-u unit
      Along with -a, request a specific unit number for the ImDisk device
      instead of automatic allocation. Along with -d or -l specifies the
      unit number of the virtual disk to remove or query.

-m mountpoint
      Specifies a drive letter or mount point for the new virtual disk, the
      virtual disk to query or the virtual disk to remove. When creating a
      new virtual disk you can specify #: as mountpoint in which case the
      first unused drive letter is automatically used.

不点 发表于 2018-1-25 15:37:21

红毛樱木 发表于 2018-1-25 13:11
这个一直都支持。。。您才知道啊,用了几年了。

哦,我跟不上形势了。能分享使用经验、心得体会吗?能给出优缺点的评价吗?

我想制作一个 U 盘,含两个分区:开头是 FAT32 分区,紧接着是 NTFS 分区。

NTFS 分区需要从分区表中去除掉,只留下 FAT32 分区,这样的单一分区结构,才能满足某些变态 BIOS 的要求(其实我认为那是垄断者用 BIOS 来封杀多分区启动盘,不然的话,U 盘到处能启动 Windows,尤其是低版本的 Windows,这可能不符合垄断者的利益)。

这个 NTFS 分区的数据还在,只是分区表上找不到它了。

请问,这种情况,进入 Win7 (或 Win10 PE)以后,怎么用 imdisk 来挂上这个 NTFS 分区?最好给出详细步骤。

红毛樱木 发表于 2018-1-25 13:11:02

这个一直都支持。。。您才知道啊,用了几年了。

红毛樱木 发表于 2018-1-25 15:59:10

本帖最后由 红毛樱木 于 2018-1-25 16:03 编辑

不点 发表于 2018-1-25 15:37
哦,我跟不上形势了。能分享使用经验、心得体会吗?能给出优缺点的评价吗?

我想制作一个 U 盘,含两 ...

我一直用PECMD操作的。IMDISK命令行应该差不多。
ENVI^ EnviMode=1
ENVI^ ForceLocal=1
//定义磁盘号
ENVI &HD=6
//定义分区号
ENVI &ID=2
//要挂载的盘符
ENVI &Drv=Z:
part -hextp -phy -fill list part %&hd%#%&ID%,&&DiskInfo
MSTR &&a,&&b,&&c,&&d=<2><8><4><5>%&DiskInfo%
RAMD ImDisk*ret*%&c%*%&d%*0*\\.\PhysicalDrive%&hd% -a -o hd -m %&Drv%

好像还有个更简单的方式。MOUN-udm -udmid:pt1,具体格式忘记了。
------------------我这个好像需要通过分区表的信息获取分区长度。。。估计不适合你用。。。

不点 发表于 2018-1-25 17:24:55

红毛樱木 发表于 2018-1-25 15:59
我一直用PECMD操作的。IMDISK命令行应该差不多。




那我以后有机会就试试吧。看看这个 imdisk 会不会比 winvblock 更好用。

不点 发表于 2018-1-27 09:28:49

红毛樱木 发表于 2018-1-25 15:59
我一直用PECMD操作的。IMDISK命令行应该差不多。




我用笨办法搞定了。步骤如下:

在 U 盘开头建立 Fat32 分区,提高启动成功率(我实际上是使用我自己开发的 multimbr,本身就是 FAT32 格式)。剩余空间创建 NTFS 分区,用来存放大文件。

然后,用 bootice 查看分区表上 NTFS 分区的起始扇区号和分区长度,用计算器转换成 10 进制。这个必须准确无误。以下假定起始扇区号是 12345678,分区长度是 87654321。在 U 盘的 FAT32 分区创建批处理文件,名字是 imdisk0.bat,内容只有一行:

imdisk-a-f\\.\PhysicalDrive0-b12345678b-s87654321b-m#:

类似地,创建 imdisk1.bat,imdisk2.bat,......,直到 imdisk9.bat,分别相应于 PhysicalDrive1,2,......,直到 9。

为什么要创建这么多批处理文件呢?因为事先不知道哪个 PhysicalDrive 是 U 盘。

好的,现在可以用 bootice 修改 U 盘分区表,抹掉 NTFS 表项,这就彻底隐藏了 NTFS 分区。

任何时候需要访问 NTFS 分区时,只需执行上述某个批处理即可把隐藏的 NTFS 分区挂到一个新盘符上。这些批处理里面,只有一个是成功的,其它都会失败。没关系,我们要的就是成功的这个,而那些失败的,直接在资源管理器中卸载无效盘符即可。


这个办法很笨,不求大家打赏。但它管用,也简单易懂,我就满意了。

经过测试,无论在 pe 下还是在正常 Windows下都能工作。

红毛樱木 发表于 2018-1-27 09:43:12

不点 发表于 2018-1-27 09:28
我用笨办法搞定了。步骤如下:

在 U 盘开头建立 Fat32 分区,提高启动成功率(我实际上是使用我自己开 ...

原理是一样的。

不点 发表于 2018-1-28 08:58:04

本帖最后由 不点 于 2018-1-28 08:59 编辑

太棒了!!!!google 了 “batch nt-style native path”,找到如下网页:

DOS to NT: A Path’s Journey
https://blogs.msdn.microsoft.com/jeremykuhne/2016/05/02/dos-to-nt-a-paths-journey/

重要部分摘录:

all of the following (and many other variants) are equivalent:

    C:\bar\foo.txt
    \\.\C:\bar\foo.txt
    \\?\C:\bar\foo.txt
    \??\C:\bar\foo.txt
    \\?\Harddisk0Partition2\bar\foo.txt
    \\?\HarddiskVolume4\bar\foo.txt
    \\?\Volume{0FAF43C1-2AED-4824-B2D4-2339C14E93A}\bar\foo.txt
    \\?\Volume{d1655348-000-000-000-f0150000000}\bar\foo.txt
    \\?\GLOBALROOT\Device\Harddisk0\Partition2\bar\foo.txt
    \\.\GLOBALROOT\Device\HarddiskVolume4\bar\foo.txt
    \\LOCALHOST\C$\bar\foo.txt
    \\?\UNC\C$\bar\foo.txt
    \\?\GLOBALROOT\Device\Mup\C$\bar\foo.txt



我在 cmd 命令提示符下试验,有些不支持,但有些是支持的,特别是正好支持了我想要的这个:

type \\?\GLOBALROOT\Device\Harddisk1\Partition1\imdisk0.bat

此命令成功显示出我的 U 盘上的 imdisk0.bat 的内容!

这样,我通过 for 循环 和 if 语句来枚举测试 Harddisk? 就能确定究竟 imdisk0.bat 是在哪个 PhysicalDrive 上了。知道了这一点,也就可以写挂载虚拟 ntfs 分区的命令了。棒极了!前几天费了好大牛劲,也没找到想要的简单办法。


dos时代菜鸟 发表于 2018-1-28 09:38:29

vbs脚本
'获取 磁盘以及其分区列表,包括接口信息。
Set wmi=GetObject("winmgmts:\\.\root\cimv2")
Set disk_s=wmi.instancesof("win32_LogicalDiskToPartition")
Set d_s=wmi.instancesof("win32_diskdrive")
sn=""
d0=Split("x,y",",",-1,1)
For Each s In disk_s
        dx=d0(1)
'记录 分区对应的 硬盘index
        d0=split(Split(Split(s.antecedent,"=",-1,1)(1),",",-1,1)(0),"#",-1,1)

        d1=Split(s.Dependent,"=",-1,1)
        If (dx = d0(1) ) then
                sn=sn&(d1(1))
        Else
                For Each d In d_s
                   If (""&d.index = ""&d0(1)) Then id=chr(10)&d.name&""&d.interfacetype
                Next
                sn=sn+id&" "&(d1(1))
        End If

Next
wscript.echo sn

不点 发表于 2018-1-28 10:43:19

dos时代菜鸟 发表于 2018-1-28 09:38
vbs脚本

在 win PE 下能运行吗?我需要在多种环境都能起作用的方法。

不点 发表于 2018-1-28 10:56:27

本帖最后由 不点 于 2018-1-28 10:58 编辑

找到了一个 c++ 的程序,能够得到逻辑盘号所对应物理驱动器号。C 代码比较折腾,不如脚本方便,聊胜于无吧。

https://www.codeproject.com/Messages/3155060/Re-Translate-Logical-Drive-to-Physical-Drive.aspx

You could use the IOCTL_STORAGE_GET_DEVICE_NUMBER[^] control code to obtain the physical drive and volume number.

For example:

#include <Winioctl.h>
VOID LogicalToPhysical(TCHAR *szDrive)
{
      CString szPhysical;
      HANDLE h = CreateFile(szDrive, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
      if(INVALID_HANDLE_VALUE != h)
      {
                STORAGE_DEVICE_NUMBER sd;
                DWORD dwRet;
                if(DeviceIoControl(h, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &sd, sizeof(STORAGE_DEVICE_NUMBER), &dwRet, NULL))
                {
                        szPhysical.Format(_T("\\\\.\\PhysicalDrive%d"), sd.DeviceNumber);
                }
                CloseHandle(h);
      }
}

//Usage:
LogicalToPhysical(_T("\\\\.\\\\C:"));


Note that this control code will fail to return correct information for mirrored and striped volumes. A more complete solution for these types of drives would be the IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS[^] control code which will return an array of partitions for the drive.

Best Wishes,
-David Delaune



dos时代菜鸟 发表于 2018-1-28 11:10:24

不点 发表于 2018-1-28 10:56
找到了一个 c++ 的程序,能够得到逻辑盘号所对应物理驱动器号。C 代码比较折腾,不如脚本方便,聊胜于无吧 ...

嗯,如果winpe 没有 vbs 和 wmic
vbs 就不好用了。

不点 发表于 2018-1-28 11:34:44

又找到一个 VB 脚本

http://www.vbforums.com/showthread.php?466828-RESOLVED-Get-physical-drive-number-given-a-drive-letter

    Option Explicit
    Private Enum IOCOMMANDS
      IOCTL_STORAGE_GET_DEVICE_NUMBER = &H2D1080
    End Enum

    Private Declare Function DeviceIoControl Lib "kernel32" _
      (ByVal hDevice As Long, _
       ByVal dwIoControlCode As Long, _
       lpInBuffer As Any, _
       ByVal nInBufferSize As Long, _
       lpOutBuffer As Any, _
       ByVal nOutBufferSize As Long, _
       lpBytesReturned As Long, _
       lpOverlapped As Any) As Long

    Private Declare Function CreateFile Lib "kernel32" _
       Alias "CreateFileA" _
      (ByVal lpFileName As String, _
       ByVal dwDesiredAccess As Long, _
       ByVal dwShareMode As Long, _
       lpSecurityAttributes As Any, _
       ByVal dwCreationDisposition As Long, _
       ByVal dwFlagsAndAttributes As Long, _
       ByVal hTemplateFile As Long) As Long

    Private Declare Function CloseHandle Lib "kernel32" _
       (ByVal hObject As Long) As Long

    Private Const INVALID_HANDLE_VALUE As Long = -1&
    Private Const GENERIC_READ As Long = &H80000000
    Private Const FILE_SHARE_READ As Long = &H1
    Private Const FILE_SHARE_WRITE As Long = &H2
    Private Const OPEN_EXISTING As Long = 3

    Type ddevicetype
      DEVICE_TYPE As Long
      deviceno As Long
      partionno As Long
    End Type

    Public Function DeviceCheckMedia(sDrive As String) As ddevicetype

      Dim hDevice As Long
      Dim bytesReturned As Long
      Dim success As Long
      Dim sdn As ddevicetype

    'Open a handle to drive
      hDevice = CreateFile("\\.\" & sDrive, _
                            GENERIC_READ, _
                            FILE_SHARE_READ Or FILE_SHARE_WRITE, _
                            ByVal 0&, _
                            OPEN_EXISTING, _
                            0&, 0&)
    'Issue GET_DEVICE_NUMBER command to DeviceIoControl
      If hDevice <> INVALID_HANDLE_VALUE Then
            success = DeviceIoControl(hDevice, _
                                    IOCTL_STORAGE_GET_DEVICE_NUMBER, _
                                    0&, _
                                    0&, _
                                    sdn, _
                                    Len(sdn), _
                                    bytesReturned, _
                                    ByVal 0&)
      End If
    'Close Handle to drive
      Call CloseHandle(hDevice)
    'Return sdn contianing drive type, drive #,and partition #
      DeviceCheckMedia = sdn
    End Function




    Sorry, I mis-spoke there. I did mean physical drive.
    I'm not sure if this will help you generating the input you listed, this will give you the physical drive numbers as they are listed in the drive managment console. I'm not sure how you would find out which controller it is connected to becasue windows will assign a drive number the same whether you add a second drive to an IDE controller or plug in a USB drive. There may be a way to get the serial number directly with DeviceIoControl instead?

    Just to clarify. The function returns 3 things

    sdn.DEVICE_TYPE - type of drive, 7 for fixed disk, there is a list of the other return codes somewhere if you need them. I was only concerned with fixed disks.

    sdn.deviceno - the device number or phycial disk number of the drive, 0 for first physical drive, 1 for 2nd, etc...

    sdn.partitionno - the number of the partition, 1st partion on a physical disk is 1, second is 2 etc...

    So, using your 100GB dirve with 2 partitons as an example

    devicecheckmedia (C:)

    returns
    sdn.DEVICE_TYPE = 7
    sdn.deviceno = 0
    sdn.partitionno = 1


    devicecheckmedia (D:)

    returns
    sdn.DEVICE_TYPE = 7
    sdn.deviceno = 0
    sdn.partitionno = 2

    if we have a second physical drive with one partition E:


    devicecheckmedia (E:)

    returns
    sdn.DEVICE_TYPE = 7
    sdn.deviceno = 1
    sdn.partitionno = 1

不点 发表于 2018-1-28 13:57:00

从这里 https://msfn.org/board/topic/174825-get-disk-number-from-drive-letter-in-cmd/
找到这里 http://reboot.pro/topic/20240-how-to-get-partitions-path-in-command-prompt/
又找到这里:http://www.ltr-data.se/opencode.html/ 这里有 imdisk 作者自己写的很多工具软件。
太棒了!!!!devioctl.exe 就够用了:

D:\>devioctl.exe extents c:
Disk number    : 0
Starting offset: 160039276544
Extent length: 34359742464 (32 GB)


c:: 操作成功完成。

D:\>devioctl.exe extents f:
Disk number    : 1
Starting offset: 32256
Extent length: 67786129920 (63.13 GB)


f:: 操作成功完成。

D:\>

给出 F: 盘符(它是我的 U 盘),就能得到 disk number = 1,这就是 PhysicalDrive 的号码。要的就是它呀!

dos时代菜鸟 发表于 2018-1-28 14:55:22

不点 发表于 2018-1-28 13:57
从这里 https://msfn.org/board/topic/174825-get-disk-number-from-drive-letter-in-cmd/
找到这里 http: ...

{:1_191:}
{:1_183:}
大师威武

不点 发表于 2018-1-28 18:41:56

本帖最后由 不点 于 2018-2-9 16:52 编辑

mount_NTFS.bat 批处理做好了,以下是示例代码:

请自己下载 devioctl 放在 U 盘上,与 mount_NTFS.bat 放在一起。

可不要把 mount_NTFS.bat 放在硬盘上啊!如果是在硬盘上,就把硬盘的扇区序列虚拟成盘符了,这很危险!

批处理在哪个盘上,就会把哪个盘上的扇区序列虚拟成一个新盘!一定要明白!

【说明】下面这个版本不要用了,请下载 19 楼的修正增强版。


:: Use VER to Reset ERRORLEVEL to 0
ver > NUL
pushd "%CD%"
cd /d "%~dp0"
if not exist imdisk.exe for %%I in (imdisk.exe) do if "%%~$PATH:I"=="" if exist imdiskinst.exe imdiskinst.exe
if not exist imdisk.exe for %%I in (imdisk.exe) do if "%%~$PATH:I"=="" goto :NO_IMDISK
if not exist devioctl.exe for %%I in (devioctl.exe) do if "%%~$PATH:I"=="" goto :NO_DEVIOCTL
for /F "tokens=1,2,3,4,*" %%A in ('devioctl.exe extents %~d0') do (
if not [%%A]== goto :NO_DISK
if not [%%B]== goto :NO_NUMBER
if not [%%C]==[:] goto :NO_COLON
if not [%%E]==[] goto :E_NOT_EMPTY
if %%D GTR 9 goto :TOO_MANY_DRIVES

:: 下面这句是关键,请修改好以后,去掉前面的 echo,就真正起作用了!危险!
echo imdisk.exe -a -f \\.\PhysicalDrive%%D -b 132395008b -s 110219264b -m #:

if %ERRORLEVEL% NEQ 0 goto :IMDISK_FAILED
goto :END
)

:NO_DEVIOCTL
echo Error: No devioctl.exe!
pause
goto :END

:NO_DISK
echo Error: No disk!
pause
goto :END

:NO_NUMBER
echo Error: No number!
pause
goto :END

:NO_COLON
echo Error: No colon!
pause
goto :END

:E_NOT_EMPTY
echo Error: E not empty!
pause
goto :END

:TOO_MANY_DRIVES
echo Error: Too many drives!
pause
goto :END

:NO_IMDISK
echo Error: No imdisk.exe!
pause
goto :END

:IMDISK_FAILED
echo Error: imdisk failed!
pause
goto :END

:END
popd

不点 发表于 2018-2-2 09:48:56

从 chenall 的 Blog 上又找到一个好东西——

批处理检测外部命令是否存在的模块
http://chenall.net/post/cmd_if_exist/

作者 chenall 发表于 2009-09-29

编写批处理时经常需要用到外部命令,一些常用的命令一般的系统都会有,但是一些精简的系统上可能就没有了。如果没有作判断就可能导致程序出现未知的错误。

一般检测文件是否存在可以使用

    IF EXIST filename 执行某个命令…

但是这样只能检测当前目录下或指定目录的,而批处理的外部命令是通过 PATH 变量来确定位置的。正常情况下可以通过以下命令来确定这个外部命令是否存在:

    for %I in (find.exe) do if “%~$PATH:I”==”” echo find 命令不存在

为了以后方便就写了一个模块,用于判断命令是否存在。

@echo off
cls&echo.IF_EXIST.cmd by chenall 2009-09-29 http://www.chenall.net
echo.
echo.功能:
echo.   从环境变量PATH,当前目录,程序所在目录中查找指定的文件,如果找到就显示并返回值0,否则就返回1
echo.
echo.使用方法:
echo.   直接复制下面::模块开始::到::模块结束::之间的代码到你的批处理程序中.然后使用以下命令调用.
echo.   CALL :IF_EXIST xxxx.xxx
echo.
echo.使用例子:
echo.   CALL :IF_EXIST find.exe || echo.find.exe 不存在
echo.
echo.注:只是简单查找,并且不支持查找子目录.主要用于批处理中判断某个外部命是否存在.
echo.   实际应用中可以删除echo %~$PATH:1语句删除输出显示,或者在调用时加一个>nul
echo.
echo.
ECHO.以下是测试命令.
ECHO.查找FIND.EXE
CALL :IF_EXIST FIND.EXE || ECHO.FIND.EXE 不存在
CALL :IF_EXIST FIND.EXE >nul ||echo.出错了,find.exe不存在.
ECHO.查找noEXIST.FILE
CALL :IF_EXIST noEXIST.FILE || ECHO.noEXIST.FILE 不存在
PAUSE
GOTO :EOF

::::::::::::::::::::::::模块开始::::::::::::::::::::::::
:IF_EXIST       BY chenall QQ:366840202   2009-09-29
SETLOCAL&PATH %PATH%;%~dp0;%cd%
if "%~$PATH:1"=="" exit /b 1
echo %~$PATH:1
exit /b 0       http://www.chenall.net
:::::::::::::::::::::::模块结束:::::::::::::::::::::::::

不点 发表于 2018-2-3 01:29:29

本帖最后由 不点 于 2020-4-28 20:28 编辑


下面的代码是 2020-04-28 更新的。


注意!设计的目标,就是只在 U 盘上使用。请不要在硬盘上使用。为避免硬盘受到伤害,请不要把这个脚本放在硬盘上!脚本在哪个盘上,就会对哪个盘进行操作。

主要用于 U 盘单分区的情况。U 盘多分区的情况,能否使用,请您自行判断。Ventoy 的 exFAT + FAT 双分区,在 Win7 下只有 exFAT 是可见的。我已经证明可以用这个脚本来把不可见的 FAT 分区虚拟出来,变成可见的 FAT 卷。

注意,U 盘扇区总数应该低于 2T,也即低于 2000G。这是因为,脚本采用 4 字节的整数来表示扇区号,因此,最大只能处理 2T 的容量。而且,U 盘应该是 MBR 格式。我没有测试 GPT 格式是否支持,所以,不要在 GPT 格式的 U 盘上使用。

程序会查找 U 盘的第一个分区之后的空间,看看它是不是一个合法的文件系统卷。如果是的,就挂载为虚拟盘。

程序使用了两个工具:imdisk.exe 以及 devioctl.exe。

你的系统中必须已经安装了 imdisk。你必须把 devioctl.exe 与该脚本放在一起,或者放在 C 盘的 Windows 系统中 PATH 可以查找的位置。


另外,你可能需要用管理员的身份,才能正常运行脚本。运行失败时,你可以试试用鼠标右键单击脚本,然后选择 “以管理员的身份运行”。





@echo off
setlocal EnableDelayedExpansion
pushd "%CD%"
cd /d "%~dp0"
if not exist imdisk.exe for %%I in (imdisk.exe) do if "%%~$PATH:I"=="" if exist imdisk\imdiskinst.exe imdisk\imdiskinst.exe
if not exist imdisk.exe for %%I in (imdisk.exe) do if "%%~$PATH:I"=="" goto :NO_IMDISK
if not exist devioctl.exe for %%I in (devioctl.exe) do if "%%~$PATH:I"=="" goto :NO_DEVIOCTL
REM 准备获取物理驱动器号、FAT32 分区位置、长度等信息
set L=6
echo devioctl.exe geometry %~d0
for /F "skip=6 tokens=1,2,3,4,*" %%A in ('devioctl.exe geometry %~d0') do (
set /a L+=1
if !L! GTR 21 goto :END
REM 下面这句显示一个“.”,模拟动画进度条。echo 命令无法做到不换行。
set /p =. < NUL
call :do_lines%%A %%B %%C %%D
)
echo devioctl.exe needs to run as Administrator!
echo Right click the batch file and select "Run as administrator".
pause
goto :END

:do_lines
if "%1"=="" exit /b
if %L%==7 (
if not "%1 %2 %3"=="Total CHS size:" goto :NO_Total_CHS_size

exit /b
)
if %L%==8 (
if not "%1 %2 %3"=="LBA length :" goto :NO_LBA_length

REM 成功获取分区长度 %4。
set LENGTH=%4

exit /b
)
if %L%==9 exit /b
if %L%==10 (
if not "%1 %2 %3"=="Start offset :" goto :NO_Start_offset

REM 成功获取分区起始偏移 %4。
set OFFSET=%4

exit /b
)
if %L% GTR 10 if %L% LSS 20 exit /b
if %L%==20 (
if not "%1 %2 %3"=="Device number :" goto :NO_Device_number
if %4 GTR 9 goto :TOO_MANY_DRIVES

REM 成功获取物理驱动器号 %4。
set PHYDRV=%4
exit /b
)

if not %L%==21 exit /b

REM 把 64 位的 offset 除以 512 转化为 32 位值(扇区数)。
set HI=%OFFSET:~0,-3%
set LO=%OFFSET:~-3%
set /a "Q=%HI%/512"
set /a "R=%HI% %% 512"
REM %Q%000 就是 %Q% * 1000,同理,%R%000 也是 %R% * 1000
set /a "OFFSET=%Q%000 + (%R%000 + %LO%)/512"
echo %OFFSET%

REM 把 64 位的 length 除以 512 转化为 32 位值(扇区数)。
set HI=%LENGTH:~0,-3%
set LO=%LENGTH:~-3%
set /a "Q=%HI%/512"
set /a "R=%HI% %% 512"
REM %Q%000 就是 %Q% * 1000,同理,%R%000 也是 %R% * 1000
set /a "LENGTH=%Q%000 + (%R%000 + %LO%)/512"
echo %LENGTH%

set /a B=%OFFSET%+%LENGTH%
set BB=%B%
REM 虚拟盘的起始扇区 B,对齐到下一个 MB 的边界,就是 BB 了。
REM 后面的代码会先尝试从 B 处挂载;若失败,再尝试从 BB 处挂载。
set /a BB+=2047
set /a "BB&=-2048"
echo %B%, %BB%

REM 准备获取物理驱动器 PHYDRV 的总扇区数。
set L=0
echo devioctl.exe extents PhysicalDrive%PHYDRV%
for /F "tokens=1,2,3,4,*" %%A in ('devioctl.exe extents PhysicalDrive%PHYDRV%') do (
set /a L+=1
if !L! GTR 3 goto :done_phy
set /p =. < NUL
call :do_lines_phy%%A %%B %%C %%D
if !L! GTR 3 goto :done_phy
)
echo devioctl.exe needs to run as Administrator!
echo Right click the batch file and select "Run as administrator".
pause
goto :END

:done_phy

REM 把 64 位的 total 除以 512 转化为 32 位值(扇区数)。
set HI=%TOTAL:~0,-3%
set LO=%TOTAL:~-3%
set /a "Q=%HI%/512"
set /a "R=%HI% %% 512"
REM %Q%000 就是 %Q% * 1000,同理,%R%000 也是 %R% * 1000
set /a "TOTAL=%Q%000 + (%R%000 + %LO%)/512"
echo %TOTAL%

if %BB% GEQ %TOTAL% goto :mount_fail

set /a S=%TOTAL%-%B%
set /a SS=%TOTAL%-%BB%
echo %S%

:try_mount

REM 选项 -o rem 是挂载为“可移动磁盘”,虚拟盘可以“弹出”。
REM 若用默认的 -o fix 挂为“本地磁盘”,则虚拟盘无法弹出,也无法安全卸载。
echo.
echo imdisk.exe -a -f \\.\PhysicalDrive%PHYDRV% -b %B%b -s %S%b -m #: -o rem

REM Use VER to Reset ERRORLEVEL to 0
ver > NUL

set CREATED=NODRIVE:

for /F "tokens=1,2,3,4,*" %%A in ('imdisk.exe -a -f \\.\PhysicalDrive%PHYDRV% -b %B%b -s %S%b -m #: -o rem') do (
rem set /a L+=1
rem if !L! GTR 3 goto :done_phy
set /p =. < NUL
echo %%A %%B %%C %%D %%E
if "%%A %%B"=="Created device" set CREATED=%%D
rem call :do_lines_phy%%A %%B %%C %%D
rem if !L! GTR 3 goto :done_phy
)

REM if !ERRORLEVEL! NEQ 0 goto :IMDISK_FAILED

REM 如果想要挂载一个未格式化的卷,可以去掉下面这句开头的注释符
rem if "%BB%"=="%B%" goto :finish

REM 检查是否成功挂载了一个带有文件系统的卷
if exist %CREATED% goto :finish

REM 失败,没有发现文件系统,现在卸掉已经挂上的无效虚拟盘
REM devioctl.exe dismount %CREATED% <--- 这个卸载方法不起作用
imdisk -D -m %CREATED%

if "%B%"=="%BB%" goto :mount_fail
REM 让虚拟盘的起始位置按 MB 对齐,再试一次
set B=%BB%
set S=%SS%
goto :try_mount

:mount_fail
echo 挂载失败!可能不存在隐藏分区,或隐藏分区的位置很特殊。60 秒后自动退出。
ping -n 60 localhost > nul

REM 设置退出条件,让第一个 for 循环体正常退出
set L=22

exit /b

:finish
echo 操作成功!请检查上述信息是否正常,60 秒后自动退出。
ping -n 60 localhost > nul

REM 设置退出条件,让第一个 for 循环体正常退出
set L=22

exit /b


:do_lines_phy
if "%1"=="" exit /b
if %L%==1 (
if not "%1 %2 %3"=="Disk number :" goto :NO_Disk_number
if not "%4"=="%PHYDRV%" goto :Wrong_Disk_number
exit /b
)
if %L%==2 (
if not "%1 %2 %3"=="Starting offset: 0" goto :Wrong_Starting_offset
exit /b
)

if not %L%==3 exit /b

REM 设置退出条件,让 for 循环体正常退出
set L=22

if not "%1 %2 %3"=="Extent length :" goto :NO_Extent_length
REM 成功获取物理驱动器总长度 %4。
set TOTAL=%4

exit /b


:Wrong_Disk_number
echo Fatal: Wrong Disk number( %4 != %PHYDRV% )! Exit!
pause
exit /b

:Wrong_Starting_offset
echo Fatal: Wrong Starting offset (should be 0)! Exit!
pause
exit /b

:NO_Start_offset
echo Error: No Start offset!
pause
exit /b

:NO_LBA_length
echo Error: No LBA length!
pause
exit /b

:NO_Total_CHS_size
echo Error: No Total CHS size!
pause
exit /b

:NO_Device_number
echo Error: No Device number!
pause
exit /b

:NO_Disk_number
echo Fatal: No Disk number!
pause
exit /b

:NO_Extent_length
echo Fatal: No Extent length!
pause
exit /b

:TOO_MANY_DRIVES
echo Error: Too many drives!
pause
exit /b

:IMDISK_FAILED
echo Error: imdisk failed!
pause
exit /b

:NO_IMDISK
echo Error: No imdisk.exe!
pause
goto :END

:NO_DEVIOCTL
echo Error: No devioctl.exe!
pause
goto :END

:END
popd
goto :eof


上面的是新版,请使用。






下面是以前的旧版,请不要用了。

mount_NTFS.bat 批处理修正增强版,检查更严格了,运行速度会慢一些,但更安全一些。

如果不是以 Administrator 的身份运行,则 devioctl.exe 会显示 “拒绝操作” 信息。出现这个失败信息时,用鼠标右键点击 mount_NTFS.bat,选择 “以管理员身份运行” 即可。


@echo off
setlocal EnableDelayedExpansion
pushd "%CD%"
cd /d "%~dp0"
if not exist imdisk.exe for %%I in (imdisk.exe) do if "%%~$PATH:I"=="" if exist imdiskinst.exe imdiskinst.exe
if not exist imdisk.exe for %%I in (imdisk.exe) do if "%%~$PATH:I"=="" goto :NO_IMDISK
if not exist devioctl.exe for %%I in (devioctl.exe) do if "%%~$PATH:I"=="" goto :NO_DEVIOCTL
REM 检查分区位置、长度等几何参数信息,避免挂载错误的物理驱动器
set L=6
echo devioctl.exe geometry %~d0
for /F "skip=6 tokens=1,2,3,4,*" %%A in ('devioctl.exe geometry %~d0') do (
set /a L+=1
if !L! GTR 20 goto :END
set /p =. < NUL
call :do_lines%%A %%B %%C %%D
)
echo devioctl.exe needs to run as Administrator!
echo Right click the batch file and select "Run as administrator".
pause
goto :END

:do_lines
if "%1"=="" exit /b
if %L%==7 (
if not "%1 %2 %3"=="Total CHS size:" goto :NO_Total_CHS_size

REM 下面这句中的数值是 devioctl 探测的 U 盘总扇区数 * 512,请修改好。
if not "%4"=="124218178560" goto :Wrong_Total_CHS_size

exit /b
)
if %L%==8 (
if not "%1 %2 %3"=="LBA length :" goto :NO_LBA_length

REM 下面这句中的数值等于 FAT32 分区的总扇区数 * 512,请修改好。
if not "%4"=="67786129920" goto :Wrong_LBA_length

exit /b
)
if %L%==9 exit /b
if %L%==10 (
if not "%1 %2 %3"=="Start offset :" goto :NO_Start_offset

REM 下面这句中的数值等于 FAT32 分区的起始扇区号 * 512,请修改好。
if not "%4"=="32256" goto :Wrong_Start_offset

exit /b
)
if %L% GTR 10 if %L% LSS 20 exit /b
if %L%==20 (
if not "%1 %2 %3"=="Device number :" goto :NO_Device_number
if %4 GTR 9 goto :TOO_MANY_DRIVES

REM Use VER to Reset ERRORLEVEL to 0
ver > NUL

echo.
echo imdisk.exe -a -f \\.\PhysicalDrive%4 -b 132395008b -s 110219264b -m #:

REM 下面这句是关键,请修改好以后,去掉前面的 REM,就真正起作用了!危险!
REM imdisk.exe -a -f \\.\PhysicalDrive%4 -b 132395008b -s 110219264b -m #:

if !ERRORLEVEL! NEQ 0 goto :IMDISK_FAILED

ping -n 5 localhost > nul

exit /b
)
exit /b

:Wrong_Total_CHS_size
echo Error: Wrong Total CHS size! Cannot run on drive %~d0!
pause
exit /b

:Wrong_Start_offset
echo Error: Wrong Start offset! Cannot run on drive %~d0!
pause
exit /b

:Wrong_LBA_length
echo Error: Wrong LBA length! Cannot run on drive %~d0!
pause
exit /b

:NO_Start_offset
echo Error: No Start offset!
pause
exit /b

:NO_LBA_length
echo Error: No LBA length!
pause
exit /b

:NO_Total_CHS_size
echo Error: No Total CHS size!
pause
exit /b

:NO_Device_number
echo Error: No Device number!
pause
exit /b

:TOO_MANY_DRIVES
echo Error: Too many drives!
pause
exit /b

:IMDISK_FAILED
echo Error: imdisk failed!
pause
exit /b

:NO_IMDISK
echo Error: No imdisk.exe!
pause
goto :END

:NO_DEVIOCTL
echo Error: No devioctl.exe!
pause
goto :END

:END
popd
goto :eof

上面是以前的旧版,只用于备忘,请不要使用了。请使用本帖开头的新版。

512154224 发表于 2018-2-4 14:41:03

看不懂,支持下!

不点 发表于 2018-2-9 07:16:58

本帖最后由 不点 于 2018-2-9 16:45 编辑

batch 文件需要以 administrator 账户运行。因此,普通管理员账户需提升权限至 administrator 账户。搜到以下解决方案:

https://stackoverflow.com/questions/41481655/cant-run-as-admin
https://stackoverflow.com/questions/7044985/how-can-i-auto-elevate-my-batch-file-so-that-it-requests-from-uac-administrator/12264592#

上述方案虽然可行,但不能在精简的 PE 下运行。PE 缺少很多命令,比如,mshta,runas,以及运行 vbs 脚本的命令。

最后只有一招是通用的(兼容 PE 环境):鼠标右键单击 .bat 文件,在弹出菜单上选择 “以管理员身份运行” 即可。

510819776 发表于 2018-2-9 22:20:29

做一份备忘录
采用imdisk的注册表方式开机自动加载所需的镜像文件
Windows Registry Editor Version 5.00


"LoadDevices"=dword:00000002
"Size0"=hex(b):00,00,00,08,00,00,00,00
"ImageOffset0"=hex(b):00,10,00,00,00,00,00,00
"FileName0"="\\DosDevices\\D:\\1.vhd"
"DriveLetter0"="O"
"DriveLetter1"="R"
"FileName1"="\\??\\physicaldrive0"
"Flags0"=dword:00000000
"ImageOffset1"=hex(b):00,00,00,c0,07,00,00,00
"Size1"=hex(b):00,00,00,c0,00,00,00,00

一个是用1.vhd开机挂载,另一个是把扇区序列拿来开机挂载了
其中flagsx参数如果修改为0x200 会把镜像加载到内存
已经win7 64位测试成功了

不点 发表于 2018-2-10 09:54:02

我们遇到的困难之一,是不知道 Windows 物理驱动器与 BIOS 驱动器号码的对应关系。
前面我们已经通过 devioctl 知道了某个已知盘符所在的物理驱动器号码。
但我们真正想知道的,却是 Windows 物理驱动器号码与 BIOS 驱动器号码的对应关系。
一旦知道了这个对应关系,我们就可以用 imdisk 来驱动 grub4dos 扇区映射的虚拟盘了。
这是因为,imdisk 是 Windows 程序,只能识别 Windows 驱动器号码,不能识别 BIOS 驱动器号码。
如果找到对应关系,就等于打通了 imdisk 和 grub4dos 的脉络,不再有障碍。

以下这篇文章似乎正是需要的。

Editing the MountedDevices Registry Key
http://diddy.boot-land.net/firadisk/files/mounteddevices.htm

通过磁盘签名,就能够唯一地找到磁盘。

驱动程序在进入保护模式之前,在实模式阶段,首先保存各个 BIOS 磁盘的签名。
在进入 Windows 的保护模式之后,就检查 Windows 的各个物理磁盘的签名。
这样就建立了 BIOS 磁盘和 Windows 磁盘的对应关系。

我猜 winvblock 可能就是这么做的。

要是有人能够整合 firadisk、winvblock、imdisk,那就太好了。

gnuxwy 发表于 2018-2-10 17:31:51

嗯,大师辛苦了。。。很有趣的解决问题办法。。。可以拓展启动思路。

不点 发表于 2018-2-11 07:55:18

本帖最后由 不点 于 2018-2-11 08:29 编辑

找到 WinVblock 的处理方法了(见下面代码)。果然有磁盘签名的处理!【更正】遗憾,不是检查磁盘签名,而只是检查 mbr 尾部的 55 AA 标志。

如果扇区数据所在介质是软盘,则拒绝处理(这是没问题的,因为现在没有软盘了,而 U 盘在 Windows 下会被识别为硬盘)。
如果扇区数据所在介质是硬盘,则先检查硬盘上的磁盘签名,如果匹配(通常都能匹配),则成功;如果不匹配,继续检查扇区序列尾部是否 VHD 格式,如果是的,也成功。(我认为 VHD 格式就不用检查了,但可以增加检查虚拟盘第一扇区的内容,见接下来的详述)
如果扇区数据所在介质是光盘,则检查光盘上的 "CD001" 标识符,如果匹配,则成功。

我觉得可以改进一下,无论数据介质是在硬盘还是光盘上,再增加一个检查,即,检查该盘相应于扇区序列的第一扇区内容是否正好是虚拟盘的第一扇区内容,如果不是,则失败。这要求驱动程序在实模式已经保存好虚拟盘的第一扇区。如果虚拟盘是虚拟光盘,则保存含有 "CD001" 的那个扇区(只保存512字节就行)。如果觉得 512 字节太多,可以考虑只保存扇区的 “校验和”(4字节)。

【补充】好的,既然知道了 winvblock 并未使用磁盘签名技术,我们就可以改进了,即,使用磁盘签名,或者干脆使用整个 mbr 扇区,即可唯一确定数据介质所在的物理盘。在实模式阶段,保存所有物理盘的第一扇区数据,同时也保存所有虚拟盘的第一扇区数据。这样,在保护模式就可以对比确认了。

/**
* Check if a disk might be the matching backing disk for
* a GRUB4DOS sector-mapped disk.
*
* @v file            HANDLE to an open disk.
* @v filedisk          Points to the filedisk to match against.
*/
static BOOLEAN STDCALL WvFilediskG4dCheckDiskMatch_(
    IN HANDLE file,
    IN WV_SP_FILEDISK_T filedisk
) {
    BOOLEAN ok = FALSE;

    switch (filedisk->disk->Media) {
      case WvlDiskMediaTypeFloppy:
          break;

      case WvlDiskMediaTypeHard:
          ok = WvFilediskG4dCheckDiskMatchMbrSig_(file, filedisk);
          if (ok)
            break;
          ok = WvFilediskG4dCheckDiskMatchVHD_(file, filedisk);
          break;
      case WvlDiskMediaTypeOptical:
          ok = WvFilediskG4dCheckDiskMatchIsoSig_(file, filedisk);
          break;
      }
    return ok;
}

chenall 发表于 2018-2-11 09:19:43

我觉得把firadisk、winvblock的一些特性整合进imdisk是最理想的,因为imdisk已经实现了所有需要的功能, 整合其实主要是作一些映射处理.

不懂驱动开发,帮不上忙.

不点 发表于 2018-2-11 09:26:16

chenall 发表于 2018-2-11 09:19
我觉得把firadisk、winvblock的一些特性整合进imdisk是最理想的,因为imdisk已经实现了所有需要的功能, 整合 ...

chenall 你必须帮忙。你只要有编译环境即可,不需要懂得很多驱动开发知识。主要的代码,在这三个软件当中可能都有了,所需要的仅仅是局部改进而已。

不点 发表于 2018-2-11 11:31:33

本帖最后由 不点 于 2018-2-11 11:42 编辑

有个问题,不知在 Windows 保护模式下,能否暂时回到实模式,执行 int13 读盘,然后再返回保护模式。

如果可行的话,那就好办了。

Win98 是可以的,估计 NT 以后都不行了。

如果不行的话,还真得从 grub4dos 身上“打主意” 了。用一个内存盘,类似于 firadisk 的 (99) 或 winvblock 的 (55),用来存放各种信息。内存盘可以弄大一点,比如 32K,这样可以存放很多信息。

imdisk 只需读取这个内存盘信息,即可知道该怎么建立虚拟盘了。

赶紧行动!最好由 chenall 和 yaya 设计这个内存盘的格式,尽量兼容 firadisk 和 winvblock(我从未接触过,对它们都不了解)。还有谁能帮忙在 Windows 下编译软件的,请主动出手(由于 imdisk 需要进行相应的调整,因此需要编译)。我目前只能提供思路,尽自己所能吧。

【补充】不可能同时兼容 (99) 和 (55)。只需兼容 firadisk 的 (99) 即可。就是说,我们也采用 (99) 这个盘号,格式尽量与 firadisk 完全兼容,只不过我们的内存盘要大得多,能放下几十个扇区数据。

为什么要兼容 firadisk 而不是兼容 winvblock 呢?因为 winvblock 不需要兼容。winvblock 功能强,能支持纯扇区映射,大家通常都不需要 (55) 里面的信息。而 firadisk 在这方面就做得不太好了,它需要 (99) 里面的信息,否则,它根本就无法成功。

不点 发表于 2018-2-11 18:09:37

又想到一个方面的问题,提出来,供大家讨论、研究。

我们先前的开源虚拟盘驱动大致有三个(仅就我们感兴趣的而言)。其中 firadisk 和 winvblock 都是为 bios 启动程序在实模式阶段所建立的虚拟盘提供驱动的。

而 imdisk 则不为这样的目的服务。imdisk 能够接受命令行参数,直接提供磁盘虚拟功能。

imdisk 不依赖于 grub4dos 或 memdisk 在内存中建立的虚拟盘数据结构,而直接进行 “一般化” 的操作,具有 “一般性” (或 “通用”)的那种方便(也可以说是一种 “美感”)。

因此我想,也许我们可以换个思路,利用 imdisk 的这种美感,或者向 imdisk 的这种美感 “靠拢”。

好了,就不 “云里雾里”、“海阔天空” 了,直接来 “干货”:

我们有时候需要在没有 grub4dos 的情况下使用虚拟盘功能。比如,可见 FAT + 隐藏 NTFS 的 U 盘,插在电脑上(可能是别人的电脑),而且电脑不是从 U 盘启动的。此时,我们仅仅希望 imdisk 能够自动挂上隐藏了的 NTFS 卷。注意此时没有 grub4dos,内存中也就不可能存在 grub4dos 的虚拟盘数据结构。此时,firadisk 和 winvblock 都无法起作用。

这一情况就暴露出 firadisk 和 winvblock 的弱点了——它们专用于 grub4dos(或 memdisk),不能脱离 grub4dos(或 memdisk)而成为应用更加广泛的一般化的虚拟磁盘工具。


假如一个磁盘虚拟工具(比如 imdisk)能够识别出任意一个卷(例如 U 盘)上的特定文件(比如叫做 drivemap.tab,含义是 “驱动器映射记录”),该文件含有 “虚拟盘和扇区序列相关信息”。imdisk 一旦检测到这一信息,就按照信息的指示,自动挂上相应的虚拟盘。除了让 imdisk 能够识别卷(即某分区)上的控制文件以外,还可以让 imdisk 在内存中寻找虚拟盘的指示信息,一旦找到,就自动挂上相应的虚拟盘。

就是说,imdisk 不仅可以识别内存中的虚拟盘指示信息,也可以识别卷上含有虚拟盘指示信息的特定文件。如此一来,imdisk 的用法就自由了,应用范围也就扩大了。就是说,无论有没有 grub4dos 的存在,imdisk 都可以自动挂上虚拟盘。另一方面,grub4dos 也可以把内存中的虚拟盘信息拷贝到磁盘文件(drivemap.tab)里面,这样,imdisk 就能够从磁盘上发现 grub4dos 所提供的虚拟盘信息了。

总的来说,需要着力改造的是 imdisk,而不是 grub4dos。改造 imdisk 需要做大量工作,而 grub4dos 可能只需少量改造,就是前述 “在内存盘 (99) 中增加一些扇区信息” 罢了 。


freesoft00 发表于 2018-2-11 21:50:16

不点 发表于 2018-2-11 18:09
又想到一个方面的问题,提出来,供大家讨论、研究。

我们先前的开源虚拟盘驱动大致有三个(仅就我们感兴 ...

可以考虑把想法和imdisk作者说说,看他是否可以把需要的功能添加上去。

sp_star 发表于 2018-2-11 22:09:24

不点 发表于 2018-2-11 18:09
又想到一个方面的问题,提出来,供大家讨论、研究。

我们先前的开源虚拟盘驱动大致有三个(仅就我们感兴 ...

瞎猜的......
================================
看firadisk的实现,好像就是在0~64K这一段内存中直接查找grub4dos映射的磁盘,主要就是需要访问物理内存的权限,这要在驱动中完成,驱动又需要签名。
如果imdisk愿意实现,应该很简单,只要找到grub4dos的ramdisk的位置信息就可以映射了。
如果imdisk没有实现,需要一个第三方程序找到grub4dos的ramdisk的位置信息,调用imdisk来映射。这个第三方程序可能要能访问物理内存。
页: [1] 2
查看完整版本: imdisk支持sector map扇区映射