none
ChangeWindowMessageFilterExと0x0049について RRS feed

  • 質問

  • とうとうWindows XP 32bit 「+何か」にできるようになり、いざという時の7へのダウングレード権に期待してWindows 8 Pro 64bitを購入できたので、とりあえずMicrosoft Visual Studio Express 2012 for Windows Desktopの使用感を調べたり64bitへの移植を本格的にチェックし行い、だいたいの確認はできてきたっぽいです。

    ※※ハードもOSも違いますが、やはりこっち向けにチューニングがされてるんでしょうか。素晴らしく速いですね。XP 32bitで2010使った場合と比べて実測上ビルドが8倍速ぐらいになりました。ただ、XPモードがなくHyperVなどを使おうにもXPライセンスを新規購入するというのが難しいため、XPじゃないと動かないソフトが色々と使えない事のベストな解決法を模索中です。※※

    ただ、少々気になったことがありました。

    少なくともネイティブコードにおいて、WM_DROPFILESとかWM_COPYDATAとかがVista以降UIPIでフィルタがかけられる、とのことなのですが、単にChangeWindowMessageFilterExでWM_DRAPFILESをAllowするだけでは「x64用のDebug ビルド」の時だけダメでした。(リリース版では可。…実際にはコンパイルオプションの違い?)

    つまり

    HWND hw; //が目的のウインドウハンドルとして
    
    ChangeWindowMessageFilterEx( hw, WM_DROPFILES, MSGFLT_ALLOW, nullptr ); //だけではだめで
    
    ChangeWindowMessageFilterEx( hw, 0x0049, MSGFLT_ALLOW, nullptr ); //があると出来る

    この0x0049は複数の英語のサイトに書かれてたものなので、一般的に言ってこれでいいのかもしれませんが、これは実際には何を示すのでしょうか?本当にこれで今後もまずOKといえるようなものなのでしょうか?

    ChangeWindowMessageFilterEx function (Windows)

    には、

    Minimum supported client → Windows 7 [desktop apps only]

    Minimum supported server → Windows Server 2008 R2 [desktop apps only]

    と書いてありますが、その下のコードにあるように

    #if (WINVER >= _WIN32_WINNT_WIN7)
    とかだけだと、Windows7以降かとかVista以降かとかしか見てないと思うのですが( [desktop apps only]について言及されてないコードに思える)この対処法で問題ないのでしょうか?
    2013年1月9日 14:47

回答

  • >システムの設定変更をするアプリでないのならば管理者権限で動作させるべきではありません。

    もちろん、今のところそういった操作を含む必要がない(と思う)ので、自分で直接やることは実験以外には今のところないでしょうが、では通常はユーザーが自分で「管理者権限として実行」をしないと仮定して組むのは十分一般的なこと、ということなのでしょうか?

    必要もないのに管理者として実行する方が悪いと、私は考えます。(何のための LUA なのかと問いたくなります)
    管理者として実行する必然性がないはずのアプリでは、管理者として実行されたときのために、UIPI による制限の緩和などを考える必要性はないでしょう。(セキュアに作るなら別かもしれませんが)

    高い権限で実行されているアプリが安易に低い権限のプロセスからのメッセージを受け付けると、悪意あるアプリが管理者として実行されているプロセスに攻略ファイルをドロップしたかのようにメッセージを送りつけることで、権限の昇格がはかれるかもしれません。そういう意味ではデフォルトで制限されていることに理解を持てますし、通常あり得ない使い方をされたときに不便になるのは容認すべきことだと思います。

    2013年1月10日 13:59
    モデレータ
  • 0x0049 が何かとかはよくわからないですね、確かに。WM_COPYGLOBALDATA とかいう名前も見かけますが、それも裏付けがとれませんし…。
    将来的に大丈夫か?と問われると、どこにもドキュメントで保障がないわけですから、安全とは言えないでしょうね。
    それでもやりたいときに、今の実装なら大丈夫と言うことで使う手段なのでしょう。

    ところで、UIPI で防がれるのは権限の異なるアプリ間だけなので、管理者として実行しているプロセスにドロップしたいというまれな状況で考えるべきことですが、今はそうなのですか?

    しかしそういう目でコードを見て再考してみると、これっていうのは逆に言うとdesktop appsでなければXP以前と同様これらの呼び出しをしなくてもはじかれない、ということなのでしょうか?

    ここに書かれている「desktop apps でなければ」というのは何を期待されているのでしょうか。

    Windows ストアアプリ(WinRT アプリ)と対比して、従来の Windows アプリのことを desktop apps と指しているだと、私はとらえています。そして、ストアアプリは共有コントラクトでやりとりするのが基本のはずなので、エクスプローラーからのドラッグ&ドロップの概念はありません。

    2013年1月9日 16:55
    モデレータ
  • WM_DROPFILES messageには特に説明がないので気付きませんでしたが、Handling Shell Data Transfer Scenarios

    Implement and register an OLE drop target. Avoid using Windows 3.1 targets or the WM_DROPFILES message, if possible.

    と書かれていました。よく考えたらOLEが実装されてからはそちらが推奨でしたね。そう思ってWM_DROPFILES messageを読み返すとRemarksには

    For further discussion of how to use drag-and-drop to transfer Shell data, see Transferring Shell Data Using Drag-and-Drop or the Clipboard.

    と書かれていて、そのリンク先ドキュメントではWM_DROPFILESに触れていませんでした。要するに使うなってことでしょう。(もしくは使うならWindows 3.1時代の知識を持っている必要があると。)

    • 回答としてマーク mr.setup 2013年1月10日 4:37
    2013年1月10日 1:27
  • WM_COPYGLOBALDATA ではないかと思います。
    • 回答としてマーク mr.setup 2013年1月10日 4:37
    2013年1月10日 1:46
  • 今後絶対不要かどうかがわからないため知っておきたいのですが、こっちサイドで管理者権限で実行時でもやるにはどういう手順が必要なんでしょうか?

    「こっちサイド」の意味が分かりませんでした。

    とりあえず…システムの設定変更をするアプリでないのならば管理者権限で動作させるべきではありません。管理者権限が必要な操作が含まれている場合は、本当に必要なことか?という観点で見直すことをお勧めします。

    • 回答としてマーク mr.setup 2013年1月10日 7:05
    2013年1月10日 5:39

