64 ビット プリンター ドライバーの作成

重要

Windows でプリンターとの通信手段として推奨されるのは、最新の印刷プラットフォームです。 プリンターデバイス開発におけるWindows 10および11での印刷体験をカスタマイズするために、MicrosoftのIPPインボックスクラスドライバーとPrint Support Apps (PSA)の使用を推奨します。

詳細については、最新の印刷プラットフォームに関する記事および「印刷サポート アプリの設計ガイド」を参照してください。

64 ビット ドライバーを作成する場合、または 32 ビット システムと 64 ビット システムの両方で実行できるようにコンパイルできるドライバーを作成する場合は、「ドライバーを 64 ビット Windows に移植する」の 64 ビット移植ガイドラインに従ってください。 このトピックでは、64 ビット プリンター ドライバーの作成時に発生する可能性があるいくつかの制限と問題について説明します。

デコレーションを使用して 64 ビット アーキテクチャを識別する方法の詳細については、次のトピックを参照してください。

デバイス コンテキスト ハンドルの制限事項

32 ビット アプリケーションが 64 ビット バージョンの Microsoft Windows オペレーティング システムで実行されている場合、Splwow64.exeサンキング プロセスのコンテキストで実行されているプリンター ドライバー プラグインは GDI CreateDC 関数を呼び出すべきではありません。この呼び出しは失敗します。

64ビットドライバの作成に関する問題

既存の 32 ビット ドライバー コードでは、ポインター型と DWORD や ULONG などの整数型との間の変換に注意してください。 32 ビット コンピューター用のコードを記述した経験がある場合は、ポインター値が DWORD または ULONG に収まると想定することに慣れている可能性があります。 64 ビット コードの場合、この仮定は危険です。 ポインターを DWORD 型または ULONG 型にキャストすると、64 ビット ポインターが切り捨てられる可能性があります。

代わりに、ポインターを型DWORD_PTRまたはULONG_PTRにキャストします。 DWORD_PTR 型または ULONG_PTR 型の符号なし整数は、コードが 32 ビット コンピューター用と 64 ビット コンピューターのどちら用にコンパイルされているかに関係なく、常にポインター全体を格納するのに十分な大きさです。

たとえば、OEMCUIPPARAM 構造体の pDrvOptItems.UserData ポインター フィールドは、ULONG_PTR型です。 次のコード例は、このフィールドに 64 ビットのポインター値をコピーする場合に行わないことを示しています。

PUSERDATA pData;
OEMCUIPPARAM->pDrvOptItems.UserData = (ULONG)pData;  // Wrong

前のコード例では、pData ポインターを ULONG 型にキャストします。これは、sizeof (pData) >sizeof(ULONG) の場合にポインター値を切り捨てる可能性があります。 正しい方法は、次のコード例に示すように、ポインターを ULONG_PTR にキャストすることです。

PUSERDATA pData;
OEMCUIPPARAM->pDrvOptItems.UserData = (ULONG_PTR)pData;  // Correct

上記のコード例では、ポインター値の 64 ビットすべてが保持されます。

PtrToUlongUlongToPtr などのインライン 64 ビット関数は、ポインター型と整数型の相対的なサイズを前提とせずに、これらの型の間で安全に変換できます。 一方のタイプがもう一方のタイプより短い場合は、長いタイプに変換するときに拡張する必要があります。 短い型を符号ビットまたはゼロで埋めることによって拡張された場合、各 Win64 関数はこれらの状況を処理できます。 次のコード例について考えます。

ULONG ulHWPhysAddr[NUM_PHYS_ADDRS];
ulSlotPhysAddr[0] = ULONG(pulPhysHWBuffer) + HW_BUFFER_SIZE;  // wrong

前のコード例を次のコード例に置き換える必要があります。

ULONG_PTR ulHWPhysAddr[NUM_PHYS_ADDRS];
ulSlotPhysAddr[0] = PtrToUlong(pulPhysHWBuffer) + HW_BUFFER_SIZE;  // correct

2 番目のコード例が推奨されますが、

ulSlotPhysAddr

は、長さが 64 ビットではなく 32 ビットのハードウェア レジスタの値を表す場合があります。 ポインター型と整数型の間で変換するためのすべての新しい Win64 ヘルパー関数の一覧については、 新しいデータ型を参照してください。