-
Notifications
You must be signed in to change notification settings - Fork 839
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
190 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
// ignore_for_file: constant_identifier_names, non_constant_identifier_names | ||
|
||
import 'dart:ffi'; | ||
import 'dart:io'; | ||
import 'dart:typed_data'; | ||
import 'package:base32/encodings.dart'; | ||
import 'package:charset/charset.dart'; | ||
import 'package:crypto/crypto.dart'; | ||
|
||
import 'package:base32/base32.dart'; | ||
import 'package:ffi/ffi.dart'; | ||
import 'package:win32/win32.dart'; | ||
|
||
import '../utils/string_utils.dart'; | ||
|
||
|
||
const _INITIAL_OUTPUT_BUFFER_CHARS = 256; | ||
|
||
class WinPkg { | ||
static String getPublisherId(String publisher) { | ||
return base32.encode(Uint8List.fromList(sha256.convert((utf16.encoder as Utf16Encoder).encodeUtf16Le(publisher)).bytes.sublist(0, 8)), encoding: Encoding.crockford).toLowerCase(); | ||
} | ||
|
||
static String? getPackageFamilyName(String fullName) { | ||
final lpName = ("MicrosoftCorporationII.WindowsSubsystemForAndroid_1.8.32822.0_x64__8wekyb3d8bbwe").toNativeUtf16(); | ||
var lpFamilyName = malloc<WCHAR>(_INITIAL_OUTPUT_BUFFER_CHARS).cast<Utf16>(); | ||
final lpBufferLenght = malloc<DWORD>()..value = _INITIAL_OUTPUT_BUFFER_CHARS; | ||
|
||
try { | ||
int exitCode = PackageFamilyNameFromFullName(lpName, lpBufferLenght, lpFamilyName); | ||
if (exitCode == ERROR_INSUFFICIENT_BUFFER) { | ||
free(lpFamilyName); | ||
lpFamilyName = malloc<WCHAR>(lpBufferLenght.value).cast<Utf16>(); | ||
PackageFamilyNameFromFullName(lpName, lpBufferLenght, lpFamilyName); | ||
} | ||
return lpFamilyName.toDartString(); | ||
} | ||
finally { | ||
free(lpName); | ||
free(lpFamilyName); | ||
free(lpBufferLenght); | ||
} | ||
} | ||
} | ||
|
||
|
||
class WinPkgInfo { | ||
late final String name; | ||
late final String publisherId; | ||
late final String version; | ||
late final String architecture; | ||
|
||
String get fullName => "${name}_${version}_${architecture}__$publisherId"; | ||
String get familyName => "${name}_$publisherId"; | ||
|
||
WinPkgInfo(String manifest) { | ||
try { | ||
String? identity = RegExp(r'<\s*Identity[^">]*("[^"]*"[^">]*)*>', multiLine: true).firstMatch(manifest)?.group(0)?.replaceAll('\n', ' '); | ||
name = identity?.find(r'\s+Name\s*=\s*"([^"]*)', 1) ?? 'UNKNOWN_APP_NAME'; | ||
String? publisher = identity?.find(r'\s+Publisher\s*=\s*"([^"]*)', 1); | ||
publisherId = (publisher != null) ? WinPkg.getPublisherId(publisher) : 'UNKNOWN_PUBLISHER_ID'; | ||
version = identity?.find(r'\s+Version\s*=\s*"([^"]*)', 1) ?? 'UNKNOWN_VERSION'; | ||
architecture = identity?.find(r'\s+ProcessorArchitecture\s*=\s*"([^"]*)', 1) ?? 'UNKNOWN_ARCHITECTURE'; | ||
} | ||
catch(e) {/**/} | ||
} | ||
|
||
factory WinPkgInfo.fromSystemPath(String systemPath) { | ||
try {return WinPkgInfo(File("$systemPath\\AppxManifest.xml").readAsStringSync());} | ||
catch(_) {return WinPkgInfo("");} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
// ignore_for_file: constant_identifier_names, non_constant_identifier_names | ||
|
||
import 'dart:developer'; | ||
import 'dart:ffi'; | ||
|
||
import 'package:ffi/ffi.dart'; | ||
import 'package:win32/win32.dart'; | ||
|
||
const _MAX_ITEMLENGTH = 1024; | ||
|
||
extension on String { | ||
static final RegExp _KEY_PATH_NORMALIZER = RegExp(r'[\\]*(.*)'); | ||
String? get normalizedRegKey => _KEY_PATH_NORMALIZER.firstMatch(this)?.group(1); | ||
} | ||
|
||
enum RegHKey { | ||
HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_PERFORMANCE_DATA, HKEY_PERFORMANCE_TEXT, | ||
HKEY_PERFORMANCE_NLSTEXT, HKEY_CURRENT_CONFIG, HKEY_DYN_DATA, HKEY_CURRENT_USER_LOCAL_SETTINGS | ||
} | ||
|
||
extension on RegHKey { | ||
int get value {switch(this) { | ||
case RegHKey.HKEY_CLASSES_ROOT: return HKEY_CLASSES_ROOT; | ||
case RegHKey.HKEY_CURRENT_USER: return HKEY_CURRENT_USER; | ||
case RegHKey.HKEY_LOCAL_MACHINE: return HKEY_LOCAL_MACHINE; | ||
case RegHKey.HKEY_USERS: return HKEY_USERS; | ||
case RegHKey.HKEY_PERFORMANCE_DATA: return HKEY_PERFORMANCE_DATA; | ||
case RegHKey.HKEY_PERFORMANCE_TEXT: return HKEY_PERFORMANCE_TEXT; | ||
case RegHKey.HKEY_PERFORMANCE_NLSTEXT: return HKEY_PERFORMANCE_NLSTEXT; | ||
case RegHKey.HKEY_CURRENT_CONFIG: return HKEY_CURRENT_CONFIG; | ||
case RegHKey.HKEY_DYN_DATA: return HKEY_DYN_DATA; | ||
case RegHKey.HKEY_CURRENT_USER_LOCAL_SETTINGS: return HKEY_CURRENT_USER_LOCAL_SETTINGS; | ||
}} | ||
} | ||
|
||
class RegValue { | ||
RegValue._create(this.type, this.value); | ||
String value; | ||
int type; | ||
} | ||
|
||
class WinReg { | ||
static RegValue? getString(RegHKey hKey, String keyPath, String? valName, {bool noExpand = false}) { | ||
String? keyPathN = keyPath.normalizedRegKey; | ||
if (keyPathN == null) return null; | ||
|
||
final lpKey = keyPathN.toNativeUtf16(); | ||
final lpValue = (valName != null && valName.isNotEmpty) ? valName.toNativeUtf16() : nullptr; | ||
final lpType = calloc<DWORD>(); | ||
final lpData = calloc<BYTE>(_MAX_ITEMLENGTH); | ||
final lpcbData = calloc<DWORD>()..value = _MAX_ITEMLENGTH; | ||
|
||
int flags = RRF_RT_ANY; | ||
if (noExpand) flags |= RRF_NOEXPAND; | ||
|
||
try { | ||
final status = RegGetValue(hKey.value, lpKey, lpValue, flags, lpType, lpData, lpcbData); | ||
|
||
switch (status) { | ||
case ERROR_SUCCESS: | ||
int type = lpType.value; | ||
if (type != REG_SZ && type != REG_EXPAND_SZ && type != REG_MULTI_SZ) { | ||
log('win_reg: Non-string content; type: $type'); | ||
return null; | ||
} | ||
log('win_reg: value type: $type'); | ||
return RegValue._create(type, lpData.cast<Utf16>().toDartString()); | ||
|
||
case ERROR_MORE_DATA: | ||
log('win_reg: An item required more than $_MAX_ITEMLENGTH bytes'); | ||
return null; | ||
//throw Exception('An item required more than $_MAX_ITEMLENGTH bytes.'); | ||
|
||
case ERROR_NO_MORE_ITEMS: | ||
return null; | ||
|
||
default: | ||
log('win_reg: Unknown error'); | ||
return null; | ||
//throw Exception('unknown error'); | ||
} | ||
} finally { | ||
free(lpKey); | ||
free(lpValue); | ||
free(lpType); | ||
free(lpData); | ||
free(lpcbData); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters