Non Vista più rigorose di controllo di Id di Interfaccia DCOM chiamate?(Stub di cattiva ricezione Dati)?

StackOverflow https://stackoverflow.com/questions/63720

  •  09-06-2019
  •  | 
  •  

Domanda

Spero che tutti si perdono per la lunghezza, e la narrazione di moda, di questa domanda.Ho deciso di descrivere la situazione in dettaglio nel mio blog.Poi ho visto Joel invito a questo sito e ho pensato di incollare qui per vedere se qualcuno ha spaccato la situazione.

Ho scritto, e ora supporto, un'applicazione che consiste di un Visual Basic client spesso parlare DCOM per il livello medio di componenti COM+ scritto in C++ utilizzando ATL.Funziona in tutti e otto i nostri uffici.In ogni ufficio, ospita un server back-end che contiene l'applicazione COM+ (composto da 18 componenti separati) e SQLServer.Sql server è in genere sullo stesso server back-end, ma non è necessario.

Abbiamo recentemente migrato il server back-end in nostra più grande ufficio di New York -- da MSC cluster per una nuova macchina virtuale ospitato su VMWare ESX tecnologia.Dal momento che la posizione dell'applicazione COM+ era trasferito dal vecchio server al nuovo con un nome diverso, ho avuto per reindirizzare tutti i clienti che hanno attivato l'applicazione COM+ sul nuovo server.La procedura è stata cappello vecchio, come avevo fatto essenzialmente la stessa cosa per molti dei miei piccoli uffici che aveva attraversato simili infrastrutture.

Tutto sembrava routine e lunedì mattina, l'intero ufficio -- circa 1.000 le workstation Windows XP -- in esecuzione senza problemi sul nuovo server.Ma poi è arrivata la chiamata dal mio cellulare gruppo-c'era un avvocato che lavora da casa con una connessione VPN che è stato sempre uno strano errore dopo essere stato reindirizzato al nuovo server:

Error on FillTreeView2 - The stub received bad data.

Eh?Non avevo mai visto questo messaggio di errore prima.Era il nuovo server?Ma tutte le postazioni di lavoro in ufficio erano a lavorare bene.Ho detto che il gruppo mobile per passare il procuratore di nuovo al vecchio server (che era ancora), e l'errore è scomparso.Così che cosa è la differenza?Si scopre che questo avvocato era in esecuzione Vista a casa.

