51 lines
2.1 KiB
Dart
51 lines
2.1 KiB
Dart
import 'dart:ffi';
|
|
import 'dart:io';
|
|
|
|
import 'package:ffi/ffi.dart';
|
|
|
|
// 약속 (나누기 file_ops): Windows 저장 장치 - 드라이브 목록 · 드라이브 종류 · 네트워크 공유의 맨 위.
|
|
// 입력: 드라이브 맨 위 ("C:\") · 경로. 출력: 목록 · 종류 번호 · 글.
|
|
// 오류: 던지지 않는다. Windows API 를 부르지 못하면 [windowsDrives] 는 C: 하나, [driveType] 은 0 (모름).
|
|
// 드라이브를 열어 보지 않는다 (끊긴 네트워크 드라이브에서 멈추지 않게).
|
|
|
|
/// 저장 장치 (맨 위 폴더): Windows 는 드라이브 (C:\ …), 그 밖은 주어진 목록.
|
|
/// 165: 드라이브 문자는 Windows 가 알려 주는 목록 (GetLogicalDrives) 으로 - 드라이브마다 열어 보지 않는다
|
|
/// (끊긴 · 느린 네트워크 드라이브 (NAS) 를 열어 보느라 탐색기가 10초씩 멈췄다)
|
|
List<(String path, String label)> windowsDrives() {
|
|
int mask;
|
|
try {
|
|
mask = DynamicLibrary.open('kernel32.dll').lookupFunction<Uint32 Function(), int Function()>('GetLogicalDrives')();
|
|
} catch (_) {
|
|
mask = 0;
|
|
}
|
|
if (mask == 0) return [(r'C:\', 'C:')];
|
|
return [
|
|
for (final c in 'CDEFGHIJKLMNOPQRSTUVWXYZAB'.split(''))
|
|
if (mask & (1 << (c.codeUnitAt(0) - 65)) != 0) ('$c:\\', '$c:'),
|
|
];
|
|
}
|
|
|
|
/// 165: 드라이브 종류 (GetDriveTypeW: 2 꺼내는 장치 (카드 리더 · USB) · 3 고정 · 4 네트워크 · 5 CD). 드라이브를 열어 보지 않는다. 모르면 0
|
|
int driveType(String root) {
|
|
if (!Platform.isWindows) return 0;
|
|
final w = root.toNativeUtf16();
|
|
try {
|
|
final f = DynamicLibrary.open('kernel32.dll')
|
|
.lookupFunction<Uint32 Function(Pointer<Utf16>), int Function(Pointer<Utf16>)>('GetDriveTypeW');
|
|
return f(w);
|
|
} catch (_) {
|
|
return 0;
|
|
} finally {
|
|
calloc.free(w);
|
|
}
|
|
}
|
|
|
|
/// 네트워크 드라이브인지
|
|
bool isNetworkDrive(String root) => driveType(root) == 4;
|
|
|
|
/// Windows 네트워크 공유 경로의 맨 위 (\\서버\공유). 37
|
|
String uncRoot(String path) {
|
|
final parts = path.replaceAll('/', r'\').split(r'\').where((s) => s.isNotEmpty).toList();
|
|
return parts.length < 2 ? path : '\\\\${parts[0]}\\${parts[1]}';
|
|
}
|