Skip to content

Commit 212fff2

Browse files
authored
log machine id mappings for VS to VS Code (#11308)
* log machine id mappings for VS to VS Code * update comment * in case execChildProcess throws
1 parent 44e3bbe commit 212fff2

File tree

2 files changed

+70
-0
lines changed

2 files changed

+70
-0
lines changed

Extension/src/id.ts

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/* --------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All Rights Reserved.
3+
* See 'LICENSE' in the project root for license information.
4+
* ------------------------------------------------------------------------------------------ */
5+
6+
import { execChildProcess } from './common';
7+
import { isWindows } from './constants';
8+
import { logLanguageServerEvent } from './telemetry';
9+
10+
/**
11+
* Hash the MAC addresses on the machine (Windows-only) and log telemetry.
12+
*/
13+
export async function logMachineIdMappings(): Promise<void> {
14+
if (!isWindows) {
15+
return;
16+
}
17+
18+
const macAddresses = await getMacAddresses();
19+
20+
// The first MAC address is the one Visual Studio uses
21+
const primary = await getMachineId(macAddresses.shift());
22+
if (primary) {
23+
logLanguageServerEvent('machineIdMap', {primary});
24+
}
25+
26+
// VS Code uses os.networkInterfaces() which has different sorting and availability,
27+
// but all MAC addresses are returned by getmac.exe. The ID VS Code uses may change
28+
// based on changes to the network configuration. Log the extras so we can assess
29+
// how frequently this impacts the machine id.
30+
for (const macAddress of macAddresses) {
31+
const additional = await getMachineId(macAddress);
32+
if (additional) {
33+
logLanguageServerEvent('machineIdMap', {additional});
34+
}
35+
}
36+
}
37+
38+
/**
39+
* Parse the output of getmac.exe to get the list of MAC addresses for the PC.
40+
*/
41+
async function getMacAddresses(): Promise<string[]> {
42+
try {
43+
const output = await execChildProcess('getmac');
44+
const regex = /(?:[a-z0-9]{2}[:\-]){5}[a-z0-9]{2}/gmi;
45+
return output.match(regex) ?? [];
46+
} catch (err) {
47+
return [];
48+
}
49+
}
50+
51+
/**
52+
* Code below is adapted from:
53+
* - vscode\src\vs\base\node\id.ts
54+
*/
55+
56+
async function getMachineId(macAddress?: string): Promise<string | undefined> {
57+
if (!macAddress) {
58+
return undefined;
59+
}
60+
61+
try {
62+
const crypto = await import('crypto');
63+
const normalized = macAddress.toUpperCase().replace(/:/g, '-');
64+
return crypto.createHash('sha256').update(normalized, 'utf8').digest('hex');
65+
} catch (err) {
66+
return undefined;
67+
}
68+
}

Extension/src/main.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import { PersistentState } from './LanguageServer/persistentState';
2222
import { CppSettings } from './LanguageServer/settings';
2323
import { logAndReturn, returns } from './Utility/Async/returns';
2424
import { CppTools1 } from './cppTools1';
25+
import { logMachineIdMappings } from './id';
2526
import { disposeOutputChannels, log } from './logger';
2627
import { PlatformInformation } from './platform';
2728

@@ -214,6 +215,7 @@ function sendTelemetry(info: PlatformInformation): void {
214215
break;
215216
}
216217
Telemetry.logDebuggerEvent("acquisition", telemetryProperties);
218+
logMachineIdMappings().catch(logAndReturn.undefined);
217219
}
218220

219221
async function checkVsixCompatibility(): Promise<void> {

0 commit comments

Comments
 (0)