すべての返信

  • ・・・と、思ったら

    #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)

    でデスクトップに関しては対処済みなんですね。失礼しました(ChangeWindowMessageFilter系統のごく周辺しか見てませんでした)

    しかしそういう目でコードを見て再考してみると、これっていうのは逆に言うとdesktop appsでなければXP以前と同様これらの呼び出しをしなくてもはじかれない、ということなのでしょうか?

    2013年1月9日 15:29
  • 0x0049 が何かとかはよくわからないですね、確かに。WM_COPYGLOBALDATA とかいう名前も見かけますが、それも裏付けがとれませんし…。
    将来的に大丈夫か?と問われると、どこにもドキュメントで保障がないわけですから、安全とは言えないでしょうね。
    それでもやりたいときに、今の実装なら大丈夫と言うことで使う手段なのでしょう。

    ところで、UIPI で防がれるのは権限の異なるアプリ間だけなので、管理者として実行しているプロセスにドロップしたいというまれな状況で考えるべきことですが、今はそうなのですか?

    しかしそういう目でコードを見て再考してみると、これっていうのは逆に言うとdesktop appsでなければXP以前と同様これらの呼び出しをしなくてもはじかれない、ということなのでしょうか?

    ここに書かれている「desktop apps でなければ」というのは何を期待されているのでしょうか。

    Windows ストアアプリ(WinRT アプリ)と対比して、従来の Windows アプリのことを desktop apps と指しているだと、私はとらえています。そして、ストアアプリは共有コントラクトでやりとりするのが基本のはずなので、エクスプローラーからのドラッグ&ドロップの概念はありません。

    2013年1月9日 16:55
    モデレータ
  • WM_DROPFILES messageには特に説明がないので気付きませんでしたが、Handling Shell Data Transfer Scenarios

    Implement and register an OLE drop target. Avoid using Windows 3.1 targets or the WM_DROPFILES message, if possible.

    と書かれていました。よく考えたらOLEが実装されてからはそちらが推奨でしたね。そう思ってWM_DROPFILES messageを読み返すとRemarksには

    For further discussion of how to use drag-and-drop to transfer Shell data, see Transferring Shell Data Using Drag-and-Drop or the Clipboard.

    と書かれていて、そのリンク先ドキュメントではWM_DROPFILESに触れていませんでした。要するに使うなってことでしょう。(もしくは使うならWindows 3.1時代の知識を持っている必要があると。)

    • 回答としてマーク mr.setup 2013年1月10日 4:37
    2013年1月10日 1:27
  • WM_COPYGLOBALDATA ではないかと思います。
    • 回答としてマーク mr.setup 2013年1月10日 4:37
    2013年1月10日 1:46
  • Azuleanさん、佐祐理さん、仲澤さん、ご回答ありがとうございます♪

    何しろ、ほんの少し借りてちょこっといじっただけというのは今までVista・7でもありましたが、XP以外が「本格的に」使えるようになってから今日で3日目(しかもVS2012は昨日初めていじった分)というレベルで、さらに面倒だったためXPでも管理者でしかやってなかったため、把握してないことが非常に多かったので、いろいろと助かりました。


    >WM_COPYGLOBALDATA

    確かに、ちょくちょくと見かけました。でもやっぱり公式の裏付けはない、詳細は不明、ということですね。

    ところで、UIPI で防がれるのは権限の異なるアプリ間だけなので、管理者として実行しているプロセスにドロップしたいというまれな状況で考えるべきことですが、今はそうなのですか?

    いえ、必然性は全くありませんでした。なんで64bitのDebug版だけこうなるの?と、わかってなかったような状況だったのですが、そういうことなら、Program Files配下の問題とか色々小耳にはさんでいたので、本当だったらむしろ管理者権限じゃない状態をメインに想定してどうのこうのやったほうがずっといいはずと思いました。

    生成されたexeファイルを右クリックから互換性のタブを開いてみると「管理者としてこのプログラムを実行する」がチェックされていないにもかかわらず「管理者として実行」的なマークがexeファイルについてて、デフォルトでそうなってるっぽかったので、これはVSのプロジェクトの設定だろうなと思って調べてみて


    プロジェクトのプロパティ→構成プロパティ→リンカー→マニフェストファイル→UACの実行レベル

    が「requireAdministrator」になってたのでasInvoker (/level='asInvoker')にしたら、Release版と同じようにできるようになりました。(「既定の場合」でもそっちになるようになってました。たぶん前なんか実験でやった時にいじったままだったんでしょうね)

    Azuleanさんの仰る通り、実際にはasInvokerで通常起動ではChangeWindowMessageFilter系統を全く呼び出さずともできました。


    ただ、実行時の権限はプロジェクトの設定の変更や、コードからAPIを使うとかせずとも、上記exeを右クリック…から変更することもでき、それでチェックを入れても同じ状況になることが確認できたのですが、この状況、通常のアプリでは、むしろ何もしないほうがいいと考えるのが普通なのでしょうか?それとも、実行時の権限を取得して処理を切り分けるほうがいいのでしょうか?

    Windows ストアアプリ(WinRT アプリ)と対比して、従来の Windows アプリのことを desktop apps と指しているだと、私はとらえています。そして、ストアアプリは共有コントラクトでやりとりするのが基本のはずなので、エクスプローラーからのドラッグ&ドロップの概念はありません。

    なるほど、そういう感じの意味なのですか。それなら心配無用ですね。

    よく考えたらOLEが実装されてからはそちらが推奨でしたね。

    あ、そうなんですね。それは重要な情報ですよ。

    と、いうわけで

    COM研究室のChapter 7. IDropTargetとOLEドラッグ&ドロップ

    のコードをちょこちょこっと拝借させていただき、先ほど動作確認ができました。
    ただこの場合でも、他に何もやらないと管理者権限では機能しませんでした。

    今後絶対不要かどうかがわからないため知っておきたいのですが、こっちサイドで管理者権限で実行時でもやるにはどういう手順が必要なんでしょうか?

    2013年1月10日 4:37
  • 今後絶対不要かどうかがわからないため知っておきたいのですが、こっちサイドで管理者権限で実行時でもやるにはどういう手順が必要なんでしょうか?

    「こっちサイド」の意味が分かりませんでした。

    とりあえず…システムの設定変更をするアプリでないのならば管理者権限で動作させるべきではありません。管理者権限が必要な操作が含まれている場合は、本当に必要なことか?という観点で見直すことをお勧めします。

    • 回答としてマーク mr.setup 2013年1月10日 7:05
    2013年1月10日 5:39
  • 再度ありがとうございます♪「こっちサイド」は、Window MessageではなくOLEでやる場合では、という意味です。

    >システムの設定変更をするアプリでないのならば管理者権限で動作させるべきではありません。

    もちろん、今のところそういった操作を含む必要がない(と思う)ので、自分で直接やることは実験以外には今のところないでしょうが、では通常はユーザーが自分で「管理者権限として実行」をしないと仮定して組むのは十分一般的なこと、ということなのでしょうか?

    2013年1月10日 7:05
  • >システムの設定変更をするアプリでないのならば管理者権限で動作させるべきではありません。

    もちろん、今のところそういった操作を含む必要がない(と思う)ので、自分で直接やることは実験以外には今のところないでしょうが、では通常はユーザーが自分で「管理者権限として実行」をしないと仮定して組むのは十分一般的なこと、ということなのでしょうか?

    必要もないのに管理者として実行する方が悪いと、私は考えます。(何のための LUA なのかと問いたくなります)
    管理者として実行する必然性がないはずのアプリでは、管理者として実行されたときのために、UIPI による制限の緩和などを考える必要性はないでしょう。(セキュアに作るなら別かもしれませんが)

    高い権限で実行されているアプリが安易に低い権限のプロセスからのメッセージを受け付けると、悪意あるアプリが管理者として実行されているプロセスに攻略ファイルをドロップしたかのようにメッセージを送りつけることで、権限の昇格がはかれるかもしれません。そういう意味ではデフォルトで制限されていることに理解を持てますし、通常あり得ない使い方をされたときに不便になるのは容認すべきことだと思います。

    2013年1月10日 13:59
    モデレータ
  • ありがとうございます♪なるほど、そう考えると確かにその方が納得がいく感じですね。

    まとめると、高い権限で実行する必要のないアプリでは、そういったことにはむしろ対処しないほうが、容易に安全性を高くできる可能性があるということで、今回の件に関してはとりあえず「権限の取得やそれへの対応については何もせず(デフォルトに任せて)」WM_DROPFILESよりOLEを使う、という方向で行くのが良いのかな、という感じですね。

    2013年1月11日 4:32