UNPKG

native-reg

Version:

Native in-process low-level windows registry access.

240 lines (188 loc) 7.95 kB
const assert = require('assert').strict; const reg = require('..'); const testingSubKeyName = 'Software\\native-reg-testing-key'; suiteSetup(() => { reg.deleteTree(reg.HKCU, testingSubKeyName); }); suite('predefined HKEYS', () => { suite('isKEY', () => { test('accepts valid', () => { assert(reg.isHKEY(1)); assert(reg.isHKEY(reg.HKCU)); assert(reg.isHKEY(reg.HKEY.CURRENT_USER)); }); test('rejects invalid', () => { assert(!reg.isHKEY(undefined)); assert(!reg.isHKEY('HKCU')); assert(!reg.isHKEY(0)); assert(!reg.isHKEY(0.1)); assert(!reg.isHKEY(Number.MAX_SAFE_INTEGER)); assert(!reg.isHKEY({ native: 1 })); class HKEY { } assert(!reg.isHKEY(new HKEY())); }); }); test('enumKeyNames', () => { assertNameList(reg.enumKeyNames(reg.HKCU)); }); test('enumKeyValues', () => { assertNameList(reg.enumValueNames(reg.HKCU)); }); }); suite('openKey', () => { test('rejects invalid keys', () => { assert.throws(() => { reg.openKey('HKCU', 'Environment', reg.Access.ALL_ACCESS); }, (error) => error instanceof assert.AssertionError); assert.throws(() => { reg.openKey(reg.HKCU, 123, reg.Access.ALL_ACCESS); }, (error) => error instanceof assert.AssertionError); }); test('returns null for missing key', () => { const hkcuNoSuchKey = reg.openKey(reg.HKLM, 'NoSuchKey', reg.Access.ALL_ACCESS); assert.equal(hkcuNoSuchKey, null); reg.closeKey(hkcuNoSuchKey); }); test('can open and close HKLM with read access', () => { const userEnvKey = reg.openKey(reg.HKLM, 'SOFTWARE', reg.Access.READ); assert.notEqual(userEnvKey, null); reg.closeKey(userEnvKey); }); test('will throw access denied for HKLM ALL_ACCESS', () => { assert.throws(() => { reg.openKey(reg.HKLM, 'SOFTWARE', reg.Access.ALL_ACCESS); }, (error) => error.errno === 5); }); test('can open and close HKCU with ALL_ACCESS', () => { const userEnvKey = reg.openKey(reg.HKCU, 'SOFTWARE', reg.Access.ALL_ACCESS); reg.closeKey(userEnvKey); }); test('create and delete key', () => { const createdKey = reg.createKey(reg.HKCU, testingSubKeyName, reg.Access.ALL_ACCESS); const openedKey = reg.openKey(reg.HKCU, testingSubKeyName, reg.Access.READ); assert.notEqual(openedKey, null); reg.closeKey(openedKey); reg.deleteKey(reg.HKCU, testingSubKeyName); assert.equal(reg.openKey(reg.HKCU, testingSubKeyName, reg.Access.READ), null); }); }); suite('with HKCU\\Environment', () => { let userEnvKey = null; function closeUserEnvKey() { if (userEnvKey) { reg.closeKey(userEnvKey); userEnvKey = null; } } setup(() => { userEnvKey = reg.openKey(reg.HKCU, 'Environment', reg.Access.ALL_ACCESS); }); teardown(closeUserEnvKey); test('isKEY', () => { assert(reg.isHKEY(userEnvKey)); assert(reg.isHKEY(userEnvKey.native)); }); test('enumKeyNames', () => { assertNameList(reg.enumKeyNames(userEnvKey)); }); test('enumKeyValues', () => { assertNameList(reg.enumValueNames(userEnvKey)); }); test('read values', () => { const envTempQueryValueRaw = reg.queryValueRaw(userEnvKey, 'TEMP'); assert.equal(envTempQueryValueRaw.type, reg.ValueType.EXPAND_SZ); const envTempQueryValue = reg.queryValue(userEnvKey, 'TEMP'); assert.equal(envTempQueryValue, reg.parseString(envTempQueryValueRaw)); const envTempGetValueRaw = reg.getValueRaw( reg.HKCU, 'Environment', 'TEMP', reg.GetValueFlags.RT_ANY | reg.GetValueFlags.NO_EXPAND, ); console.log('getValueRaw(TEMP): %O', envTempGetValueRaw.toString('ucs-2')); assert.equal(envTempGetValueRaw.toString('ucs-2'), envTempQueryValueRaw.toString('ucs-2')); }); test('read missing value returns null', () => { const envNoSuchQueryValueRaw = reg.queryValueRaw(userEnvKey, 'NO_SUCH_VALUE'); assert.equal(envNoSuchQueryValueRaw, null); const envNoSuchQueryValue = reg.queryValue(userEnvKey, 'NO_SUCH_VALUE'); assert.equal(envNoSuchQueryValue, null); const envNoSuchGetValueRaw = reg.getValueRaw(reg.HKCU, 'Environment', 'NO_SUCH_VALUE'); assert.equal(envNoSuchGetValueRaw, null); const envNoSuchGetValue = reg.getValue(reg.HKCU, 'Environment', 'NO_SUCH_VALUE'); assert.equal(envNoSuchGetValue, null); }); test('read closed value throws', () => { let closedKey = userEnvKey; closeUserEnvKey(); // clears userEnvKey to avoid double-closing assert.throws(() => { reg.queryValue(closedKey, 'TEMP'); }, error => error.message === 'HKEY already closed'); // FIXME: something like instanceof reg.ClosedKeyError? }); }); suite('with temporary key', () => { let testKey = null; setup(() => { testKey = reg.createKey(reg.HKCU, testingSubKeyName, reg.Access.ALL_ACCESS); }); teardown(() => { reg.deleteKey(testKey, testingSubKeyName); }); test('write values', () => { reg.setValueRaw(testKey, 'Testing', reg.ValueType.DWORD, reg.formatDWORD(0x010203)); assert.equal(reg.getValueRaw(testKey, null, 'Testing').toString(), '\x03\x02\x01\x00'); assert.equal(reg.getValueRaw(testKey, null, 'Testing', reg.GetValueFlags.RT_REG_DWORD).toString(), '\x03\x02\x01\x00'); assert.throws( () => reg.getValueRaw(testKey, null, 'Testing', reg.GetValueFlags.RT_REG_QWORD).toString(), (error) => error.errno === 1630, // ERROR_UNSUPPORTED_TYPE ); assert.throws( () => reg.getValueRaw(testKey, null, 'Testing', reg.GetValueFlags.RT_REG_SZ).toString(), (error) => error.errno === 1630, ); const testValueData = Buffer.from('Test Value\0', 'ucs-2'); reg.setValueRaw(testKey, 'Testing', reg.ValueType.SZ, testValueData); const testQueryValueRaw = reg.queryValueRaw(testKey, 'Testing'); assert.equal(testQueryValueRaw.type, reg.ValueType.SZ); assert.equal(testQueryValueRaw.toString('ucs-2'), testValueData.toString('ucs-2')); const testNativeQueryValueRaw = reg.queryValueRaw(testKey.native, 'Testing'); assert.equal(testNativeQueryValueRaw.type, reg.ValueType.SZ); assert.equal(testNativeQueryValueRaw.toString('ucs-2'), testValueData.toString('ucs-2')); const testGetValueRaw = reg.getValueRaw( reg.HKCU, testingSubKeyName, 'Testing', reg.GetValueFlags.NO_EXPAND, ); assert.equal(testGetValueRaw.type, reg.ValueType.SZ); assert.equal(testGetValueRaw.toString('ucs-2'), testValueData.toString('ucs-2')); reg.setValueDWORD(testKey, 'Testing', 0x010203); const testGetValueRaw2 = reg.getValueRaw( reg.HKCU, testingSubKeyName, 'Testing', reg.GetValueFlags.RT_ANY | reg.GetValueFlags.NO_EXPAND, ); assert.equal(testGetValueRaw2.toString(), '\x03\x02\x01\x00'); reg.createKey(testKey, 'A', reg.Access.ALL_ACCESS); assert.deepEqual(reg.enumKeyNames(testKey), ['A']); reg.renameKey(testKey, 'A', 'B'); assert.deepEqual(reg.enumKeyNames(testKey), ['B']); const srcKey = reg.createKey(testKey, 'Src', reg.Access.ALL_ACCESS); reg.createKey(srcKey, 'C', reg.Access.ALL_ACCESS); const destKey = reg.createKey(testKey, 'Dest', reg.Access.ALL_ACCESS); assert.deepEqual(reg.enumKeyNames(srcKey), ['C']); reg.copyTree(testKey, 'Src', destKey); assert.deepEqual(reg.enumKeyNames(srcKey), ['C']); assert.deepEqual(reg.enumKeyNames(destKey), ['C']); reg.deleteValue(testKey, 'Testing'); assert.equal(reg.queryValue(testKey, 'Testing'), null); }); }); function assertNameList(nameList) { assert(Array.isArray(nameList)); for (const name of nameList) { assert(typeof name === 'string'); } }