无忧启动论坛

 找回密码
 注册
搜索
系统gho:最纯净好用系统下载站广告联系 微信:wuyouceo QQ:184822951
查看: 14537|回复: 51

imdisk支持sector map扇区映射

    [复制链接]
发表于 2018-1-25 12:06:46 | 显示全部楼层 |阅读模式
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:

  1. 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  /? 命令,可以获得如下的帮助信息:


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

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

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

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

  14. -e      Edit an existing virtual disk.

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

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

  24. -t type
  25.         Select the backingstore for the virtual disk.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  105. -o option
  106.         Set or reset options.

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

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

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

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

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

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

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

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

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

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

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

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

  151. -m mountpoint
  152.         Specifies a drive letter or mount point for the new virtual disk, the
  153.         virtual disk to query or the virtual disk to remove. When creating a
  154.         new virtual disk you can specify #: as mountpoint in which case the
  155.         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 分区?最好给出详细步骤。

点评

我一直用PECMD操作的。IMDISK命令行应该差不多。 好像还有个更简单的方式。MOUN-udm -udmid:pt1,具体格式忘记了。  详情 回复 发表于 2018-1-25 15:59

评分

参与人数 1无忧币 +5 收起 理由
ge + 5 不排除是微软捣的鬼!

查看全部评分

回复

使用道具 举报

发表于 2018-1-25 13:11:02 | 显示全部楼层
这个一直都支持。。。您才知道啊,用了几年了。

点评

哦,我跟不上形势了。能分享使用经验、心得体会吗?能给出优缺点的评价吗? 我想制作一个 U 盘,含两个分区:开头是 FAT32 分区,紧接着是 NTFS 分区。 NTFS 分区需要从分区表中去除掉,只留下 FAT32 分区,这  详情 回复 发表于 2018-1-25 15:37
回复

使用道具 举报

发表于 2018-1-25 15:59:10 | 显示全部楼层
本帖最后由 红毛樱木 于 2018-1-25 16:03 编辑
不点 发表于 2018-1-25 15:37
哦,我跟不上形势了。能分享使用经验、心得体会吗?能给出优缺点的评价吗?

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


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


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

点评

我用笨办法搞定了。步骤如下: 在 U 盘开头建立 Fat32 分区,提高启动成功率(我实际上是使用我自己开发的 multimbr,本身就是 FAT32 格式)。剩余空间创建 NTFS 分区,用来存放大文件。 然后,用 bootice 查  详情 回复 发表于 2018-1-27 09:28
那我以后有机会就试试吧。看看这个 imdisk 会不会比 winvblock 更好用。  详情 回复 发表于 2018-1-25 17:24
回复

使用道具 举报

 楼主| 发表于 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  -b  12345678b  -s  87654321b  -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
回复

使用道具 举报

发表于 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/

重要部分摘录:


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

  2.     C:\bar\foo.txt
  3.     \\.\C:\bar\foo.txt
  4.     \\?\C:\bar\foo.txt
  5.     \??\C:\bar\foo.txt
  6.     \\?\Harddisk0Partition2\bar\foo.txt
  7.     \\?\HarddiskVolume4\bar\foo.txt
  8.     \\?\Volume{0FAF43C1-2AED-4824-B2D4-2339C14E93A}\bar\foo.txt
  9.     \\?\Volume{d1655348-000-000-000-f0150000000}\bar\foo.txt
  10.     \\?\GLOBALROOT\Device\Harddisk0\Partition2\bar\foo.txt
  11.     \\.\GLOBALROOT\Device\HarddiskVolume4\bar\foo.txt
  12.     \\LOCALHOST\C$\bar\foo.txt
  13.     \\?\UNC\C$\bar\foo.txt
  14.     \\?\GLOBALROOT\Device\Mup\C$\bar\foo.txt

复制代码


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

  1. type \\?\GLOBALROOT\Device\Harddisk1\Partition1\imdisk0.bat
复制代码


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

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


回复

使用道具 举报

