Skip to content

Instantly share code, notes, and snippets.

@mfelsche
Created December 28, 2018 21:48
Show Gist options
  • Save mfelsche/e3360014335855a68911d6eaf4f6e7e4 to your computer and use it in GitHub Desktop.
Save mfelsche/e3360014335855a68911d6eaf4f6e7e4 to your computer and use it in GitHub Desktop.
Getting some known folders on windows with Pony
use "debug"
use "lib:shell32" if windows
use "lib:ole32" if windows
primitive KnownFolderIds
"""
Known folder ids as described in:
https://docs.microsoft.com/en-ca/windows/desktop/shell/knownfolderid
functions return the little endian byte values of the folderid GUIDs
"""
fun profile(): Array[U8] val =>
"""
FOLDERID_Profile
5E6C858F-0E22-4760-9AFE-EA3317B67173
"""
[as U8: 0x8f; 0x85; 0x6c; 0x5e; 0x22; 0x0e; 0x60; 0x47; 0x9A; 0xFE; 0xEA; 0x33; 0x17; 0xB6; 0x71; 0x73]
fun appdata_roaming(): Array[U8] val =>
"""
FOLDERID_RoamingAppData
3EB685DB-65F9-4CF6-A03A-E3EF65729F3D
"""
[as U8: 0xdb; 0x85; 0xb6; 0x3e; 0xf9; 0x65; 0xf6; 0x4c; 0xa0; 0x3a; 0xe3; 0xef; 0x65; 0x72; 0x9f; 0x3d]
fun appdata_local(): Array[U8] val =>
"""
FOLDERID_LocalAppData
F1B32785-6FBA-4FCF-9D55-7B8E7F157091
"""
[as U8: 0x85; 0x27; 0xb3; 0xf1; 0xba; 0x6f; 0xcf; 0x4f; 0x9d; 0x55; 0x7b; 0x8e; 0x7f; 0x15; 0x70; 0x91]
fun appdata_common(): Array[U8] val =>
"""
FOLDERID_ProgramData
62AB5D82-FDC1-4DC3-A9DD-070D1D495D97
"""
[as U8: 0x82; 0x5d; 0xab; 0x62; 0xc1; 0xfd; 0xc3; 0x4d; 0xa9; 0xdd; 0x07; 0x0d; 0x1d; 0x49; 0x5d; 0x97]
primitive CodePages
fun utf8(): U32 => 65001
actor Main
new create(env: Env) =>
try
env.out.print(get_known_path(KnownFolderIds.profile())?)
env.out.print(get_known_path(KnownFolderIds.appdata_roaming())?)
env.out.print(get_known_path(KnownFolderIds.appdata_local())?)
env.out.print(get_known_path(KnownFolderIds.appdata_common())?)
end
fun get_known_path(folderid: Array[U8] val): String iso^ ? =>
var path_pointer: Pointer[U16] = Pointer[U16]
let result: U32 =
@SHGetKnownFolderPath[U32](
// REFKNOWNFOLDERID
folderid.cpointer(),
U32(0), // retrieval flags -- no flags
Pointer[U32], // some strange handle, pass NULL
addressof path_pointer
)
if result != 0 then
Debug("error getting known folder path: " + result.string())
error
end
// extract path from path_pointer
let bytes_necessary: I32 = @WideCharToMultiByte[I32](
CodePages.utf8(),
USize(0),
path_pointer,
I32(-1), // length of path pointer, -1 for null terminated
Pointer[U8].create(),
I32(0),
Pointer[U8].create(), // NULL
Pointer[U8].create() // NULL
)
//Debug("need " + bytes_necessary.string() + " bytes for utf8 path")
let utf8_path: Array[U8] iso = recover Array[U8](bytes_necessary.usize()) end
utf8_path.undefined(bytes_necessary.usize())
let convert_result: I32 = @WideCharToMultiByte[I32](
CodePages.utf8(),
USize(0),
path_pointer,
I32(-1), // length of path pointer, -1 for null terminated
utf8_path.cpointer(),
utf8_path.size(),
Pointer[U8].create(), // NULL
Pointer[U8].create() // NULL
)
if convert_result == 0 then
Debug("error converting from wchar to utf8.")
error
end
//Debug("bytes converted: " + convert_result.string())
@CoTaskMemFree[None](path_pointer)
try utf8_path.pop()? end // remove 0 terminator
String.from_iso_array(consume utf8_path)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment