Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Moduł dostawcy musi zainicjować wiele struktur danych, zanim będzie mógł zarejestrować się w Rejestrze Modułów Sieciowych (NMR). Struktury te obejmują strukturę NPI_MODULEID , strukturę NPI_PROVIDER_CHARACTERISTICS , strukturę NPI_REGISTRATION_INSTANCE (zawartą w strukturze NPI_PROVIDER_CHARACTERISTICS) oraz strukturę zdefiniowaną przez moduł dostawcy używany na potrzeby kontekstu rejestracji modułu dostawcy.
Jeśli moduł dostawcy rejestruje się w NMR jako dostawca interfejsu programowania sieciowego (NPI), który definiuje charakterystykę dostawcy specyficzną dla NPI, moduł dostawcy musi również zainicjować instancję struktury charakterystyki dostawcy zdefiniowanej przez NPI.
Wszystkie te struktury danych muszą pozostać prawidłowe i znajdować się w pamięci, o ile moduł dostawcy jest zarejestrowany w nmR.
Załóżmy na przykład, że npI "EXNPI" definiuje następujące elementy w pliku nagłówkowym Exnpi.h:
// EXNPI NPI identifier
const NPIID EXNPI_NPIID = { ... };
// EXNPI provider characteristics structure
typedef struct EXNPI_PROVIDER_CHARACTERISTICS_
{
.
. // NPI-specific members
.
} EXNPI_PROVIDER_CHARACTERISTICS, *PEXNPI_PROVIDER_CHARACTERISTICS;
Poniżej przedstawiono sposób, w jaki moduł dostawcy, który rejestruje się jako dostawca NPI EXNPI, może zainicjować wszystkie te struktury danych:
// Include the NPI specific header file
#include "exnpi.h"
// Structure for the provider module's NPI-specific characteristics
const EXNPI_PROVIDER_CHARACTERISTICS NpiSpecificCharacteristics =
{
.
. // The NPI-specific characteristics of the provider module
.
};
// Structure for the provider module's identification
const NPI_MODULEID ProviderModuleId =
{
sizeof(NPI_MODULEID),
MIT_GUID,
{ ... } // A GUID that uniquely identifies the provider module
};
// Prototypes for the provider module's callback functions
NTSTATUS
ProviderAttachClient(
IN HANDLE NmrBindingHandle,
IN PVOID ProviderContext,
IN PNPI_REGISTRATION_INSTANCE ClientRegistrationInstance,
IN PVOID ClientBindingContext,
IN CONST VOID *ClientDispatch,
OUT PVOID *ProviderBindingContext,
OUT PVOID *ProviderDispatch
);
NTSTATUS
ProviderDetachClient(
IN PVOID ProviderBindingContext
);
VOID
ProviderCleanupBindingContext(
IN PVOID ProviderBindingContext
);
// Structure for the provider module's characteristics
const NPI_PROVIDER_CHARACTERISTICS ProviderCharacteristics =
{
0,
sizeof(NPI_PROVIDER_CHARACTERISTICS),
ProviderAttachClient,
ProviderDetachClient,
ProviderCleanupBindingContext,
{
0,
sizeof(NPI_REGISTRATION_INSTANCE),
&EXNPI_NPIID,
&ProviderModuleId,
0,
&NpiSpecificCharacteristics
}
};
// Context structure for the provider module's registration
typedef struct PROVIDER_REGISTRATION_CONTEXT_ {
.
. // Provider-specific members
.
} PROVIDER_REGISTRATION_CONTEXT, *PPROVIDER_REGISTRATION_CONTEXT;
// Structure for the provider's registration context
PROVIDER_REGISTRATION_CONTEXT ProviderRegistrationContext =
{
.
. // Initial values for the registration context
.
};
Moduł dostawcy zwykle inicjuje się w ramach funkcji DriverEntry . Główne zadania inicjowania modułu dostawcy to:
Określ funkcję zwalniania. System operacyjny wywołuje tę funkcję, gdy moduł dostawcy jest zwalniany z systemu. Jeśli moduł dostawcy nie udostępnia funkcji zwolnienia, moduł dostawcy nie może zostać zwolniony z systemu.
Wywołaj funkcję NmrRegisterProvider , aby zarejestrować moduł dostawcy za pomocą nmR.
Na przykład:
// Prototype for the provider module's unload function
VOID
Unload(
PDRIVER_OBJECT DriverObject
);
// Variable to contain the handle for the registration
HANDLE ProviderHandle;
// DriverEntry function
NTSTATUS
DriverEntry(
PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath
)
{
NTSTATUS Status;
// Specify the unload function
DriverObject->DriverUnload = Unload;
.
. // Other initialization tasks
.
// Register the provider module with the NMR
Status = NmrRegisterProvider(
&ProviderCharacteristics,
&ProviderRegistrationContext,
&ProviderHandle
);
// Return the result of the registration
return Status;
}
Jeśli moduł dostawcy jest dostawcą więcej niż jednego serwera NPI, musi zainicjować niezależny zestaw struktur danych i wywołać element NmrRegisterProvider dla każdego obsługiwanego serwera NPI. Jeśli moduł sieciowy jest zarówno modułem dostawcy, jak i modułem klienta (czyli dostawcą jednego serwera NPI i klientem innego serwera NPI), musi zainicjować dwa niezależne zestawy struktur danych, jeden dla interfejsu dostawcy i jeden dla interfejsu klienta oraz wywołać zarówno NmrRegisterProvider , jak i NmrRegisterClient.
Moduł dostawcy nie jest wymagany do wywołania elementu NmrRegisterProvider z poziomu funkcji DriverEntry . Na przykład w sytuacji, gdy moduł dostawcy jest podskładnikem złożonego sterownika, rejestracja modułu dostawcy może wystąpić tylko wtedy, gdy podskładnik modułu dostawcy jest aktywowany.
Aby uzyskać więcej informacji na temat implementowania funkcji Unload modułu dostawcy, zobacz Zwalnianie modułu dostawcy.