2012-03-30 16 views
3

私はいくつかの従来のDefineDosDeviceユーザ空間コードを置き換えようとしています(Vista上では管理者ユーザでは動作しません)。これは、昇格されたセッションと通常のセッションが異なるDosDeviceストアによって表されるためです。平坦でないプロセスから作成された場合は表示されますが、昇格したプロセスから作成された場合は表示されません)。ドライブマガジンを割り当てるためのNTマウントマネージャとのインターフェース方法は?

これに代わる、私はTruecrypt sourceを調べ、このWDM sample通って発見したようにMOUNTMGR.SYS、その後IOCTL_MOUNTMGR_CREATE_POINT/IOCTL_MOUNTMGR_DELETE_POINTするIOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATIONメッセージを発行することです。だから、これは私がやっているものです

- 私のコードは次のようになります。

をはじめ、様々な地元の人々:

NTSTATUS ntStatus; 
PDEVICE_EXTENSION device_extension; 
UNICODE_STRING uVolumeName; 

ULONG mntNameLen = 0; 
ULONG mntPointLen = 0; 
PMOUNTMGR_TARGET_NAME mntName = NULL; 
PMOUNTMGR_CREATE_POINT_INPUT mntPoint = NULL; 

その後、私は私の2つの要求を構築します。最初のコードは上記のステータスコードで失敗します。 2番目のコードは、異なるステータスコードで失敗します(ただし、最初のコードが失敗した場合は動作しません)。

mntNameLen = sizeof(MOUNTMGR_TARGET_NAME) + device_extension->sDevName.Length; 
mntName = ExAllocatePool(PagedPool, mntNameLen); 

mntName->DeviceNameLength = device_extension->sDevName.Length; 
RtlCopyMemory(mntName->DeviceName, device_extension->sDevName.Buffer, 
       mntName->DeviceNameLength); 

ntStatus = MakeDeviceIoRequest (MOUNTMGR_DEVICE_NAME, 
    IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION, 
    mntName, mntNameLen, 0, 0); 

mntPointLen = sizeof(PMOUNTMGR_CREATE_POINT_INPUT) + 
    device_extension->sDevName.Length + uVolumeName.Length; 
mntPoint = ExAllocatePool(PagedPool, mntPointLen); 

mntPoint->SymbolicLinkNameOffset = sizeof (MOUNTMGR_CREATE_POINT_INPUT); 
RtlCopyMemory(&mntPoint+mntPoint->SymbolicLinkNameOffset, 
    uVolumeName.Buffer, uVolumeName.Length * sizeof(WCHAR)); 
mntPoint->SymbolicLinkNameLength = uVolumeName.Length; 

mntPoint->DeviceNameOffset = mntPoint->SymbolicLinkNameOffset + 
    mntPoint->SymbolicLinkNameLength; 
RtlCopyMemory(&mntPoint+mntPoint->DeviceNameOffset, 
    device_extension->sDevName.Buffer, device_extension->sDevName.Length); 
mntPoint->DeviceNameLength = device_extension->sDevName.Length; 

ntStatus = MakeDeviceIoRequest(MOUNTMGR_DEVICE_NAME, 
    IOCTL_MOUNTMGR_CREATE_POINT, mntPoint, 
mntPointLen, 0, 0); 

は、その後、私は、\ GLOBAL ??の\ Lのシンボリックリンクを作成します。 - > \デバイスの\ DeviceNameの

ntStatus = IoCreateSymbolicLink(&uVolumeName, &(device_extension->sDevName)); 
DbgPrint("Mapped %wZ -> %wZ\n", &uVolumeName, &(device_extension->sDevName)); 
RtlFreeUnicodeString(&uVolumeName); 
if (mntName != NULL) 
{ 
    ExFreePool(mntName); 
} 
if (mntPoint != NULL) 
{ 
    ExFreePool(mntPoint); 
} 

しかし、マウントマネージャからntStatus応答が0xC0000010STATUS_INVALID_DEVICE_REQUESTです。私のデバイス文字列は、フォーム\Device\DevNameであり、それぞれに応答します。

  • IOCTL_VOLUME_ONLINE
  • IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME
  • IOCTL_MOUNTDEV_QUERY_UNIQUE_ID
  • IOCTL_MOUNTDEV_QUERY_DEVICE_NAME

とストレージデバイスに期待される他のIOCTLの一覧。しかし、私はこれらすべてのルーチンにブレークポイントを設定しており、どれも到達していません。

マイデバイスはこの小さなスニペットを介して作成されます。

// Security descriptor 
RtlInitUnicodeString(&sddl, 
    _T("D:P(A;;GA;;;SY)(A;;GA;;;BA)(A;;GA;;;BU)(A;;GA;;;WD)")); 

// named device 
status = IoCreateDeviceSecure(
    DriverObject, 
    sizeof(DEVICE_EXTENSION), 
    &device_name,  // \Device\DeviceName 
    DeviceType,  // valid devicetype. 
    0, 
    FALSE, 
    &sddl,   // security descriptor 
    NULL,    // no idea what this does. 
    &device_object // output device object. 
); 

ので、その後、ダウンいくつかの質問に:

  1. は私が正しくマウントマネージャ用のメッセージを作成していますか? MakeDeviceIoRequestコールは基本的にIoCallDriverをラップしていますが、私はそれが問題ではないことを合理的に確信しています。
  2. CreateDeviceで何をしているのですか? this blog postは、正直なところ理解していないデバイス名、FDO、PDOなどを暗示しているからです。
  3. 私はあまりにも深いように見える場合、これがどのように機能するかについての私の理解を明確にする機会はありますか?

注::いくつかの制限があります。私が構築しているコードはかなり古いものなので、ntddk.h and wdmsec.hを含めています。この段階では、wdm.hまたはntifs.hに変更することはできません。

答えて

2

DefineDosDeviceへの呼び出しをサービスに移動する可能性はありますか?それをサービスから呼び出すと、そのリンクがグローバルディレクトリに置かれます。グローバルディレクトリには、あなたが持っているエイリアシングの問題を完全に取り除きます。

あなたがそれを行うことができないのであれば、私の最初の推測はあなたが他のいくつかの必要なマウントマネージャIOCTLを処理していないということです。特定のIOCTLすべてにブレークポイントがあることは分かっていますが、デフォルトハンドラにブレークポイントがありますか?通常、STATUS_INVALID_DEVICE_REQUESTの元の場所です。

+0

私はデフォルトのハンドラを忘れていました。確かに見る価値がある - それは試してみましょう。サービス上 - 私たちは実際にそれを実際に行っています:(それは元々の回避策でしたが、サービスコードを完全に取り除こうとしています。私はデフォルトのハンドラであなたに戻ってきます。 –

+0

私はデフォルトのハンドラを見てみました。マウントマネージャは['IOCTL_VOLUME_GET_GPT_ATTRIBUTES'](http://msdn.microsoft.com/en-us/library/dd627175%28vs.85%29.aspx)を送信しますディスクがGPT(この場合は仮想CD ROM)として記述されているかどうかを確認します。適切な応答で実装すると、ボリューム到着通知が成功します。残りの問題は、作成ポイントですが、入力のメモリ私はなぜそれが動作していないと私の悪いコーディングのため、緑のチックを持っている理由がわかります:) –

+0

優秀!それが聞こえてうれしが、そのトリックでした。 – snoone

関連する問題