2011-02-02 13 views
6

Io uso questo codice per copiare i file negli Appunti:Copia il file dal volume TrueCrypt negli appunti?

IDataObject data = new DataObject(); 
data.SetData(DataFormats.FileDrop, new string[] {@"X:\test.doc"}); 
MemoryStream memo = new MemoryStream(4); 
byte[] bytes = new byte[] { (byte)(5), 0, 0, 0 }; 
memo.Write(bytes, 0, bytes.Length); 
data.SetData("Preferred DropEffect", memo); 
Clipboard.SetDataObject(data); 

Purtroppo, questo non funziona se il disco è un volume montato TrueCrypt. Qual è il modo di farlo su un volume TrueCrypt?

+0

Buona domanda +1. – Shoban

+0

Congratulazioni per il tuo secolo :) –

+2

come funziona esattamente? è presente nel visualizzatore di appunti? – fejesjoco

risposta

5

Sfortunatamente, non penso che tu possa andare via senza un adeguato elenco ID shell, sul mio Windows 7 il tuo codice non funziona nemmeno con il normale file system. Il codice corretto sarebbe prima di tutto fornire una CIDL:

var data = new DataObject(); 
    var files = new StringCollection() { @"T:\Test.doc" }; 
    data.SetFileDropList(files); 
    data.SetData("Preferred DropEffect", true, new MemoryStream(new byte[] { 5, 0, 0, 0 })); 
    data.SetData("Shell IDList Array", true, CreateShellIDList(files)); 
    Clipboard.SetDataObject(data, true); 

Dove CreateShellIDList crea una rappresentazione binaria di CIDA (CFSTR_SHELLIDLIST) struttura necessaria. L'implementazione è qui sotto:

[DllImport("shell32.dll", CharSet = CharSet.Auto)] 
public static extern IntPtr ILCreateFromPath(string path); 
[DllImport("shell32.dll", CharSet = CharSet.None)] 
public static extern void ILFree(IntPtr pidl); 
[DllImport("shell32.dll", CharSet = CharSet.None)] 
public static extern int ILGetSize(IntPtr pidl); 

private static MemoryStream CreateShellIDList(StringCollection filenames) 
{ 
    // first convert all files into pidls list 
    int pos = 0; 
    byte[][] pidls = new byte[filenames.Count][]; 
    foreach (var filename in filenames) 
    { 
     // Get pidl based on name 
     IntPtr pidl = ILCreateFromPath(filename); 
     int pidlSize = ILGetSize(pidl); 
     // Copy over to our managed array 
     pidls[pos] = new byte[pidlSize]; 
     Marshal.Copy(pidl, pidls[pos++], 0, pidlSize); 
     ILFree(pidl); 
    } 

    // Determine where in CIDA we will start pumping PIDLs 
    int pidlOffset = 4 * (filenames.Count + 2); 
    // Start the CIDA stream stream 
    var memStream = new MemoryStream(); 
    var sw = new BinaryWriter(memStream); 
    // Initialize CIDA witha count of files 
    sw.Write(filenames.Count); 
    // Calcualte and write relative offsets of every pidl starting with root 
    sw.Write(pidlOffset); 
    pidlOffset += 4; // root is 4 bytes 
    foreach(var pidl in pidls) 
    { 
     sw.Write(pidlOffset); 
     pidlOffset += pidl.Length; 
    } 

    // Write the root pidl (0) followed by all pidls 
    sw.Write(0); 
    foreach(var pidl in pidls) sw.Write(pidl); 
    // stream now contains the CIDA 
    return memStream; 
} 

non posso prendere tutto il merito qui, ho trovato questo codice CIDA qualche tempo fa e solo il porting in C#. Non riesco a ricordare la fonte originale ma funziona bene finora (l'ho appena testato su TrueCrypt)

+0

Per la risposta, controllerò (prima devo installare TrueCrypt su questo computer.Ma il mio codice funziona su Winodws 7 Professional, ho appena fatto copia e collaudo, ma è meno importante. –

+0

Beh, funziona , Sapevo che qualcosa in attesa di impostare le posizioni di Shell doveva essere fatto, ma non riuscivo a trovare nulla su di esso –

+0

Lo sviluppatore originale dell'implementazione C++ di CreateShellIDList era Pascal Hurni. – pcunite