int LuaVFSDownload::DownloadArchive(lua_State* L) { const std::string filename = luaL_checkstring(L, 1); const std::string categoryStr = luaL_checkstring(L, 2); if (filename.empty()) { return luaL_error(L, "Missing download archive name."); } DownloadEnum::Category cat; if (categoryStr == "map") { cat = DownloadEnum::CAT_MAP; } else if (categoryStr == "game") { cat = DownloadEnum::CAT_GAME; } else if (categoryStr == "engine") { cat = DownloadEnum::CAT_ENGINE; } else { return luaL_error(L, "Category must be one of: map, game, engine."); } queueIDCount++; queueMutex.lock(); queue.push_back(DownloadItem(queueIDCount, filename, cat)); queueMutex.unlock(); eventHandler.DownloadQueued(queueIDCount, filename, categoryStr); if (!isDownloading) { if (queue.size() == 1) { StartDownload(); } } return 0; }
// This function enumerates items recursively starting from the root item and calls DownloadItem() on those items // after checking their item types. // DownloadItem() will only be called on file items. Folder items are recursively enumerated. HRESULT EnumerateAndDownloadItems( IWiaItem2 *pWiaItem2 ) { // Validate arguments if (NULL == pWiaItem2) { HRESULT hr = E_INVALIDARG; ReportError(TEXT("Invalid argument passed to EnumerateAndDownloadItems()"),hr); return hr; } // Get the item type for this item LONG lItemType = 0; HRESULT hr = pWiaItem2->GetItemType( &lItemType ); // Print the item name. PrintItemName( pWiaItem2 ); //Find the item category GUID itemCategory = GUID_NULL; ReadPropertyGuid(pWiaItem2,WIA_IPA_ITEM_CATEGORY,&itemCategory ); // If this is an transferrable file(except finished files) , download it. // We have deliberately left finished files for simplicity if ( (lItemType & WiaItemTypeFile) && (lItemType & WiaItemTypeTransfer) && (itemCategory != WIA_CATEGORY_FINISHED_FILE) ) { hr = DownloadItem( pWiaItem2 ); } // If it is a folder, enumerate its children if (lItemType & WiaItemTypeFolder) { // Get the child item enumerator for this item IEnumWiaItem2 *pEnumWiaItem2 = NULL; hr = pWiaItem2->EnumChildItems(0, &pEnumWiaItem2 ); if (SUCCEEDED(hr)) { // We will loop until we get an error or pEnumWiaItem->Next returns // S_FALSE to signal the end of the list. while (S_OK == hr ) { // Get the next child item IWiaItem2 *pChildWiaItem2 = NULL; hr = pEnumWiaItem2->Next( 1, &pChildWiaItem2, NULL ); // pEnumWiaItem->Next will return S_FALSE when the list is // exhausted, so check for S_OK before using the returned // value. if (S_OK == hr) { // Recurse into this item EnumerateAndDownloadItems( pChildWiaItem2 ); // Release this item pChildWiaItem2->Release(); pChildWiaItem2 = NULL; } else if (FAILED(hr)) { // Report that an error occurred during enumeration ReportError( TEXT("Error calling pEnumWiaItem2->Next"), hr ); } } // If the result of the enumeration is S_FALSE, since this // is normal, we will change it to S_OK if (S_FALSE == hr) { hr = S_OK; } // Release the enumerator pEnumWiaItem2->Release(); pEnumWiaItem2 = NULL; } else { ReportError(TEXT("pWiaItem2->EnumChildItems() failed"),hr); } } return hr; }