none
Windows10にてWindowsUpdate後、PrinterSettingの復元でOutOfMemoryエラーが発生する RRS feed

  • 質問

  • C#のWindowsFormアプリケーションで、PrinterSettingクラスのGetHdevmode、GetHdevnames、メソッドを使用して、

    DEVMODE 構造体情報・DEVNAMES 構造体情報を取得し、ファイルに保存。

    保存したファイルを読み込み、PrinterSettingクラスのSetHdevmode、SetHdevnames、メソッドを使用して、

    DEVMODE 構造体情報・DEVNAMES 構造体情報をコピーする。

    このような実装方法で、プリンター設定情報の保存・復元が出来るようなアプリケーションを作っています。

    (開発環境:VisualStudio2010、.NetFramework2.0)

    4/11に配信されたWindows10のWindowsUpdate(KB4093112など)適用以降、

    KB適用前に保存したプリンタ設定情報を、KB適用後の環境で復元するとOutOfMemoryエラーが発生するようになってしまいました。

    どうやらKBを適用する事で、DEVNAMES 構造体情報のサイズに変更が起きているようです。

    ※KB適用前よりもKB適用後の方がサイズが小さくなっている模様。

    ※KB4093112をアンインストしたらエラーが起こらなくなったと報告を受けています。

    更新情報を見ても、特にそのような記述は見当たらなかったのですが、今回のWindowsUpdateにプリンタ情報の

    仕様変更が含まれているのでしょうか?


    株式会社システムリサーチ 川端 修(Kaji)

    2018年4月17日 5:22

