Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Rozważ użycie następujących technik specyficznych dla języka IDL w celu zwiększenia bezpieczeństwa i wydajności podczas opracowywania interfejsów i metod RPC, które obsługują zarówno zgodne, jak i wariantowe dane. Atrybuty, o których mowa w tym temacie, to atrybuty IDL ustawione dla parametrów metody, które obsługują dane zgodne (na przykład atrybuty [size_is] i [max_is] lub dane wariantu (na przykład atrybuty [length_is] i [ciąg] ).
Używanie atrybutu [range] ze zgodnymi parametrami danych
Atrybut [zakres] instruuje czas wykonywania RPC w celu przeprowadzenia dodatkowej weryfikacji rozmiaru podczas procesu unmarshaling danych. W szczególności sprawdza, czy podany rozmiar danych przekazanych jako skojarzony parametr znajduje się w określonym zakresie.
Atrybut [zakres] nie ma wpływu na format przewodu.
Jeśli wartość na przewodzie znajduje się poza dozwolonym zakresem, RPC zgłosi wyjątek RPC_X_INVALID_BOUND lub RPC_X_BAD_STUB_DATA. Zapewnia to dodatkowy poziom weryfikacji danych i może pomóc w zapobieganiu typowym błędom zabezpieczeń, takim jak przepełnienie buforu. Podobnie użycie [zakresu] może zwiększyć wydajność aplikacji, ponieważ zgodne dane oznaczone za jej pomocą mają jasno zdefiniowane ograniczenia dostępne do rozważenia przez usługę RPC.
Reguły zarządzania pamięcią wycinków serwera RPC
Ważne jest, aby zrozumieć reguły zarządzania pamięcią wycinkową serwera RPC podczas tworzenia plików IDL dla aplikacji obsługującej RPC. Aplikacje mogą poprawić wykorzystanie zasobów serwera przy użyciu [zakresu] w połączeniu z zgodnymi danymi, jak wskazano powyżej, a także celowo unikać stosowania atrybutów IDL danych o zmiennej długości, takich jak [length_is] w celu zachowania zgodności danych.
Stosowanie [length_is] do pól struktury danych zdefiniowanych w pliku IDL nie jest zalecane.
Najlepsze rozwiązania dotyczące parametrów danych o zmiennej długości
Poniżej przedstawiono kilka najlepszych rozwiązań, które należy wziąć pod uwagę podczas definiowania atrybutów IDL dla struktur danych o zmiennym rozmiarze, parametrów metody i pól.
Użyj wczesnej korelacji. Ogólnie lepiej jest zdefiniować parametr lub pole o zmiennym rozmiarze, tak aby odbywało się ono bezpośrednio po kontrolującym typ całkowity.
Na przykład
earlyCorr ( [in, range(MIN_COUNT, MAX_COUNT)] long size, [in,size_is(size)] char *pv );jest lepszy niż
lateCorr ( [in,size_is(size)] char *pv, [in, range(MIN_COUNT, MAX_COUNT)] long size) );wherein earlyCorr deklaruje parametr rozmiaru bezpośrednio przed parametrem danych o zmiennej długości, a lateCorr deklaruje parametr rozmiaru po nim. Korzystanie z wczesnej korespondencji poprawia ogólną wydajność, szczególnie w przypadkach, gdy metoda jest często wywoływana.
W przypadku parametrów oznaczonych [out, size_is] krotki atrybutu i gdzie długość danych jest znana po stronie klienta lub gdzie klient ma rozsądną górną granicę, definicja metody powinna być podobna do następującej w zakresie przypisywania parametrów i sekwencji:
outKnownSize ( [in,range(MIN_COUNT, MAX_COUNT)] long lSize, [out,size_is(lSize)] UserDataType * pArr );W takim przypadku klient udostępnia bufor o stałym rozmiarze dla pArr, dzięki czemu usługa RPC po stronie serwera może przydzielić odpowiednio duży bufor z dobrym stopniem pewności. Należy pamiętać, że w przykładzie dane są odbierane z serwera ([się]). Definicja jest podobna dla danych przekazywanych do serwera ([w]).
W sytuacjach, w których składnik po stronie serwera aplikacji RPC decyduje o długości danych, definicja metody powinna być podobna do następującej:
typedef [range(MIN_COUNT,MAX_COUNT)] long RANGED_LONG; outUnknownSize ( [out] RANGED_LONG *pSize, [out,size_is(,*pSize)] UserDataType **ppArr );RANGED_LONG jest typem zdefiniowanym dla wycinków klienta i serwera oraz o określonym rozmiarze, który klient może poprawnie przewidzieć. W tym przykładzie klient przekazuje ppArr jako null, a składnik aplikacji serwera RPC przydziela prawidłową ilość pamięci. Po powrocie usługa RPC po stronie klienta przydziela pamięć dla zwracanych danych.
Jeśli klient chce wysłać podzbiór dużej tablicy zgodnej z serwerem, aplikacja może określić rozmiar podzestawu, jak pokazano w poniższym przykładzie:
inConformantVaryingArray ( [in,range(MIN_COUNT,MAX_COUNT)] long lSize, [in] long lLength, [in,size_is(lSize), length_is(lLength)] UserDataType *pArr );W ten sposób RPC będzie przesyłać tylko lLength elementów tablicy przez drut. Jednak ta definicja wymusza, aby usługa RPC przydzielała pamięć o rozmiarze lSize po stronie serwera.
Jeśli składnik aplikacji klienckiej określa maksymalny rozmiar tablicy, którą serwer może zwrócić, ale umożliwia serwerowi przesyłanie podzestawu tej tablicy, aplikacja może określić takie zachowanie, definiując kod IDL podobny do następującego przykładu:
inMaxSizeOutLength ( [in, range(MIN_COUNT, MAX_COUNT)] long lSize, [out] long *pLength, [out,size_is(lSize), length_is(*pLength)] UserDataType *pArr );Składnik aplikacji klienckiej określa maksymalny rozmiar tablicy, a serwer określa, ile elementów przesyła z powrotem do klienta.
Jeśli składnik aplikacji serwera musi zwrócić ciąg do składnika aplikacji klienckiej, a klient wie, że maksymalny rozmiar ma zostać zwrócony z serwera, aplikacja może użyć zgodnego typu ciągu, jak pokazano w poniższym przykładzie:
outStringKnownSize ( [in,range(MIN_COUNT, MAX_STRING)] long lSize, [out,size_is(lSize),string] wchar_t *pString );Jeśli składnik aplikacji klienckiej nie powinien kontrolować rozmiaru ciągu, usługa RPC może w szczególności przydzielić pamięć, jak pokazano w poniższym przykładzie:
outStringUnknownSize ( [out] LPWSTR *ppStr );Składnik aplikacji klienckiej musi ustawić ppStr na null podczas wywoływania metody RPC.