他人の空似自作物置場

StartAppContainer.zip/TestWinRT/TestWinRT.cpp


#include <iostream>
#include <vector>

#include <boost/filesystem.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/foreach.hpp>
#include <boost/format.hpp>

#include <Windows.h>
#include <sddl.h>
#include <Userenv.h>
#include <Shlobj.h>
#include <Winstring.h>

#include <wrl/wrappers/corewrappers.h>
#include <wrl/client.h>
#include <wrl/event.h>

#include <Windows.Foundation.h>
#include <Windows.Storage.h>
#include <Windows.System.Threading.h>
#include <Windows.Foundation.Collections.h>

#pragma comment(lib, "runtimeobject.lib")
#pragma comment(lib, "Userenv.lib")

void MyLocalFree(PSID sid) {
  if (sid != NULL) {
    ::LocalFree(sid);
  }
}

typedef boost::shared_ptr<boost::remove_pointer<PSID>::type> SHARED_SID;
SHARED_SID ToSharedSID(PSID sid) {
  return SHARED_SID(sid, &MyLocalFree);
}

void MyFreeSid(PSID sid) {
  if (sid != NULL) {
    ::FreeSid(sid);
  }
}

SHARED_SID ToSharedSID2(PSID sid) {
  return SHARED_SID(sid, &MyFreeSid);
}

void MyCoTaskMemFree(void * const ptr) {
  if (ptr != NULL) {
    ::CoTaskMemFree(ptr);
  }
}

std::wstring getEnv(const wchar_t * const name) {
  wchar_t *str;
  size_t len;
  if (::_wdupenv_s(&str, &len, name) != 0 || str == NULL) {
    return std::wstring();
  }
  const std::wstring result(str);
  ::free(str);
  return result;
}

SHARED_SID GetAppContainerSid(const wchar_t * const name) {
  PSID sidImpl;
  if (FAILED(::DeriveAppContainerSidFromAppContainerName(name, &sidImpl))) {
    return SHARED_SID();
  }
  return ToSharedSID2(sidImpl);
}

bool GetAppContainerFolderPath(SHARED_SID sid, std::wstring &result) {
  wchar_t *sidStrImpl;
  if (::ConvertSidToStringSidW(sid.get(), &sidStrImpl) == FALSE) {
    return false;
  }
  const boost::shared_ptr<wchar_t> sidStr(sidStrImpl, &MyLocalFree);
  wchar_t *appContainerPathImpl;
  if (FAILED(::GetAppContainerFolderPath(sidStr.get(), &appContainerPathImpl))) {
    return false;
  }
  const boost::shared_ptr<wchar_t> appContainerPath(appContainerPathImpl, &MyCoTaskMemFree);
  result.assign(appContainerPath.get());
  return true;
}

const wchar_t *GetPath(Microsoft::WRL::ComPtr<ABI::Windows::Storage::IStorageItem> item) {
  HSTRING name;
  item->get_Path(&name);
  unsigned int len;
  return WindowsGetStringRawBuffer(name, &len);
}

const wchar_t *GetPath(Microsoft::WRL::ComPtr<ABI::Windows::Storage::IStorageFolder> folder) {
  Microsoft::WRL::ComPtr<ABI::Windows::Storage::IStorageItem> item;
  folder.As(&item);
  return GetPath(item);
}

const wchar_t *GetPath(Microsoft::WRL::ComPtr<ABI::Windows::Storage::IStorageFile> folder) {
  Microsoft::WRL::ComPtr<ABI::Windows::Storage::IStorageItem> item;
  folder.As(&item);
  return GetPath(item);
}

