すべてのネットワーク プリンターで [ポート] タブが空になっている Windows 環境を用意しますが、一部の win7 クライアントでのみです。これらのクライアントからの他のすべての印刷機能は、これらのプリント サーバー上のプリンターに対して機能します。環境のセットアップ方法が原因で、これらの vSphere 仮想マシンにカーネル デバッガーを簡単にアタッチできません。
- Server 2008 R2 マシン - OK
- Win7 マシンのクリーニング - OK
- Win7 マシン + 多くのサードパーティ製ソフトウェア (サードパーティ製デバイス ドライバ、複数の API フック ソフトウェアなどを含む) - BROKEN
すべてのマシンが同じドメインに参加し、同じユーザーとしてログインしています。Explorer.exe でRohitab API Monitorを使用すると、winspool EnumPortsが成功していることが確認されましたが、失敗したマシンでは 0 ポートが返されましたが、同じユーザー アカウント/同じネットワークと同じパラメーターの下では、動作している両方のマシンで 600 以上のポートが返されました。
EnumPorts を単独でテストするためのテスト C++ プログラムを作成しました。Visual Studio 2015 プロジェクト + バイナリはこちら
このプログラムの重要な部分は次のとおりです。
pPortInfo = (PORT_INFO_2 *)malloc(cbNeeded);
bResult = EnumPorts(argv[1],
2,
(LPBYTE)pPortInfo,
cbNeeded,
&cbNeeded,
&cbReturned);
pPortInfo からの作業マシンの出力は次のとおりです。
CALL: EnumPorts("\\PRINTSERVER01",(LPBYTE)pPortInfo,4096,&cbNeeded,&cbReturned)
RETURNED: false ERROR CODE: 122 ERROR MSG: The data area passed to a system call is too small.
CALL: EnumPorts("\\PRINTSERVER01",(LPBYTE)pPortInfo,121800,&cbNeeded,&cbReturned)
RETURNED: true ERROR CODE: 0 ERROR MSG: The operation completed successfully.
cbReturned = 629
PORT #0
Port Name: TS005
Monitor Name: Dynamic Print Monitor
Description: Inactive TS Port
Port Type: WRITE READ
PORT #1
Port Name: TS004
Monitor Name: Dynamic Print Monitor
Description: Inactive TS Port
Port Type: WRITE READ
etc...
壊れたマシンで:
CALL: EnumPorts("\\PRINTSERVER01",(LPBYTE)pPortInfo,4096,&cbNeeded,&cbReturned)
RETURNED: true ERROR CODE: 0 ERROR MSG: The operation completed successfully.
cbReturned = 0
これまでに特定/試したこと
- SysInternals AutoRunsを使用してマシンを比較すると、両方のマシンの Windows サービス構成/ドライバー/フック DLL の間に何百もの違いがあります。これらのアイテムをすべて削除/無効にすることなく、これを潜在的な原因に絞り込む手法を見つけたい
- AppInit_DLLsキーの名前を変更し、これらの DLL がプロセスで読み込まれなくなったことを確認して、すべてのフック DLL を無効にしようとしましたが、壊れたままです
- キャプチャされた WireSharkトレース - 動作中のマシンでは、EnumPorts が呼び出されると、ネットワーク トラフィックがプリント サーバーに送受信されます。壊れたマシンでは、プリント サーバーに送信されるネットワーク トラフィックはまったくありません。ただし、壊れたマシンでも net view /all \ などのコマンドを実行して、リモート プリント サーバーのプリンター/ドライブにマップすることができます。
- Microsoft Message Analyzer RPC トレースを使用すると、RPC 呼び出しがログに記録されますが、このデータを解釈する方法がわかりません。どの呼び出しも失敗していないようです。
- winspool!EnumPorts を詳しく調べると、 NdrClientCall2を使用してプリント サーバーと通信しますが、これらの呼び出しは失敗しません。
- ローカルファイアウォールを無効にしてみました
- netsh winsock のリセットと再起動を試みました
- ウイルス対策を無効にしてテスト済み
- Windows イベント ビューアーにフィルターを作成して、テストの実行中にすべての Windows イベント ログ エントリを確認し、一見関連するエラーが見つからないようにしました。
- WinDbg を介してテスト ツールを実行すると、初回例外やその他のエラーは発生しません
- EnumPort 関数の完了時にブレークポイントを設定しようとした後、 NotMyFaultを使用して完全なメモリ dmp を作成しましたが、何も見つかりませんでした。そもそも何を探していたのかわかりませんでした。
- Process Monitorを使用して、不足しているレジストリ キー/ファイルを探しましたが、何も見つかりませんでした