Salin file dari volume TrueCrypt ke clipboard?

Saya menggunakan kode ini untuk menyalin file ke Clipboard:

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);

Sayangnya, ini tidak berfungsi jika disk merupakan volume yang dipasang TrueCrypt. Apa cara untuk melakukan ini pada volume TrueCrypt?


person Ivan Ičin    schedule 02.02.2011    source sumber
comment
Selamat atas abadmu :)   -  person Javed Akram    schedule 02.02.2011
comment
bagaimana tepatnya itu tidak berhasil? apakah itu muncul di penampil clipboard?   -  person fejesjoco    schedule 02.02.2011


Jawaban (1)


Sayangnya, menurut saya Anda tidak dapat lolos tanpa daftar ID Shell yang tepat, di Windows 7 saya, kode Anda bahkan tidak berfungsi dengan sistem file biasa. Kode yang tepat pertama-tama dan terutama akan menyediakan 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);

Dimana CreateShellIDList membuat representasi biner dari struktur CIDA (CFSTR_SHELLIDLIST) yang diperlukan. Implementasinya di bawah ini:

[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;
}

Saya tidak dapat mengambil semua kredit di sini, saya menemukan kode CIDA ini beberapa waktu lalu dan baru saja mem-portingnya ke c#. Saya tidak dapat mengingat sumber aslinya tetapi sejauh ini berfungsi dengan baik (saya baru saja mengujinya di TrueCrypt juga)

person mmix    schedule 07.02.2011
comment
Terima kasih atas jawabannya, saya akan memeriksanya (perlu menginstal TrueCrypt di komputer ini terlebih dahulu. Lagi pula, kode saya berfungsi di Winodws 7 Professional, saya baru saja copy paste dan mengujinya, tapi itu kurang penting. - person Ivan Ičin; 08.02.2011
comment
Berhasil, saya tahu bahwa sesuatu yang mempertimbangkan pengaturan lokasi Shell harus dilakukan, tetapi tidak dapat menemukan apa pun di dalamnya. - person Ivan Ičin; 08.02.2011
comment
Pengembang asli implementasi C++ dari CreateShellIDList adalah Pascal Hurni. - person pcunite; 26.04.2014