Microsoft::WRL::ComPtr<ABI::Windows::Storage::IStorageFolder> GetFolder(const wchar_t * const pathImpl) {
  Microsoft::WRL::ComPtr<IActivationFactory> storageFolderFactory;
  ABI::Windows::Foundation::GetActivationFactory(Microsoft::WRL::Wrappers::HStringReference(RuntimeClass_Windows_Storage_StorageFolder).Get(), &storageFolderFactory);
  Microsoft::WRL::ComPtr<ABI::Windows::Storage::IStorageFolderStatics> storageFolder;
  storageFolderFactory.As(&storageFolder);
  HSTRING path;
  WindowsCreateString(pathImpl, wcslen(pathImpl), &path);
  Microsoft::WRL::Wrappers::Event event(::CreateEventExW(NULL, NULL, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS));
  Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IAsyncOperation<ABI::Windows::Storage::StorageFolder*> > operation;
  storageFolder->GetFolderFromPathAsync(path, operation.GetAddressOf());
  Microsoft::WRL::ComPtr<ABI::Windows::Storage::IStorageFolder> folder;
  auto callback = Microsoft::WRL::Callback<ABI::Windows::Foundation::IAsyncOperationCompletedHandler<ABI::Windows::Storage::StorageFolder*> >(
    [&event, &folder](ABI::Windows::Foundation::IAsyncOperation<ABI::Windows::Storage::StorageFolder*> *operation, AsyncStatus aStatus)->HRESULT
  {
    if (aStatus == Completed) {
      operation->GetResults(folder.GetAddressOf());
    }
    ::SetEvent(event.Get());
    return S_OK;
  });
  Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IAsyncOperationCompletedHandler<ABI::Windows::Storage::StorageFolder*> > handler(callback);
  operation->put_Completed(handler.Get());
  ::WaitForSingleObjectEx(event.Get(), INFINITE, FALSE);
  return folder;
}

Microsoft::WRL::ComPtr<ABI::Windows::Storage::IStorageFolder> GetFolder(const std::wstring &path) {
  return GetFolder(path.c_str());
}

typedef HRESULT(WINAPI ABI::Windows::Storage::IKnownFoldersStatics::*KnownFoldersMethod)(ABI::Windows::Storage::IStorageFolder **);
Microsoft::WRL::ComPtr<ABI::Windows::Storage::IStorageFolder> GetKnownFolder(KnownFoldersMethod method) {
  Microsoft::WRL::ComPtr<IActivationFactory> knownFoldersFactory;
  ABI::Windows::Foundation::GetActivationFactory(Microsoft::WRL::Wrappers::HStringReference(RuntimeClass_Windows_Storage_KnownFolders).Get(), &knownFoldersFactory);
  Microsoft::WRL::ComPtr<ABI::Windows::Storage::IKnownFoldersStatics> knownFolders;
  knownFoldersFactory.As(&knownFolders);
  Microsoft::WRL::ComPtr<ABI::Windows::Storage::IStorageFolder> folder;
  (knownFolders.Get()->*method)(&folder);
  return folder;
}

void PrintChildFiles(Microsoft::WRL::ComPtr<ABI::Windows::Storage::IStorageFolder> folder) {
  Microsoft::WRL::Wrappers::Event event(::CreateEventExW(NULL, NULL, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS));
  auto callback = Microsoft::WRL::Callback<ABI::Windows::Foundation::IAsyncOperationCompletedHandler<ABI::Windows::Foundation::Collections::IVectorView<ABI::Windows::Storage::StorageFile*>*> >(
    [&event](ABI::Windows::Foundation::IAsyncOperation<ABI::Windows::Foundation::Collections::IVectorView<ABI::Windows::Storage::StorageFile*> *> *operation, AsyncStatus aStatus) -> HRESULT
  {
    Microsoft::WRL::ComPtr<ABI::Windows::Foundation::Collections::IVectorView<ABI::Windows::Storage::StorageFile*> > list;
    operation->GetResults(list.GetAddressOf());
    unsigned int size;
    list->get_Size(&size);
    for (unsigned int i = 0; i < size; i++) {
      Microsoft::WRL::ComPtr<ABI::Windows::Storage::IStorageFile> file;
      list->GetAt(i, file.GetAddressOf());
      std::wcout << GetPath(file) << std::endl;
    }
    ::SetEvent(event.Get());
    return S_OK;
  });
  Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IAsyncOperationCompletedHandler<ABI::Windows::Foundation::Collections::IVectorView<ABI::Windows::Storage::StorageFile*>*> > handler(callback);
  Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IAsyncOperation<ABI::Windows::Foundation::Collections::IVectorView<ABI::Windows::Storage::StorageFile*> *> > operation;
  folder->GetFilesAsyncOverloadDefaultOptionsStartAndCount(operation.GetAddressOf());
  operation->put_Completed(handler.Get());
  ::WaitForSingleObjectEx(event.Get(), INFINITE, FALSE);
}

