{"id":17902158,"url":"https://github.com/basharast/uwp2win32","last_synced_at":"2025-03-23T13:31:56.541Z","repository":{"id":82570957,"uuid":"590619295","full_name":"basharast/UWP2Win32","owner":"basharast","description":"UWP Storage layer that help to deal with storage by string path just like Win32 methods","archived":false,"fork":false,"pushed_at":"2024-11-12T20:36:53.000Z","size":198,"stargazers_count":14,"open_issues_count":0,"forks_count":3,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-18T20:48:20.345Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/basharast.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-01-18T20:27:34.000Z","updated_at":"2025-03-18T06:50:42.000Z","dependencies_parsed_at":null,"dependency_job_id":"64d023c4-0948-4584-b580-9587234f7ead","html_url":"https://github.com/basharast/UWP2Win32","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/basharast%2FUWP2Win32","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/basharast%2FUWP2Win32/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/basharast%2FUWP2Win32/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/basharast%2FUWP2Win32/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/basharast","download_url":"https://codeload.github.com/basharast/UWP2Win32/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245108243,"owners_count":20562014,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-28T16:05:03.624Z","updated_at":"2025-03-23T13:31:56.527Z","avatar_url":"https://github.com/basharast.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# UWP Storage manager\n\nThis manager will help developers to deal with the storage in any **C++** UWP app\nusing only string path and not to aware about UWP side.\n\n- **CX**\n- **WinRT**\n\n# Overview\n\nThere was big confusion since the new UWP APIs made such as `CreateFile2FromApp`\n\nthose were not able to deal with the future access list correctly in early builds 17134\n\neven on Windows 10 they had many internal bugs, after build 22000 a lot of things got corrected\n\nso on the recent builds on Windows once the folder/file is added to the future access list then:\n\n## API direct access\n\nit will be allowed for direct access using the API that made for UWP (those ends with `FromApp`)\nthis is allowed even without `FileSystem` enabled.\n\n## Get StorageFile with full path\n\nalso functions such as `StorageFolder::GetFolderFromPathAsync` allowed to get files from outside local data\nas long the target in the future access list\n\nnot to mention that by default APIs can be used in case:\n\n- Accessing to AppData\n- Accessing to AppFolder\n- Accessing to USB (if capability added)\n\n## Advanced\n\nThis will not be included in this project yet\n\nbut you can always resolve any DLL API to forward the request to your UWP replacement\n\nyou can check the nice idea made by Team Kodi at [this file](https://github.com/xbmc/xbmc/blob/8a90f175f53fa3f86415e6a376aed54d244cad0e/xbmc/cores/DllLoader/Win32DllLoader.cpp)\n\nwith this solution you can increase the app compatibility with UWP environment\n\n\n# Usage \u0026 Structure\n\n## Target\n\nWorks fine with builds 14393+, anything below that require manual extra helpers because the solution get HANDLE over StorageFile was introduced 14393+\n\n## Version 1.5\n\n- Added check using API before UWP\n- Added Get/Put file contents\n- Implemented files into projects\n- License changed to MIT\n- Fix many build errors (WinRT)\n- Fixed minor issues\n- Added wstring version for functions\n\n## Capabilities\n\nBelow can be done with `string path` you don't have to do major changes:\n\n- Lookup locations for gaining access histoy without any extra action\n- Extra lookup locations like `Documents`, `Videos`.etc can be activated\n- Easy to use pickers file/folder (auto sync with lookup locations)\n- Get file `HANDLE` or `FILE*`\n- Get folder contents\n- Perform many actions like `Delete`, `Copy`, `Move` and more\n- libzip integration for extract will be detailed below (at the end)\n- More will be detailed below\n\n\n## Structure\n\n- StorageConfig (Config) \u003c- Main usage (`StorageConfig.h`)\n- StorageManager (Engine) \u003c- Main usage (`StorageManager.h`)\n- StoragePickers (Pickers file/folders) \u003c- Main usage (`StoragePickers.h`)\n- StorageItemW (Wrapped `StorageItem`) [Main entry for File/Folder]\n- StorageFileW (Wrapped `StorageFile`)\n- StorageFolderW (Wrapped `StorageFolder`)\n- StorageAccess (Future access)\n- StorageAsync (Async operation/action helpers)\n- StorageHandler (File `HANDLE` functions) [Internal usage]\n- StorageExtensions (String helpers only)\n- StoragePath (PathUWP class) [Internal usage]\n- StorageInfo (item info struct)\n- StorageLog (Log configuration)\n- UWP2C (libzip helpers)\n\n\nYour code will `#include` in general:\n\n- `StorageManager.h`\n- `StoragePickers.h` (if needed)\n- `UWP2C.h` (for libzip)\n\nThe usage simplified to be similar to Win32 functions.\n\n## Note \n\nBecause I'm always aware for legacy support, some parts can be skipped\n\nfor recent Windows builds the call will mostly finished at UWP API level, \n\nrarely will use wrapped StorageItem or others.\n\nin case you went into unneccesary delay, modify the code and disable the wrapped StorageItem fallback if you sure it's not needed\n\n```cpp\n// Example what fallback means\nbool IsExistsUWP(std::string path) {\n\tbool defaultState = IsExistsAPI(path); // \u003c-- Usually this succeed\n\tif (!defaultState \u0026\u0026 IsValidUWP(path)) {\n\t\t// ... Here the fallback ...\n\t}\n\n\treturn false;\n}\n```\n\n\n# Usage\n\n## Tips\n\n- To force legacy APIs define `UWP_LEGACY`\n- By default legacy forced for ARM32 only\n- Turn off precompiled header from your project\n- Add preprocessors `_CRT_SECURE_NO_WARNINGS` and `NOMINMAX`\n- For best results make things centralized in custom folder picked by the user, it's better in case the app removed and installed again\n\n\n## Lookup lists\n\nBy default storage manager will append these locations:\n\n- App installation folder\n- App local data\n- Picked files\n- Picked folders\n\nIf you want to add extra locations such as `Documents`:\n\nOpen `StorageConfig.h` at the top you will find:\n\n```c++\n// Known locations\n#define APPEND_APP_LOCALDATA_LOCATION 1 \n#define APPEND_APP_INSTALLATION_LOCATION 1 \n#define APPEND_DOCUMENTS_LOCATION 0\n#define APPEND_VIDEOS_LOCATION 0\n#define APPEND_MUSIC_LOCATION 0\n#define APPEND_PICTURES_LOCATION 0\n```\n\n**BE CAREFUL** you must add the related capability or your app will crash.\n\n### Known folders (capabilities)\n\n- Documents: `documentsLibrary` \u003c-(manually via XML editor)\n- Videos: `videosLibrary`\n- Pictures: `picturesLibrary`\n- Music: `musicLibrary`\n\n**Note:** try to avoid `documentsLibrary` \nit will throw exception in case you're trying to reach type is not declared in `appxmanifest` file\n\n## Pick files/folders\n\nJust `#include \"StoragePickers.h\"` in the target page\n\nthen you can invoke picker like this:\n\n### File Picker\n\n```c++\n// Supported types\nstd::vector\u003cstd::string\u003e supportedExtensions = { \".cso\", \".bin\", \".iso\", \".elf\", \".zip\"};\n\n// Call file picker\nChooseFile(supportedExtensions).then([](std::string filePath) {\n\tif (filePath.size() \u003e 1) {\n\t\t// Do something here\n\t}\n});\n```\n\n### Folder Picker\n\n```c++\nChooseFolder().then([](std::string folderPath) {\n\tif (folderPath.size() \u003e 1) {\n\t\t// Do something here\n\t}\n});\n```\n\nWhen user cancel the picker empty string will be returned\n\n\n# Management\n\nAll you need is to `#include \"StorageManager.h\"` in your code\n\nthen you can deal with the files using the following functions:\n\n\n## Locations\n\n```c++\nstd::string GetWorkingFolder();\nvoid SetWorkingFolder(std::string location);\nstd::string GetInstallationFolder();\nstd::string GetLocalFolder();\nstd::string GetTempFolder();\nstd::string GetPicturesFolder();\nstd::string GetVideosFolder();\nstd::string GetDocumentsFolder();\nstd::string GetMusicFolder();\nstd::string GetPreviewPath(std::string path);\n```\n\n`GetWorkingFolder()` is optional, use it in case you have main folder for data\n\n`GetPreviewPath()` for WorkingFolder it will return \"App Local Data\"\n\nin case the working folder was in app local folder instead of long path\n\n\n## Handling\n\nGet `HANDLE` for file/folder:\n\n```c++\n// This call is almost similar to CreateFile2\nHANDLE CreateFileUWP(std::string path, int accessMode, int shareMode, int openMode);\nHANDLE CreateFileUWP(std::wstring path, int accessMode, int shareMode, int openMode);\n```\n\nGet `FILE*` stream for file:\n\n```c++\n// This call will be similar to fopen\nFILE* GetFileStream(std::string path, const char* mode)\n```\n\nGet `FILE*` stream for file (DirectAPI):\n\nThis function is important to avoid using `fopen`, \n\npreferred to be used before `GetFileStream()`\n\nit will call `CreateFile2FromAppW` with `mode` converted to it's args\n\n```c++\n// This call will be similar to fopen\nFILE* GetFileStreamFromApp(std::string path, const char* mode)\n```\n\n## Restrictions\n\n- You cannot use `FindFirstFile`, `FindNextFile` with folder `HANDLE`\n- You must use the alternative function `GetFolderContents`\n- By default `GetFolderContents` will try API (FindFirstFile..) before UWP to fetch the results\n\n\nGet folder contents:\n\n```c++\n// Get list of file and folder\n// be aware using 'deepScan' is slow\n// because it will use WindowsQuery\nstd::list\u003cItemInfoUWP\u003e GetFolderContents(std::string path, bool deepScan);\n```\n\nGet single file info:\n\n```c++\n// Get single file info\nItemInfoUWP GetItemInfoUWP(std::string path);\n```\n\n\n## ItemInfoUWP (Struct)\n\n```c++\nstruct ItemInfoUWP {\n\tstd::string name;\n\tstd::string fullName;\n\n\tbool isDirectory = false;\n\n\tuint64_t size = 0;\n\tuint64_t lastAccessTime = 0;\n\tuint64_t lastWriteTime = 0;\n\tuint64_t changeTime = 0;\n\tuint64_t creationTime = 0;\n\n\tDWORD attributes = 0;\n};\n```\n\n### Important\n\nIf you want to change `ItemInfoUWP` structure \n\ndon't forget to apply the changes at `StorageManager.cpp`\n\nit's used only in this file\n\n\n## Validation\n\n```c++\n// Check if file/folder exists\nbool IsExistsUWP(std::string path);\n\n// Check if target is directory \nbool IsDirectoryUWP(std::string path);\n\n// Check if drive is accessible \n// 'checkIfContainsFutureAccessItems' for listing purposes not real access, 'driveName' like C:\nbool CheckDriveAccess(std::string driveName, bool checkIfContainsFutureAccessItems);\n```\n\n\n## Actions\n\n```c++\nint64_t GetSizeUWP(std::string path);\nbool DeleteUWP(std::string path);\nbool CreateDirectoryUWP(std::string path, bool replaceExisting = true);\nbool RenameUWP(std::string path, std::string name);\nbool CopyUWP(std::string path, std::string name);\nbool MoveUWP(std::string path, std::string name);\n```\n\n## Extra\n\n```c++\nbool OpenFile(std::string path);\nbool OpenFolder(std::string path);\nbool IsFirstStart(); // Return true if first start\nbool GetDriveFreeSpace(PathUWP path, int64_t\u0026 space) // Get drive free space by folder path (must be in FutureAccess)\n```\n\n\n\n# libzip Integration\n\nAs per my test on PPSSPP emulator \n\nI was able to make zip function working by doing the following:\n\n- Open `zip_source_file_win32_utf16.c` file\n- Do the following changes:\n\n```c++\n// Include headers\n#ifdef MS_UWP\n#include \"UWP2C.h\"\n// For latest builds include 'fileapifromapp.h'\n#include \u003cfileapi.h\u003e\n#endif\n\n// Replace `zip_win32_file_operations_t ops_utf16` by below\n#ifdef MS_UWP\nstatic BOOL __stdcall GetFileAttr(const void* name, GET_FILEEX_INFO_LEVELS info_level, void* lpFileInformation) {\n\t// For latest builds use 'GetFileAttributesExFromAppW'\n\tBOOL state = GetFileAttributesExW(name, info_level, lpFileInformation);\n\tif (state == FALSE) {\n\t\t// Ignore `info_level` not in use for now\n\t\tstate = GetFileAttributesUWP(name, lpFileInformation);\n\t}\n\treturn state;\n}\n\nstatic BOOL __stdcall DelFile(const void* name) {\n\t// For latest builds use 'DeleteFileFromAppW'\n\tBOOL state = DeleteFileW(name);\n\tif (state == FALSE) {\n\t\tstate = DeleteFileUWP(name);\n\t}\n\treturn state;\n}\n\n// You got the idea so you can add more if you want\n\nzip_win32_file_operations_t ops_utf16 = {\n\tutf16_allocate_tempname,\n\tutf16_create_file, // Will invoke UWP Storage manager (If needed)\n\tDelFile, // Will invoke UWP Storage manager (If needed)\n\tGetFileAttributesW,\n\tGetFileAttr, // Will invoke UWP Storage manager (If needed)\n\tutf16_make_tempname,\n\tMoveFileExW,\n\tSetFileAttributesW,\n\tutf16_strdup\n};\n#else\n // Here goes the original `ops_utf16`\n#endif\n\n```\n\nNow scroll to `utf16_create_file` function\n\nand make the following changes:\n\n```c++\n#ifdef MS_UWP\n\t// For latest builds use 'CreateFile2FromAppW'\n\tHANDLE h = CreateFile2((const wchar_t*)name, access, share_mode, creation_disposition, NULL);\n\tif (h == INVALID_HANDLE_VALUE) {\n\t\th = CreateFileUWP(name, (int)access, (int)share_mode, (int)creation_disposition);\n\t}\n    return h;\n#else\n    return CreateFileW((const wchar_t *)name, access, share_mode, security_attributes, creation_disposition, file_attributes, template_file);\n#endif\n```\n\nDone.\n\n\n# Logger\n\nIf you want to attach your own log function\n\njust open `StorageLog.h` and do the required changes\n\nusing `StorageManager.h` you will be able to:\n\n```c++\nstd::string GetLogFile();\nbool SaveLogs(); // With picker\nvoid CleanupLogs(); // Delete empty logs\n```\n\nUsually `LOGS` folder will be created in `WorkingFolder`\n\nand inside it will be new file for each launch at the time `GetLogFile()` called\n\n\n# Important\n\nBe aware, `Contain` function is case senstive for now\n\ntry to use exact chars case in your path when requesting file/folder\n\nI will consider to force lowercase in future\n\n\n# Credits\n\n- Bashar Astifan (Days of work to make in the best possible shape)\n- Peter Torr - MSFT for Win32 `HANDLE` solution\n- `PathUWP` based on `Path.h` type from **PPSSPP**\n- Libretro/RetroArch team for `async` idea\n- Team Kodi for `WaitTask` solution\n- StackOverflow for various string helpers\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbasharast%2Fuwp2win32","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbasharast%2Fuwp2win32","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbasharast%2Fuwp2win32/lists"}