Udostępnij za pośrednictwem


Zapisywanie sterowników drukarek 64-bitowych

Ważny

Nowoczesna platforma drukowania jest preferowanym sposobem komunikacji z drukarkami w systemie Windows. Zalecamy używanie sterownika klasy skrzynki odbiorczej IPP firmy Microsoft wraz z aplikacjami do obsługi drukowania (PSA), aby dostosować środowisko drukowania w systemie Windows 10 i 11 na potrzeby opracowywania urządzeń drukarki.

Aby uzyskać więcej informacji, zobacz przewodnik projektowania aplikacji wspierającej drukowanie .

Jeśli piszesz sterownik 64-bitowy lub zapisujesz sterownik, który można skompilować w celu uruchomienia w systemach 32-bitowych i 64-bitowych, postępuj zgodnie z wytycznymi dotyczącymi przenoszenia 64-bitowego w Przenoszenie sterownika do 64-bitowego systemu Windows. W tym temacie opisano niektóre ograniczenia i problemy, które mogą wystąpić podczas pisania 64-bitowego sterownika drukarki.

Aby uzyskać więcej informacji na temat używania dekoracji do identyfikowania architektury 64-bitowej, zobacz następujące tematy:

Ograniczenia dotyczące uchwytów kontekstu urządzenia

Jeśli aplikacja 32-bitowa jest uruchomiona w 64-bitowej wersji systemu operacyjnego Microsoft Windows, wtyczka sterownika drukarki uruchomiona w kontekście procesu Splwow64.exe thunking nie powinna wywoływać funkcji GDI CreateDC; to wywołanie zakończy się niepowodzeniem.

Problemy z pisaniem sterowników 64-bitowych

W istniejącym 32-bitowym kodzie sterownika należy zachować ostrożność podczas konwersji między typami wskaźnika a typami całkowitymi, takimi jak DWORD lub ULONG. Jeśli masz doświadczenie w pisaniu kodu dla maszyn 32-bitowych, prawdopodobnie jesteś przyzwyczajony do zakładania, że wartość wskaźnika pasuje do DWORD lub ULONG. W przypadku 64-bitowego kodu to założenie jest niebezpieczne. Jeśli rzutujesz wskaźnik, aby wpisać DWORD lub ULONG, wskaźnik 64-bitowy może zostać obcięty.

Zamiast tego rzutuj wskaźnik, aby wpisać DWORD_PTR lub ULONG_PTR. Liczba całkowita bez znaku typu DWORD_PTR lub ULONG_PTR jest zawsze wystarczająco duża, aby przechowywać cały wskaźnik, niezależnie od tego, czy kod jest kompilowany dla komputera 32-bitowego, czy 64-bitowego.

Na przykład pole wskaźnika pDrvOptItems.UserData w strukturze OEMCUIPPARAM jest typu ULONG_PTR. Poniższy przykład kodu pokazuje, czego nie robić, jeśli skopiujesz do tego pola wartość wskaźnika 64-bitowego.

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

Powyższy przykład kodu rzutuje wskaźnik pData na typ ULONG, co może spowodować obcięcie wartości wskaźnika, jeśli sizeof(pData) >sizeof(ULONG). Właściwym podejściem jest rzutowanie wskaźnika na ULONG_PTR, jak pokazano w poniższym przykładzie kodu.

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

Powyższy przykład kodu zachowuje wszystkie 64 bity wartości wskaźnika.

64-bitowe funkcje wbudowane, takie jak PtrToUlong i UlongToPtr, bezpiecznie konwertują między typami wskaźników a typami liczb całkowitych, nie polegając na założeniach dotyczących względnych rozmiarów tych typów. Jeśli jeden typ jest krótszy niż drugi, należy go rozszerzyć podczas konwertowania na dłuższy typ. Jeśli krótszy typ jest rozszerzony przez wypełnienie bitem znaku lub zerami, każda funkcja Win64 może obsługiwać te sytuacje. Rozważmy poniższy przykład kodu.

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

Powyższy przykład kodu należy zastąpić poniższym przykładem kodu.

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

Drugi przykład kodu jest preferowany, mimo że

ulSlotPhysAddr

może reprezentować wartość rejestru sprzętowego, który ma długość tylko 32 bitów, a nie 64 bity długości. Aby uzyskać listę wszystkich nowych funkcji pomocnika Win64 do konwertowania między typami wskaźników i liczb całkowitych, zobacz Nowe typy danych.