記憶装置ドライバーのデータ セット管理の実行

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 構造体の先頭からのオフセットを指定します。 システム バッファー構造を次の図に示します。

DSM IOCTL Input Buffer.

管理アクションが出力を返す場合は、IOCTL の OutputBufferDEVICE_DSM_OUTPUT 構造体へのポインターが渡されます。 アクションが追加のアクション固有の出力を返す場合、出力ブロックは DEVICE_DSM_OUTPUT 構造体の直後に、 OutputBlockOffset はパラメーター ブロックが開始される DEVICE_DSM_OUTPUT 構造体の先頭からのオフセットを指定します。 出力バッファー構造を次の図に示します。

DSM IOCTL Output Buffer.

DSM アクションのプロセス フロー

DSM アクションのプロセス フローについては、以下で説明します。 送信者 はアクションリクエスタであり、 ハンドラー は要求されたアクションを処理します。 スタックには複数の ハンドラー が存在する可能性があることに注意してください。

DSM Action Flow.

  1. 送信者 は DSM を初期化し、次の手順を実行してスタック内の最初の ハンドラー に送信します。

    • アクションに関連付けられた定義を使用して、 DEVIC_DEFINITION 構造体を割り当てて初期化します。
    • DeviceDsmGetInputLength を呼び出して、アクションの入力バッファーに必要なサイズを決定し、このバッファーのメモリを割り当てます。
    • DeviceDsmInitializeInput を呼び出して、DSM_DEVICE_INPUT 構造体を初期化し、アクションにパラメーターがある場合はパラメーター ブロックを初期化します。 パラメーター ブロックの形式は、アクションによって異なります。 詳細については、「 DEVICE_DSM_ACTIONの説明 」を参照してください。
    • アクションに範囲がある場合は、各範囲の DeviceDsmAddDataSetRange を呼び出して、DEVICE_DSM_RANGE 構造体を入力バッファーに追加します。
    • DSM に出力がある場合は、DeviceDsmGetOutputLength を呼び出して、アクションの出力バッファーに必要なサイズを決定し、このバッファーのメモリを割り当てます。
    • IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES 要求を送信し、IOCTL のシステム バッファーに初期化された入力データを、割り当てられた出力バッファー (存在する場合) と共に渡します。
  2. ハンドラー は、次の 3 つの方法のいずれかで DSM IOCTL 要求を処理します。

    1. 要求を処理し、ある場合は出力で返します。
    2. 要求を処理し、スタック内の次の下位ドライバーに転送します。
    3. DSM を処理せずに、スタック内の次の下位ドライバーに要求を転送します。

    Note

    ドライバーが DSM を処理するかどうかに関係なく、DEVICE_DSM_ACTION の最上位ビット (DeviceDsmActionFlag_NonDestructive) が設定されている場合にのみ、要求を安全に転送できます。 DeviceDsmActionFlag_NonDestructiveが設定されていない場合、ドライバーは代わりにエラーを返す必要があります。

    ハンドラーが DSM を処理する場合は、次の手順を実行します。

    • DeviceDsmValidateInput を呼び出して入力を検証します。
    • 入力が有効な場合、 ハンドラー は入力を抽出してアクションを取得します。 アクションにパラメーター ブロックがある場合、ハンドラーDeviceDsmParameterBlock を呼び出してパラメーター ブロックを取得します。 アクションに範囲データがある場合、ハンドラーDeviceDsmDataSetRanges を呼び出してデータ セット範囲のブロックへのポインターを取得し、ブロックに対して通常の処理を実行します。 このブロックは DataSetRangesOffset にあり、DEVICE_DSM_RANGE 構造体として書式設定された 1 つ以上の連続したエントリで構成されます。 データ セット範囲の長さ (バイト単位) は、DEVICE_DSM_INPUTDataSetRangesLength メンバーで設定されます。
    • アクションに出力が必要な場合、ハンドラーDeviceDsmValidateOutputLength を呼び出して、送信者が指定した出力バッファーを検証します。 有効な場合、ハンドラーは DeviceDsmInitializeOutput を呼び出して出力バッファーの DEVICE_DSM_OUTPUT 部分を初期化し、アクション固有の出力がある場合は出力ブロックに設定します。 ハンドラーは、IOCTL を完了し、返すか、スタック内の次のドライバーに IOCTL を転送します。
  3. DSM が処理され、送信者に返されると、送信者DeviceDsmValidateOutput を呼び出すことによって出力 (存在する場合) を検証します。 出力が有効な場合、 送信者DeviceDsmOutputBlock を呼び出して出力ブロック (存在する場合) を抽出します。

特定の DSM アクションの詳細については、「デバイス DSM アクションの説明」を参照してください。