すべての返信

  • 取り敢えず調査を進めた中で分かった事を追記します。

    現在確認でているプリンタドライバはPrimoPDFだけなので、ちょっと微妙ですが・・・

    DEVMODE 構造体情報 では、dmDriverExtraに差異がありました。

    KBを当てる前の値が「1420」で、KBを当てた後の値が「908」となっていました。

    dmDriverExtraが指す値で拡張情報が存在するメモリ空間の情報を取得・保存し、

    復元時にはDEVMODE構造体に続くデータ領域に、保存時のdmDriverExtraの値分の

    メモリ空間に保存していた拡張情報を復元させています。(この時点で溢れている事になりますね)

    これまでのところ、Canonのプリンタでは現象は出ず、Epsonのドットインパクトプリンタでは現象が出ている

    との報告が来ていますので、Canon・Epsonでも検証をしてみようと思います。

    また進展があれば、追加投稿しますが、今回のKBでプリンタドライバ関連に何か変更があったか?について

    出来れば真相を知りたいと思いますので、情報がありましたら提供をお願いしたいです。


    株式会社システムリサーチ 川端 修(Kaji)

    2018年4月20日 7:48
  • 下記ドキュメントは、ちゃんと確認しましたか?
    ------------------------------------------------------
    DEVMODE structure
    https://msdn.microsoft.com/ja-jp/library/windows/desktop/dd183565(v=vs.85).aspx

    dmSize
    Specifies the size, in bytes, of the DEVMODE structure,
    not including any private driver-specific data
    that might follow the structure's public members.
    Set this member to sizeof (DEVMODE) to indicate
    the version of the DEVMODE structure being used.

    dmDriverExtra
    Contains the number of bytes of private driver-data
    that follow this structure.
    If a device driver does not use device-specific information,
    set this member to zero.

    Remarks
    A device driver's private data follows the public portion
    of the DEVMODE structure.
    The size of the public data can vary for different versions
    of the structure.
    The dmSize member specifies the number of bytes of public data,
    and the dmDriverExtra member specifies the number of
    bytes of private data.
    ------------------------------------------------------

    DEVMODE 構造体は、すべてのプリンタ ドライバで共通の Public Member と個々のプリンタ ドライバ毎にユニークな Private Member で構成されています。
    即ち、Private Member は個々のプリンタ ドライバ毎に変化します。
    例えば、同じメーカーの同じ名前のプリンタ ドライバであってもドライバ ファイル バージョンが異なれば、Private Member は変化する可能性があります。
    DEVMODE 構造体の Public Member サイズは dmSize に、Private Member サイズは dmDriverExtra にそれぞれ保持されていて、Public Member の直後に Private Member が定義されています。
    さらに Public Member は OS の違い (Windows 2000 以降とそれ以前) により変化するので、DEVMODE 構造体の Public Member を参照する場合でも、厳密にチェックする必要があります。

    つまり提示されている方法では、同一メーカーの同一プリンタ モデルの同一プリンタ ドライバの同一バージョンのみで有効。。。。ということです。
    KB4093112 の適用の有無で dmDriverExtra の値が変化したということは、プリンタ ドライバが更新され異なるバージョンになったため、DEVMODE 構造体の Private Member 構成が変わってサイズがでかくなった。。。ということです。
    (その結果、Out Of Memory Error になった。)


    • 編集済み お馬鹿 2018年4月20日 9:11
    2018年4月20日 9:05
  • お馬鹿様

    情報ありがとう御座います。

    ただ失礼を承知で意見させて下さい。

    DEVMODE 構造体のpublic memberがWindowsのバージョンによって構成に差異がある事は承知しています。

    ドライバのバージョンアップ等で、固有の情報に差が出る事も想定しています。

    ただ、今回のKBでドライバのバージョンに差異はなく、public member(dmSize)にも差異はありませんし

    private member に関しては、どのような情報があるのかドライバメーカーでは無いので判りませんが

    要素が増えて情報量が増えるならまだしも、今回は情報量が減っているように見えます。

    (dmDriverExtra の価が小さくなっている)

    private member に関して、ドライバメーカー以外が変更を加えるとは考え難いため

    KBによって何らかの問題が発生しているのでは?という疑念が拭えません。

    ※過去にもKBがWindowsUpdateで印刷が出来なくなってしまう問題は何度か発生しています。

     2017/11/15のKB4048955で、Epson製のプリンタで印刷が出来なくなってしまった事件は、記憶に新しいです。

    プログラムの作りが悪いと言われても仕方ない作りになっている事は、実際例外エラーが起きてしまっているので

    反論のしようもありませんが、今回のKBでどうしてプリンタドライバに影響が出ているのか、その理由が知りたいのです。

    それによって、印刷処理に影響が出ていないのか?拡張情報でこれまで使えていた設定が使えなくなっているものはないのか?

    その辺りの情報が欲しいというのは間違っている事でしょうか?


    株式会社システムリサーチ 川端 修(Kaji)

    2018年4月20日 10:09
  • 現在取得できている情報を掲載します。

    KB適用前に取得したDEVMODE

    dmDeviceName:PrimoPDF
    dmSpecVersion:1025
    dmDriverVersion:1539
    dmSize:220
    dmDriverExtra:1420
    dmFields:25227091
    dmOrientation:2
    dmPaperSize:9
    dmPaperLength:2970
    dmPaperWidth:2100
    dmScale:100
    dmCopies:1
    dmDefaultSource:15
    dmPrintQuality:600
    dmColor:2
    dmDuplex:1
    dmYResolution:600
    dmTTOption:3
    dmCollate:0
    dmFormName:A4
    dmUnusedPadding:0
    dmBitsPerPel:0
    dmPelsWidth:0
    dmPelsHeight:0
    dmDisplayFlags:1
    dmDisplayFrequency:0
    dmICMMethod:1
    dmICMIntent:2
    dmMediaType:1
    dmDitherType:0
    dmReserved1:0
    dmReserved2:0
    dmPanningWidth:0
    dmPanningHeight:0

    KB適用後に取得したDEVMODE

    dmDeviceName:PrimoPDF
    dmSpecVersion:1025
    dmDriverVersion:1539
    dmSize:220
    dmDriverExtra:908
    dmFields:25227091
    dmOrientation:2
    dmPaperSize:9
    dmPaperLength:2970
    dmPaperWidth:2100
    dmScale:100
    dmCopies:1
    dmDefaultSource:15
    dmPrintQuality:600
    dmColor:2
    dmDuplex:1
    dmYResolution:600
    dmTTOption:3
    dmCollate:0
    dmFormName:A4
    dmUnusedPadding:0
    dmBitsPerPel:0
    dmPelsWidth:0
    dmPelsHeight:0
    dmDisplayFlags:1
    dmDisplayFrequency:0
    dmICMMethod:1
    dmICMIntent:2
    dmMediaType:1
    dmDitherType:0
    dmReserved1:0
    dmReserved2:0
    dmPanningWidth:0
    dmPanningHeight:0


    株式会社システムリサーチ 川端 修(Kaji)

    2018年4月20日 10:16
  • 今回のKBでどうしてプリンタドライバに影響が出ているのか、その理由が知りたいのです。

    (略)
    その辺りの情報が欲しいというのは間違っている事でしょうか?

    Microsoft 自身で公開しているか、同じ問題を抱える人の中で解析した人がいない限り、そういった情報をフォーラムで入手することは難しいかと。
    「理由」とか「仕様」とかを尋ねているわけですので、フォーラムに参加する第三者には答えを出せません。
    また、Micorosoft のエンジニアが回答してくれるわけでもありません。

    リバースを含んだ解析の動きを取られるか、有償サポートで聞き出すとかそういったアプローチが必要になるのではないでしょうか。

    2018年4月20日 13:39
  • DEVMODE 構造体の dmDriverExtra 以外のメンバーに差異がないのであれば、これ以上 Public Member を調べても意味がないような。。。。

    そのプロセスにデバッガをアタッチさせ、DEVMODE 構造体の Private Member の中身を確認してみては?

    具体的なメンバー構成が不明であっても、たとえば文字列あるいはポインタ等が保持されている場合は、それが重要なヒントになると思います。

    さらにドライバ プロパティ設定の変更で Private Member の領域にどのような変化が起きるのかを調べれば、非公開部分であっても結構わかるもんです。

    とにかく「根性」さえあれば、調べる方法はいくらでもあります。

    2018年4月21日 2:52
  • 幾つかプリンタを変えて試してみたところ、分かった事があります。

    EPSON、CANON、複合機など、プリンタメーカーが出しているプリンタドライバは、調べた限りでは問題ありませんでした。

    Windows10に標準搭載されているプリンタドライバは、全てNG(拡張情報が変わってしまっている)という結論に至りました。

    恐らくWindowsUpdateの公開情報には載せていないが、標準搭載のプリンタドライバに関連する修正があったのだと思います。

    また、PrinterSettingsクラスに保存した情報を復元したら、即座に例外が発生すると思っていましたが、

    検証用にアプリを作って調べてみたところ、復元する際に自分で保存時と同じ容量でメモリ領域を確保しているので、

    ここでは例外エラーは起きていませんでした。

    PrintDocumentにPrinterSettingsを設定しても例外は起きません。

    例外が起きるパターンとしては、以下の3パターンでした。

    ① PrintDialog.Document プロパティに、復元したPrinterSettingsを設定したPrintDocumentを設定し、ShowDialogを実行した場合。

    ② PageSetupDialog.PageSettings.PrinterSettings プロパティに、復元したPrinterSettingsを設定した場合。

    ③ PrintDocument.PrinterSettings プロパティに、復元したPrinterSettingsを設定してPrintを実行した場合。

    ※条件は、4月のWindowsUpdateを当てる前に保存したWindows10に標準搭載されているプリンタドライバのプリンタ設定を

     4月のWindowsUpdateを当てた後の環境で復元した場合になります。

    上記が分かった時点で私の「根性」は尽きてしまったので、後はユーザーへの対処をどうするかに注力したいと思います。

    願わくば、次の「Spring Creators Update」で被害が拡大しませんように。。。


    株式会社システムリサーチ 川端 修(Kaji)

    2018年4月21日 11:34
  • 思うに、「プリンタードライバーの private 領域のサイズが違うときは復元しない」という仕様にしておけば、そういった、プリンタードライバーか、それに関わるモジュールのアップデートがあったとしても、「その境界をまたぐ一度だけ設定がリセットされる」という仕様で落ち着けられるのでは。
    (ただ、そういった仕様のアプリを設計・実装していないので、そういったことができない振る舞いがあるのであればすみません…)

    原因・理由を知ることよりも、現行製品の市場対応が重要なのであれば、そういった「変化に対する柔軟性」を備える路線で進めた方が良さそうです。
    Windows は半年に一度は大規模な変更が投下される現状ですので、「安定を願う」だけでなく、「現実的な対応」も必要だと考えています。

    // エンジニアとして原因を知ることも重要な場面があることは否定しません。
    // が、今回はそういった方向の努力に時間をかけられない&因果関係がわかっても、
    // ソフトウェアでの回避自体が必要な場面とお見受けしました。

    • 編集済み AzuleanMVP 2018年4月21日 12:12
    • 回答の候補に設定 お馬鹿 2018年4月21日 14:48
    2018年4月21日 12:01
  • 検証したのは、v3, v4 どっちのアーキテクチャのドライバ?

    もし v3 アーキテクチャのみで発生しているのであれば unidrv.dll とかの、Universal Printer Driver 関連のモジュールが更新されたのかも。

    だとしたら Uni/Mini アーキテクチャの Printer Driver は、全部ダメだと思います。

    ちなみに、Canon や EPSON は伝統的に、Uni/Mini と Native の2 つのアーキテクチャ ドライバをリリースしてます。

    P.S.

    ここは技術的な議論をする場所ぢゃないの?

    • 編集済み お馬鹿 2018年4月21日 13:31
    2018年4月21日 13:27
  • もし v3 アーキテクチャのみで発生しているのであれば unidrv.dll とかの、Universal Printer Driver 関連のモジュールが更新されたのかも。

    KB4093112 の Win10 向けのパッケージを展開していくと得られる、ファイル情報を羅列した _manifest_.cix.xml に以下の記載はあるので、その線は可能性高いでしょうね。

    x86 パッケージ
    x86_ntprint.inf_31bf3856ad364e35_10.0.16299.334_none_ec788f536d1663b4\i386\unidrv.dll

    x64 パッケージ
    amd64_ntprint.inf_31bf3856ad364e35_10.0.16299.334_none_48972ad72573d4ea\amd64\unidrv.dll

    ここは技術的な議論をする場所ぢゃないの?

    フォーラムとしてどうあるべきかは定義されていませんし、コンセンサスを取るような仕組みもないため、スレッドの提起者の希望が尊重されるべきだと思っています。

    「ディスカッション」として投稿されているのであれば、議論を望まれていると解釈できます。
    「質問」の場合は、スレッドの提起者がどういったことを望んでいるか次第です。
    運用での回避を望んでいる場合もありますし、真因を本気で知りたい(技術を習得したい)という場合もあるでしょう。

    今回は ”私の「根性」は尽きてしまった” や "後はユーザーへの対処をどうするかに注力したい" と言われているので、当初明示されていた「理由・原因が知りたい」は撤回され、解き明かす努力よりも、現実的な対応に舵を切られていると解釈しました。

    2018年4月21日 14:32