Schreiben von 64-Bit-Druckertreibern

Wichtig

Es wird empfohlen, den IPP-Posteingangsklassentreiber von Microsoft zusammen mit Druckunterstützungs-Apps (PSA) zu verwenden, um die Druckoberfläche in Windows 10 und 11 für die Druckergeräteentwicklung anzupassen.

Weitere Informationen finden Sie im Designhandbuch für Druckunterstützungs-Apps.

Wenn Sie einen 64-Bit-Treiber schreiben oder einen Treiber schreiben, der für die Ausführung auf 32-Bit- und 64-Bit-Systemen kompiliert werden kann, befolgen Sie die 64-Bit-Portierungsrichtlinien unter Portieren Ihres Treibers auf 64-Bit-Windows. In diesem Thema werden einige Der Einschränkungen und Probleme beschrieben, die beim Schreiben eines 64-Bit-Druckertreibers auftreten können.

Weitere Informationen zur Verwendung von Dekorationen zum Identifizieren der 64-Bit-Architektur finden Sie in den folgenden Themen:

Einschränkungen für Gerätekontexthandles

Wenn eine 32-Bit-Anwendung unter einer 64-Bit-Version des Microsoft Windows-Betriebssystems ausgeführt wird, sollte ein Druckertreiber-Plug-In, das im Kontext des Splwow64.exe Thunking-Prozesses ausgeführt wird, die GDI CreateDC-Funktion nicht aufrufen. Dieser Aufruf schlägt fehl.

Probleme beim Schreiben von 64-Bit-Treibern

Achten Sie in vorhandenem 32-Bit-Treibercode auf Konvertierungen zwischen Zeigertypen und ganzzahligen Typen wie DWORD oder ULONG. Wenn Sie Erfahrung beim Schreiben von Code für 32-Bit-Computer haben, können Sie davon ausgehen, dass ein Zeigerwert in eine DWORD- oder ULONG-Datei passt. Für 64-Bit-Code ist diese Annahme gefährlich. Wenn Sie einen Zeiger auf den Typ DWORD oder ULONG umwandeln, kann ein 64-Bit-Zeiger abgeschnitten werden.

Wandeln Sie stattdessen den Zeiger auf DWORD_PTR oder ULONG_PTR ein. Eine ganze Zahl ohne Vorzeichen vom Typ DWORD_PTR oder ULONG_PTR ist immer groß genug, um den gesamten Zeiger zu speichern, unabhängig davon, ob der Code für einen 32-Bit- oder 64-Bit-Computer kompiliert wird.

Beispielsweise ist das Zeigerfeld pDrvOptItems.UserData in der OEMCUIPPARAM-Struktur vom Typ ULONG_PTR. Das folgende Codebeispiel zeigt, was nicht zu tun ist, wenn Sie einen 64-Bit-Zeigerwert in dieses Feld kopieren.

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

Im vorherigen Codebeispiel wird der pData-Zeiger in den Typ ULONG umgewandelt, wodurch der Zeigerwert abgeschnitten werden kann, wenn sizeof(pData) sizeof(ULONG) > ist. Der richtige Ansatz besteht darin, den Zeiger auf ULONG_PTR umzustellen, wie im folgenden Codebeispiel gezeigt.

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

Im vorherigen Codebeispiel werden alle 64 Bits des Zeigerwerts beibehalten.

Inline-64-Bit-Funktionen wie PtrToUlong und UlongToPtr konvertieren sicher zwischen Zeiger- und Ganzzahltypen, ohne sich auf Annahmen über die relativen Größen dieser Typen zu verlassen. Wenn ein Typ kürzer als der andere ist, muss er beim Konvertieren in den längeren Typ erweitert werden. Wenn der kürzere Typ durch Füllen mit dem Zeichenbit oder mit Nullen erweitert wird, kann jede Win64-Funktion diese Situationen behandeln. Betrachten Sie das folgende Codebeispiel.

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

Sie sollten das vorherige Codebeispiel durch das folgende Codebeispiel ersetzen.

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

Das zweite Codebeispiel wird bevorzugt, obwohl

ulSlotPhysAddr

kann den Wert eines Hardwareregisters darstellen, das nur 32 Bit lang und nicht 64 Bit lang ist. Eine Liste aller neuen Win64-Hilfsfunktionen zum Konvertieren zwischen Zeiger- und Ganzzahltypen finden Sie unter Neue Datentypen.