2010-08-09 11 views
6

Sto usando Delphi 2010 e il mio programma vuole ottenere il percorso temp del sistema. Sto usando TPath.GetTempPath e tutto sta funzionando bene ... almeno per me e per i miei colleghi. Ma su alcune macchine clienti questo metodo restituisce un percorso ritagliato che (ovviamente) non esiste. Ho scoperto che il problema sembra essere il risultato della chiamata sottostante a GetLongPathName().Delphi Il risultato TPath.GetTempPath è ritagliato

Il codice completo è simile al seguente:

[...] 
var 
TmpDir : String; 
Len : Integer; 
begin 

[... Call to GetTempPath succeeds and we have a valid temp directory in short "~" notation in var TmpDir ...] 

Len := GetLongPathName(PChar(TmpDir), nil, 0);  // Len = 37 
    SetLength(TmpDir, Len - 1);       // We want to set the len of TmpDir to 37 - 1. 
    GetLongPathName(PChar(TmpDir), PChar(TmpDir), Len); // Only 32 (instead of 36) characters are copied - so we have a cropped path - But why?! 

end; 
[...] 

Ciò accade soltanto su alcuni sistemi e non so perché. Ho trovato una brutta soluzione per questo, ma mi piacerebbe sapere cosa sta succedendo qui.

Qualcuno può far luce su questo?

+0

Puoi fornirci esempi dei nomi dei percorsi corretti (previsti) e negativi (effettivi)? Potrebbe essere un problema Unicode o di codifica? –

+0

Abbiamo pensato anche al primo posto, ma i nomi dei percorsi non contengono caratteri che potrebbero causare problemi con le conversioni Unicode. Il nome del percorso risultato di GetLongPathName manca solo degli ultimi 4 caratteri ("emp \" di "Temp \") - tutti gli altri caratteri sono validi. – Patrick

+0

Suoni come http://qc.embarcadero.com/wc/qcmain.aspx?d=92006 –

risposta

4

C'è una nota su questa funzione API di Windows sulle pagine Homeland Security:

"Il buffer di cambio di GetLongPathName() e simili funzioni potrebbe restituire un tronco percorso e portare a difficili da -Trova gli errori. "

https://buildsecurityin.us-cert.gov/bsi-rules/home/g1/753-BSI.html

Se hai il codice sorgente, si potrebbe verificare se il problema descritto in questo articolo esiste nell'implementazione Delphi 2010.

+0

Hai ragione, ho trovato anche questo e la mia "brutta soluzione" è impostare inizialmente Len su MAX_PATH e verificare il risultato di GetLongPathName(), ma mi chiedo perché Embarcadero stia usando l'altro approccio ... ma grazie per aver postato questo, perché ha verificato il mio approccio. – Patrick

+0

Si dovrebbe segnalare questo a QC. –

+1

Quindi qual è il problema? Il codice nella domanda chiama correttamente la funzione due volte, vero? Una volta per scoprire la lunghezza richiesta e poi una seconda volta per riempire il buffer per davvero. Il codice che cite alloca prima il buffer in modo che la prima chiamata alla funzione possa funzionare, ma se fallisce, alloca un nuovo buffer e lo usa al suo posto. È davvero una differenza importante? L'articolo mette in guardia dal presupporre che la prima chiamata avrà sempre esito positivo se viene fornito un buffer di dimensioni MAX_PATH. Come si applica questo avviso a questa situazione? –

3

Cosa succede se si prova:

var 
    longpath : string; 

SetLength(longpath,MAX_PATH); 
SetLength(longpath, GetLongPathName(PChar(TmpDir),PChar(LongPath),MAX_PATH)); 

Questo ha funzionato per me, la vostra versione troncata del percorso.

+0

Ecco cosa sto facendo nella mia "soluzione alternativa" - se il problema si verifica sulla tua macchina: sarebbe interessante se la funzione TPath.GetTempPath() funzioni per te? – Patrick

+1

Questo codice potrebbe lasciare una stringa più lunga di Max_Path, ma con solo i caratteri Max_Path assegnati. Cioè, 'Lunghezza (longpath)> StrLen (PChar (longpath))'. Si potrebbe anche essere lasciati con una stringa con garbage in esso - i documenti non dicono ciò che la funzione memorizza nel buffer quando il buffer è troppo piccolo. Il bollettino sulla sicurezza e la documentazione descrivono entrambi il modo di evitare questo problema. –

+0

Ok, dovremmo menzionare qui, che il valore di ritorno di GetLongPathName è importante e dovrebbe essere controllato. – Patrick

Problemi correlati