发表于 2018-1-28 09:38:29 | 显示全部楼层
vbs脚本
  1. '获取 磁盘以及其分区列表,包括接口信息。
  2. Set wmi=GetObject("winmgmts:\\.\root\cimv2")
  3. Set disk_s=wmi.instancesof("win32_LogicalDiskToPartition")
  4. Set d_s=wmi.instancesof("win32_diskdrive")
  5. sn=""
  6. d0=Split("x,y",",",-1,1)
  7. For Each s In disk_s
  8.         dx=d0(1)
  9. '记录 分区对应的 硬盘index
  10.         d0=split(Split(Split(s.antecedent,"=",-1,1)(1),",",-1,1)(0),"#",-1,1)

  11.         d1=Split(s.Dependent,"=",-1,1)
  12.         If (dx = d0(1) ) then
  13.                 sn=sn&(d1(1))
  14.         Else
  15.                 For Each d In d_s
  16.                    If (""&d.index = ""&d0(1)) Then id=chr(10)&d.name&"  "&d.interfacetype
  17.                 Next
  18.                 sn=sn+id&" "&(d1(1))
  19.         End If

  20. Next
  21. wscript.echo sn
复制代码


无标题.png
无标题2.png

parts.7z

516 Bytes, 下载次数: 12, 下载积分: 无忧币 -2

利用 vbs 调用 wmic 获取硬盘 、接口、分区盘符

点评

谢谢分享好东西!  详情 回复 发表于 2018-2-12 23:44
在 win PE 下能运行吗?我需要在多种环境都能起作用的方法。  详情 回复 发表于 2018-1-28 10:43
回复

使用道具 举报

 楼主| 发表于 2018-1-28 10:43:19 | 显示全部楼层

