NTSTATUS Bus_IoCtl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { // このルーチンで使う変数を定義する PIO_STACK_LOCATION irpStack; // スタックロケーションのポインタ NTSTATUS status; // 完了ステータス ULONG inlen, outlen; // バイト長 PFDO_DEVICE_DATA fdoData; // デバイスエクステンションのポインタ PVOID buffer; // バッファのポインタ
PAGED_CODE(); // このルーチンはページプールメモリで実行します
fdoData = (PFDO_DEVICE_DATA) DeviceObject->DeviceExtension; // デバイスオブジェクトからデバイスエクステンションのポインタの取得 // 取得したデバイスオブジェクトがFDOでないとき、以下の処理を行う if (!fdoData->IsFDO) { status = STATUS_INVALID_DEVICE_REQUEST; // IRPの完了状態はデバイスが無効 Irp->IoStatus.Status = status; // IRPに状態を設定 IoCompleteRequest(Irp, IO_NO_INCREMENT); // IRPの完了を伝える return status; }
if (fdoData->DevicePnPState == Deleted) { // デバイスがすでに抜かれている際、以下の処理を行う Irp->IoStatus.Status = status = STATUS_DELETE_PENDING; // 状態の設定 IoCompleteRequest(Irp, IO_NO_INCREMENT); // IRPの完了 return status; }
Bus_IncIoCount(fdoData); // デバイスの受け取った要求回数を1増やす irpStack = IoGetCurrentIrpStackLocation(Irp); // 現在のスタックロケーションを取得 buffer = Irp->AssociatedIrp.SystemBuffer; // システムバッファの取得 inlen = irpStack->Parameters.DeviceIoControl.InputBufferLength; // 入力バッファのバイト長を取得 outlen = irpStack->Parameters.DeviceIoControl.OutputBufferLength; // 出力バッファのバイト長を取得 status = STATUS_INVALID_PARAMETER; // 定義していないコントロールコード
// I/Oコントロールコードの分岐 switch (irpStack->Parameters.DeviceIoControl.IoControlCode) { case IOCTL_BUSENUM_PLUGIN_HARDWARE: if ((inlen == outlen) && // 次の条件の場合、メッセージの表示、状態の設定、読み書きしたバイト数の設定を行う ((sizeof(BUSENUM_PLUGIN_HARDWARE) + sizeof(UNICODE_NULL) * 2) <= inlen) && (sizeof(BUSENUM_PLUGIN_HARDWARE) == ((PBUSENUM_PLUGIN_HARDWARE) buffer)->Size)) { Bus_KdPrint(fdoData, BUS_DBG_IOCTL_TRACE, ("PlugIn called\n")); // メッセージの表示 status = Bus_PlugInDevice((PBUSENUM_PLUGIN_HARDWARE)buffer, inlen, fdoData); // 完了状態を設定 Irp->IoStatus.Information = outlen; // 読み書きしたバイト長の設定 } break;
case IOCTL_BUSENUM_UNPLUG_HARDWARE: if ((sizeof(BUSENUM_UNPLUG_HARDWARE) == inlen) && (inlen == outlen) && (((PBUSENUM_UNPLUG_HARDWARE)buffer)->Size == inlen)) { Bus_KdPrint(fdoData, BUS_DBG_IOCTL_TRACE, ("UnPlug called\n")); // メッセージの表示 status = Bus_UnPlugDevice((PBUSENUM_UNPLUG_HARDWARE)buffer, fdoData); // 完了状態を設定 Irp->IoStatus.Information = outlen; // 読み書きしたバイト長の設定 } break;
case IOCTL_BUSENUM_EJECT_HARDWARE: if ((sizeof(BUSENUM_EJECT_HARDWARE) == inlen) && (inlen == outlen) && (((PBUSENUM_EJECT_HARDWARE)buffer)->Size == inlen)) { Bus_KdPrint(fdoData, BUS_DBG_IOCTL_TRACE, ("Eject called\n")); // メッセージの表示 status = Bus_EjectDevice((PBUSENUM_EJECT_HARDWARE)buffer, fdoData); // 完了状態を設定 Irp->IoStatus.Information = outlen; // 読み書きしたバイト長の設定 } break;
default: // I/Oコントロールコードがデフォルトの場合、処理は行わず、STATUS_INVALID_PARAMETER を戻す break; }
Irp->IoStatus.Status = status; // 完了状態を設定 IoCompleteRequest(Irp, IO_NO_INCREMENT); // IRPの完了 Bus_DecIoCount(fdoData); // デバイスの受け取った要求回数を1減少させる
return status;
|