void PrintChildFolders(Microsoft::WRL::ComPtr<ABI::Windows::Storage::IStorageFolder> folder) {
  Microsoft::WRL::Wrappers::Event event(::CreateEventExW(NULL, NULL, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS));
  auto callback = Microsoft::WRL::Callback<ABI::Windows::Foundation::IAsyncOperationCompletedHandler<ABI::Windows::Foundation::Collections::IVectorView<ABI::Windows::Storage::StorageFolder*>*> >(
    [&event](ABI::Windows::Foundation::IAsyncOperation<ABI::Windows::Foundation::Collections::IVectorView<ABI::Windows::Storage::StorageFolder*> *> *operation, AsyncStatus aStatus)->HRESULT
  {
    Microsoft::WRL::ComPtr<ABI::Windows::Foundation::Collections::IVectorView<ABI::Windows::Storage::StorageFolder*> > list;
    operation->GetResults(list.GetAddressOf());
    unsigned int size;
    list->get_Size(&size);
    for (unsigned int i = 0; i < size; i++) {
      Microsoft::WRL::ComPtr<ABI::Windows::Storage::IStorageFolder> folder;
      list->GetAt(i, folder.GetAddressOf());
      std::wcout << GetPath(folder) << std::endl;
    }
    ::SetEvent(event.Get());
    return S_OK;
  });
  Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IAsyncOperationCompletedHandler<ABI::Windows::Foundation::Collections::IVectorView<ABI::Windows::Storage::StorageFolder*>*> > handler(callback);
  Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IAsyncOperation<ABI::Windows::Foundation::Collections::IVectorView<ABI::Windows::Storage::StorageFolder*> *> > operation;
  folder->GetFoldersAsyncOverloadDefaultOptionsStartAndCount(operation.GetAddressOf());
  operation->put_Completed(handler.Get());
  ::WaitForSingleObjectEx(event.Get(), INFINITE, FALSE);
}

void PrintChild(Microsoft::WRL::ComPtr<ABI::Windows::Storage::IStorageFolder> folder) {
  PrintChildFolders(folder);
  PrintChildFiles(folder);
}

void PrintDir(const wchar_t * const path) {
  PrintChild(GetFolder(path));
}

int main() {
  std::locale::global(std::locale("japanese"));
  Microsoft::WRL::Wrappers::RoInitializeWrapper initialize(RO_INIT_MULTITHREADED);

  typedef std::pair<std::wstring, Microsoft::WRL::ComPtr<ABI::Windows::Storage::IStorageFolder> > ITEM;
  std::vector<ITEM> list;

  list.push_back(std::make_pair(L"SystemRoot", GetFolder(getEnv(L"SystemRoot"))));
  list.push_back(std::make_pair(L"ProgramFiles", GetFolder(getEnv(L"ProgramFiles"))));
  std::wstring applicationFolder;
  GetAppContainerFolderPath(GetAppContainerSid(L"AppConteinerTest"), applicationFolder);
  list.push_back(std::make_pair(L"アプリケーションフォルダ", GetFolder(applicationFolder)));
  list.push_back(std::make_pair(L"Tempフォルダ", GetFolder(getEnv(L"TEMP"))));
  list.push_back(std::make_pair(L"ミュージックフォルダ", GetKnownFolder(&ABI::Windows::Storage::IKnownFoldersStatics::get_MusicLibrary)));
  list.push_back(std::make_pair(L"システムドライブ直下", GetFolder(getEnv(L"SystemDrive") + L"\\")));
  list.push_back(std::make_pair(L"ユーザーフォルダ", GetFolder(getEnv(L"USERPROFILE"))));

  BOOST_FOREACH(const ITEM &item, list) {
    const wchar_t * path = (item.second ? GetPath(item.second) : L"");
    std::wcout << boost::wformat(L"%1%(%2%)を取得します。\nEnter押下で実行") % item.first % (path[0] != L'\0' ? path : L"PATH取得失敗");
    std::wcin.ignore();
    if (!item.second) {
      std::wcout << L"取得に失敗しました" << std::endl;
    } else {
      PrintChild(item.second);
    }
    std::wcout << std::endl;
  }

  std::wcout << L"すべての処理が終了しました" << std::endl;
  std::wcout << L"Enter押下で終了します" << std::endl;
  std::wcin.ignore();
  return 0;
}