La nostra non è Vista in uno dei nostri uffici, ma ci sono alcuni avvocati che eseguono Vista a casa (certo un po ' nel mio ufficio di New York).Faccio così e non ho mai visto questo problema.Per confermare che c'è stato un problema, ho sparato il mio portatile Vista, puntata verso il nuovo server, e ha ottenuto lo stesso errore.Ho fatto ritorno al vecchio server, e ha funzionato bene.Chiaramente c'è stato qualche problema con Vista e i componenti sul nuovo server -- un problema che non sembrano influenzare i clienti XP.Cosa potrebbe essere?

Prossima fermata -- l'applicazione di errore del registro sul mio portatile.Questo ha reso più informazioni sull'errore:

Source:        Microsoft-Windows-RPC-Events
Date:          9/2/2008 11:56:07 AM
Event ID:      10
Level:         Error
Computer:      DevLaptop
Description:   Application has failed to complete a COM call because an incorrect
interface ID was passed as a parameter.

The expected Interface ID was 00000555-0000-0010-8000-00aa006d2ea4, 
The Interface ID returned was 00000556-0000-0010-8000-00aa006d2ea4.

User Action - Contact the application vendor for updated version of the application.

L'id di interfaccia fornito l'indizio che ho bisogno di svelare il mistero.Il "previsto" id interfaccia identifica MDAC Recordset interfaccia, nello specifico la versione 2.1 di tale interfaccia.Il "ritorno" interfaccia corrisponde a una versione successiva del Recordset (versione 2.5, che differisce dalla versione 2.1 con l'inserimento di una ulteriore voce alla fine della vtable -- metodo di Salvataggio).

In effetti il mio interfacce del componente esporre molti metodi che passano Recordset come un parametro di output.Erano improvvisamente la restituzione di una versione successiva di Recordset -- con un'interfaccia diversa id?Certamente sembrava essere il caso.E poi ho pensato, perché, poco importa.La vtable sembra la stessa, per i clienti di vecchia interfaccia.Anzi, ho il sospetto che se stessimo parlando di COM in-process, e non DCOM, questo apparentemente innocuo mancata corrispondenza di impedenza sarebbe stata ignorata e non avrebbe causato nessun problema.

Naturalmente, quando il processo e la macchina confini entrano in gioco, c'è un proxy e stub tra il client e il server.In questo caso, ho utilizzato un tipo di libreria di marshalling con la connessione filettata gestore di marshalling.Quindi c'erano due misteri da risolvere:

"Perché io e la restituzione di un interfaccia diversa nei parametri di output da metodi sul mio nuovo server?

Perché ha fatto questo effetto solo client Vista?

Come il mio software del server è ospitato su server a ciascuno dei miei otto uffici, ho deciso di provare a indirizzare il mio client di Vista a tutti loro in sequenza per vedere che aveva problemi con Vista e che non.Illuminante test.Alcuni dei vecchi server ancora lavorato con Vista, ma quelli più recenti non.Anche se alcuni dei vecchi server erano ancora in esecuzione Windows 2000, mentre quelli più recenti sono stati al 2003, che non sembra essere il problema.

Dopo aver confrontato le date delle Dll del componente sembrava che ogni volta che il client ha sottolineato server con Dll del componente datato prima del 2003 Vista è stato bene.Ma quelli che avevano Dll con date dopo il 2003 sono stati problematici.Credere o non, non c'erano (o almeno non significativo) le modifiche al codice del server di componenti in molti anni.A quanto pare le diverse date sono state semplicemente a causa di ricompilazioni dei componenti sulla mia macchina di sviluppo(s).E sembrava che uno di quei ricompila accaduto nel 2003.

La lampadina si è accesa.Quando si passa al Recordset dal server al client, il mio ATL C++ componenti fare riferimento per l'interfaccia come _Recordset.Questo simbolo deriva dal tipo di libreria incorporata all'interno di msado15.dll.Questa è la linea che ho avuto il codice C++:

#import "c:\Program Files\Common Files\System\ADO\msado15.dll" no_namespace rename ( "EOF", "adoEOF" )

Non essere ingannati dalle 15 in msdad15.dll.A quanto pare questa DLL non è cambiato nome nella lunga serie delle versioni di MDAC.

Quando ho compilato la domanda indietro nel giorno, la versione di MDAC è stato 2.1.Così _Recordset compilato con la 2.1 id di interfaccia e che è l'interfaccia restituito dal server per l'esecuzione di tali componenti.

Tutti i client di utilizzare l'applicazione COM+ che è stato generato (credo) nel 1999.Il tipo di libreria che definisce la mia interfacce include la riga:

importlib("msado21.tlb");

il che spiega perché si aspettano la versione 2.1 del Recordset nel mio metodo e i parametri di output.Chiaramente il problema è stato con la mia 2003 ricompilare e il fatto che a quel tempo la _Recordset simbolo non più rispondenti alla versione 2.1.Infatti _Recordset corrisponde alla versione 2.5, con la sua inconfondibile id di interfaccia.La soluzione per me è stato quello di modificare tutti i riferimenti da _Recordset per Recordset21 nel mio codice C++.Ho ricostruito i componenti e schierate per il nuovo server.Voilà -- i clienti sembrava di nuovo felice.

In conclusione, ci sono due assillanti domande che rimangono per me.

Perché il proxy/stub infrastrutture sembrano comportarsi in modo diverso con Vista?Sembra che Vista sta facendo controlli più severi dell'id di interfaccia di ritorno da parametri di metodo rispetto a XP.

Come dovrebbe ho scritto questo in modo diverso nel 1999 in modo che questo non sarebbe successo?Le interfacce sono supposti per essere immutabile e quando ho ricompilato in una versione più recente di MDAC, ho inavvertitamente cambiato la mia interfaccia, perché i metodi che ora è tornato a una diversa interfaccia di Recordset come un parametro di output.Per quanto ne so, il libreria dei tipi allora non dispone di una versione specifica simbolo -- che è, le successive versioni di MDAC tipo di librerie definire Recordset21, ma quel simbolo non era disponibile tra il 2,1 e il tipo di raccolta.

È stato utile?

Soluzione

Quando Microsoft ha avuto la sicurezza di religione, DCOM (e il sottostante RPC) ha ottenuto un sacco di attenzione, e sicuramente non ci sono state modifiche apportate a chiudere le falle di sicurezza che hanno portato più rigorose di marshalling.Mi sorprende è vedere questo in Vista, ma non in XP, ma la sua possibile che ulteriori controlli sono stati aggiunti per Vista.In alternativa, e ' possibile che opzionale rigore in XP è stata resa obbligatoria in Vista.

Mentre io non so abbastanza di MDAC sapere se si potrebbe avere impedito questo, so che la sicurezza è uno dei pochi settori in cui Microsoft è abbastanza disposti a sacrificare la compatibilità, quindi è possibile che si potrebbe non aver fatto nulla di "meglio" nel 1999.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top