Skip to content

Instantly share code, notes, and snippets.

@johanlindfors
Created February 27, 2016 08:31
Show Gist options
  • Save johanlindfors/308f7eb7c44097f80145 to your computer and use it in GitHub Desktop.
Save johanlindfors/308f7eb7c44097f80145 to your computer and use it in GitHub Desktop.
A first attempt of an InstallId for Vendor/Publisher on the UAP in C++
#pragma once
using namespace Platform;
using namespace Windows::Storage;
using namespace Windows::Storage::Streams;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::Security::Cryptography;
using namespace Windows::Security::Cryptography::Core;
using namespace Windows::System::UserProfile;
using namespace concurrency;
ref class InstallIdForPublisher sealed {
public:
static IAsyncOperation<String^>^ GetAsync(String^ folderName, String^ fileName)
{
auto storageFolder = ApplicationData::Current->GetPublisherCacheFolder(folderName);
return create_async([=]() -> task<String^>
{
return create_task(storageFolder->TryGetItemAsync(fileName))
.then([=](IStorageItem^ storageItem) {
auto storageFile = dynamic_cast<StorageFile^>(storageItem);
if (storageFile != nullptr) {
return create_task(FileIO::ReadTextAsync(storageFile));
}
else {
return create_task([]() { return ref new String(); });
}
})
.then([=](String^ installId) {
if (installId == nullptr || installId->Length() == 0) {
installId = Generate();
return create_task(SetAsync(folderName, fileName, installId))
.then([installId]() -> String^ {
return installId;
});
}
else {
return create_task([installId]() {
return installId;
});
}
});
});
}
private:
static IAsyncAction^ SetAsync(String^ folderName, String^ fileName, String^ installId)
{
auto storageFolder = ApplicationData::Current->GetPublisherCacheFolder(folderName);
return create_async([=]()
{
create_task(storageFolder->TryGetItemAsync(fileName))
.then([=](IStorageItem^ storageItem) {
auto storageFile = dynamic_cast<StorageFile^>(storageItem);
if (storageFile != nullptr) {
return create_task([storageFile]() {
return storageFile;
});
}
else {
return create_task(storageFolder->CreateFileAsync(fileName)).then([installId](StorageFile^ storageFile) {
return storageFile;
});
}
})
.then([=](StorageFile^ storageFile) {
return FileIO::WriteTextAsync(storageFile, installId);
});
});
}
static String^ GenerateGuid() {
GUID nativeGuid;
CoCreateGuid(&nativeGuid);
Guid guid(nativeGuid);
return guid.ToString();
}
static String^ Generate()
{
// First try with advertising id as base for id
auto id = AdvertisingManager::AdvertisingId;
if (id == nullptr || id->Length() == 0) {
// Secondly generate a new guid as base for id
id = GenerateGuid();
}
auto algorithm = HashAlgorithmProvider::OpenAlgorithm("MD5");
auto vector = CryptographicBuffer::ConvertStringToBinary(id, BinaryStringEncoding::Utf8);
auto buffer = algorithm->HashData(vector);
if (buffer->Length != algorithm->HashLength) {
throw ref new Platform::Exception(0, "Failed to generate hash!");
}
return CryptographicBuffer::EncodeToHexString(buffer);
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment