Decoding SkypeIdentityList Clipboard Data Using Qt

Whilst working on SocialClient (one of my numerous projects), I decided that I wanted to provide users with the ability to import Skype contact usernames from the clipboard (or via drag-and-drop), whilst using the Contact Builder dialogue:

Contact Builder UI

After briefly spending time searching the Web, I stumbled across an old post on the Skype fora (which happens to be the sole Google search result for “SkypeIdentityList“, at the moment), where someone requested information regarding the content of clipboard data generated by the Skype client – and provided some useful pointers for my own exploration.

With that knowledge in mind, I then obtained a copy of the Microsoft ClipBook Viewer (which doesn’t ship with Windows 7), and had a look at its “View” menu, after copying a random contact from the client’s contact list:

ClipBook Viewer

Saving the file, and then opening it with a hex editor (I used PSPad’s “Open in Hex Editor” feature – but any will suffice) revealed that the clipboard data was UTF-16-encoded text:

I initially planned to utilise QString‘s fromUtf16() method. However, further investigation lead me to believe that it was worse than useless in this case – since all that I had was the aforementioned opaque blob of data, which consisted of a header denoting the size of the following text payload, and I couldn’t find a way to convert it into the necessary format (a pointer to an unsigned, short integer; and a standard integer).

After much deliberation, and testing various potential solutions (some of which involved extracting the length data, and using it whilst iterating over the rest of the payload) that often resulted in dismal failure – involving either receiving C++ runtime assertions after attempting to access non-existent data within an array, or simply obtaining too little data to be useful, I settled upon a variant of the following solution:

QString Skype::FetchUsernameFromClipboard() {

QClipboard *clipboard = QApplication::clipboard();

if (clipboard->mimeData(QClipboard::Clipboard)
     ->data("SkypeIdentityList").length() != 0) {
QByteArray mimeData =
clipboard->mimeData(QClipboard::Clipboard)
     ->data("SkypeIdentityList");
return Skype::ParseClipboardData(mimeData);
}

else

{
return "";
}
}

QString Skype::ParseClipboardData(QByteArray aRawData) {
QByteArray workingData = aRawData;
int stringSize = aRawData.at(0);
int pos = 0;

QString round1Data, round2Data;
char tempChar;

QMap charMap;

qDebug() << "Got data:" << aRawData.toHex() <<
    "of internal length" << QString::number(stringSize);
qDebug() << "Size of array after filling is" << aRawData.size();

for (pos = 0; pos < aRawData.length() - 5; pos++) {
tempChar = workingData.at(pos + 2 + 2);
qDebug() << pos << tempChar;
round1Data = round1Data + tempChar;
}

qDebug() << "Processed data is " << round1Data.size();

for (pos = 0; pos < round1Data.size() ; pos++) {
int notNull;

if (!round1Data.at(pos).isNull()) {
notNull = pos;
qDebug() << "NOT A NULL: " << round1Data.at(pos)
   << "AT: " << pos;
charMap.insert(notNull, round1Data.at(pos));
}
}

foreach (QChar value, charMap)
round2Data = round2Data + value;

return round2Data.simplified();
}

The aforementioned implementation produces the following output, when used in conjunction with the demo method:

Got data: "070000006500630068006f00310032003300" of
    internal length "7"
Size of array after filling is 18
0 e
1
2 c
3
4 h
5
6 o
7
8 1
9
10 2
11
12 3
Processed data is 13
NOT A NULL: 'e' AT: 0
NOT A NULL: 'c' AT: 2
NOT A NULL: 'h' AT: 4
NOT A NULL: 'o' AT: 6
NOT A NULL: '1' AT: 8
NOT A NULL: '2' AT: 10
NOT A NULL: '3' AT: 12
"echo123"

Of course, code that triggers FetchUsernameFromClipboard() (or ParseClipboardData() itself) is also necessary – and the FetchUsernameFromClipboard() demo function doesn’t even exist within the SocialClient codebase; but that should give a good idea as to how I implemented this.

It probably isn’t the most efficient technique ever, either…

Still, as always, please feel free to comment and make alternative suggestions.

Advertisements
Explore posts in the same categories: Everything

Tags: , , , , , , , , , , , , ,

You can comment below, or link to this permanent URL from your own site.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: