driverclient 0.2.28__tar.gz → 0.2.30__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {driverclient-0.2.28 → driverclient-0.2.30}/PKG-INFO +1 -1
- {driverclient-0.2.28 → driverclient-0.2.30}/pyproject.toml +1 -1
- {driverclient-0.2.28 → driverclient-0.2.30}/src/driverclient/__init__.py +1 -1
- {driverclient-0.2.28 → driverclient-0.2.30}/src/driverclient/ops/capture.py +3 -15
- {driverclient-0.2.28 → driverclient-0.2.30}/src/driverclient/ops/download.py +19 -1
- {driverclient-0.2.28 → driverclient-0.2.30}/.gitignore +0 -0
- {driverclient-0.2.28 → driverclient-0.2.30}/README.md +0 -0
- {driverclient-0.2.28 → driverclient-0.2.30}/src/driverclient/__main__.py +0 -0
- {driverclient-0.2.28 → driverclient-0.2.30}/src/driverclient/config.json +0 -0
- {driverclient-0.2.28 → driverclient-0.2.30}/src/driverclient/config.py +0 -0
- {driverclient-0.2.28 → driverclient-0.2.30}/src/driverclient/core/__init__.py +0 -0
- {driverclient-0.2.28 → driverclient-0.2.30}/src/driverclient/core/hardware.py +0 -0
- {driverclient-0.2.28 → driverclient-0.2.30}/src/driverclient/core/http.py +0 -0
- {driverclient-0.2.28 → driverclient-0.2.30}/src/driverclient/core/hwid.py +0 -0
- {driverclient-0.2.28 → driverclient-0.2.30}/src/driverclient/core/proc.py +0 -0
- {driverclient-0.2.28 → driverclient-0.2.30}/src/driverclient/events.py +0 -0
- {driverclient-0.2.28 → driverclient-0.2.30}/src/driverclient/main.py +0 -0
- {driverclient-0.2.28 → driverclient-0.2.30}/src/driverclient/ops/__init__.py +0 -0
- {driverclient-0.2.28 → driverclient-0.2.30}/src/driverclient/ops/automate.py +0 -0
- {driverclient-0.2.28 → driverclient-0.2.30}/src/driverclient/ops/diagnose.py +0 -0
- {driverclient-0.2.28 → driverclient-0.2.30}/src/driverclient/ops/install.py +0 -0
- {driverclient-0.2.28 → driverclient-0.2.30}/src/driverclient/ops/offline.py +0 -0
- {driverclient-0.2.28 → driverclient-0.2.30}/src/driverclient/ops/resolve.py +0 -0
- {driverclient-0.2.28 → driverclient-0.2.30}/src/driverclient/ops/scan.py +0 -0
- {driverclient-0.2.28 → driverclient-0.2.30}/src/driverclient/py.typed +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: driverclient
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.30
|
|
4
4
|
Summary: Driver Server client with an embeddable connector for config injection at runtime.
|
|
5
5
|
Project-URL: Homepage, https://example.com/driverclient
|
|
6
6
|
Author-email: Raja Sanaullah <sanaullah@99technologies.com>
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "driverclient"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.30"
|
|
8
8
|
description = "Driver Server client with an embeddable connector for config injection at runtime."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -404,22 +404,12 @@ def wu_full() -> CaptureResult:
|
|
|
404
404
|
|
|
405
405
|
# ══ Missing-HWID classification ═══════════════════════════════════════════════
|
|
406
406
|
|
|
407
|
-
_INBOX_INADEQUATE_CLASSES = {"display adapters"}
|
|
408
|
-
|
|
409
407
|
|
|
410
408
|
def classify_missing(not_found: list[str], scan_result: ScanResult) -> dict[str, list[str]]:
|
|
411
409
|
"""Bucket repo-missing HWIDs by what the machine says about their device:
|
|
412
410
|
inbox (Windows ships the driver — not applicable), oem_local (OEM driver
|
|
413
411
|
installed locally — capturable), driverless (genuinely missing — WU
|
|
414
|
-
candidate), unknown (HWID not in scan).
|
|
415
|
-
|
|
416
|
-
Display adapters are excluded from the inbox bucket: Microsoft Basic
|
|
417
|
-
Display Adapter is Windows' inbox fallback for a GPU whose real driver
|
|
418
|
-
was never bound, and it leaves the device non-accelerated — unlike other
|
|
419
|
-
inbox drivers (HID, mass storage, ...) it is not adequate coverage. Such
|
|
420
|
-
a device is treated as driverless so it still reaches WU / gets captured
|
|
421
|
-
once a real driver shows up, instead of being silently written off.
|
|
422
|
-
"""
|
|
412
|
+
candidate), unknown (HWID not in scan)."""
|
|
423
413
|
hwid_to_device: dict[str, Device] = {}
|
|
424
414
|
for scanned in scan_result.devices:
|
|
425
415
|
for h in scanned.hwids:
|
|
@@ -437,10 +427,8 @@ def classify_missing(not_found: list[str], scan_result: ScanResult) -> dict[str,
|
|
|
437
427
|
buckets["unknown"].append(hwid)
|
|
438
428
|
elif not dev.has_driver:
|
|
439
429
|
buckets["driverless"].append(hwid)
|
|
440
|
-
elif dev.is_inbox and dev.class_name.lower() not in _INBOX_INADEQUATE_CLASSES:
|
|
441
|
-
buckets["inbox"].append(hwid)
|
|
442
430
|
elif dev.is_inbox:
|
|
443
|
-
buckets["
|
|
431
|
+
buckets["inbox"].append(hwid)
|
|
444
432
|
else:
|
|
445
433
|
buckets["oem_local"].append(hwid)
|
|
446
434
|
return buckets
|
|
@@ -1214,4 +1202,4 @@ def _upload_worker(upload_q: queue.Queue, counts: dict, lock: threading.Lock, cf
|
|
|
1214
1202
|
# Extension selection was removed: capture now packs every file
|
|
1215
1203
|
# pnputil /export-driver produces (see _do_export), so the dump_extensions /
|
|
1216
1204
|
# dump_extensions_overrides config keys are no longer consulted — filtering by
|
|
1217
|
-
# extension is what caused incomplete packages (broken link D).
|
|
1205
|
+
# extension is what caused incomplete packages (broken link D).
|
|
@@ -12,6 +12,7 @@ Factored out here so the two modes share one download implementation:
|
|
|
12
12
|
• download_drivers() — fan the above out across a driver list in parallel
|
|
13
13
|
"""
|
|
14
14
|
|
|
15
|
+
import shutil
|
|
15
16
|
from concurrent.futures import ThreadPoolExecutor, as_completed
|
|
16
17
|
from pathlib import Path
|
|
17
18
|
|
|
@@ -20,7 +21,21 @@ from driverclient.core.http import http_download_retry
|
|
|
20
21
|
|
|
21
22
|
def download_driver(driver: dict, base: Path, repo_url: str, cfg: dict) -> tuple[Path, bool]:
|
|
22
23
|
"""Download all files for one driver into base/<binding_id>/.
|
|
23
|
-
Returns (dest_dir, success). success is False if ANY file failed.
|
|
24
|
+
Returns (dest_dir, success). success is False if ANY file failed.
|
|
25
|
+
|
|
26
|
+
On failure, dest is removed before returning. The live install path stages
|
|
27
|
+
every driver under one shared `base` and installs it with a single batched
|
|
28
|
+
`pnputil /add-driver base\\*.inf /subdirs` — that command globs the
|
|
29
|
+
filesystem directly, so a driver this function reports as failed (and the
|
|
30
|
+
caller correctly excludes from the install list) would otherwise still
|
|
31
|
+
leave its already-downloaded files (commonly just the small .inf, if a
|
|
32
|
+
large companion .sys/.dll timed out) sitting under base/<binding_id>/ for
|
|
33
|
+
pnputil to find anyway. pnputil then tries to add that incomplete package —
|
|
34
|
+
"cannot find the file specified" for its missing payload — which large
|
|
35
|
+
graphics drivers hit most often (biggest files, likeliest to time out
|
|
36
|
+
partway), and can poison the whole batched pass for the OTHER, fully
|
|
37
|
+
downloaded drivers riding in the same pnputil call.
|
|
38
|
+
"""
|
|
24
39
|
bid = driver.get("binding_id") or driver.get("package_id", "")
|
|
25
40
|
pkg_id = driver["package_id"]
|
|
26
41
|
dest = base / bid
|
|
@@ -36,6 +51,9 @@ def download_driver(driver: dict, base: Path, repo_url: str, cfg: dict) -> tuple
|
|
|
36
51
|
if not http_download_retry(url, path, f["sha256"], timeout=cfg["timeout_long"]):
|
|
37
52
|
ok = False
|
|
38
53
|
|
|
54
|
+
if not ok:
|
|
55
|
+
shutil.rmtree(dest, ignore_errors=True)
|
|
56
|
+
|
|
39
57
|
return dest, ok
|
|
40
58
|
|
|
41
59
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|