在 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:


  1. #include <Winioctl.h>
  2. VOID LogicalToPhysical(TCHAR *szDrive)
  3. {
  4.         CString szPhysical;
  5.         HANDLE h = CreateFile(szDrive, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
  6.         if(INVALID_HANDLE_VALUE != h)
  7.         {
  8.                 STORAGE_DEVICE_NUMBER sd;
  9.                 DWORD dwRet;
  10.                 if(DeviceIoControl(h, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &sd, sizeof(STORAGE_DEVICE_NUMBER), &dwRet, NULL))
  11.                 {
  12.                         szPhysical.Format(_T("\\\\.\\PhysicalDrive%d"), sd.DeviceNumber);
  13.                 }
  14.                 CloseHandle(h);
  15.         }
  16. }

  17. //Usage:
  18. 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



点评

嗯,如果winpe 没有 vbs 和 wmic vbs 就不好用了。  详情 回复 发表于 2018-1-28 11:10
回复

使用道具 举报

发表于 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

  1.     Option Explicit
  2.     Private Enum IOCOMMANDS
  3.         IOCTL_STORAGE_GET_DEVICE_NUMBER = &H2D1080
  4.     End Enum

  5.     Private Declare Function DeviceIoControl Lib "kernel32" _
  6.       (ByVal hDevice As Long, _
  7.        ByVal dwIoControlCode As Long, _
  8.        lpInBuffer As Any, _
  9.        ByVal nInBufferSize As Long, _
  10.        lpOutBuffer As Any, _
  11.        ByVal nOutBufferSize As Long, _
  12.        lpBytesReturned As Long, _
  13.        lpOverlapped As Any) As Long

  14.     Private Declare Function CreateFile Lib "kernel32" _
  15.        Alias "CreateFileA" _
  16.       (ByVal lpFileName As String, _
  17.        ByVal dwDesiredAccess As Long, _
  18.        ByVal dwShareMode As Long, _
  19.        lpSecurityAttributes As Any, _
  20.        ByVal dwCreationDisposition As Long, _
  21.        ByVal dwFlagsAndAttributes As Long, _
  22.        ByVal hTemplateFile As Long) As Long

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

  25.     Private Const INVALID_HANDLE_VALUE As Long = -1&
  26.     Private Const GENERIC_READ As Long = &H80000000
  27.     Private Const FILE_SHARE_READ As Long = &H1
  28.     Private Const FILE_SHARE_WRITE As Long = &H2
  29.     Private Const OPEN_EXISTING As Long = 3

  30.     Type ddevicetype
  31.         DEVICE_TYPE As Long
  32.         deviceno As Long
  33.         partionno As Long
  34.     End Type

  35.     Public Function DeviceCheckMedia(sDrive As String) As ddevicetype

  36.         Dim hDevice As Long
  37.         Dim bytesReturned As Long
  38.         Dim success As Long
  39.         Dim sdn As ddevicetype

  40.     'Open a handle to drive
  41.         hDevice = CreateFile("\\." & sDrive, _
  42.                             GENERIC_READ, _
  43.                             FILE_SHARE_READ Or FILE_SHARE_WRITE, _
  44.                             ByVal 0&, _
  45.                             OPEN_EXISTING, _
  46.                             0&, 0&)
  47.     'Issue GET_DEVICE_NUMBER command to DeviceIoControl
  48.         If hDevice <> INVALID_HANDLE_VALUE Then
  49.             success = DeviceIoControl(hDevice, _
  50.                                     IOCTL_STORAGE_GET_DEVICE_NUMBER, _
  51.                                     0&, _
  52.                                     0&, _
  53.                                     sdn, _
  54.                                     Len(sdn), _
  55.                                     bytesReturned, _
  56.                                     ByVal 0&)
  57.         End If
  58.     'Close Handle to drive
  59.         Call CloseHandle(hDevice)
  60.     'Return sdn contianing drive type, drive #,  and partition #
  61.         DeviceCheckMedia = sdn
  62.     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

  1.     devicecheckmedia (C:)
复制代码


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


  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:


  1.     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 就够用了:


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


  5. c:: 操作成功完成。

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


  10. f:: 操作成功完成。

  11. D:\>
复制代码


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

点评

大师威武  详情 回复 发表于 2018-1-28 14:55
回复

使用道具 举报

发表于 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: ...



大师威武
回复

使用道具 举报

 楼主| 发表于 2018-1-28 18:41:56 | 显示全部楼层
本帖最后由 不点 于 2018-2-9 16:52 编辑

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

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

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

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

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


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

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

  16. if %ERRORLEVEL% NEQ 0 goto :IMDISK_FAILED
  17. goto :END
  18. )

  19. :NO_DEVIOCTL
  20. echo Error: No devioctl.exe!
  21. pause
  22. goto :END

  23. :NO_DISK
  24. echo Error: No disk!
  25. pause
  26. goto :END

  27. :NO_NUMBER
  28. echo Error: No number!
  29. pause
  30. goto :END

  31. :NO_COLON
  32. echo Error: No colon!
  33. pause
  34. goto :END

  35. :E_NOT_EMPTY
  36. echo Error: E not empty!
  37. pause
  38. goto :END

  39. :TOO_MANY_DRIVES
  40. echo Error: Too many drives!
  41. pause
  42. goto :END

  43. :NO_IMDISK
  44. echo Error: No imdisk.exe!
  45. pause
  46. goto :END

  47. :IMDISK_FAILED
  48. echo Error: imdisk failed!
  49. pause
  50. goto :END

  51. :END
  52. popd
复制代码

评分

参与人数 1无忧币 +5 收起 理由
freesoft00 + 5

查看全部评分

回复

使用道具 举报

 楼主| 发表于 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 命令不存在

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


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

  26. ::::::::::::::::::::::::模块开始::::::::::::::::::::::::
  27. :IF_EXIST       BY chenall QQ:366840202     2009-09-29
  28. SETLOCAL&PATH %PATH%;%~dp0;%cd%
  29. if "%~$PATH:1"=="" exit /b 1
  30. echo %~$PATH:1
  31. exit /b 0       http://www.chenall.net
  32. :::::::::::::::::::::::模块结束:::::::::::::::::::::::::
复制代码


回复

使用道具 举报

 楼主| 发表于 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 可以查找的位置。


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





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

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

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

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

  32. exit /b
  33. )
  34. if %L%==9 exit /b
  35. if %L%==10 (
  36. if not "%1 %2 %3"=="Start offset :" goto :NO_Start_offset

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

  39. exit /b
  40. )
  41. if %L% GTR 10 if %L% LSS 20 exit /b
  42. if %L%==20 (
  43. if not "%1 %2 %3"=="Device number :" goto :NO_Device_number
  44. if %4 GTR 9 goto :TOO_MANY_DRIVES

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

  49. if not %L%==21 exit /b

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

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

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

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

  87. :done_phy

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

  96. if %BB% GEQ %TOTAL% goto :mount_fail

  97. set /a S=%TOTAL%-%B%
  98. set /a SS=%TOTAL%-%BB%
  99. echo %S%

  100. :try_mount

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

  105. REM Use VER to Reset ERRORLEVEL to 0
  106. ver > NUL

  107. set CREATED=NODRIVE:

  108. 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 (
  109. rem set /a L+=1
  110. rem if !L! GTR 3 goto :done_phy
  111. set /p =. < NUL
  112. echo %%A %%B %%C %%D %%E
  113. if "%%A %%B"=="Created device" set CREATED=%%D
  114. rem call :do_lines_phy  %%A %%B %%C %%D
  115. rem if !L! GTR 3 goto :done_phy
  116. )

  117. REM if !ERRORLEVEL! NEQ 0 goto :IMDISK_FAILED

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

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

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

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

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

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

  135. exit /b

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

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

  141. exit /b


  142. :do_lines_phy
  143. if "%1"=="" exit /b
  144. if %L%==1 (
  145. if not "%1 %2 %3"=="Disk number :" goto :NO_Disk_number
  146. if not "%4"=="%PHYDRV%" goto :Wrong_Disk_number
  147. exit /b
  148. )
  149. if %L%==2 (
  150. if not "%1 %2 %3"=="Starting offset: 0" goto :Wrong_Starting_offset
  151. exit /b
  152. )

  153. if not %L%==3 exit /b

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

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

  159. exit /b


  160. :Wrong_Disk_number
  161. echo Fatal: Wrong Disk number( %4 != %PHYDRV% )! Exit!
  162. pause
  163. exit /b

  164. :Wrong_Starting_offset
  165. echo Fatal: Wrong Starting offset (should be 0)! Exit!
  166. pause
  167. exit /b

  168. :NO_Start_offset
  169. echo Error: No Start offset!
  170. pause
  171. exit /b

  172. :NO_LBA_length
  173. echo Error: No LBA length!
  174. pause
  175. exit /b

  176. :NO_Total_CHS_size
  177. echo Error: No Total CHS size!
  178. pause
  179. exit /b

  180. :NO_Device_number
  181. echo Error: No Device number!
  182. pause
  183. exit /b

  184. :NO_Disk_number
  185. echo Fatal: No Disk number!
  186. pause
  187. exit /b

  188. :NO_Extent_length
  189. echo Fatal: No Extent length!
  190. pause
  191. exit /b

  192. :TOO_MANY_DRIVES
  193. echo Error: Too many drives!
  194. pause
  195. exit /b

  196. :IMDISK_FAILED
  197. echo Error: imdisk failed!
  198. pause
  199. exit /b

  200. :NO_IMDISK
  201. echo Error: No imdisk.exe!
  202. pause
  203. goto :END

  204. :NO_DEVIOCTL
  205. echo Error: No devioctl.exe!
  206. pause
  207. goto :END

  208. :END
  209. popd
  210. goto :eof
复制代码


上面的是新版,请使用。







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

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

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


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

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

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

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

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

  33. exit /b
  34. )
  35. if %L%==9 exit /b
  36. if %L%==10 (
  37. if not "%1 %2 %3"=="Start offset :" goto :NO_Start_offset

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

  40. exit /b
  41. )
  42. if %L% GTR 10 if %L% LSS 20 exit /b
  43. if %L%==20 (
  44. if not "%1 %2 %3"=="Device number :" goto :NO_Device_number
  45. if %4 GTR 9 goto :TOO_MANY_DRIVES

  46. REM Use VER to Reset ERRORLEVEL to 0
  47. ver > NUL

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

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

  52. if !ERRORLEVEL! NEQ 0 goto :IMDISK_FAILED

  53. ping -n 5 localhost > nul

  54. exit /b
  55. )
  56. exit /b

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

  61. :Wrong_Start_offset
  62. echo Error: Wrong Start offset! Cannot run on drive %~d0!
  63. pause
  64. exit /b

  65. :Wrong_LBA_length
  66. echo Error: Wrong LBA length! Cannot run on drive %~d0!
  67. pause
  68. exit /b

  69. :NO_Start_offset
  70. echo Error: No Start offset!
  71. pause
  72. exit /b

  73. :NO_LBA_length
  74. echo Error: No LBA length!
  75. pause
  76. exit /b

  77. :NO_Total_CHS_size
  78. echo Error: No Total CHS size!
  79. pause
  80. exit /b

  81. :NO_Device_number
  82. echo Error: No Device number!
  83. pause
  84. exit /b

  85. :TOO_MANY_DRIVES
  86. echo Error: Too many drives!
  87. pause
  88. exit /b

  89. :IMDISK_FAILED
  90. echo Error: imdisk failed!
  91. pause
  92. exit /b

  93. :NO_IMDISK
  94. echo Error: No imdisk.exe!
  95. pause
  96. goto :END

  97. :NO_DEVIOCTL
  98. echo Error: No devioctl.exe!
  99. pause
  100. goto :END

  101. :END
  102. popd
  103. goto :eof
