記憶装置ドライバーのデータ セット管理の実行
Windows 7 以降では、ドライバーはデバイスのデータ セットに対して管理アクションを実行できます。 記憶装置で実行できるデータ セット管理 (DSM) アクションの一覧は、Microsoft によって定義されます。
IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES の使用
DEVICE_DSM_ACTION定数は、アクションを指定します。 この定数は、IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES 要求のシステム バッファーに含まれる DEVICE_DSM_INPUT 構造体の Action メンバーで渡されます。 アクションに追加のパラメーターが必要な場合、パラメーター ブロックは DEVICE_DSM_INPUT 構造体のすぐ後に続き、ParameterBlockOffset は、パラメーター ブロックが開始される DEVICE_DSM_INPUT 構造体の先頭からのオフセットを指定します。 データ セットの範囲がある場合は、パラメーター ブロックの直後に、また DataSetRangesOffset は、範囲が開始される DEVICE_DSM_INPUT 構造体の先頭からのオフセットを指定します。 システム バッファー構造を次の図に示します。
管理アクションが出力を返す場合は、IOCTL の OutputBuffer で DEVICE_DSM_OUTPUT 構造体へのポインターが渡されます。 アクションが追加のアクション固有の出力を返す場合、出力ブロックは DEVICE_DSM_OUTPUT 構造体の直後に、 OutputBlockOffset はパラメーター ブロックが開始される DEVICE_DSM_OUTPUT 構造体の先頭からのオフセットを指定します。 出力バッファー構造を次の図に示します。
DSM アクションのプロセス フロー
DSM アクションのプロセス フローについては、以下で説明します。 送信者 はアクションリクエスタであり、 ハンドラー は要求されたアクションを処理します。 スタックには複数の ハンドラー が存在する可能性があることに注意してください。
送信者 は DSM を初期化し、次の手順を実行してスタック内の最初の ハンドラー に送信します。
- アクションに関連付けられた定義を使用して、 DEVIC_DEFINITION 構造体を割り当てて初期化します。
- DeviceDsmGetInputLength を呼び出して、アクションの入力バッファーに必要なサイズを決定し、このバッファーのメモリを割り当てます。
- DeviceDsmInitializeInput を呼び出して、DSM_DEVICE_INPUT 構造体を初期化し、アクションにパラメーターがある場合はパラメーター ブロックを初期化します。 パラメーター ブロックの形式は、アクションによって異なります。 詳細については、「 DEVICE_DSM_ACTIONの説明 」を参照してください。
- アクションに範囲がある場合は、各範囲の DeviceDsmAddDataSetRange を呼び出して、DEVICE_DSM_RANGE 構造体を入力バッファーに追加します。
- DSM に出力がある場合は、DeviceDsmGetOutputLength を呼び出して、アクションの出力バッファーに必要なサイズを決定し、このバッファーのメモリを割り当てます。
- IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES 要求を送信し、IOCTL のシステム バッファーに初期化された入力データを、割り当てられた出力バッファー (存在する場合) と共に渡します。
ハンドラー は、次の 3 つの方法のいずれかで DSM IOCTL 要求を処理します。
- 要求を処理し、ある場合は出力で返します。
- 要求を処理し、スタック内の次の下位ドライバーに転送します。
- DSM を処理せずに、スタック内の次の下位ドライバーに要求を転送します。
Note
ドライバーが DSM を処理するかどうかに関係なく、DEVICE_DSM_ACTION の最上位ビット (DeviceDsmActionFlag_NonDestructive) が設定されている場合にのみ、要求を安全に転送できます。 DeviceDsmActionFlag_NonDestructiveが設定されていない場合、ドライバーは代わりにエラーを返す必要があります。
ハンドラーが DSM を処理する場合は、次の手順を実行します。
- DeviceDsmValidateInput を呼び出して入力を検証します。
- 入力が有効な場合、 ハンドラー は入力を抽出してアクションを取得します。 アクションにパラメーター ブロックがある場合、ハンドラー は DeviceDsmParameterBlock を呼び出してパラメーター ブロックを取得します。 アクションに範囲データがある場合、ハンドラー は DeviceDsmDataSetRanges を呼び出してデータ セット範囲のブロックへのポインターを取得し、ブロックに対して通常の処理を実行します。 このブロックは DataSetRangesOffset にあり、DEVICE_DSM_RANGE 構造体として書式設定された 1 つ以上の連続したエントリで構成されます。 データ セット範囲の長さ (バイト単位) は、DEVICE_DSM_INPUT の DataSetRangesLength メンバーで設定されます。
- アクションに出力が必要な場合、ハンドラーは DeviceDsmValidateOutputLength を呼び出して、送信者が指定した出力バッファーを検証します。 有効な場合、ハンドラーは DeviceDsmInitializeOutput を呼び出して出力バッファーの DEVICE_DSM_OUTPUT 部分を初期化し、アクション固有の出力がある場合は出力ブロックに設定します。 ハンドラーは、IOCTL を完了し、返すか、スタック内の次のドライバーに IOCTL を転送します。
DSM が処理され、送信者に返されると、送信者は DeviceDsmValidateOutput を呼び出すことによって出力 (存在する場合) を検証します。 出力が有効な場合、 送信者 は DeviceDsmOutputBlock を呼び出して出力ブロック (存在する場合) を抽出します。
特定の DSM アクションの詳細については、「デバイス DSM アクションの説明」を参照してください。