none
プリンタドライバ開発 RRS feed

  • 質問

  • プリンタドライバの開発を行っているのですが、以下の問題が発生し、解決に至っておりません。

    ご存知の方がいらっしゃれば、情報頂きたく、宜しくお願いします。

    動作環境:Windows8

    動作内容:アプリケーションからの印刷実行時に、プリンタドライバ(ポートモニタドライバ)にて、データをフックしたい。

    問題内容:ドライバの初期化関数(InitializePrintMonitor2)、ポート検索(EnumPorts)まではコールされるが、StartDocPortがコールされない。(WindowsXP/7では動作しているが、Windows8では動作しない。)


    • 移動 星 睦美 2014年12月12日 4:01 Visual Studio 共通 から
    2014年12月12日 2:17

すべての返信

  • フォーラム オペレーターの星 睦美です。
    ドライバ開発未熟者 さん、投稿ありがとうございます。

    質問の内容から、私のほうで後ほど別のフォーラム カテゴリ( Windows クライアント開発 -全般 ) に移動させていただきますね。アラートを設定していただくと質問への返信があった際にメールでお知らせします。詳しくはヘルプをご覧ください。

    フォーラム ユーザーから役立つ情報がありましたら、投稿者からの[回答としてマーク] をお願いいたします。

    フォーラムのご利用方法、ヘルプ、回答のガイドラインに関するお知らせ


    フォーラム オペレーター 星 睦美 - MSDN Community Support



    • 編集済み 星 睦美 2014年12月12日 2:41 改行
    2014年12月12日 2:39
  • > 問題内容:ドライバの初期化関数(InitializePrintMonitor2)、ポート検索(EnumPorts)まではコールされるが、
    > StartDocPortがコールされない。(WindowsXP/7では動作しているが、Windows8では動作しない。)

    なんか非常に漠然とした質問のような気もしますが。。。
    Port Monitor 内の OpenPort() ルーチンは呼び出されてるんですか?
    Port Monitor 内 OpenPort() ルーチンのエントリ ポイントは、InitializePrintMonitor2() ルーチンが呼び出されたときに返す MONITOR2 構造体の pfnOpenPort メンバにセットしているはずですが、この部分の設定は大丈夫なのでしょうか?
    StartDocPort() は 1st パラメータに Port Handle を必要とするので、この関数コールの前に予め OpenPort() ルーチンが呼び出されていることが前提となるはずです。
    (個人的には、ポート モニタとプリンタ ドライバはまったく別物だと思ってますけど。)


    • 編集済み お馬鹿 2014年12月12日 8:08 一部修正
    • 回答の候補に設定 星 睦美 2014年12月17日 4:55
    • 回答の候補の設定解除 星 睦美 2015年1月8日 8:22
    2014年12月12日 6:27
  •  ポートモニタサーバDLL、ですよね?InitializePrintMonitor2 関数は、確かにポートモニタの関数なのですが、EnumPorts は SDK の範囲ですよね?「EnumPorts まではコールされるが、」というところから、何か勘違いか、確認ミスがあるように思います。ポートモニタサーバDLLで定義する関数の一覧は、Port Monitor Server DLL Functions (英語)にあります。


    Jitta@わんくま同盟

    2014年12月17日 8:12
  • > ポートモニタサーバDLL、ですよね?
    > InitializePrintMonitor2 関数は、確かにポートモニタの関数なのですが、
    > EnumPorts は SDK の範囲ですよね?
    > 「EnumPorts まではコールされるが、」というところから、何か勘違いか、
    > 確認ミスがあるように思います。
    > ポートモニタサーバDLLで定義する関数の一覧は、
    > Port Monitor Server DLL Functions (英語)にあります。

    FYI
    --------------------------------------------------------------------------
    MONITOR2 structure
    http://msdn.microsoft.com/en-us/library/windows/hardware/ff557532(v=vs.85).aspx

    typedef struct _MONITOR2 {
      DWORD cbSize;
      BOOL  (WINAPI *pfnEnumPorts)(
          HANDLE hMonitor,
          LPWSTR pName,
          DWORD Level,
          LPBYTE pPorts,
          DWORD cbBuf,
          LPDWORD pcbNeeded,
          LPDWORD pcReturned);
      BOOL  (WINAPI *pfnOpenPort)(
          HANDLE hMonitor,
          LPWSTR pName,
          PHANDLE pHandle);
      BOOL  (WINAPI *pfnOpenPortEx)(
          HANDLE hMonitor,
          HANDLE hMonitorPort,
          LPWSTR pPortName,
          LPWSTR pPrinterName,
          PHANDLE pHandle,
          struct _MONITOR2 * pMonitor2);
      ....
      ....
    } MONITOR2, *PMONITOR2, *LPMONITOR2;

    pfnEnumPorts
    Pointer to the print monitor's EnumPorts function. (Port monitors only.)

    EnumPorts function pointer
    http://msdn.microsoft.com/en-us/library/ff548754.aspx
    --------------------------------------------------------------------------

    ※ 普段から質問者さんからの投稿に対してご自身の意見を色々と主張されている Jitta さんのことですから、今後このスレッドを参照される(かもしれない)方々のためにも、今回のご自身の返信に関して、責任ある適切な対応をされることと確信しております。
    • 編集済み お馬鹿 2014年12月18日 1:46 再編集
    2014年12月17日 8:21
  • 情報提供不足で申し訳ありません。

    Windows7で動作確認した際、InitializePrintMonitor2()ルーチン、MONITOR2構造体のメンバ関数は、以下の順にコールされています。

    ① InitializePrintMonitor2

    ② EnumPorts()

    ③ OpenPort() or OpenPortEx() <--- どちらか一方

    ④ StartDocPort()

    ⑤ EndDocPort()

    Windows8で動作確認を行うと、③のOpenPort()までが動作し、StartDocPort()がコールされない状態です。OpenPort()内では、該当するポートを検索し、PORTポインタをPHANDLEにセットしています。

    BOOL WINAPI iOpenPort(HANDLE hMonitor, LPWSTR pName, PHANDLE pHandle)
    {
    	EnterCritSection();
    	PORT*	pPort = m_portlist->FindPort(pName);
    	*pHandle = (HANDLE)pPort;
    	pPort->dwStatus |= PS_OPENED;
    	LeaveCritSection();
    	return pPort != NULL;
    }
    

    2015年1月8日 7:48
  • MONITOR2構造体で以下の関数を登録しています。

    MONITOR2 Monitor2 = {
        sizeof(MONITOR2),
        iEnumPorts,
        iOpenPort,
        iOpenPortEx,
        iStartDocPort,
        iWritePort,
        iReadPort,
        iEndDocPort,
        iClosePort,
        iAddPort,
        iAddPortEx,
        iConfigurePort,
        iDeletePort,
        NULL, /* GetPrinterDataFromPort */
        NULL, /* SetPortTimeOuts */
        NULL, /* XcvOpenPort */
        NULL, /* XcvDataPort */
        NULL, /* XcvClosePort */
        NULL, /* Shutdown */
        NULL /* SendRecvBidiDataFromPort */
    };
    

    Windows7で動作できているので、各処理の中身は間違っていないと考えているのですが・・・。

    2015年1月8日 7:55
  • > ③ OpenPort() or OpenPortEx() <--- どちらか一方
    ↑ これよくわかりません。
    作成したのは Port Monitor ですよね?
    なんで Port Monitor で OpenPortEx() ルーチンをサポートしているのでしょうか?
    それに「どちらか一方」とはどのような意味でしょうか?
    OpenPortEx() ルーチンが呼び出されるケースもある。。。ということなのでしょうか?
    もしかして、1つの DLL で Language Monitor と Port Monitor の2つのモニタ機能をサポートしてる。。。ということなのでしょうか?
    (私は、そのような実装は無理だと思っていましたけど。)
    そもそも一番初めの質問では、「ポート検索(EnumPorts)まではコールされるが」となっていたのに、今回は「Windows8で動作確認を行うと、③のOpenPort()までが動作し」となっているのはなぜでしょうか?
    (前回のは確認不足だったのでしょうか?)
    さらに iOpenPort() ルーチンが呼び出されたときに、確実に TRUE が返されていることを確認されているのでしょうか?


    > Windows7で動作できているので、各処理の中身は間違っていないと考えているのですが・・・。
    たまたま運よく動いていたのでは?
    もし Language Monitor をサポートしていないのであれば、OpenPortEx() ルーチンを登録/実装している時点でおかしいと思います。

    デバッグはどのようにされているのでしょうか?
    ちょっと情報が断片化しすぎていて、そちらの状況がわからす、コメントのしようがないです。。。
    (音沙汰なかったから、自力で解決されたのだと思ってました。)


    • 編集済み お馬鹿 2015年1月8日 9:55 誤字訂正
    2015年1月8日 9:35