Tecniche IDL per una migliore progettazione di interfacce e metodi
È consigliabile usare le tecniche specifiche di IDL seguenti per migliorare la sicurezza e le prestazioni quando si sviluppano interfacce e metodi RPC che gestiscono dati conformi e varianti. Gli attributi indicati in questo argomento sono gli attributi IDL impostati sui parametri del metodo che gestiscono dati conformi ,ad esempio gli attributi [size_is] e [max_is] o i dati varianti (ad esempio, gli attributi [length_is] e [string].
Uso dell'attributo [range] con parametri di dati conformi
L'attributo [range] indica al runtime RPC di eseguire la convalida delle dimensioni aggiuntive durante il processo di annullamento delmarshaling dei dati. In particolare, verifica che la dimensione specificata dei dati passati come parametro associato sia compresa nell'intervallo specificato.
L'attributo [intervallo] non influisce sul formato di collegamento.
Se il valore in transito non rientra nell'intervallo consentito, RPC genererà un'eccezione RPC_X_INVALID_BOUND o RPC_X_BAD_STUB_DATA. Ciò offre un livello aggiuntivo di convalida dei dati e può contribuire a evitare errori di sicurezza comuni, ad esempio sovraccarichi del buffer. Analogamente, l'uso di [intervallo] può migliorare le prestazioni dell'applicazione, poiché i dati conformi contrassegnati con esso hanno vincoli chiaramente definiti per la considerazione da parte del servizio RPC.
Regole di gestione della memoria Stub del server RPC
È importante comprendere le regole di gestione della memoria stub del server RPC durante la creazione dei file IDL per un'applicazione abilitata per RPC. Le applicazioni possono migliorare l'utilizzo delle risorse del server usando [intervallo] insieme ai dati conformi come indicato in precedenza, oltre a evitare deliberatamente l'applicazione di attributi IDL di dati a lunghezza variabile come [length_is] ai dati conformi.
L'applicazione di [length_is] ai campi della struttura dei dati definiti in un file IDL non è consigliata.
Procedure consigliate per i parametri di dati a lunghezza variabile
Di seguito sono riportate diverse procedure consigliate da considerare quando si definiscono gli attributi IDL per strutture di dati di dimensioni variabili, parametri del metodo e campi.
Usare la correlazione anticipata. In genere è preferibile definire il parametro o il campo delle dimensioni delle variabili in modo che si verifichi immediatamente dopo il tipo integrale di controllo.
Ad esempio,
earlyCorr ( [in, range(MIN_COUNT, MAX_COUNT)] long size, [in,size_is(size)] char *pv );
è meglio di
lateCorr ( [in,size_is(size)] char *pv, [in, range(MIN_COUNT, MAX_COUNT)] long size) );
wherein earlyCorr dichiara il parametro size immediatamente prima del parametro di dati a lunghezza variabile e lateCorr dichiara il parametro size dopo di esso. L'uso della corrispondenza anticipata migliora le prestazioni complessivamente, soprattutto nei casi in cui il metodo viene chiamato frequentemente.
Per i parametri contrassegnati con la tupla dell'attributo [out, size_is] e dove la lunghezza dei dati è nota sul lato client o in cui il client ha un limite superiore ragionevole, la definizione del metodo deve essere simile alla seguente in termini di attribuzione e sequenza di parametri:
outKnownSize ( [in,range(MIN_COUNT, MAX_COUNT)] long lSize, [out,size_is(lSize)] UserDataType * pArr );
In questo caso, il client fornisce un buffer a dimensione fissa per pArr, consentendo al servizio RPC lato server di allocare un buffer di dimensioni ragionevoli con un buon grado di garanzia. Si noti che nell'esempio i dati sono ricevuti dal server ([out]). La definizione è simile per i dati passati al server ([in]).
Per le situazioni in cui il componente lato server di un'applicazione RPC determina la lunghezza dei dati, la definizione del metodo deve essere simile alla seguente:
typedef [range(MIN_COUNT,MAX_COUNT)] long RANGED_LONG; outUnknownSize ( [out] RANGED_LONG *pSize, [out,size_is(,*pSize)] UserDataType **ppArr );
RANGED_LONG è un tipo definito per gli stub client e server e di una dimensione specificata che il client può prevedere correttamente. Nell'esempio il client passa ppArr come NULL e il componente applicazione server RPC alloca la quantità di memoria corretta. Al termine, il servizio RPC sul lato client alloca la memoria per i dati restituiti.
Se il client vuole inviare un subset di una matrice conforme di grandi dimensioni al server, l'applicazione può specificare le dimensioni del subset, come illustrato nell'esempio seguente:
inConformantVaryingArray ( [in,range(MIN_COUNT,MAX_COUNT)] long lSize, [in] long lLength, [in,size_is(lSize), length_is(lLength)] UserDataType *pArr );
In questo modo RPC trasmetterà solo gli elementi lLength della matrice attraverso il filo. Tuttavia, questa definizione forza il servizio RPC ad allocare memoria di dimensioni lSize sul lato server.
Se il componente dell'applicazione client determina le dimensioni massime di una matrice che il server può restituire, ma consente al server di trasmettere un subset di tale matrice, l'applicazione può specificare tale comportamento definendo l'IDL simile all'esempio seguente:
inMaxSizeOutLength ( [in, range(MIN_COUNT, MAX_COUNT)] long lSize, [out] long *pLength, [out,size_is(lSize), length_is(*pLength)] UserDataType *pArr );
Il componente applicazione client specifica le dimensioni massime della matrice e il server specifica il numero di elementi che trasmette al client.
Se il componente dell'applicazione server deve restituire una stringa al componente applicazione client e se il client conosce le dimensioni massime da restituire dal server, l'applicazione può usare un tipo stringa conforme, come illustrato nell'esempio seguente:
outStringKnownSize ( [in,range(MIN_COUNT, MAX_STRING)] long lSize, [out,size_is(lSize),string] wchar_t *pString );
Se il componente dell'applicazione client non deve controllare le dimensioni della stringa, il servizio RPC può allocare specificamente la memoria, come illustrato nell'esempio seguente:
outStringUnknownSize ( [out] LPWSTR *ppStr );
Il componente dell'applicazione client deve impostare ppStr su NULL quando si chiama il metodo RPC.