widget/windows/tests/TestWinDND.cpp

Thu, 15 Jan 2015 15:59:08 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:59:08 +0100
branch
TOR_BUG_9701
changeset 10
ac0c01689b40
permissions
-rw-r--r--

Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5 #define MOZILLA_INTERNAL_API
michael@0 6
michael@0 7 #include <ole2.h>
michael@0 8 #include <shlobj.h>
michael@0 9
michael@0 10 #include "TestHarness.h"
michael@0 11 #include "nsIArray.h"
michael@0 12 #include "nsIFile.h"
michael@0 13 #include "nsNetUtil.h"
michael@0 14 #include "nsISupportsPrimitives.h"
michael@0 15 #include "nsIFileURL.h"
michael@0 16 #include "nsITransferable.h"
michael@0 17 #include "nsClipboard.h"
michael@0 18 #include "nsDataObjCollection.h"
michael@0 19
michael@0 20 nsIFile* xferFile;
michael@0 21
michael@0 22 nsresult CheckValidHDROP(STGMEDIUM* pSTG)
michael@0 23 {
michael@0 24 if (pSTG->tymed != TYMED_HGLOBAL) {
michael@0 25 fail("Received data is not in an HGLOBAL");
michael@0 26 return NS_ERROR_UNEXPECTED;
michael@0 27 }
michael@0 28
michael@0 29 HGLOBAL hGlobal = pSTG->hGlobal;
michael@0 30 DROPFILES* pDropFiles;
michael@0 31 pDropFiles = (DROPFILES*)GlobalLock(hGlobal);
michael@0 32 if (!pDropFiles) {
michael@0 33 fail("There is no data at the given HGLOBAL");
michael@0 34 return NS_ERROR_UNEXPECTED;
michael@0 35 }
michael@0 36
michael@0 37 if (pDropFiles->pFiles != sizeof(DROPFILES))
michael@0 38 fail("DROPFILES struct has wrong size");
michael@0 39
michael@0 40 if (pDropFiles->fWide != true) {
michael@0 41 fail("Received data is not Unicode");
michael@0 42 return NS_ERROR_UNEXPECTED;
michael@0 43 }
michael@0 44 nsString s;
michael@0 45 unsigned long offset = 0;
michael@0 46 while (1) {
michael@0 47 s = (char16_t*)((char*)pDropFiles + pDropFiles->pFiles + offset);
michael@0 48 if (s.IsEmpty())
michael@0 49 break;
michael@0 50 nsresult rv;
michael@0 51 nsCOMPtr<nsIFile> localFile(
michael@0 52 do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv));
michael@0 53 rv = localFile->InitWithPath(s);
michael@0 54 if (NS_FAILED(rv)) {
michael@0 55 fail("File could not be opened");
michael@0 56 return NS_ERROR_UNEXPECTED;
michael@0 57 }
michael@0 58 offset += sizeof(char16_t) * (s.Length() + 1);
michael@0 59 }
michael@0 60 return NS_OK;
michael@0 61 }
michael@0 62
michael@0 63 nsresult CheckValidTEXT(STGMEDIUM* pSTG)
michael@0 64 {
michael@0 65 if (pSTG->tymed != TYMED_HGLOBAL) {
michael@0 66 fail("Received data is not in an HGLOBAL");
michael@0 67 return NS_ERROR_UNEXPECTED;
michael@0 68 }
michael@0 69
michael@0 70 HGLOBAL hGlobal = pSTG->hGlobal;
michael@0 71 char* pText;
michael@0 72 pText = (char*)GlobalLock(hGlobal);
michael@0 73 if (!pText) {
michael@0 74 fail("There is no data at the given HGLOBAL");
michael@0 75 return NS_ERROR_UNEXPECTED;
michael@0 76 }
michael@0 77
michael@0 78 nsCString string;
michael@0 79 string = pText;
michael@0 80
michael@0 81 if (!string.Equals(NS_LITERAL_CSTRING("Mozilla can drag and drop"))) {
michael@0 82 fail("Text passed through drop object wrong");
michael@0 83 return NS_ERROR_UNEXPECTED;
michael@0 84 }
michael@0 85 return NS_OK;
michael@0 86 }
michael@0 87
michael@0 88 nsresult CheckValidTEXTTwo(STGMEDIUM* pSTG)
michael@0 89 {
michael@0 90 if (pSTG->tymed != TYMED_HGLOBAL) {
michael@0 91 fail("Received data is not in an HGLOBAL");
michael@0 92 return NS_ERROR_UNEXPECTED;
michael@0 93 }
michael@0 94
michael@0 95 HGLOBAL hGlobal = pSTG->hGlobal;
michael@0 96 char* pText;
michael@0 97 pText = (char*)GlobalLock(hGlobal);
michael@0 98 if (!pText) {
michael@0 99 fail("There is no data at the given HGLOBAL");
michael@0 100 return NS_ERROR_UNEXPECTED;
michael@0 101 }
michael@0 102
michael@0 103 nsCString string;
michael@0 104 string = pText;
michael@0 105
michael@0 106 if (!string.Equals(NS_LITERAL_CSTRING("Mozilla can drag and drop twice over"))) {
michael@0 107 fail("Text passed through drop object wrong");
michael@0 108 return NS_ERROR_UNEXPECTED;
michael@0 109 }
michael@0 110 return NS_OK;
michael@0 111 }
michael@0 112
michael@0 113 nsresult CheckValidUNICODE(STGMEDIUM* pSTG)
michael@0 114 {
michael@0 115 if (pSTG->tymed != TYMED_HGLOBAL) {
michael@0 116 fail("Received data is not in an HGLOBAL");
michael@0 117 return NS_ERROR_UNEXPECTED;
michael@0 118 }
michael@0 119
michael@0 120 HGLOBAL hGlobal = pSTG->hGlobal;
michael@0 121 char16_t* pText;
michael@0 122 pText = (char16_t*)GlobalLock(hGlobal);
michael@0 123 if (!pText) {
michael@0 124 fail("There is no data at the given HGLOBAL");
michael@0 125 return NS_ERROR_UNEXPECTED;
michael@0 126 }
michael@0 127
michael@0 128 nsString string;
michael@0 129 string = pText;
michael@0 130
michael@0 131 if (!string.Equals(NS_LITERAL_STRING("Mozilla can drag and drop"))) {
michael@0 132 fail("Text passed through drop object wrong");
michael@0 133 return NS_ERROR_UNEXPECTED;
michael@0 134 }
michael@0 135 return NS_OK;
michael@0 136 }
michael@0 137
michael@0 138 nsresult CheckValidUNICODETwo(STGMEDIUM* pSTG)
michael@0 139 {
michael@0 140 if (pSTG->tymed != TYMED_HGLOBAL) {
michael@0 141 fail("Received data is not in an HGLOBAL");
michael@0 142 return NS_ERROR_UNEXPECTED;
michael@0 143 }
michael@0 144
michael@0 145 HGLOBAL hGlobal = pSTG->hGlobal;
michael@0 146 char16_t* pText;
michael@0 147 pText = (char16_t*)GlobalLock(hGlobal);
michael@0 148 if (!pText) {
michael@0 149 fail("There is no data at the given HGLOBAL");
michael@0 150 return NS_ERROR_UNEXPECTED;
michael@0 151 }
michael@0 152
michael@0 153 nsString string;
michael@0 154 string = pText;
michael@0 155
michael@0 156 if (!string.Equals(NS_LITERAL_STRING("Mozilla can drag and drop twice over"))) {
michael@0 157 fail("Text passed through drop object wrong");
michael@0 158 return NS_ERROR_UNEXPECTED;
michael@0 159 }
michael@0 160 return NS_OK;
michael@0 161 }
michael@0 162
michael@0 163 nsresult GetTransferableFile(nsCOMPtr<nsITransferable>& pTransferable)
michael@0 164 {
michael@0 165 nsresult rv;
michael@0 166
michael@0 167 nsCOMPtr<nsISupports> genericWrapper = do_QueryInterface(xferFile);
michael@0 168
michael@0 169 pTransferable = do_CreateInstance("@mozilla.org/widget/transferable;1");
michael@0 170 pTransferable->Init(nullptr);
michael@0 171 rv = pTransferable->SetTransferData("application/x-moz-file", genericWrapper,
michael@0 172 0);
michael@0 173 return rv;
michael@0 174 }
michael@0 175
michael@0 176 nsresult GetTransferableText(nsCOMPtr<nsITransferable>& pTransferable)
michael@0 177 {
michael@0 178 nsresult rv;
michael@0 179 NS_NAMED_LITERAL_STRING(mozString, "Mozilla can drag and drop");
michael@0 180 nsCOMPtr<nsISupportsString> xferString =
michael@0 181 do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID);
michael@0 182 rv = xferString->SetData(mozString);
michael@0 183 NS_ENSURE_SUCCESS(rv, rv);
michael@0 184
michael@0 185 nsCOMPtr<nsISupports> genericWrapper = do_QueryInterface(xferString);
michael@0 186
michael@0 187 pTransferable = do_CreateInstance("@mozilla.org/widget/transferable;1");
michael@0 188 pTransferable->Init(nullptr);
michael@0 189 rv = pTransferable->SetTransferData("text/unicode", genericWrapper,
michael@0 190 mozString.Length() * sizeof(char16_t));
michael@0 191 return rv;
michael@0 192 }
michael@0 193
michael@0 194 nsresult GetTransferableTextTwo(nsCOMPtr<nsITransferable>& pTransferable)
michael@0 195 {
michael@0 196 nsresult rv;
michael@0 197 NS_NAMED_LITERAL_STRING(mozString, " twice over");
michael@0 198 nsCOMPtr<nsISupportsString> xferString =
michael@0 199 do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID);
michael@0 200 rv = xferString->SetData(mozString);
michael@0 201 NS_ENSURE_SUCCESS(rv, rv);
michael@0 202
michael@0 203 nsCOMPtr<nsISupports> genericWrapper = do_QueryInterface(xferString);
michael@0 204
michael@0 205 pTransferable = do_CreateInstance("@mozilla.org/widget/transferable;1");
michael@0 206 pTransferable->Init(nullptr);
michael@0 207 rv = pTransferable->SetTransferData("text/unicode", genericWrapper,
michael@0 208 mozString.Length() * sizeof(char16_t));
michael@0 209 return rv;
michael@0 210 }
michael@0 211
michael@0 212 nsresult GetTransferableURI(nsCOMPtr<nsITransferable>& pTransferable)
michael@0 213 {
michael@0 214 nsresult rv;
michael@0 215
michael@0 216 nsCOMPtr<nsIURI> xferURI;
michael@0 217
michael@0 218 rv = NS_NewURI(getter_AddRefs(xferURI), "http://www.mozilla.org");
michael@0 219 NS_ENSURE_SUCCESS(rv, rv);
michael@0 220
michael@0 221 nsCOMPtr<nsISupports> genericWrapper = do_QueryInterface(xferURI);
michael@0 222
michael@0 223 pTransferable = do_CreateInstance("@mozilla.org/widget/transferable;1");
michael@0 224 pTransferable->Init(nullptr);
michael@0 225 rv = pTransferable->SetTransferData("text/x-moz-url", genericWrapper, 0);
michael@0 226 return rv;
michael@0 227 }
michael@0 228
michael@0 229 nsresult MakeDataObject(nsISupportsArray* transferableArray,
michael@0 230 nsRefPtr<IDataObject>& itemToDrag)
michael@0 231 {
michael@0 232 nsresult rv;
michael@0 233 uint32_t itemCount = 0;
michael@0 234
michael@0 235 nsCOMPtr<nsIURI> uri;
michael@0 236 rv = NS_NewURI(getter_AddRefs(uri), "http://www.mozilla.org");
michael@0 237 NS_ENSURE_SUCCESS(rv, rv);
michael@0 238
michael@0 239 rv = transferableArray->Count(&itemCount);
michael@0 240 NS_ENSURE_SUCCESS(rv, rv);
michael@0 241
michael@0 242 // Copied more or less exactly from nsDragService::InvokeDragSession
michael@0 243 // This is what lets us play fake Drag Service for the test
michael@0 244 if (itemCount > 1) {
michael@0 245 nsDataObjCollection * dataObjCollection = new nsDataObjCollection();
michael@0 246 if (!dataObjCollection)
michael@0 247 return NS_ERROR_OUT_OF_MEMORY;
michael@0 248 itemToDrag = dataObjCollection;
michael@0 249 for (uint32_t i=0; i<itemCount; ++i) {
michael@0 250 nsCOMPtr<nsISupports> supports;
michael@0 251 transferableArray->GetElementAt(i, getter_AddRefs(supports));
michael@0 252 nsCOMPtr<nsITransferable> trans(do_QueryInterface(supports));
michael@0 253 if (trans) {
michael@0 254 nsRefPtr<IDataObject> dataObj;
michael@0 255 rv = nsClipboard::CreateNativeDataObject(trans,
michael@0 256 getter_AddRefs(dataObj), uri);
michael@0 257 NS_ENSURE_SUCCESS(rv, rv);
michael@0 258 // Add the flavors to the collection object too
michael@0 259 rv = nsClipboard::SetupNativeDataObject(trans, dataObjCollection);
michael@0 260 NS_ENSURE_SUCCESS(rv, rv);
michael@0 261
michael@0 262 dataObjCollection->AddDataObject(dataObj);
michael@0 263 }
michael@0 264 }
michael@0 265 } // if dragging multiple items
michael@0 266 else {
michael@0 267 nsCOMPtr<nsISupports> supports;
michael@0 268 transferableArray->GetElementAt(0, getter_AddRefs(supports));
michael@0 269 nsCOMPtr<nsITransferable> trans(do_QueryInterface(supports));
michael@0 270 if (trans) {
michael@0 271 rv = nsClipboard::CreateNativeDataObject(trans,
michael@0 272 getter_AddRefs(itemToDrag),
michael@0 273 uri);
michael@0 274 NS_ENSURE_SUCCESS(rv, rv);
michael@0 275 }
michael@0 276 } // else dragging a single object
michael@0 277 return rv;
michael@0 278 }
michael@0 279
michael@0 280 nsresult Do_CheckOneFile()
michael@0 281 {
michael@0 282 nsresult rv;
michael@0 283 nsCOMPtr<nsITransferable> transferable;
michael@0 284 nsCOMPtr<nsISupportsArray> transferableArray;
michael@0 285 nsCOMPtr<nsISupports> genericWrapper;
michael@0 286 nsRefPtr<IDataObject> dataObj;
michael@0 287 rv = NS_NewISupportsArray(getter_AddRefs(transferableArray));
michael@0 288 if (NS_FAILED(rv)) {
michael@0 289 fail("Could not create the necessary nsISupportsArray");
michael@0 290 return rv;
michael@0 291 }
michael@0 292
michael@0 293 rv = GetTransferableFile(transferable);
michael@0 294 if (NS_FAILED(rv)) {
michael@0 295 fail("Could not create the proper nsITransferable!");
michael@0 296 return rv;
michael@0 297 }
michael@0 298 genericWrapper = do_QueryInterface(transferable);
michael@0 299 rv = transferableArray->AppendElement(genericWrapper);
michael@0 300 if (NS_FAILED(rv)) {
michael@0 301 fail("Could not append element to transferable array");
michael@0 302 return rv;
michael@0 303 }
michael@0 304
michael@0 305 rv = MakeDataObject(transferableArray, dataObj);
michael@0 306 if (NS_FAILED(rv)) {
michael@0 307 fail("Could not create data object");
michael@0 308 return rv;
michael@0 309 }
michael@0 310
michael@0 311 FORMATETC fe;
michael@0 312 SET_FORMATETC(fe, CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL);
michael@0 313 if (dataObj->QueryGetData(&fe) != S_OK) {
michael@0 314 fail("File data object does not support the file data type!");
michael@0 315 return NS_ERROR_UNEXPECTED;
michael@0 316 }
michael@0 317
michael@0 318 STGMEDIUM* stg;
michael@0 319 stg = (STGMEDIUM*)CoTaskMemAlloc(sizeof(STGMEDIUM));
michael@0 320 if (dataObj->GetData(&fe, stg) != S_OK) {
michael@0 321 fail("File data object did not provide data on request");
michael@0 322 return NS_ERROR_UNEXPECTED;
michael@0 323 }
michael@0 324
michael@0 325 rv = CheckValidHDROP(stg);
michael@0 326 if (NS_FAILED(rv)) {
michael@0 327 fail("HDROP was invalid");
michael@0 328 return rv;
michael@0 329 }
michael@0 330
michael@0 331 ReleaseStgMedium(stg);
michael@0 332
michael@0 333 return NS_OK;
michael@0 334 }
michael@0 335
michael@0 336 nsresult Do_CheckTwoFiles()
michael@0 337 {
michael@0 338 nsresult rv;
michael@0 339 nsCOMPtr<nsITransferable> transferable;
michael@0 340 nsCOMPtr<nsISupportsArray> transferableArray;
michael@0 341 nsCOMPtr<nsISupports> genericWrapper;
michael@0 342 nsRefPtr<IDataObject> dataObj;
michael@0 343 rv = NS_NewISupportsArray(getter_AddRefs(transferableArray));
michael@0 344 if (NS_FAILED(rv)) {
michael@0 345 fail("Could not create the necessary nsISupportsArray");
michael@0 346 return rv;
michael@0 347 }
michael@0 348
michael@0 349 rv = GetTransferableFile(transferable);
michael@0 350 if (NS_FAILED(rv)) {
michael@0 351 fail("Could not create the proper nsITransferable!");
michael@0 352 return rv;
michael@0 353 }
michael@0 354 genericWrapper = do_QueryInterface(transferable);
michael@0 355 rv = transferableArray->AppendElement(genericWrapper);
michael@0 356 if (NS_FAILED(rv)) {
michael@0 357 fail("Could not append element to transferable array");
michael@0 358 return rv;
michael@0 359 }
michael@0 360
michael@0 361 rv = GetTransferableFile(transferable);
michael@0 362 if (NS_FAILED(rv)) {
michael@0 363 fail("Could not create the proper nsITransferable!");
michael@0 364 return rv;
michael@0 365 }
michael@0 366 genericWrapper = do_QueryInterface(transferable);
michael@0 367 rv = transferableArray->AppendElement(genericWrapper);
michael@0 368 if (NS_FAILED(rv)) {
michael@0 369 fail("Could not append element to transferable array");
michael@0 370 return rv;
michael@0 371 }
michael@0 372
michael@0 373 rv = MakeDataObject(transferableArray, dataObj);
michael@0 374 if (NS_FAILED(rv)) {
michael@0 375 fail("Could not create data object");
michael@0 376 return rv;
michael@0 377 }
michael@0 378
michael@0 379 FORMATETC fe;
michael@0 380 SET_FORMATETC(fe, CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL);
michael@0 381 if (dataObj->QueryGetData(&fe) != S_OK) {
michael@0 382 fail("File data object does not support the file data type!");
michael@0 383 return NS_ERROR_UNEXPECTED;
michael@0 384 }
michael@0 385
michael@0 386 STGMEDIUM* stg;
michael@0 387 stg = (STGMEDIUM*)CoTaskMemAlloc(sizeof(STGMEDIUM));
michael@0 388 if (dataObj->GetData(&fe, stg) != S_OK) {
michael@0 389 fail("File data object did not provide data on request");
michael@0 390 return NS_ERROR_UNEXPECTED;
michael@0 391 }
michael@0 392
michael@0 393 rv = CheckValidHDROP(stg);
michael@0 394 if (NS_FAILED(rv)) {
michael@0 395 fail("HDROP was invalid");
michael@0 396 return rv;
michael@0 397 }
michael@0 398
michael@0 399 ReleaseStgMedium(stg);
michael@0 400
michael@0 401 return NS_OK;
michael@0 402 }
michael@0 403
michael@0 404 nsresult Do_CheckOneString()
michael@0 405 {
michael@0 406 nsresult rv;
michael@0 407 nsCOMPtr<nsITransferable> transferable;
michael@0 408 nsCOMPtr<nsISupportsArray> transferableArray;
michael@0 409 nsCOMPtr<nsISupports> genericWrapper;
michael@0 410 nsRefPtr<IDataObject> dataObj;
michael@0 411 rv = NS_NewISupportsArray(getter_AddRefs(transferableArray));
michael@0 412 if (NS_FAILED(rv)) {
michael@0 413 fail("Could not create the necessary nsISupportsArray");
michael@0 414 return rv;
michael@0 415 }
michael@0 416
michael@0 417 rv = GetTransferableText(transferable);
michael@0 418 if (NS_FAILED(rv)) {
michael@0 419 fail("Could not create the proper nsITransferable!");
michael@0 420 return rv;
michael@0 421 }
michael@0 422 genericWrapper = do_QueryInterface(transferable);
michael@0 423 rv = transferableArray->AppendElement(genericWrapper);
michael@0 424 if (NS_FAILED(rv)) {
michael@0 425 fail("Could not append element to transferable array");
michael@0 426 return rv;
michael@0 427 }
michael@0 428
michael@0 429 rv = MakeDataObject(transferableArray, dataObj);
michael@0 430 if (NS_FAILED(rv)) {
michael@0 431 fail("Could not create data object");
michael@0 432 return rv;
michael@0 433 }
michael@0 434
michael@0 435 FORMATETC fe;
michael@0 436 SET_FORMATETC(fe, CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL);
michael@0 437 if (dataObj->QueryGetData(&fe) != S_OK) {
michael@0 438 fail("String data object does not support the ASCII text data type!");
michael@0 439 return NS_ERROR_UNEXPECTED;
michael@0 440 }
michael@0 441
michael@0 442 STGMEDIUM* stg;
michael@0 443 stg = (STGMEDIUM*)CoTaskMemAlloc(sizeof(STGMEDIUM));
michael@0 444 if (dataObj->GetData(&fe, stg) != S_OK) {
michael@0 445 fail("String data object did not provide ASCII data on request");
michael@0 446 return NS_ERROR_UNEXPECTED;
michael@0 447 }
michael@0 448
michael@0 449 rv = CheckValidTEXT(stg);
michael@0 450 if (NS_FAILED(rv)) {
michael@0 451 fail("TEXT was invalid");
michael@0 452 return rv;
michael@0 453 }
michael@0 454
michael@0 455 ReleaseStgMedium(stg);
michael@0 456
michael@0 457 SET_FORMATETC(fe, CF_UNICODETEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL);
michael@0 458 if (dataObj->QueryGetData(&fe) != S_OK) {
michael@0 459 fail("String data object does not support the wide text data type!");
michael@0 460 return NS_ERROR_UNEXPECTED;
michael@0 461 }
michael@0 462
michael@0 463 if (dataObj->GetData(&fe, stg) != S_OK) {
michael@0 464 fail("String data object did not provide wide data on request");
michael@0 465 return NS_ERROR_UNEXPECTED;
michael@0 466 }
michael@0 467
michael@0 468 rv = CheckValidUNICODE(stg);
michael@0 469 if (NS_FAILED(rv)) {
michael@0 470 fail("UNICODE was invalid");
michael@0 471 return rv;
michael@0 472 }
michael@0 473
michael@0 474 return NS_OK;
michael@0 475 }
michael@0 476
michael@0 477 nsresult Do_CheckTwoStrings()
michael@0 478 {
michael@0 479 nsresult rv;
michael@0 480 nsCOMPtr<nsITransferable> transferable;
michael@0 481 nsCOMPtr<nsISupportsArray> transferableArray;
michael@0 482 nsCOMPtr<nsISupports> genericWrapper;
michael@0 483 nsRefPtr<IDataObject> dataObj;
michael@0 484 rv = NS_NewISupportsArray(getter_AddRefs(transferableArray));
michael@0 485 if (NS_FAILED(rv)) {
michael@0 486 fail("Could not create the necessary nsISupportsArray");
michael@0 487 return rv;
michael@0 488 }
michael@0 489
michael@0 490 rv = GetTransferableText(transferable);
michael@0 491 if (NS_FAILED(rv)) {
michael@0 492 fail("Could not create the proper nsITransferable!");
michael@0 493 return rv;
michael@0 494 }
michael@0 495 genericWrapper = do_QueryInterface(transferable);
michael@0 496 rv = transferableArray->AppendElement(genericWrapper);
michael@0 497 if (NS_FAILED(rv)) {
michael@0 498 fail("Could not append element to transferable array");
michael@0 499 return rv;
michael@0 500 }
michael@0 501
michael@0 502 rv = GetTransferableTextTwo(transferable);
michael@0 503 if (NS_FAILED(rv)) {
michael@0 504 fail("Could not create the proper nsITransferable!");
michael@0 505 return rv;
michael@0 506 }
michael@0 507 genericWrapper = do_QueryInterface(transferable);
michael@0 508 rv = transferableArray->AppendElement(genericWrapper);
michael@0 509 if (NS_FAILED(rv)) {
michael@0 510 fail("Could not append element to transferable array");
michael@0 511 return rv;
michael@0 512 }
michael@0 513
michael@0 514 rv = MakeDataObject(transferableArray, dataObj);
michael@0 515 if (NS_FAILED(rv)) {
michael@0 516 fail("Could not create data object");
michael@0 517 return rv;
michael@0 518 }
michael@0 519
michael@0 520 FORMATETC fe;
michael@0 521 SET_FORMATETC(fe, CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL);
michael@0 522 if (dataObj->QueryGetData(&fe) != S_OK) {
michael@0 523 fail("String data object does not support the ASCII text data type!");
michael@0 524 return NS_ERROR_UNEXPECTED;
michael@0 525 }
michael@0 526
michael@0 527 STGMEDIUM* stg;
michael@0 528 stg = (STGMEDIUM*)CoTaskMemAlloc(sizeof(STGMEDIUM));
michael@0 529 if (dataObj->GetData(&fe, stg) != S_OK) {
michael@0 530 fail("String data object did not provide ASCII data on request");
michael@0 531 return NS_ERROR_UNEXPECTED;
michael@0 532 }
michael@0 533
michael@0 534 rv = CheckValidTEXTTwo(stg);
michael@0 535 if (NS_FAILED(rv)) {
michael@0 536 fail("TEXT was invalid");
michael@0 537 return rv;
michael@0 538 }
michael@0 539
michael@0 540 ReleaseStgMedium(stg);
michael@0 541
michael@0 542 SET_FORMATETC(fe, CF_UNICODETEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL);
michael@0 543 if (dataObj->QueryGetData(&fe) != S_OK) {
michael@0 544 fail("String data object does not support the wide text data type!");
michael@0 545 return NS_ERROR_UNEXPECTED;
michael@0 546 }
michael@0 547
michael@0 548 if (dataObj->GetData(&fe, stg) != S_OK) {
michael@0 549 fail("String data object did not provide wide data on request");
michael@0 550 return NS_ERROR_UNEXPECTED;
michael@0 551 }
michael@0 552
michael@0 553 rv = CheckValidUNICODETwo(stg);
michael@0 554 if (NS_FAILED(rv)) {
michael@0 555 fail("UNICODE was invalid");
michael@0 556 return rv;
michael@0 557 }
michael@0 558
michael@0 559 return NS_OK;
michael@0 560 }
michael@0 561
michael@0 562 nsresult Do_CheckSetArbitraryData(bool aMultiple)
michael@0 563 {
michael@0 564 nsresult rv;
michael@0 565 nsCOMPtr<nsITransferable> transferable;
michael@0 566 nsCOMPtr<nsISupportsArray> transferableArray;
michael@0 567 nsCOMPtr<nsISupports> genericWrapper;
michael@0 568 nsRefPtr<IDataObject> dataObj;
michael@0 569 rv = NS_NewISupportsArray(getter_AddRefs(transferableArray));
michael@0 570 if (NS_FAILED(rv)) {
michael@0 571 fail("Could not create the necessary nsISupportsArray");
michael@0 572 return rv;
michael@0 573 }
michael@0 574
michael@0 575 rv = GetTransferableText(transferable);
michael@0 576 if (NS_FAILED(rv)) {
michael@0 577 fail("Could not create the proper nsITransferable!");
michael@0 578 return rv;
michael@0 579 }
michael@0 580 genericWrapper = do_QueryInterface(transferable);
michael@0 581 rv = transferableArray->AppendElement(genericWrapper);
michael@0 582 if (NS_FAILED(rv)) {
michael@0 583 fail("Could not append element to transferable array");
michael@0 584 return rv;
michael@0 585 }
michael@0 586
michael@0 587 if (aMultiple) {
michael@0 588 rv = GetTransferableText(transferable);
michael@0 589 if (NS_FAILED(rv)) {
michael@0 590 fail("Could not create the proper nsITransferable!");
michael@0 591 return rv;
michael@0 592 }
michael@0 593 genericWrapper = do_QueryInterface(transferable);
michael@0 594 rv = transferableArray->AppendElement(genericWrapper);
michael@0 595 if (NS_FAILED(rv)) {
michael@0 596 fail("Could not append element to transferable array");
michael@0 597 return rv;
michael@0 598 }
michael@0 599 }
michael@0 600
michael@0 601 rv = MakeDataObject(transferableArray, dataObj);
michael@0 602 if (NS_FAILED(rv)) {
michael@0 603 fail("Could not create data object");
michael@0 604 return rv;
michael@0 605 }
michael@0 606
michael@0 607 static CLIPFORMAT mozArbitraryFormat =
michael@0 608 ::RegisterClipboardFormatW(L"MozillaTestFormat");
michael@0 609 FORMATETC fe;
michael@0 610 STGMEDIUM stg;
michael@0 611 SET_FORMATETC(fe, mozArbitraryFormat, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL);
michael@0 612
michael@0 613 HGLOBAL hg = GlobalAlloc(GPTR, 1024);
michael@0 614 stg.tymed = TYMED_HGLOBAL;
michael@0 615 stg.hGlobal = hg;
michael@0 616 stg.pUnkForRelease = nullptr;
michael@0 617
michael@0 618 if (dataObj->SetData(&fe, &stg, true) != S_OK) {
michael@0 619 if (aMultiple) {
michael@0 620 fail("Unable to set arbitrary data type on data object collection!");
michael@0 621 } else {
michael@0 622 fail("Unable to set arbitrary data type on data object!");
michael@0 623 }
michael@0 624 return NS_ERROR_UNEXPECTED;
michael@0 625 }
michael@0 626
michael@0 627 if (dataObj->QueryGetData(&fe) != S_OK) {
michael@0 628 fail("Arbitrary data set on data object is not advertised!");
michael@0 629 return NS_ERROR_UNEXPECTED;
michael@0 630 }
michael@0 631
michael@0 632 STGMEDIUM* stg2;
michael@0 633 stg2 = (STGMEDIUM*)CoTaskMemAlloc(sizeof(STGMEDIUM));
michael@0 634 if (dataObj->GetData(&fe, stg2) != S_OK) {
michael@0 635 fail("Data object did not provide arbitrary data upon request!");
michael@0 636 return NS_ERROR_UNEXPECTED;
michael@0 637 }
michael@0 638
michael@0 639 if (stg2->hGlobal != hg) {
michael@0 640 fail("Arbitrary data was not returned properly!");
michael@0 641 return rv;
michael@0 642 }
michael@0 643 ReleaseStgMedium(stg2);
michael@0 644
michael@0 645 return NS_OK;
michael@0 646 }
michael@0 647
michael@0 648 // This function performs basic drop tests, testing a data object consisting
michael@0 649 // of one transferable
michael@0 650 nsresult Do_Test1()
michael@0 651 {
michael@0 652 nsresult rv = NS_OK;
michael@0 653 nsresult workingrv;
michael@0 654
michael@0 655 workingrv = Do_CheckOneFile();
michael@0 656 if (NS_FAILED(workingrv)) {
michael@0 657 fail("Drag object tests failed on a single file");
michael@0 658 rv = NS_ERROR_UNEXPECTED;
michael@0 659 } else {
michael@0 660 passed("Successfully created a working file drag object!");
michael@0 661 }
michael@0 662
michael@0 663 workingrv = Do_CheckOneString();
michael@0 664 if (NS_FAILED(workingrv)) {
michael@0 665 fail("Drag object tests failed on a single string");
michael@0 666 rv = NS_ERROR_UNEXPECTED;
michael@0 667 } else {
michael@0 668 passed("Successfully created a working string drag object!");
michael@0 669 }
michael@0 670
michael@0 671 workingrv = Do_CheckSetArbitraryData(false);
michael@0 672 if (NS_FAILED(workingrv)) {
michael@0 673 fail("Drag object tests failed on setting arbitrary data");
michael@0 674 rv = NS_ERROR_UNEXPECTED;
michael@0 675 } else {
michael@0 676 passed("Successfully set arbitrary data on a drag object");
michael@0 677 }
michael@0 678
michael@0 679 return rv;
michael@0 680 }
michael@0 681
michael@0 682 // This function performs basic drop tests, testing a data object consisting of
michael@0 683 // two transferables.
michael@0 684 nsresult Do_Test2()
michael@0 685 {
michael@0 686 nsresult rv = NS_OK;
michael@0 687 nsresult workingrv;
michael@0 688
michael@0 689 workingrv = Do_CheckTwoFiles();
michael@0 690 if (NS_FAILED(workingrv)) {
michael@0 691 fail("Drag object tests failed on multiple files");
michael@0 692 rv = NS_ERROR_UNEXPECTED;
michael@0 693 } else {
michael@0 694 passed("Successfully created a working multiple file drag object!");
michael@0 695 }
michael@0 696
michael@0 697 workingrv = Do_CheckTwoStrings();
michael@0 698 if (NS_FAILED(workingrv)) {
michael@0 699 fail("Drag object tests failed on multiple strings");
michael@0 700 rv = NS_ERROR_UNEXPECTED;
michael@0 701 } else {
michael@0 702 passed("Successfully created a working multiple string drag object!");
michael@0 703 }
michael@0 704
michael@0 705 workingrv = Do_CheckSetArbitraryData(true);
michael@0 706 if (NS_FAILED(workingrv)) {
michael@0 707 fail("Drag object tests failed on setting arbitrary data");
michael@0 708 rv = NS_ERROR_UNEXPECTED;
michael@0 709 } else {
michael@0 710 passed("Successfully set arbitrary data on a drag object");
michael@0 711 }
michael@0 712
michael@0 713 return rv;
michael@0 714 }
michael@0 715
michael@0 716 // This function performs advanced drag and drop tests, testing a data object
michael@0 717 // consisting of multiple transferables that have different data types
michael@0 718 nsresult Do_Test3()
michael@0 719 {
michael@0 720 nsresult rv = NS_OK;
michael@0 721 nsresult workingrv;
michael@0 722
michael@0 723 // XXX TODO Write more advanced tests in Bug 535860
michael@0 724 return rv;
michael@0 725 }
michael@0 726
michael@0 727 int main(int argc, char** argv)
michael@0 728 {
michael@0 729 ScopedXPCOM xpcom("Test Windows Drag and Drop");
michael@0 730
michael@0 731 nsCOMPtr<nsIFile> file;
michael@0 732 file = xpcom.GetProfileDirectory();
michael@0 733 xferFile = file;
michael@0 734
michael@0 735 if (NS_SUCCEEDED(Do_Test1()))
michael@0 736 passed("Basic Drag and Drop data type tests (single transferable) succeeded!");
michael@0 737
michael@0 738 if (NS_SUCCEEDED(Do_Test2()))
michael@0 739 passed("Basic Drag and Drop data type tests (multiple transferables) succeeded!");
michael@0 740
michael@0 741 //if (NS_SUCCEEDED(Do_Test3()))
michael@0 742 // passed("Advanced Drag and Drop data type tests succeeded!");
michael@0 743
michael@0 744 return gFailCount;
michael@0 745 }

mercurial