Win9x系とNT系で共用出来るストレージドライバの製作

Win9x系とNT系はドライバモデルが異なっており、基本的には共用出来ません。 しかし、特定の様式に従うドライバに限り、共用出来るような仕組みが用意されています。 このような共用が出来るドライバとしてWDMが有名ですが、実はWDM登場前にも限定的にドライバを共有可能な仕組みが用意されています。

本稿ではWin9xに搭載されているNT互換機能を用いてWin9x系とNT系で共用出来るストレージドライバを製作するための情報を掲載します。このドライバはWDM登場前のWindows 95でも使用出来ます。

実装の詳細については、Neko Project 21/Wのソース内のnp2tool\npstorが参考になります。

ドライバの作成方法

まず、ドライバはWindowsNTのSCSIミニポートドライバ(SCSIPORT)に準拠した形で作る必要があります。 こうして作成されたドライバはSYS形式のWinNT系用のものになりますが、ある条件を満たしていればWin9xでも共用出来るものになります。

条件だけを先に書くと以下の通りです。

  1. WindowsNT互換のSCSIミニポートドライバであること
  2. SCSIPORT.PDRで定義されている関数だけを使用すること
  3. 拡張子をMPDにすること(必須ではないかもしれません)

1. はWin9x系のVxD形式ではなくNT系のドライバとして作成しなければならないという条件です。 原則アセンブラのVxDと比べると、NT系のドライバとして作成する方が一般に難易度は低いという観点ではあまり困らないと思います。

2. はWinNT系の関数を自由に使うことはできず、SCSIPORT.PDR(WinNTのSCSIPORT.SYS互換)で定義されている関数のみ使用可能という条件です。 具体的には以下の関数のみ使用出来ます。

上記以外の関数をインポートしている場合、WinNTでは動きますがWin9xでは動きません。 作成したドライバが実際にどの関数をインポートしているかは、DLLの関数エクスポートを覗く系のソフトで簡単にチェック出来ます。

3. はWinNT系ドライバの拡張子は通常SYSですが、これをMPDにしなければならないというものです。 拡張子が違うだけで中身は同じですから、単に拡張子を変えるだけでOKです。

ドライバのインストール方法

Win9xとWin2000は共通のINFファイルでインストール出来ます。

以下はNeko Project II SCSI Host Controllerという名前のSCSIミニポートドライバをインストールする例です。 WinNT用のドライバはnpstor.sys、Win9x用のドライバはnpstor.mpdです。 先に述べた通り、この2つのファイルは拡張子が異なるだけで全く同じものです。


[Version]
signature="$CHICAGO$"
Class=SCSIAdapter
ClassGUID={4D36E97B-E325-11CE-BFC1-08002BE10318}
Provider=%INF_PROVIDER%
LayoutFile=layout.inf
DriverVer=06/21/2025

[SourceDisksNames]
1 = %FLOPPY_DESCRIPTION%,,,.

[SourceDisksFiles]
npstor.sys = 1
npstor.mpd = 1
SCSIPORT.PDR = 2

[Manufacturer]
%NP2%=NP2

[NP2]
%*NPSTOR.DeviceDesc%= NPSTOR,*NPSTOR

[NPSTOR]
CopyFiles=@npstor.mpd,@SCSIPORT.PDR
LogConfig=*NPSTOR.LogConfig
AddReg = ios, win98.reg

[NPSTOR.NTx86]
CopyFiles=@npstor.sys
LogConfig=*NPSTOR.LogConfig

[NPSTOR.NTx86.Services]
AddService = npstor, 2, npstor_Service_Inst, Miniport_EventLog_Inst

[npstor_Service_Inst]
ServiceType    = 1      ; SERVICE_KERNEL_DRIVER
StartType      = 0      ; SERVICE_BOOT_START
ErrorControl   = 1      ; SERVICE_ERROR_NORMAL
ServiceBinary  = %12%\npstor.sys
LoadOrderGroup = SCSI Miniport
AddReg         = pnpsafe_isa_addreg

[pnpsafe_isa_addreg]
HKR, "Parameters\PnpInterface", "1", 0x00010001, 0x00000001

[*NPSTOR.LogConfig]
ConfigPriority = HARDRECONFIG
IOConfig       = 7EA-7EB

[Miniport_EventLog_Inst]
AddReg = Miniport_EventLog_AddReg

[Miniport_EventLog_AddReg]
HKR,,EventMessageFile,0x00020000,"%%SystemRoot%%\System32\IoLogMsg.dll"
HKR,,TypesSupported,0x00010001,7

[DestinationDirs]
DefaultDestDir = 12

[IOS]
HKR,,DevLoader,,*IOS
HKR,,DontLoadIfConflict,,"Y"

[WIN98.REG]
HKR,,PortDriver,,npstor.mpd

[Strings]
INF_PROVIDER="ねこさん開発ちーむ"
NP2="Neko Project II"
FLOPPY_DESCRIPTION="Neko Project II ユーティリティディスク"
*NPSTOR.DeviceDesc="Neko Project II SCSI Host Controller"

ポイントとして、Win9xではSCSIPORT.PDRを同時にインストールするように指示している点があります。 SCSIPORT.PDRはWinNTにおけるSCSIPORT.SYSをエミュレーションするためのVxDです。 SCSIPORT.PDRは通常初めからインストールされているはずですが、依存ファイルではあるので明示的にインストールする方が丁寧だと思います。

なお、WinNT4.0以前は上記のINIファイルでインストールしようとするとうまく動きません。 レガシーなOEMSETUP.INFを使用する必要があります。 詳細については、Neko Project 21/Wのソース内のnp2tool\npstor\wntが参考になります。

ドライバ作成時の注意

Windows 2000以降はHW_INITIALIZATION_DATA構造体のサイズが4byte増えています。 このため、Windows 2000以降のHW_INITIALIZATION_DATA構造体でScsiPortInitializeを呼ぶと、それより前のバージョンのWindowsでエラーになります。

これを回避してドライバを共通にするには、以下のようにScsiPortInitialize失敗時に構造体サイズを4byte減らして再試行する方法が使えます。


status = ScsiPortInitialize(DriverObject, RegistryPath, &hwInit, NULL);
if(status != STATUS_SUCCESS){
	g_isNT4 = TRUE;
	hwInit.HwInitializationDataSize -= 4;
	status = ScsiPortInitialize(DriverObject, RegistryPath, &hwInit, NULL);
}

他に、HwFindAdapterで渡されるPORT_CONFIGURATION_INFORMATION構造体のメンバなども違いがあったりしますので、上記のg_isNT4のような互換フラグを用意して処理を分岐させるのをおすすめします。

資料集に戻る

トップに戻る