复制代码

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

使用道具 举报

发表于 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 文件,在弹出菜单上选择 “以管理员身份运行” 即可。
回复

使用道具 举报

发表于 2018-2-9 22:20:29 | 显示全部楼层
做一份备忘录
采用imdisk的注册表方式开机自动加载所需的镜像文件
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\ImDisk\Parameters]
"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位测试成功了

评分

参与人数 1无忧币 +5 收起 理由
freesoft00 + 5

查看全部评分

回复

使用道具 举报

 楼主| 发表于 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,那就太好了。

回复

使用道具 举报

发表于 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 扇区,即可唯一确定数据介质所在的物理盘。在实模式阶段,保存所有物理盘的第一扇区数据,同时也保存所有虚拟盘的第一扇区数据。这样,在保护模式就可以对比确认了。


  1. /**
  2. * Check if a disk might be the matching backing disk for
  3. * a GRUB4DOS sector-mapped disk.
  4. *
  5. * @v file              HANDLE to an open disk.
  6. * @v filedisk          Points to the filedisk to match against.
  7. */
  8. static BOOLEAN STDCALL WvFilediskG4dCheckDiskMatch_(
  9.     IN HANDLE file,
  10.     IN WV_SP_FILEDISK_T filedisk
  11.   ) {
  12.     BOOLEAN ok = FALSE;

  13.     switch (filedisk->disk->Media) {
  14.         case WvlDiskMediaTypeFloppy:
  15.           break;

  16.         case WvlDiskMediaTypeHard:
  17.           ok = WvFilediskG4dCheckDiskMatchMbrSig_(file, filedisk);
  18.           if (ok)
  19.             break;
  20.           ok = WvFilediskG4dCheckDiskMatchVHD_(file, filedisk);
  21.           break;
  22.         case WvlDiskMediaTypeOptical:
  23.           ok = WvFilediskG4dCheckDiskMatchIsoSig_(file, filedisk);
  24.           break;
  25.       }
  26.     return ok;
  27.   }
复制代码


回复

使用道具 举报

发表于 2018-2-11 09:19:43 | 显示全部楼层
我觉得把firadisk、winvblock的一些特性整合进imdisk是最理想的,因为imdisk已经实现了所有需要的功能, 整合其实主要是作一些映射处理.

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

点评

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

使用道具 举报

 楼主| 发表于 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) 中增加一些扇区信息” 罢了 。


点评

瞎猜的...... ================================ 看firadisk的实现,好像就是在0~64K这一段内存中直接查找grub4dos映射的磁盘,主要就是需要访问物理内存的权限,这要在驱动中完成,驱动又需要签名。 如果imdisk  详情 回复 发表于 2018-2-11 22:09
可以考虑把想法和imdisk作者说说,看他是否可以把需要的功能添加上去。  详情 回复 发表于 2018-2-11 21:50
回复

使用道具 举报

发表于 2018-2-11 21:50:16 | 显示全部楼层
不点 发表于 2018-2-11 18:09
又想到一个方面的问题,提出来,供大家讨论、研究。

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

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

使用道具 举报

发表于 2018-2-11 22:09:24 | 显示全部楼层
不点 发表于 2018-2-11 18:09
又想到一个方面的问题,提出来,供大家讨论、研究。

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

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

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|捐助支持|无忧启动 ( 闽ICP备05002490号-1 )

闽公网安备 35020302032614号

GMT+8, 2024-3-29 04:01

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表