/* registry initialisation, allocates some default keys. */ static ULONG allocate_default_keys(void) { static const WCHAR StatDataW[] = {'D','y','n','D','a','t','a','\\', 'P','e','r','f','S','t','a','t','s','\\', 'S','t','a','t','D','a','t','a',0}; static const WCHAR ConfigManagerW[] = {'D','y','n','D','a','t','a','\\', 'C','o','n','f','i','g',' ','M','a','n','a','g','e','r','\\', 'E','n','u','m',0}; HANDLE hkey; ULONG dispos; OBJECT_ATTRIBUTES attr; UNICODE_STRING nameW; attr.Length = sizeof(attr); attr.RootDirectory = 0; attr.ObjectName = &nameW; attr.Attributes = 0; attr.SecurityDescriptor = NULL; attr.SecurityQualityOfService = NULL; RtlInitUnicodeString( &nameW, StatDataW ); if (!NtCreateKey( &hkey, KEY_ALL_ACCESS, &attr, 0, NULL, 0, &dispos )) NtClose( hkey ); if (dispos == REG_OPENED_EXISTING_KEY) return dispos; /* someone else already loaded the registry */ RtlInitUnicodeString( &nameW, ConfigManagerW ); if (!NtCreateKey( &hkey, KEY_ALL_ACCESS, &attr, 0, NULL, 0, NULL )) NtClose( hkey ); return dispos; }
void CreateKeyTest(void) { HANDLE hKey; OBJECT_ATTRIBUTES ObjectAttributes; NTSTATUS Status; UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\Software\\testkey"); dprintf("Create key '\\Registry\\Machine\\Software\\testkey':\n"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL); dprintf("NtCreateKey:\n"); Status = NtCreateKey(&hKey, KEY_ALL_ACCESS, &ObjectAttributes, 0, NULL, REG_OPTION_NON_VOLATILE, NULL); dprintf(" Status = %lx\n",Status); if (NT_SUCCESS(Status)) { NtClose(hKey); } }
BOOLEAN SetMountedDeviceValue(CHAR Letter, ULONG Signature, LARGE_INTEGER StartingOffset) { OBJECT_ATTRIBUTES ObjectAttributes; WCHAR ValueNameBuffer[16]; UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\MountedDevices"); UNICODE_STRING ValueName; REG_DISK_MOUNT_INFO MountInfo; NTSTATUS Status; HANDLE KeyHandle; swprintf(ValueNameBuffer, L"\\DosDevices\\%C:", Letter); RtlInitUnicodeString(&ValueName, ValueNameBuffer); InitializeObjectAttributes (&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = NtOpenKey (&KeyHandle, KEY_ALL_ACCESS, &ObjectAttributes); if (!NT_SUCCESS(Status)) { Status = NtCreateKey(&KeyHandle, KEY_ALL_ACCESS, &ObjectAttributes, 0, NULL, REG_OPTION_NON_VOLATILE, NULL); } if (!NT_SUCCESS(Status)) { DPRINT1("NtCreateKey() failed (Status %lx)\n", Status); return FALSE; } MountInfo.Signature = Signature; MountInfo.StartingOffset = StartingOffset; Status = NtSetValueKey (KeyHandle, &ValueName, 0, REG_BINARY, (PVOID)&MountInfo, sizeof(MountInfo)); NtClose(KeyHandle); if (!NT_SUCCESS(Status)) { DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status); return FALSE; } return TRUE; }
NTSTATUS LsapSetObjectAttribute(PLSA_DB_OBJECT DbObject, LPWSTR AttributeName, LPVOID AttributeData, ULONG AttributeSize) { OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING KeyName; HANDLE AttributeKey; NTSTATUS Status; RtlInitUnicodeString(&KeyName, AttributeName); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, DbObject->KeyHandle, NULL); Status = NtCreateKey(&AttributeKey, KEY_SET_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_NON_VOLATILE, NULL); if (!NT_SUCCESS(Status)) { ERR("NtCreateKey failed for '%S' with status 0x%lx\n", AttributeName, Status); return Status; } Status = RtlpNtSetValueKey(AttributeKey, REG_NONE, AttributeData, AttributeSize); NtClose(AttributeKey); if (!NT_SUCCESS(Status)) { ERR("RtlpNtSetValueKey failed for '%S' with status 0x%lx\n", AttributeName, Status); } return Status; }
/* registry link delete test */ void test7(void) { HANDLE hKey; OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING KeyName,ValueName; NTSTATUS Status; dprintf("Open link key\n"); dprintf(" Key: \\Registry\\Machine\\SOFTWARE\\Test\n"); RtlRosInitUnicodeStringFromLiteral(&KeyName, L"\\Registry\\Machine\\SOFTWARE\\Test"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE | OBJ_OPENIF | OBJ_OPENLINK, NULL, NULL); Status = NtCreateKey(&hKey, KEY_ALL_ACCESS, &ObjectAttributes, 0, NULL, REG_OPTION_VOLATILE | REG_OPTION_OPEN_LINK, NULL); dprintf(" NtCreateKey() called (Status %lx)\n",Status); if (!NT_SUCCESS(Status)) { dprintf("Could not open the link key. Please run the link create test first!\n"); return; } dprintf("Delete link value\n"); RtlRosInitUnicodeStringFromLiteral(&ValueName, L"SymbolicLinkValue"); Status = NtDeleteValueKey(hKey, &ValueName); dprintf(" NtDeleteValueKey() called (Status %lx)\n",Status); dprintf("Delete link key\n"); Status=NtDeleteKey(hKey); dprintf(" NtDeleteKey() called (Status %lx)\n",Status); dprintf("Close link key\n"); NtClose(hKey); }
/*********************************************************************** * TIMEZONE_InitRegistry * * Update registry contents on startup if the user timezone has changed. * This simulates the action of the Windows control panel. */ void TIMEZONE_InitRegistry(void) { static const WCHAR szTimezoneInformation[] = { 'M','a','c','h','i','n','e','\\','S','y','s','t','e','m','\\', 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\', 'C','o','n','t','r','o','l','\\', 'T','i','m','e','Z','o','n','e','I','n','f','o','r','m','a','t','i','o','n','\0' }; WCHAR standardnameW[] = {'S','t','a','n','d','a','r','d','N','a','m','e','\0'}; WCHAR timezonekeynameW[] = {'T','i','m','e','Z','o','n','e','K','e','y','N','a','m','e','\0'}; DYNAMIC_TIME_ZONE_INFORMATION tzinfo; UNICODE_STRING keyName; OBJECT_ATTRIBUTES attr; HANDLE hkey; DWORD tzid; tzid = GetDynamicTimeZoneInformation(&tzinfo); if (tzid == TIME_ZONE_ID_INVALID) { ERR("fail to get timezone information.\n"); return; } RtlInitUnicodeString(&keyName, szTimezoneInformation); InitializeObjectAttributes(&attr, &keyName, 0, 0, NULL); if (NtCreateKey(&hkey, KEY_ALL_ACCESS, &attr, 0, NULL, 0, NULL) != STATUS_SUCCESS) { ERR("fail to create timezone information key.\n"); return; } RtlInitUnicodeString(&keyName, standardnameW); NtSetValueKey(hkey, &keyName, 0, REG_SZ, tzinfo.StandardName, (strlenW(tzinfo.StandardName) + 1) * sizeof(WCHAR)); RtlInitUnicodeString(&keyName, timezonekeynameW); NtSetValueKey(hkey, &keyName, 0, REG_SZ, tzinfo.TimeZoneKeyName, (strlenW(tzinfo.TimeZoneKeyName) + 1) * sizeof(WCHAR)); NtClose( hkey ); }
void SetValueTest1(void) { HANDLE hKey; OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\Software\\testkey"); UNICODE_STRING ValueName = RTL_CONSTANT_STRING(L"TestValue"); NTSTATUS Status; dprintf("Create key '\\Registry\\Machine\\Software\\testkey':\n"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE | OBJ_OPENIF, NULL, NULL); dprintf("NtCreateKey:\n"); Status = NtCreateKey(&hKey, KEY_ALL_ACCESS, &ObjectAttributes, 0, NULL, REG_OPTION_NON_VOLATILE, NULL); dprintf(" Status = %lx\n",Status); if (!NT_SUCCESS(Status)) return; dprintf("NtSetValueKey:\n"); Status = NtSetValueKey(hKey, &ValueName, 0, REG_SZ, (PVOID)L"TestString", 24); dprintf(" Status = %lx\n",Status); NtClose(hKey); }
static NTSTATUS CreateRegKey( OUT PHANDLE KeyHandle, IN HANDLE RootKey OPTIONAL, IN PUNICODE_STRING KeyName, IN ULONG CreateOptions, OUT PULONG Disposition OPTIONAL) { OBJECT_ATTRIBUTES ObjectAttributes; InitializeObjectAttributes(&ObjectAttributes, KeyName, OBJ_CASE_INSENSITIVE, RootKey, NULL); return NtCreateKey(KeyHandle, KEY_ALL_ACCESS, &ObjectAttributes, 0, NULL, CreateOptions, Disposition); }
void test3(void) { HANDLE hKey; OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING KeyName; NTSTATUS Status; char Buffer[10]; DWORD Result; dprintf("NtCreateKey non volatile: \n"); dprintf(" \\Registry\\Machine\\Software\\test3reactos: "); RtlRosInitUnicodeStringFromLiteral(&KeyName, L"\\Registry\\Machine\\Software\\test3reactos"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE , NULL, NULL); Status = NtCreateKey ( &hKey, KEY_ALL_ACCESS , &ObjectAttributes ,0,NULL,REG_OPTION_NON_VOLATILE,NULL); dprintf("\t\tStatus=%x\n",Status); NtClose(hKey); dprintf("delete \\Registry\\Machine\\software\\test3reactos ?"); ReadConsoleA(InputHandle, Buffer, 3, &Result, NULL) ; if (Buffer[0] != 'y' && Buffer[0] != 'Y') return; dprintf("delete \\Registry\\Machine\\software\\test3reactos ?"); RtlRosInitUnicodeStringFromLiteral(&KeyName, L"\\Registry\\Machine\\Software\\test3reactos"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL); dprintf("NtOpenKey : "); Status=NtOpenKey( &hKey, KEY_ALL_ACCESS, &ObjectAttributes); dprintf("\t\t\t\tStatus =%x\n",Status); dprintf("NtDeleteKey : "); Status=NtDeleteKey(hKey); dprintf("\t\t\t\tStatus =%x\n",Status); NtClose(hKey); }
NTSTATUS CmpInitializeRegistryNode( IN PCONFIGURATION_COMPONENT_DATA CurrentEntry, IN HANDLE ParentHandle, OUT PHANDLE NewHandle, IN INTERFACE_TYPE InterfaceType, IN ULONG BusNumber, IN PUSHORT DeviceIndexTable ) /*++ Routine Description: This routine creates a node for the current firmware component and puts component data to the data part of the node. Arguments: CurrentEntry - Supplies a pointer to a configuration component. Handle - Supplies the parent handle of CurrentEntry node. NewHandle - Supplies a pointer to a HANDLE to receive the handle of the newly created node. InterfaceType - Specify the Interface type of the bus that the CurrentEntry component resides. (See BusNumber also) BusNumber - Specify the Bus Number of the bus that the CurrentEntry component resides on. If Bus number is -1, it means InterfaceType and BusNumber are meaningless for this component. Returns: None. --*/ { NTSTATUS Status; OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING KeyName; UNICODE_STRING ValueName; UNICODE_STRING ValueData; HANDLE Handle; HANDLE OldHandle; ANSI_STRING AnsiString; CHAR Buffer[12]; WCHAR UnicodeBuffer[12]; CONFIGURATION_COMPONENT *Component; ULONG Disposition; ULONG ConfigurationDataLength = 0; PCM_FULL_RESOURCE_DESCRIPTOR NewArea; Component = &CurrentEntry->ComponentEntry; // // If the component class is SystemClass, we set its Type to be // ArcSystem. The reason is because the detection code sets // its type to MaximumType to indicate it is NOT ARC compatible. // Here, we are only interested in building a System Node. So we // change its Type to ArcSystem to ease the setup. // if (Component->Class == SystemClass) { Component->Type = ArcSystem; } // // Create a new key to describe the Component. // // The type of the component will be used as the keyname of the // registry node. The class is the class of the component. // InitializeObjectAttributes( &ObjectAttributes, &(CmTypeName[Component->Type]), 0, ParentHandle, NULL ); ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE; Status = NtCreateKey( // Paht may already exist &Handle, KEY_READ | KEY_WRITE, &ObjectAttributes, 0, NULL, 0, &Disposition ); if (!NT_SUCCESS(Status)) { return(Status); } // // If this component is NOT a SystemClass component, we will // create a subkey to identify the component's ordering. // if (Component->Class != SystemClass) { RtlIntegerToChar( DeviceIndexTable[Component->Type]++, 10, 12, Buffer ); RtlInitAnsiString( &AnsiString, Buffer ); KeyName.Buffer = (PWSTR)UnicodeBuffer; KeyName.Length = 0; KeyName.MaximumLength = sizeof(UnicodeBuffer); RtlAnsiStringToUnicodeString( &KeyName, &AnsiString, FALSE ); OldHandle = Handle; InitializeObjectAttributes( &ObjectAttributes, &KeyName, 0, OldHandle, NULL ); ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE; Status = NtCreateKey( &Handle, KEY_READ | KEY_WRITE, &ObjectAttributes, 0, NULL, 0, &Disposition ); NtClose(OldHandle); if (!NT_SUCCESS(Status)) { return(Status); } ASSERT(Disposition == REG_CREATED_NEW_KEY); } // // Create a value which describes the following component information: // Flags, Cersion, Key, AffinityMask. // RtlInitUnicodeString( &ValueName, L"Component Information" ); Status = NtSetValueKey( Handle, &ValueName, TITLE_INDEX_VALUE, REG_BINARY, &Component->Flags, FIELD_OFFSET(CONFIGURATION_COMPONENT, ConfigurationDataLength) - FIELD_OFFSET(CONFIGURATION_COMPONENT, Flags) ); if (!NT_SUCCESS(Status)) { NtClose(Handle); return(Status); } // // Create a value which describes the component identifier, if any. // if (Component->IdentifierLength) { RtlInitUnicodeString( &ValueName, L"Identifier" ); RtlInitAnsiString( &AnsiString, Component->Identifier ); Status = RtlAnsiStringToUnicodeString( &ValueData, &AnsiString, TRUE ); if( NT_SUCCESS(Status) ) { Status = NtSetValueKey( Handle, &ValueName, TITLE_INDEX_VALUE, REG_SZ, ValueData.Buffer, ValueData.Length + sizeof( UNICODE_NULL ) ); RtlFreeUnicodeString(&ValueData); } if (!NT_SUCCESS(Status)) { NtClose(Handle); return(Status); } } // // Create a value entry for component configuration data. // RtlInitUnicodeString( &ValueName, L"Configuration Data" ); // // Create the configuration data based on CM_FULL_RESOURCE_DESCRIPTOR. // // Note the configuration data in firmware tree may be in the form of // CM_PARTIAL_RESOURCE_LIST or nothing. In both cases, we need to // set up the registry configuration data to be in the form of // CM_FULL_RESOURCE_DESCRIPTOR. // if (CurrentEntry->ConfigurationData) { // // This component has configuration data, we copy the data // to our work area, add some more data items and copy the new // configuration data to the registry. // ConfigurationDataLength = Component->ConfigurationDataLength + FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList); // // Make sure our reserved area is big enough to hold the data. // if (ConfigurationDataLength > CmpConfigurationAreaSize) { // // If reserved area is not big enough, we resize our reserved // area. If, unfortunately, the reallocation fails, we simply // loss the configuration data of this particular component. // NewArea = (PCM_FULL_RESOURCE_DESCRIPTOR)ExAllocatePool( PagedPool, ConfigurationDataLength ); if (NewArea) { CmpConfigurationAreaSize = ConfigurationDataLength; ExFreePool(CmpConfigurationData); CmpConfigurationData = NewArea; RtlCopyMemory( (PUCHAR)&CmpConfigurationData->PartialResourceList.Version, CurrentEntry->ConfigurationData, Component->ConfigurationDataLength ); } else { Component->ConfigurationDataLength = 0; CurrentEntry->ConfigurationData = NULL; } } else { RtlCopyMemory( (PUCHAR)&CmpConfigurationData->PartialResourceList.Version, CurrentEntry->ConfigurationData, Component->ConfigurationDataLength ); } } if (CurrentEntry->ConfigurationData == NULL) { // // This component has NO configuration data (or we can't resize // our reserved area to hold the data), we simple add whatever // is required to set up a CM_FULL_RESOURCE_LIST. // CmpConfigurationData->PartialResourceList.Version = 0; CmpConfigurationData->PartialResourceList.Revision = 0; CmpConfigurationData->PartialResourceList.Count = 0; ConfigurationDataLength = FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList) + FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST, PartialDescriptors); } // // Set up InterfaceType and BusNumber for the component. // CmpConfigurationData->InterfaceType = InterfaceType; CmpConfigurationData->BusNumber = BusNumber; // // Write the newly constructed configuration data to the hardware registry // Status = NtSetValueKey( Handle, &ValueName, TITLE_INDEX_VALUE, REG_FULL_RESOURCE_DESCRIPTOR, CmpConfigurationData, ConfigurationDataLength ); if (!NT_SUCCESS(Status)) { NtClose(Handle); return(Status); } *NewHandle = Handle; return(STATUS_SUCCESS); }
void __cdecl main( int argc, char *argv[] ) { NTSTATUS status; OBJECT_ATTRIBUTES ObjectAttributes; HANDLE BaseHandle; HANDLE WorkHandle; ULONG Disposition; UNICODE_STRING ClassName; ULONG i; ULONG j; PUCHAR p; // // Process args // processargs(argc, argv); // // Set up and create/open KeyPath|KeyName // printf("rtvbatcr: starting\n"); WorkName.MaximumLength = WORK_SIZE; WorkName.Length = 0L; WorkName.Buffer = &(workbuffer[0]); RtlCopyString((PSTRING)&WorkName, (PSTRING)&KeyPath); p = WorkName.Buffer; p += WorkName.Length; *p = '\\'; p++; *p = '\0'; WorkName.Length += 2; RtlAppendStringToString((PSTRING)&WorkName, (PSTRING)&KeyName); RtlInitUnicodeString( &ClassName, L"Test Class Name" ); InitializeObjectAttributes( &ObjectAttributes, &WorkName, 0, (HANDLE)NULL, NULL ); ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE; status = NtCreateKey( &BaseHandle, MAXIMUM_ALLOWED, &ObjectAttributes, 0, &ClassName, REG_OPTION_VOLATILE, &Disposition ); if (!NT_SUCCESS(status)) { printf("rtvbatcr: t0: %08lx\n", status); failure++; goto punt; } // // Create NumberChildren subkeys // for (i = 0; i < NumberChildren; i++) { sprintf(formatbuffer, "%s%d", BaseName, i); RtlInitString(&format, formatbuffer); RtlAnsiStringToUnicodeString(&WorkName, &format, FALSE); InitializeObjectAttributes( &ObjectAttributes, &WorkName, 0, BaseHandle, NULL ); ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE; status = NtCreateKey( &WorkHandle, MAXIMUM_ALLOWED, &ObjectAttributes, 0, &ClassName, REG_OPTION_VOLATILE, &Disposition ); if (!NT_SUCCESS(status)) { printf("rtvbatcr: t1: status = %08lx i = %d\n", status, i); failure++; } // // Create NumberValues value entries for each (current) key // for (j = 0; j < NumberValues; j++) { sprintf(formatbuffer, "%s%d", BaseName, j); RtlInitString(&format, formatbuffer); RtlAnsiStringToUnicodeString(&WorkName, &format, FALSE); sprintf( formatbuffer, "This is a rtvbatcr value for %s%d", BaseName, j ); status = NtSetValueKey( WorkHandle, &WorkName, j, j, formatbuffer, strlen(formatbuffer)+1 ); if (!NT_SUCCESS(status)) { printf("rtvbatcr: t2: status = %08lx j = %d\n", status, j); failure++; } } NtClose(WorkHandle); } punt: printf("rtvbatcr: %d failures\n", failure); exit(failure); }
NTSTATUS CmpInitializeHardwareConfiguration( IN PLOADER_PARAMETER_BLOCK LoaderBlock ) /*++ Routine Description: This routine creates \\Registry\Machine\Hardware node in the registry and calls SetupTree routine to put the hardware information to the registry. Arguments: LoaderBlock - supplies a pointer to the LoaderBlock passed in from the OS Loader. Returns: NTSTATUS code for sucess or reason of failure. --*/ { NTSTATUS Status; OBJECT_ATTRIBUTES ObjectAttributes; HANDLE BaseHandle; PCONFIGURATION_COMPONENT_DATA ConfigurationRoot; ULONG Disposition; ConfigurationRoot = (PCONFIGURATION_COMPONENT_DATA)LoaderBlock->ConfigurationRoot; if (ConfigurationRoot) { #ifdef _X86_ // // The following strings found in the registry identify obscure, // yet market dominant, non PC/AT compatible i386 machine in Japan. // #define MACHINE_TYPE_FUJITSU_FMR_NAME_A "FUJITSU FMR-" #define MACHINE_TYPE_NEC_PC98_NAME_A "NEC PC-98" { PCONFIGURATION_COMPONENT_DATA SystemNode; ULONG JapanMachineId; // // For Japan, we have to special case some non PC/AT machines, so // determine at this time what kind of platform we are on: // // NEC PC9800 Compatibles/Fujitsu FM-R Compatibles/IBM PC/AT Compatibles // // Default is PC/AT compatible. // JapanMachineId = MACHINE_TYPE_PC_AT_COMPATIBLE; // // Find the hardware description node // SystemNode = KeFindConfigurationEntry(ConfigurationRoot, SystemClass, MaximumType, NULL); // // Did we find something? // if (SystemNode) { // // Check platform from identifier string // if (RtlCompareMemory(SystemNode->ComponentEntry.Identifier, MACHINE_TYPE_NEC_PC98_NAME_A, sizeof(MACHINE_TYPE_NEC_PC98_NAME_A) - 1) == sizeof(MACHINE_TYPE_NEC_PC98_NAME_A) - 1) { // // we are running on NEC PC-9800 comaptibles. // JapanMachineId = MACHINE_TYPE_PC_9800_COMPATIBLE; SetNEC_98; } else if (RtlCompareMemory(SystemNode->ComponentEntry.Identifier, MACHINE_TYPE_FUJITSU_FMR_NAME_A, sizeof(MACHINE_TYPE_FUJITSU_FMR_NAME_A) - 1) == sizeof(MACHINE_TYPE_FUJITSU_FMR_NAME_A) - 1) { // // we are running on Fujitsu FMR comaptibles. // JapanMachineId = MACHINE_TYPE_FMR_COMPATIBLE; } } // // Now 'or' this value into the kernel global. // KeI386MachineType |= JapanMachineId; } #endif //_X86_ // // Create \\Registry\Machine\Hardware\DeviceMap // InitializeObjectAttributes( &ObjectAttributes, &CmRegistryMachineHardwareDeviceMapName, 0, (HANDLE)NULL, NULL ); ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE; Status = NtCreateKey( // Paht may already exist &BaseHandle, KEY_READ | KEY_WRITE, &ObjectAttributes, TITLE_INDEX_VALUE, NULL, 0, &Disposition ); if (!NT_SUCCESS(Status)) { return(Status); } NtClose(BaseHandle); ASSERT(Disposition == REG_CREATED_NEW_KEY); // // Create \\Registry\Machine\Hardware\Description and use the // returned handle as the BaseHandle to build the hardware tree. // InitializeObjectAttributes( &ObjectAttributes, &CmRegistryMachineHardwareDescriptionName, 0, (HANDLE)NULL, NULL ); ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE; Status = NtCreateKey( // Path may already exist &BaseHandle, KEY_READ | KEY_WRITE, &ObjectAttributes, TITLE_INDEX_VALUE, NULL, 0, &Disposition ); if (!NT_SUCCESS(Status)) { return(Status); } ASSERT(Disposition == REG_CREATED_NEW_KEY); // // Allocate 16K bytes memory from paged pool for constructing // configuration data for controller component. // NOTE: The configuration Data for controller component // usually takes less than 100 bytes. But on EISA machine, the // EISA configuration information takes more than 10K and up to // 64K. I believe 16K is the reasonable number to handler 99.9% // of the machines. Therefore, 16K is the initial value. // CmpConfigurationData = (PCM_FULL_RESOURCE_DESCRIPTOR)ExAllocatePool( PagedPool, CmpConfigurationAreaSize ); if (CmpConfigurationData == NULL) { return(STATUS_INSUFFICIENT_RESOURCES); } // // Call SetupConfigurationTree routine to go over each component // of the tree and add component information to registry database. // Status = CmpSetupConfigurationTree(ConfigurationRoot, BaseHandle, -1, (ULONG)-1 ); ExFreePool((PVOID)CmpConfigurationData); NtClose(BaseHandle); return(Status); } else { return(STATUS_SUCCESS); } }
NTSTATUS BasepMoveFileDelayed( IN PUNICODE_STRING OldFileName, IN PUNICODE_STRING NewFileName ) /*++ Routine Description: Appends the given delayed move file operation to the registry value that contains the list of move file operations to be performed on the next boot. Arguments: OldFileName - Supplies the old file name NewFileName - Supplies the new file name Return Value: NTSTATUS --*/ { OBJECT_ATTRIBUTES Obja; UNICODE_STRING KeyName; UNICODE_STRING ValueName; HANDLE KeyHandle; PWSTR ValueData, s; PKEY_VALUE_PARTIAL_INFORMATION ValueInfo; ULONG ValueLength = 1024; ULONG ReturnedLength; NTSTATUS Status; RtlInitUnicodeString( &KeyName, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Session Manager" ); RtlInitUnicodeString( &ValueName, L"PendingFileRenameOperations" ); InitializeObjectAttributes( &Obja, &KeyName, OBJ_OPENIF | OBJ_CASE_INSENSITIVE, NULL, NULL ); Status = NtCreateKey( &KeyHandle, GENERIC_READ | GENERIC_WRITE, &Obja, 0, NULL, 0, NULL ); if ( Status == STATUS_ACCESS_DENIED ) { Status = NtCreateKey( &KeyHandle, GENERIC_READ | GENERIC_WRITE, &Obja, 0, NULL, REG_OPTION_BACKUP_RESTORE, NULL ); } if (NT_SUCCESS( Status )) { retry: ValueInfo = RtlAllocateHeap(RtlProcessHeap(), MAKE_TAG(TMP_TAG), ValueLength + OldFileName->Length + sizeof(WCHAR) + NewFileName->Length + 2*sizeof(WCHAR)); if (ValueInfo == NULL) { NtClose(KeyHandle); return(STATUS_NO_MEMORY); } // // File rename operations are stored in the registry in a // single MULTI_SZ value. This allows the renames to be // performed in the same order that they were originally // requested. Each rename operation consists of a pair of // NULL-terminated strings. // Status = NtQueryValueKey(KeyHandle, &ValueName, KeyValuePartialInformation, ValueInfo, ValueLength, &ReturnedLength); if (Status == STATUS_BUFFER_OVERFLOW) { // // The existing value is too large for our buffer. // Retry with a larger buffer. // ValueLength = ReturnedLength; RtlFreeHeap(RtlProcessHeap(), 0, ValueInfo); goto retry; } if (Status == STATUS_OBJECT_NAME_NOT_FOUND) { // // The value does not currently exist. Create the // value with our data. // s = ValueData = (PWSTR)ValueInfo; } else if (NT_SUCCESS(Status)) { // // A value already exists, append our two strings to the // MULTI_SZ. // ValueData = (PWSTR)(&ValueInfo->Data); s = (PWSTR)((PCHAR)ValueData + ValueInfo->DataLength) - 1; } else { NtClose(KeyHandle); RtlFreeHeap(RtlProcessHeap(), 0, ValueInfo); return(Status); } CopyMemory(s, OldFileName->Buffer, OldFileName->Length); s += (OldFileName->Length/sizeof(WCHAR)); *s++ = L'\0'; CopyMemory(s, NewFileName->Buffer, NewFileName->Length); s += (NewFileName->Length/sizeof(WCHAR)); *s++ = L'\0'; *s++ = L'\0'; Status = NtSetValueKey(KeyHandle, &ValueName, 0, REG_MULTI_SZ, ValueData, (s-ValueData)*sizeof(WCHAR)); NtClose(KeyHandle); RtlFreeHeap(RtlProcessHeap(), 0, ValueInfo); } return(Status); }
static VOID TestCreateOpen_( _In_ ACCESS_MASK DesiredAccess, _In_ ACCESS_MASK ExpectedAccess, _In_ NTSTATUS ExpectedStatus, _In_ PCSTR File, _In_ INT Line) { NTSTATUS Status; HANDLE KeyHandle; UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\Software"); OBJECT_ATTRIBUTES ObjectAttributes; InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = NtCreateKey(&KeyHandle, DesiredAccess, &ObjectAttributes, 0, NULL, REG_OPTION_NON_VOLATILE, NULL); ok_(File, Line)(Status == ExpectedStatus, "NtCreateKey returned 0x%lx, expected 0x%lx\n", Status, ExpectedStatus); if (NT_SUCCESS(Status)) { VerifyAccess_(KeyHandle, ExpectedAccess, File, Line); Status = NtClose(KeyHandle); ok_(File, Line)(Status == STATUS_SUCCESS, "NtClose from NtCreateKey returned 0x%lx\n", Status); } else if (NT_SUCCESS(ExpectedStatus)) { skip_(File, Line)("NtCreateKey failed, skipping\n"); } Status = NtOpenKey(&KeyHandle, DesiredAccess, &ObjectAttributes); ok_(File, Line)(Status == ExpectedStatus, "NtOpenKey returned 0x%lx, expected 0x%lx\n", Status, ExpectedStatus); if (NT_SUCCESS(Status)) { VerifyAccess_(KeyHandle, ExpectedAccess, File, Line); Status = NtClose(KeyHandle); ok_(File, Line)(Status == STATUS_SUCCESS, "NtClose from NtOpenKey returned 0x%lx\n", Status); } else if (NT_SUCCESS(ExpectedStatus)) { skip_(File, Line)("NtOpenKey failed, skipping\n"); } }
VOID DoTest( HANDLE RootKey ) { NTSTATUS rc; STRING String1; UCHAR Value1[] = "This string is value 1."; UCHAR Value2[] = "Value 2 is represented by this string."; HANDLE Handle1; HANDLE Handle2; ULONG ValueLength; ULONG Type; LARGE_INTEGER Time; // // Create parent node // DbgPrint("Part1\n"); RtlInitString(&String1, "Test1"); rc = NtCreateKey( RootKey, &String1, 0, NULL, GENERIC_READ|GENERIC_WRITE, &Handle1 ); if (!NT_SUCCESS(rc)) { DbgPrint("1:CreateKey failed rc = %08lx", rc); return; } // // Set data into parent // DbgPrint("Part2\n"); rc = NtSetValueKey( Handle1, 1, // type Value1, strlen(Value1) ); if (!NT_SUCCESS(rc)) { DbgPrint("2:SetValueKey failed rc = %08lx", rc); return; } // // Query and compare data from parent // DbgPrint("Part2b\n"); ValueLength = MAX_VALUE; rc = NtQueryValueKey( Handle1, &Type, ValueBuffer, &ValueLength, &Time ); if (!NT_SUCCESS(rc)) { DbgPrint("2b:QueryValueKey failed rc = %08lx", rc); return; } if (ValueLength != (ULONG)strlen(Value1)) { DbgPrint("2b1:Wrong value length\n"); return; } else if (RtlCompareMemory( ValueBuffer, Value1, ValueLength) != ValueLength) { DbgPrint("2b2:Wrong value\n"); return; } else if (Type != 1) { DbgPrint("2b3:Wrong type\n"); return; } // // Close parent // DbgPrint("Part3\n"); NtCloseKey(Handle1); if (!NT_SUCCESS(rc)) { DbgPrint("3:CloseKey failed rc = %08lx", rc); return; } // // Reopen parent // DbgPrint("Part4\n"); rc = NtOpenKey( RootKey, &String1, 0, GENERIC_READ|GENERIC_WRITE, &Handle1 ); if (!NT_SUCCESS(rc)) { DbgPrint("4:OpenKey failed rc = %08lx", rc); return; } // // Create child // DbgPrint("Part5\n"); RtlInitString(&String1, "Test2"); rc = NtCreateKey( Handle1, &String1, 0, NULL, GENERIC_READ|GENERIC_WRITE, &Handle2 ); if (!NT_SUCCESS(rc)) { DbgPrint("5:CreateKey failed rc = %08lx", rc); return; } // // Set data into child // DbgPrint("Part6\n"); rc = NtSetValueKey( Handle2, 2, // type Value2, strlen(Value2) ); if (!NT_SUCCESS(rc)) { DbgPrint("6:SetValueKey failed rc = %08lx", rc); return; } // // Query and compare data from child // DbgPrint("Part7\n"); ValueLength = MAX_VALUE; rc = NtQueryValueKey( Handle2, &Type, ValueBuffer, &ValueLength, &Time ); if (!NT_SUCCESS(rc)) { DbgPrint("7:QueryValueKey failed rc = %08lx", rc); return; } if (ValueLength != (ULONG)strlen(Value2)) { DbgPrint("7.1:Wrong value length\n"); return; } else if (RtlCompareMemory( ValueBuffer, Value2, ValueLength) != ValueLength) { DbgPrint("7.2:Wrong value\n"); return; } else if (Type != 2) { DbgPrint("7.3:Wrong type\n"); return; } // // Query and compare data from parent again // DbgPrint("Part8\n"); ValueLength = MAX_VALUE; rc = NtQueryValueKey( Handle1, &Type, ValueBuffer, &ValueLength, &Time ); if (!NT_SUCCESS(rc)) { DbgPrint("8:QueryValueKey failed rc = %08lx", rc); return; } if (ValueLength != (ULONG)strlen(Value1)) { DbgPrint("8.1:Wrong value length\n"); return; } else if (RtlCompareMemory( ValueBuffer, Value1, ValueLength) != ValueLength) { DbgPrint("8.2:Wrong value\n"); return; } else if (Type != 1) { DbgPrint("8.3:Wrong type\n"); return; } // // Reset parent data // DbgPrint("Part9\n"); rc = NtSetValueKey( Handle1, 1, // type Value2, strlen(Value2) ); if (!NT_SUCCESS(rc)) { DbgPrint("9:SetValueKey failed rc = %08lx", rc); return; } // // Query and compare reset data // DbgPrint("Part10\n"); ValueLength = MAX_VALUE; rc = NtQueryValueKey( Handle1, &Type, ValueBuffer, &ValueLength, &Time ); if (!NT_SUCCESS(rc)) { DbgPrint("10:QueryValueKey failed rc = %08lx", rc); return; } if (ValueLength != (ULONG)strlen(Value2)) { DbgPrint("10.1:Wrong value length\n"); return; } else if (RtlCompareMemory( ValueBuffer, Value2, ValueLength) != ValueLength) { DbgPrint("10.2:Wrong value\n"); return; } else if (Type != 1) { DbgPrint("10.3:Wrong type\n"); return; } // // Close off handles and return // DbgPrint("Part11\n"); rc = NtCloseKey(Handle1); if (!NT_SUCCESS(rc)) { DbgPrint("11:CloseKey failed rc = %08lx", rc); return; } DbgPrint("Part12\n"); rc = NtCloseKey(Handle2); if (!NT_SUCCESS(rc)) { DbgPrint("12:CloseKey failed rc = %08lx", rc); return; } return; }
BOOLEAN AddKbLayoutsToRegistry( IN const MUI_LAYOUTS *MuiLayouts) { OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING KeyName; UNICODE_STRING ValueName; HANDLE KeyHandle; HANDLE SubKeyHandle; NTSTATUS Status; ULONG Disposition; ULONG uIndex = 0; ULONG uCount = 0; WCHAR szKeyName[48] = L".DEFAULT\\Keyboard Layout"; WCHAR szValueName[3 + 1]; WCHAR szLangID[8 + 1]; // Open the keyboard layout key RtlInitUnicodeString(&KeyName, szKeyName); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, GetRootKeyByPredefKey(HKEY_USERS, NULL), NULL); Status = NtCreateKey(&KeyHandle, KEY_CREATE_SUB_KEY, &ObjectAttributes, 0, NULL, REG_OPTION_NON_VOLATILE, &Disposition); if (!NT_SUCCESS(Status)) { DPRINT1("NtCreateKey() failed (Status %lx)\n", Status); return FALSE; } NtClose(KeyHandle); KeyName.MaximumLength = sizeof(szKeyName); Status = RtlAppendUnicodeToString(&KeyName, L"\\Preload"); if (!NT_SUCCESS(Status)) { DPRINT1("RtlAppend failed! (%lx)\n", Status); DPRINT1("String is %wZ\n", &KeyName); return FALSE; } InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, GetRootKeyByPredefKey(HKEY_USERS, NULL), NULL); Status = NtCreateKey(&KeyHandle, KEY_SET_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_NON_VOLATILE, &Disposition); if (!NT_SUCCESS(Status)) { DPRINT1("NtCreateKey() failed (Status %lx)\n", Status); return FALSE; } RtlInitUnicodeString(&KeyName, L".DEFAULT\\Keyboard Layout\\Substitutes"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, GetRootKeyByPredefKey(HKEY_USERS, NULL), NULL); Status = NtCreateKey(&SubKeyHandle, KEY_SET_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_NON_VOLATILE, &Disposition); if (!NT_SUCCESS(Status)) { DPRINT1("NtCreateKey() failed (Status %lx)\n", Status); NtClose(SubKeyHandle); NtClose(KeyHandle); return FALSE; } while (MuiLayouts[uIndex].LangID != NULL) { if (uIndex > 19) break; RtlStringCchPrintfW(szValueName, ARRAYSIZE(szValueName), L"%u", uIndex + 1); RtlInitUnicodeString(&ValueName, szValueName); RtlStringCchPrintfW(szLangID, ARRAYSIZE(szLangID), L"0000%s", MuiLayouts[uIndex].LangID); if (_wcsicmp(szLangID, MuiLayouts[uIndex].LayoutID) == 0) { Status = NtSetValueKey(KeyHandle, &ValueName, 0, REG_SZ, (PVOID)MuiLayouts[uIndex].LayoutID, (wcslen(MuiLayouts[uIndex].LayoutID)+1) * sizeof(WCHAR)); if (!NT_SUCCESS(Status)) { DPRINT1("NtSetValueKey() failed (Status = %lx, uIndex = %d)\n", Status, uIndex); NtClose(SubKeyHandle); NtClose(KeyHandle); return FALSE; } } else { RtlStringCchPrintfW(szLangID, ARRAYSIZE(szLangID), L"d%03lu%s", uCount, MuiLayouts[uIndex].LangID); Status = NtSetValueKey(KeyHandle, &ValueName, 0, REG_SZ, (PVOID)szLangID, (wcslen(szLangID)+1) * sizeof(WCHAR)); if (!NT_SUCCESS(Status)) { DPRINT1("NtSetValueKey() failed (Status = %lx, uIndex = %d)\n", Status, uIndex); NtClose(SubKeyHandle); NtClose(KeyHandle); return FALSE; } RtlInitUnicodeString(&ValueName, szLangID); Status = NtSetValueKey(SubKeyHandle, &ValueName, 0, REG_SZ, (PVOID)MuiLayouts[uIndex].LayoutID, (wcslen(MuiLayouts[uIndex].LayoutID)+1) * sizeof(WCHAR)); if (!NT_SUCCESS(Status)) { DPRINT1("NtSetValueKey() failed (Status = %lx, uIndex = %u)\n", Status, uIndex); NtClose(SubKeyHandle); NtClose(KeyHandle); return FALSE; } uCount++; } uIndex++; } if (uIndex > 1) AddHotkeySettings(L"2", L"2", L"1"); else AddHotkeySettings(L"3", L"3", L"3"); NtClose(SubKeyHandle); NtClose(KeyHandle); return TRUE; }
static BOOLEAN AddHotkeySettings( IN PCWSTR Hotkey, IN PCWSTR LangHotkey, IN PCWSTR LayoutHotkey) { OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING KeyName; UNICODE_STRING ValueName; HANDLE KeyHandle; ULONG Disposition; NTSTATUS Status; RtlInitUnicodeString(&KeyName, L".DEFAULT\\Keyboard Layout\\Toggle"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, GetRootKeyByPredefKey(HKEY_USERS, NULL), NULL); Status = NtCreateKey(&KeyHandle, KEY_SET_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_NON_VOLATILE, &Disposition); if (!NT_SUCCESS(Status)) { DPRINT1("NtCreateKey() failed (Status %lx)\n", Status); return FALSE; } RtlInitUnicodeString(&ValueName, L"Hotkey"); Status = NtSetValueKey(KeyHandle, &ValueName, 0, REG_SZ, (PVOID)Hotkey, (1 + 1) * sizeof(WCHAR)); if (!NT_SUCCESS(Status)) { DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status); NtClose(KeyHandle); return FALSE; } RtlInitUnicodeString(&ValueName, L"Language Hotkey"); Status = NtSetValueKey(KeyHandle, &ValueName, 0, REG_SZ, (PVOID)LangHotkey, (1 + 1) * sizeof(WCHAR)); if (!NT_SUCCESS(Status)) { DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status); NtClose(KeyHandle); return FALSE; } RtlInitUnicodeString(&ValueName, L"Layout Hotkey"); Status = NtSetValueKey(KeyHandle, &ValueName, 0, REG_SZ, (PVOID)LayoutHotkey, (1 + 1) * sizeof(WCHAR)); if (!NT_SUCCESS(Status)) { DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status); NtClose(KeyHandle); return FALSE; } NtClose(KeyHandle); return TRUE; }
printf("Could not find NtSetValueKey entry point in NTDLL.DLL\n"); exit(1); } } WCHAR HiddenKeyNameBuffer[] = L"hidekey\0"; WCHAR HiddenValueNameBuffer[]= L"hidevalue"; LocateNTDLLEntryPoints(); KeyName.Buffer = L"\\Registry\\Machine\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"; KeyName.Length = wcslen( L"\\Registry\\Machine\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run" ) *sizeof(WCHAR); InitializeObjectAttributes( &ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL ); Status = NtCreateKey( &SysKeyHandle, KEY_ALL_ACCESS, &ObjectAttributes, 0, NULL, REG_OPTION_NON_VOLATILE, &Disposition ); if( !NT_SUCCESS( Status )) { exit(1); } KeyName.Buffer = HiddenKeyNameBuffer; KeyName.Length = wcslen( HiddenKeyNameBuffer ) *sizeof(WCHAR) + sizeof(WCHAR); // length here must include terminating null InitializeObjectAttributes( &ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, SysKeyHandle, NULL ); Status = NtCreateKey( &HiddenKeyHandle, KEY_ALL_ACCESS, &ObjectAttributes, 0, NULL, REG_OPTION_NON_VOLATILE, &Disposition ); if( !NT_SUCCESS( Status )) {
/*********************************************************************** * add_boot_rename_entry * * Adds an entry to the registry that is loaded when windows boots and * checks if there are some files to be removed or renamed/moved. * <fn1> has to be valid and <fn2> may be NULL. If both pointers are * non-NULL then the file is moved, otherwise it is deleted. The * entry of the registrykey is always appended with two zero * terminated strings. If <fn2> is NULL then the second entry is * simply a single 0-byte. Otherwise the second filename goes * there. The entries are prepended with \??\ before the path and the * second filename gets also a '!' as the first character if * MOVEFILE_REPLACE_EXISTING is set. After the final string another * 0-byte follows to indicate the end of the strings. * i.e.: * \??\D:\test\file1[0] * !\??\D:\test\file1_renamed[0] * \??\D:\Test|delete[0] * [0] <- file is to be deleted, second string empty * \??\D:\test\file2[0] * !\??\D:\test\file2_renamed[0] * [0] <- indicates end of strings * * or: * \??\D:\test\file1[0] * !\??\D:\test\file1_renamed[0] * \??\D:\Test|delete[0] * [0] <- file is to be deleted, second string empty * [0] <- indicates end of strings * */ static BOOL add_boot_rename_entry( LPCWSTR source, LPCWSTR dest, DWORD flags ) { static const WCHAR ValueName[] = {'P','e','n','d','i','n','g', 'F','i','l','e','R','e','n','a','m','e', 'O','p','e','r','a','t','i','o','n','s',0}; UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\Session Manager"); static const int info_size = FIELD_OFFSET( KEY_VALUE_PARTIAL_INFORMATION, Data ); OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING nameW, source_name, dest_name; KEY_VALUE_PARTIAL_INFORMATION *info; BOOL rc = FALSE; HANDLE Reboot = NULL; DWORD len1, len2; DWORD DestLen = 0; DWORD DataSize = 0; BYTE *Buffer = NULL; WCHAR *p; NTSTATUS Status; TRACE("add_boot_rename_entry( %S, %S, %d ) \n", source, dest, flags); if(dest) DestLen = wcslen(dest); if (!RtlDosPathNameToNtPathName_U( source, &source_name, NULL, NULL )) { SetLastError( ERROR_PATH_NOT_FOUND ); return FALSE; } dest_name.Buffer = NULL; if (DestLen && !RtlDosPathNameToNtPathName_U( dest, &dest_name, NULL, NULL )) { RtlFreeHeap( RtlGetProcessHeap(), 0, source_name.Buffer ); SetLastError( ERROR_PATH_NOT_FOUND ); return FALSE; } InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_OPENIF | OBJ_CASE_INSENSITIVE, NULL, NULL); Status = NtCreateKey(&Reboot, KEY_QUERY_VALUE | KEY_SET_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_NON_VOLATILE, NULL); if (Status == STATUS_ACCESS_DENIED) { Status = NtCreateKey( &Reboot, KEY_QUERY_VALUE | KEY_SET_VALUE, &ObjectAttributes, 0, NULL, REG_OPTION_BACKUP_RESTORE, NULL); } if (!NT_SUCCESS(Status)) { WARN("NtCreateKey() failed (Status 0x%lx)\n", Status); if (source_name.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, source_name.Buffer); if (dest_name.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, dest_name.Buffer); return FALSE; } len1 = source_name.Length + sizeof(WCHAR); if (DestLen) { len2 = dest_name.Length + sizeof(WCHAR); if (flags & MOVEFILE_REPLACE_EXISTING) len2 += sizeof(WCHAR); /* Plus 1 because of the leading '!' */ } else { len2 = sizeof(WCHAR); /* minimum is the 0 characters for the empty second string */ } RtlInitUnicodeString( &nameW, ValueName ); /* First we check if the key exists and if so how many bytes it already contains. */ Status = NtQueryValueKey( Reboot, &nameW, KeyValuePartialInformation, NULL, 0, &DataSize ); if ((Status == STATUS_BUFFER_OVERFLOW) || (Status == STATUS_BUFFER_TOO_SMALL)) { if (!(Buffer = HeapAlloc(GetProcessHeap(), 0, DataSize + len1 + len2 + sizeof(WCHAR)))) goto Quit; Status = NtQueryValueKey(Reboot, &nameW, KeyValuePartialInformation, Buffer, DataSize, &DataSize); if(!NT_SUCCESS(Status)) goto Quit; info = (KEY_VALUE_PARTIAL_INFORMATION *)Buffer; if (info->Type != REG_MULTI_SZ) goto Quit; if (DataSize > sizeof(info)) DataSize -= sizeof(WCHAR); /* remove terminating null (will be added back later) */ } else { DataSize = info_size; if (!(Buffer = HeapAlloc( GetProcessHeap(), 0, DataSize + len1 + len2 + sizeof(WCHAR) ))) goto Quit; } memcpy( Buffer + DataSize, source_name.Buffer, len1 ); DataSize += len1; p = (WCHAR *)(Buffer + DataSize); if (DestLen) { if (flags & MOVEFILE_REPLACE_EXISTING) *p++ = '!'; memcpy( p, dest_name.Buffer, len2 ); DataSize += len2; } else { *p = 0; DataSize += sizeof(WCHAR); } /* add final null */ p = (WCHAR *)(Buffer + DataSize); *p = 0; DataSize += sizeof(WCHAR); rc = NT_SUCCESS(NtSetValueKey(Reboot, &nameW, 0, REG_MULTI_SZ, Buffer + info_size, DataSize - info_size)); Quit: RtlFreeHeap(RtlGetProcessHeap(), 0, source_name.Buffer); if (dest_name.Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, dest_name.Buffer); NtClose(Reboot); if(Buffer) HeapFree(GetProcessHeap(), 0, Buffer); return(rc); }
NTSTATUS CmpInitializeHardwareConfiguration( IN PLOADER_PARAMETER_BLOCK LoaderBlock ) /*++ Routine Description: This routine creates \\Registry\Machine\Hardware node in the registry and calls SetupTree routine to put the hardware information to the registry. Arguments: LoaderBlock - supplies a pointer to the LoaderBlock passed in from the OS Loader. Returns: NTSTATUS code for success or reason of failure. --*/ { NTSTATUS Status; OBJECT_ATTRIBUTES ObjectAttributes; HANDLE BaseHandle; PCONFIGURATION_COMPONENT_DATA ConfigurationRoot; ULONG Disposition; ConfigurationRoot = (PCONFIGURATION_COMPONENT_DATA)LoaderBlock->ConfigurationRoot; // // Create \\Registry\Machine\Hardware\DeviceMap // InitializeObjectAttributes( &ObjectAttributes, &CmRegistryMachineHardwareDeviceMapName, 0, (HANDLE)NULL, NULL ); ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE; Status = NtCreateKey( // Paht may already exist &BaseHandle, KEY_READ | KEY_WRITE, &ObjectAttributes, TITLE_INDEX_VALUE, NULL, 0, &Disposition ); if (!NT_SUCCESS(Status)) { return(Status); } NtClose(BaseHandle); ASSERT(Disposition == REG_CREATED_NEW_KEY); // // Create \\Registry\Machine\Hardware\Description and use the // returned handle as the BaseHandle to build the hardware tree. // InitializeObjectAttributes( &ObjectAttributes, &CmRegistryMachineHardwareDescriptionName, 0, (HANDLE)NULL, NULL ); ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE; Status = NtCreateKey( // Path may already exist &BaseHandle, KEY_READ | KEY_WRITE, &ObjectAttributes, TITLE_INDEX_VALUE, NULL, 0, &Disposition ); if (!NT_SUCCESS(Status)) { return(Status); } ASSERT(Disposition == REG_CREATED_NEW_KEY); // // Allocate 16K bytes memory from paged pool for constructing // configuration data for controller component. // NOTE: The configuration Data for controller component // usually takes less than 100 bytes. But on EISA machine, the // EISA configuration information takes more than 10K and up to // 64K. I believe 16K is the reasonable number to handler 99.9% // of the machines. Therefore, 16K is the initial value. // CmpConfigurationData = (PCM_FULL_RESOURCE_DESCRIPTOR)ExAllocatePool( PagedPool, CmpConfigurationAreaSize ); if (CmpConfigurationData == NULL) { return(STATUS_INSUFFICIENT_RESOURCES); } // // Call SetupConfigurationTree routine to go over each component // of the tree and add component information to registry database. // if (ConfigurationRoot) { Status = CmpSetupConfigurationTree(ConfigurationRoot, BaseHandle, -1, (ULONG)-1); } else { Status = STATUS_SUCCESS; } ExFreePool((PVOID)CmpConfigurationData); NtClose(BaseHandle); return(Status); }
void _CRTAPI1 main(int, char *) { NTSTATUS status; OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING KeyName; UNICODE_STRING KeyName2; UNICODE_STRING ClassName; UNICODE_STRING ClassName2; UNICODE_STRING ValueName; UNICODE_STRING ValueName2; HANDLE BaseHandle; HANDLE Testhand1; ULONG Disposition; LARGE_INTEGER CompTime; ULONG buffer[100]; ULONG bufsize = sizeof(ULONG) * 100; PKEY_NODE_INFORMATION NodeInformation; PKEY_VALUE_FULL_INFORMATION KeyValueInformation; PKEY_VALUE_BASIC_INFORMATION KeyValueBasic; ULONG ResultLength; PUCHAR datastring = "Some simple ascii data for use as a value"; PUCHAR datastring2 = "Some more not so simple data $#"; ULONG expected; PVOID tp; printf("rtmisc1: starting\n"); NodeInformation = (PKEY_NODE_INFORMATION)&(buffer[0]); KeyValueInformation = (PKEY_VALUE_FULL_INFORMATION)&(buffer[0]); KeyValueBasic = (PKEY_VALUE_BASIC_INFORMATION)&(buffer[0]); // // t0: Perform all operations against a base node, open it here. // RtlInitUnicodeString( &KeyName, L"\\REGISTRY\\MACHINE\\TEST" ); InitializeObjectAttributes( &ObjectAttributes, &KeyName, 0, (HANDLE)NULL, NULL ); ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE; status = NtOpenKey( &BaseHandle, MAXIMUM_ALLOWED, &ObjectAttributes ); if (!NT_SUCCESS(status)) { printf("rtmisc1: t0: %08lx\n", status); goto punt; } // // t1: Create a key with class and title index // RtlInitUnicodeString( &ClassName, L"t1 Class Name" ); RtlInitUnicodeString( &KeyName, L"first_test_node" ); InitializeObjectAttributes( &ObjectAttributes, &KeyName, 0, BaseHandle, NULL ); ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE; NtQuerySystemTime(&CompTime); // printf("ClassName@%08lx KeyName@%08lx\n", // ClassName.Buffer, KeyName.Buffer); status = NtCreateKey( &Testhand1, MAXIMUM_ALLOWED, &ObjectAttributes, TITLE_INDEX_1, &ClassName, 0, &Disposition ); if (!NT_SUCCESS(status)) { printf("rtmisc1: t1: %08lx\n", status); goto punt; } if (Disposition != REG_CREATED_NEW_KEY) { printf("rtmisc1: t1a: got old key, expected to create new one\n"); failure++; } // // t2: See if we can get data back, and if it makes sense // RtlZeroMemory(NodeInformation, bufsize); status = NtQueryKey( Testhand1, KeyNodeInformation, NodeInformation, bufsize, &ResultLength ); if (!NT_SUCCESS(status)) { printf("rtmisc1: t2a: %08lx\n", status); goto punt; } if (ResultLength != 80) { printf("rtmisc1: t2i: expect 80, ResultLength = %d\n", ResultLength); failure++; } NameClassAndTitle( NodeInformation, ClassName, TITLE_INDEX_1, KeyName, CompTime, FALSE, // time must be >= CompTime "rtmisc1: t2b: " ); CompTime = NodeInformation->LastWriteTime; status = NtClose(Testhand1); if (!NT_SUCCESS(status)) { printf("rtmisc1: t2c: %08lx\n"); goto punt; } // // t3: Reopen the key with create, see if data still there. // status = NtCreateKey( &Testhand1, MAXIMUM_ALLOWED, &ObjectAttributes, TITLE_INDEX_1, &ClassName, 0, &Disposition ); if (!NT_SUCCESS(status)) { printf("rtmisc1: t3: %08lx\n", status); goto punt; } if (Disposition != REG_OPENED_EXISTING_KEY) { printf("rtmisc1: t3a failure\n"); failure++; } RtlZeroMemory(NodeInformation, bufsize); status = NtQueryKey( Testhand1, KeyNodeInformation, NodeInformation, bufsize, &ResultLength ); if (!NT_SUCCESS(status)) { printf("rtmisc1: t3b: %08lx\n", status); goto punt; } NameClassAndTitle( NodeInformation, ClassName, TITLE_INDEX_1, KeyName, CompTime, FALSE, // time must be >= CompTime "rtmisc1: t3c: " ); status = NtClose(Testhand1); if (!NT_SUCCESS(status)) { printf("rtmisc1: t3d: %08lx\n"); goto punt; } // // t4: Reopen the key with open, see if data still there. // status = NtOpenKey( &Testhand1, MAXIMUM_ALLOWED, &ObjectAttributes ); if (!NT_SUCCESS(status)) { printf("rtmisc1: t4: %08lx\n", status); goto punt; } RtlZeroMemory(NodeInformation, bufsize); status = NtQueryKey( Testhand1, KeyNodeInformation, NodeInformation, bufsize, &ResultLength ); if (!NT_SUCCESS(status)) { printf("rtmisc1: t4a: %08lx\n", status); goto punt; } NameClassAndTitle( NodeInformation, ClassName, TITLE_INDEX_1, KeyName, CompTime, FALSE, // time must be >= CompTime "rtmisc1: t4b: " ); // status = NtClose(Testhand1); // if (!NT_SUCCESS(status)) { // printf("rtmisc1: t4c: %08lx\n"); // exit(1); // } // // t5: Create a value // RtlInitUnicodeString( &ValueName, L"the very first value stored in the registry" ); status = NtSetValueKey( Testhand1, &ValueName, TITLE_INDEX_2, TYPE_1, datastring, strlen(datastring)+1 ); if (!NT_SUCCESS(status)) { printf("rtmisc1: t5: %08lx\n", status); failure++; } // // t6: Read the value back // RtlZeroMemory(KeyValueInformation, bufsize); status = NtQueryValueKey( Testhand1, &ValueName, KeyValueFullInformation, KeyValueInformation, bufsize, &ResultLength ); if (!NT_SUCCESS(status)) { printf("rtmisc1: t6: %08lx\n", status); goto punt; } expected = FIELD_OFFSET(KEY_VALUE_FULL_INFORMATION, Name) + ValueName.Length + strlen(datastring) + 1; if (ResultLength != expected) { printf("rtmisc1: t6a: expected = %08lx actual = %08lx", expected, ResultLength); failure++; } if ( (KeyValueInformation->TitleIndex != TITLE_INDEX_2) || (KeyValueInformation->Type != TYPE_1) || (KeyValueInformation->NameLength != ValueName.Length) || (KeyValueInformation->DataLength != strlen(datastring)+1)) { printf("rtmisc1: t6b: wrong description data\n"); failure++; } tp = (PWSTR)&(KeyValueInformation->Name[0]); if (wcsncmp(ValueName.Buffer, tp, (ValueName.Length/sizeof(WCHAR))) != 0) { printf("rtmisc1: t6c: wrong name\n"); expectstring( ValueName.Buffer, (ValueName.Length/sizeof(WCHAR)), (PWSTR)&(KeyValueInformation->Name[0]), (KeyValueInformation->NameLength/sizeof(WCHAR)) ); failure++; } tp = (PUCHAR)KeyValueInformation + KeyValueInformation->DataOffset; if (strcmp(tp, datastring) != 0) { printf("rtmisc1: t6d: wrong data\n"); printf("expected '%s', got '%s'\n", datastring, tp); failure++; } // // t7: Create a second value // RtlInitUnicodeString( &ValueName2, L"the second value stored in the registry" ); status = NtSetValueKey( Testhand1, &ValueName2, TITLE_INDEX_3, TYPE_2, datastring2, strlen(datastring2)+1 ); if (!NT_SUCCESS(status)) { printf("rtmisc1: t7: %08lx\n", status); failure++; } // // t8: Read the second value back (short form) // RtlZeroMemory(KeyValueBasic, bufsize); status = NtQueryValueKey( Testhand1, &ValueName2, KeyValueBasicInformation, KeyValueBasic, bufsize, &ResultLength ); if (!NT_SUCCESS(status)) { printf("rtmisc1: t8: %08lx\n", status); goto punt; } expected = FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION, Name) + ValueName2.Length; if (ResultLength != expected) { printf("rtmisc1: t8a: expected = %08lx actual = %08lx", expected, ResultLength); failure++; } if ( (KeyValueBasic->TitleIndex != TITLE_INDEX_3) || (KeyValueBasic->Type != TYPE_2) || (KeyValueBasic->NameLength != ValueName2.Length)) { printf("rtmisc1: t8b: wrong description data\n"); failure++; } tp = (PWSTR)&(KeyValueBasic->Name[0]); if (wcsncmp(ValueName2.Buffer, tp, (ValueName2.Length/sizeof(WCHAR))) != 0) { printf("rtmisc1: t8c: wrong name\n"); expectstring( ValueName2.Buffer, (ValueName2.Length/sizeof(WCHAR)), (PWSTR)&(KeyValueBasic->Name[0]), (KeyValueBasic->NameLength/sizeof(WCHAR)) ); failure++; } // // t9: Enumerate the values (short form) // RtlZeroMemory(KeyValueBasic, bufsize); status = NtEnumerateValueKey( Testhand1, 0, // Index KeyValueBasicInformation, KeyValueBasic, bufsize, &ResultLength ); if (!NT_SUCCESS(status)) { printf("rtmisc1: t9: %08lx\n", status); goto punt; } expected = FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION, Name) + ValueName.Length; if (ResultLength != expected) { printf("rtmisc1: t9a: expected = %08lx actual = %08lx", expected, ResultLength); failure++; } if (KeyValueBasic->NameLength != ValueName.Length) { printf("rtmisc1: t9b: wrong description data\n"); failure++; } tp = (PWSTR)&(KeyValueBasic->Name[0]); if (wcsncmp(ValueName.Buffer, tp, (ValueName.Length/sizeof(WCHAR))) != 0) { printf("rtmisc1: t9c: wrong name\n"); expectstring( ValueName.Buffer, (ValueName.Length/sizeof(WCHAR)), (PWSTR)&(KeyValueBasic->Name[0]), (KeyValueBasic->NameLength/sizeof(WCHAR)) ); failure++; } RtlZeroMemory(KeyValueBasic, bufsize); status = NtEnumerateValueKey( Testhand1, 1, // Index KeyValueBasicInformation, KeyValueBasic, bufsize, &ResultLength ); if (!NT_SUCCESS(status)) { printf("rtmisc1: t9d: %08lx\n", status); goto punt; } expected = FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION, Name) + ValueName2.Length; if (ResultLength != expected) { printf("rtmisc1: t9e: expected = %08lx actual = %08lx", expected, ResultLength); failure++; } if (KeyValueBasic->NameLength != ValueName2.Length) { printf("rtmisc1: t9f: wrong description data\n"); failure++; } tp = (PWSTR)&(KeyValueBasic->Name[0]); if (wcsncmp(ValueName2.Buffer, tp, (ValueName2.Length/sizeof(WCHAR))) != 0) { printf("rtmisc1: t9g: wrong name\n"); expectstring( ValueName2.Buffer, (ValueName2.Length/sizeof(WCHAR)), (PWSTR)&(KeyValueBasic->Name[0]), (KeyValueBasic->NameLength/sizeof(WCHAR)) ); failure++; } status = NtEnumerateValueKey( Testhand1, 2, // Index KeyValueBasicInformation, KeyValueBasic, bufsize, &ResultLength ); if (status != STATUS_NO_MORE_ENTRIES) { printf("rtmisc1: t9h: %08lx\n", status); goto punt; } // // t10: create a second subkey and ennumerate the subkeys // status = NtClose(Testhand1); if (!NT_SUCCESS(status)) { printf("rtmisc1: t10a: %08lx\n", status); failure++; } RtlInitUnicodeString( &ClassName2, L"t2 Class Name" ); RtlInitUnicodeString( &KeyName2, L"second_test_node" ); InitializeObjectAttributes( &ObjectAttributes, &KeyName2, 0, BaseHandle, NULL ); ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE; status = NtCreateKey( &Testhand1, MAXIMUM_ALLOWED, &ObjectAttributes, TITLE_INDEX_2, &ClassName2, 0, &Disposition ); if (!NT_SUCCESS(status)) { printf("rtmisc1: t10b: %08lx\n", status); goto punt; } if (Disposition != REG_CREATED_NEW_KEY) { printf("rtmisc1: t10c: got old key, expected to create new one\n"); failure++; } // // See if we can get data back, and if it makes sense // RtlZeroMemory(NodeInformation, bufsize); status = NtQueryKey( Testhand1, KeyNodeInformation, NodeInformation, bufsize, &ResultLength ); if (!NT_SUCCESS(status)) { printf("rtmisc1: t10d: %08lx\n", status); goto punt; } CompTime = NodeInformation->LastWriteTime; NameClassAndTitle( NodeInformation, ClassName2, TITLE_INDEX_2, KeyName2, CompTime, TRUE, "rtmisc1: t10e: " ); status = NtClose(Testhand1); if (!NT_SUCCESS(status)) { printf("rtmisc1: t10f: %08lx\n"); goto punt; } RtlZeroMemory(NodeInformation, bufsize); status = NtEnumerateKey( BaseHandle, 0, KeyNodeInformation, NodeInformation, bufsize, &ResultLength ); if (!NT_SUCCESS(status)) { printf("rtmisc1: t10g: %08lx\n", status); failure++; } CompTime = NodeInformation->LastWriteTime; NameClassAndTitle( NodeInformation, ClassName, TITLE_INDEX_1, KeyName, CompTime, TRUE, "rtmisc1: t10h: " ); RtlZeroMemory(NodeInformation, bufsize); status = NtEnumerateKey( BaseHandle, 1, KeyNodeInformation, NodeInformation, bufsize, &ResultLength ); if (!NT_SUCCESS(status)) { printf("rtmisc1: t10i: %08lx\n", status); failure++; } CompTime = NodeInformation->LastWriteTime; NameClassAndTitle( NodeInformation, ClassName2, TITLE_INDEX_2, KeyName2, CompTime, TRUE, "rtmisc1: t10j: " ); status = NtEnumerateKey( BaseHandle, 2, KeyNodeInformation, NodeInformation, bufsize, &ResultLength ); if (status != STATUS_NO_MORE_ENTRIES) { printf("rtmisc1: t10k: %08lx\n", status); failure++; } // // Summary report // if (!failure) { printf("rtmisc1: success"); exit(0); } else { printf("rtmisc1: failed, %d failures\n", failure); exit(1); } punt: failure++; printf("rtmisc1: failed, %d failures\n", failure); exit(1); }
BOOLEAN InstallDriver( IN HINF hInf, IN HANDLE hServices, IN HANDLE hDeviceKey, IN LPCWSTR DeviceId, IN LPCWSTR HardwareId) { UNICODE_STRING PathPrefix = RTL_CONSTANT_STRING(L"System32\\DRIVERS\\"); UNICODE_STRING ServiceU = RTL_CONSTANT_STRING(L"Service"); UNICODE_STRING ErrorControlU = RTL_CONSTANT_STRING(L"ErrorControl"); UNICODE_STRING ImagePathU = RTL_CONSTANT_STRING(L"ImagePath"); UNICODE_STRING StartU = RTL_CONSTANT_STRING(L"Start"); UNICODE_STRING TypeU = RTL_CONSTANT_STRING(L"Type"); UNICODE_STRING StringU; OBJECT_ATTRIBUTES ObjectAttributes; HANDLE hService; INFCONTEXT Context; LPWSTR Driver, ClassGuid, ImagePath, FullImagePath; ULONG dwValue; ULONG Disposition; NTSTATUS Status; BOOLEAN deviceInstalled = FALSE; UNICODE_STRING UpperFiltersU = RTL_CONSTANT_STRING(L"UpperFilters"); LPWSTR keyboardClass = L"kbdclass\0"; /* Check if we know the hardware */ if (!SetupFindFirstLineW(hInf, L"HardwareIdsDatabase", HardwareId, &Context)) return FALSE; if (!INF_GetDataField(&Context, 1, &Driver)) return FALSE; /* Get associated class GUID (if any) */ if (!INF_GetDataField(&Context, 2, &ClassGuid)) ClassGuid = NULL; /* Find associated driver name */ /* FIXME: check in other sections too! */ if (!SetupFindFirstLineW(hInf, L"BootBusExtenders.Load", Driver, &Context) && !SetupFindFirstLineW(hInf, L"BusExtenders.Load", Driver, &Context) && !SetupFindFirstLineW(hInf, L"SCSI.Load", Driver, &Context) && !SetupFindFirstLineW(hInf, L"InputDevicesSupport.Load", Driver, &Context) && !SetupFindFirstLineW(hInf, L"Keyboard.Load", Driver, &Context)) { return FALSE; } if (!INF_GetDataField(&Context, 1, &ImagePath)) return FALSE; /* Prepare full driver path */ dwValue = PathPrefix.MaximumLength + wcslen(ImagePath) * sizeof(WCHAR); FullImagePath = (LPWSTR)RtlAllocateHeap(ProcessHeap, 0, dwValue); if (!FullImagePath) { DPRINT1("RtlAllocateHeap() failed\n"); return FALSE; } RtlCopyMemory(FullImagePath, PathPrefix.Buffer, PathPrefix.MaximumLength); wcscat(FullImagePath, ImagePath); DPRINT1("Using driver '%S' for device '%S'\n", ImagePath, DeviceId); /* Create service key */ RtlInitUnicodeString(&StringU, Driver); InitializeObjectAttributes(&ObjectAttributes, &StringU, 0, hServices, NULL); Status = NtCreateKey(&hService, KEY_SET_VALUE, &ObjectAttributes, 0, NULL, 0, &Disposition); if (!NT_SUCCESS(Status)) { DPRINT1("NtCreateKey('%wZ') failed with status 0x%08x\n", &StringU, Status); RtlFreeHeap(ProcessHeap, 0, FullImagePath); return FALSE; } /* Fill service key */ if (Disposition == REG_CREATED_NEW_KEY) { dwValue = 0; NtSetValueKey( hService, &ErrorControlU, 0, REG_DWORD, &dwValue, sizeof(dwValue)); dwValue = 0; NtSetValueKey( hService, &StartU, 0, REG_DWORD, &dwValue, sizeof(dwValue)); dwValue = SERVICE_KERNEL_DRIVER; NtSetValueKey( hService, &TypeU, 0, REG_DWORD, &dwValue, sizeof(dwValue)); } /* HACK: don't put any path in registry */ NtSetValueKey( hService, &ImagePathU, 0, REG_SZ, ImagePath, (wcslen(ImagePath) + 1) * sizeof(WCHAR)); if (ClassGuid &&_wcsicmp(ClassGuid, L"{4D36E96B-E325-11CE-BFC1-08002BE10318}") == 0) { DPRINT1("Installing keyboard class driver for '%S'\n", DeviceId); NtSetValueKey(hDeviceKey, &UpperFiltersU, 0, REG_MULTI_SZ, keyboardClass, (wcslen(keyboardClass) + 2) * sizeof(WCHAR)); } /* Associate device with the service we just filled */ Status = NtSetValueKey( hDeviceKey, &ServiceU, 0, REG_SZ, Driver, (wcslen(Driver) + 1) * sizeof(WCHAR)); if (NT_SUCCESS(Status)) { /* Restart the device, so it will use the driver we registered */ deviceInstalled = ResetDevice(DeviceId); } /* HACK: Update driver path */ NtSetValueKey( hService, &ImagePathU, 0, REG_SZ, FullImagePath, (wcslen(FullImagePath) + 1) * sizeof(WCHAR)); RtlFreeHeap(ProcessHeap, 0, FullImagePath); NtClose(hService); return deviceInstalled; }
/*********************************************************************** * COMPUTERNAME_Init (INTERNAL) */ void COMPUTERNAME_Init (void) { HANDLE hkey = INVALID_HANDLE_VALUE, hsubkey = INVALID_HANDLE_VALUE; OBJECT_ATTRIBUTES attr; UNICODE_STRING nameW; char buf[offsetof( KEY_VALUE_PARTIAL_INFORMATION, Data ) + (MAX_COMPUTERNAME_LENGTH + 1) * sizeof( WCHAR )]; DWORD len = sizeof( buf ); LPWSTR computer_name = (LPWSTR) (buf + offsetof( KEY_VALUE_PARTIAL_INFORMATION, Data )); NTSTATUS st = STATUS_INTERNAL_ERROR; TRACE("(void)\n"); _init_attr ( &attr, &nameW ); RtlInitUnicodeString( &nameW, ComputerW ); if ( ( st = NtCreateKey( &hkey, KEY_ALL_ACCESS, &attr, 0, NULL, 0, NULL ) ) != STATUS_SUCCESS ) goto out; attr.RootDirectory = hkey; RtlInitUnicodeString( &nameW, ComputerNameW ); if ( (st = NtCreateKey( &hsubkey, KEY_ALL_ACCESS, &attr, 0, NULL, 0, NULL ) ) != STATUS_SUCCESS ) goto out; st = NtQueryValueKey( hsubkey, &nameW, KeyValuePartialInformation, buf, len, &len ); if ( st != STATUS_SUCCESS || get_use_dns_option() ) { char hbuf[256]; int hlen = sizeof (hbuf); char *dot; TRACE( "retrieving Unix host name\n" ); if ( gethostname ( hbuf, hlen ) ) { strcpy ( hbuf, default_ComputerName ); WARN( "gethostname() error: %d, using host name %s\n", errno, hbuf ); } hbuf[MAX_COMPUTERNAME_LENGTH] = 0; dot = strchr ( hbuf, '.' ); if ( dot ) *dot = 0; hlen = strlen ( hbuf ); len = MultiByteToWideChar( CP_UNIXCP, 0, hbuf, hlen + 1, computer_name, MAX_COMPUTERNAME_LENGTH + 1 ) * sizeof( WCHAR ); if ( NtSetValueKey( hsubkey, &nameW, 0, REG_SZ, computer_name, len ) != STATUS_SUCCESS ) WARN ( "failed to set ComputerName\n" ); } else { len = (len - offsetof( KEY_VALUE_PARTIAL_INFORMATION, Data )); TRACE( "found in registry\n" ); } NtClose( hsubkey ); TRACE(" ComputerName: %s (%u)\n", debugstr_w (computer_name), len); RtlInitUnicodeString( &nameW, ActiveComputerNameW ); if ( ( st = NtCreateKey( &hsubkey, KEY_ALL_ACCESS, &attr, 0, NULL, REG_OPTION_VOLATILE, NULL ) ) != STATUS_SUCCESS ) goto out; RtlInitUnicodeString( &nameW, ComputerNameW ); st = NtSetValueKey( hsubkey, &nameW, 0, REG_SZ, computer_name, len ); out: NtClose( hsubkey ); NtClose( hkey ); if ( st == STATUS_SUCCESS ) TRACE( "success\n" ); else { WARN( "status trying to set ComputerName: %x\n", st ); SetLastError ( RtlNtStatusToDosError ( st ) ); } }
/* registry link create test */ void test6(void) { HANDLE hKey; OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING KeyName,ValueName; NTSTATUS Status; KEY_VALUE_FULL_INFORMATION KeyValueInformation[5]; ULONG Length,i; dprintf("Create target key\n"); dprintf(" Key: \\Registry\\Machine\\SOFTWARE\\Reactos\n"); RtlRosInitUnicodeStringFromLiteral(&KeyName, L"\\Registry\\Machine\\SOFTWARE\\Reactos"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE , NULL, NULL); Status = NtCreateKey(&hKey, KEY_ALL_ACCESS , &ObjectAttributes ,0,NULL, REG_OPTION_VOLATILE,NULL); dprintf(" NtCreateKey() called (Status %lx)\n",Status); if (!NT_SUCCESS(Status)) return; dprintf("Create target value\n"); dprintf(" Value: TestValue = 'Test String'\n"); RtlRosInitUnicodeStringFromLiteral(&ValueName, L"TestValue"); Status=NtSetValueKey(hKey,&ValueName,0,REG_SZ,(PVOID)L"TestString",22); dprintf(" NtSetValueKey() called (Status %lx)\n",Status); if (!NT_SUCCESS(Status)) return; dprintf("Close target key\n"); NtClose(hKey); dprintf("Create link key\n"); dprintf(" Key: \\Registry\\Machine\\SOFTWARE\\Test\n"); RtlRosInitUnicodeStringFromLiteral(&KeyName, L"\\Registry\\Machine\\SOFTWARE\\Test"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE | OBJ_OPENLINK, NULL, NULL); Status = NtCreateKey(&hKey, KEY_ALL_ACCESS | KEY_CREATE_LINK, &ObjectAttributes, 0, NULL, REG_OPTION_VOLATILE | REG_OPTION_CREATE_LINK, NULL); dprintf(" NtCreateKey() called (Status %lx)\n",Status); if (!NT_SUCCESS(Status)) return; dprintf("Create link value\n"); dprintf(" Value: SymbolicLinkValue = '\\Registry\\Machine\\SOFTWARE\\Reactos'\n"); RtlRosInitUnicodeStringFromLiteral(&ValueName, L"SymbolicLinkValue"); Status=NtSetValueKey(hKey,&ValueName,0,REG_LINK,(PVOID)L"\\Registry\\Machine\\SOFTWARE\\Reactos",68); dprintf(" NtSetValueKey() called (Status %lx)\n",Status); if (!NT_SUCCESS(Status)) { dprintf("Creating link value failed! Test failed!\n"); NtClose(hKey); return; } dprintf("Close link key\n"); NtClose(hKey); dprintf("Open link key\n"); dprintf(" Key: \\Registry\\Machine\\SOFTWARE\\Test\n"); RtlRosInitUnicodeStringFromLiteral(&KeyName, L"\\Registry\\Machine\\SOFTWARE\\Test"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE | OBJ_OPENIF , NULL, NULL); Status = NtCreateKey(&hKey, KEY_ALL_ACCESS , &ObjectAttributes ,0,NULL, REG_OPTION_VOLATILE, NULL); dprintf(" NtCreateKey() called (Status %lx)\n",Status); if (!NT_SUCCESS(Status)) return; dprintf("Query value\n"); dprintf(" Value: TestValue\n"); RtlRosInitUnicodeStringFromLiteral(&ValueName, L"TestValue"); Status=NtQueryValueKey(hKey, &ValueName, KeyValueFullInformation, &KeyValueInformation[0], sizeof(KeyValueInformation), &Length); dprintf(" NtQueryValueKey() called (Status %lx)\n",Status); if (Status == STATUS_SUCCESS) { dprintf(" Value: Type %d DataLength %d NameLength %d Name '", KeyValueInformation[0].Type, KeyValueInformation[0].DataLength, KeyValueInformation[0].NameLength); for (i=0; i < KeyValueInformation[0].NameLength / sizeof(WCHAR); i++) dprintf("%C",KeyValueInformation[0].Name[i]); dprintf("'\n"); if (KeyValueInformation[0].Type == REG_SZ) dprintf(" Value '%S'\n", KeyValueInformation[0].Name+1 +KeyValueInformation[0].NameLength/2); } dprintf("Close link key\n"); NtClose(hKey); dprintf("Test successful!\n"); }
NTSTATUS NTAPI CmpInitializeMachineDependentConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBlock) { UNICODE_STRING KeyName, ValueName, Data, SectionName; OBJECT_ATTRIBUTES ObjectAttributes; ULONG HavePae, CacheSize, ViewSize, Length, TotalLength = 0, i, Disposition; NTSTATUS Status; HANDLE KeyHandle, BiosHandle, SystemHandle, FpuHandle, SectionHandle; CONFIGURATION_COMPONENT_DATA ConfigData; CHAR Buffer[128]; ULONG ExtendedId = 0; //, Dummy; PKPRCB Prcb; USHORT IndexTable[MaximumType + 1] = {0}; ANSI_STRING TempString; PCHAR PartialString = NULL, BiosVersion; CHAR CpuString[48]; PVOID BaseAddress = NULL; LARGE_INTEGER ViewBase = {{0, 0}}; ULONG_PTR VideoRomBase; PCHAR CurrentVersion; extern UNICODE_STRING KeRosProcessorName, KeRosBiosDate, KeRosBiosVersion; extern UNICODE_STRING KeRosVideoBiosDate, KeRosVideoBiosVersion; /* Open the SMSS Memory Management key */ RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\" L"Control\\Session Manager\\Memory Management"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = NtOpenKey(&KeyHandle, KEY_READ | KEY_WRITE, &ObjectAttributes); if (NT_SUCCESS(Status)) { /* Detect if PAE is enabled */ HavePae = SharedUserData->ProcessorFeatures[PF_PAE_ENABLED]; /* Set the value */ RtlInitUnicodeString(&ValueName, L"PhysicalAddressExtension"); NtSetValueKey(KeyHandle, &ValueName, 0, REG_DWORD, &HavePae, sizeof(HavePae)); /* Close the key */ NtClose(KeyHandle); } /* Open the hardware description key */ RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\Hardware\\Description\\System"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = NtOpenKey(&SystemHandle, KEY_READ | KEY_WRITE, &ObjectAttributes); if (!NT_SUCCESS(Status)) return Status; /* Create the BIOS Information key */ RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\" L"Control\\BIOSINFO"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = NtCreateKey(&BiosHandle, KEY_ALL_ACCESS, &ObjectAttributes, 0, NULL, REG_OPTION_NON_VOLATILE, &Disposition); if (!NT_SUCCESS(Status)) { NtClose(SystemHandle); return Status; } /* Create the CPU Key, and check if it already existed */ RtlInitUnicodeString(&KeyName, L"CentralProcessor"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, SystemHandle, NULL); Status = NtCreateKey(&KeyHandle, KEY_READ | KEY_WRITE, &ObjectAttributes, 0, NULL, 0, &Disposition); NtClose(KeyHandle); /* The key shouldn't already exist */ if (Disposition == REG_CREATED_NEW_KEY) { /* Allocate the configuration data for cmconfig.c */ CmpConfigurationData = ExAllocatePoolWithTag(PagedPool, CmpConfigurationAreaSize, TAG_CM); if (!CmpConfigurationData) { // FIXME: Cleanup stuff!! return STATUS_INSUFFICIENT_RESOURCES; } /* Loop all CPUs */ for (i = 0; i < KeNumberProcessors; i++) { /* Get the PRCB */ Prcb = KiProcessorBlock[i]; /* Setup the Configuration Entry for the Processor */ RtlZeroMemory(&ConfigData, sizeof(ConfigData)); ConfigData.ComponentEntry.Class = ProcessorClass; ConfigData.ComponentEntry.Type = CentralProcessor; ConfigData.ComponentEntry.Key = i; ConfigData.ComponentEntry.AffinityMask = AFFINITY_MASK(i); ConfigData.ComponentEntry.Identifier = Buffer; /* Check if the CPU doesn't support CPUID */ if (!Prcb->CpuID) { /* Build ID1-style string for older CPUs */ sprintf(Buffer, CmpID1, Prcb->CpuType, (Prcb->CpuStep >> 8) + 'A', Prcb->CpuStep & 0xff); } else {
NTSTATUS EventThread(IN LPVOID lpParameter) { UNICODE_STRING EnumU = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Enum"); UNICODE_STRING ServicesU = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services"); PPLUGPLAY_EVENT_BLOCK PnpEvent; OBJECT_ATTRIBUTES ObjectAttributes; ULONG PnpEventSize; HINF hInf; HANDLE hEnum, hServices; NTSTATUS Status; hInf = *(HINF *)lpParameter; InitializeObjectAttributes(&ObjectAttributes, &EnumU, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = NtOpenKey(&hEnum, KEY_QUERY_VALUE, &ObjectAttributes); if (!NT_SUCCESS(Status)) { DPRINT1("NtOpenKey('%wZ') failed with status 0x%08lx\n", &EnumU, Status); return Status; } InitializeObjectAttributes(&ObjectAttributes, &ServicesU, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = NtCreateKey(&hServices, KEY_ALL_ACCESS, &ObjectAttributes, 0, NULL, 0, NULL); if (!NT_SUCCESS(Status)) { DPRINT1("NtCreateKey('%wZ') failed with status 0x%08lx\n", &ServicesU, Status); NtClose(hEnum); return Status; } PnpEventSize = 0x1000; PnpEvent = (PPLUGPLAY_EVENT_BLOCK)RtlAllocateHeap(ProcessHeap, 0, PnpEventSize); if (PnpEvent == NULL) { NtClose(hEnum); NtClose(hServices); return STATUS_NO_MEMORY; } for (;;) { DPRINT("Calling NtGetPlugPlayEvent()\n"); /* Wait for the next pnp event */ Status = NtGetPlugPlayEvent(0, 0, PnpEvent, PnpEventSize); /* Resize the buffer for the PnP event if it's too small. */ if (Status == STATUS_BUFFER_TOO_SMALL) { PnpEventSize += 0x400; RtlFreeHeap(ProcessHeap, 0, PnpEvent); PnpEvent = (PPLUGPLAY_EVENT_BLOCK)RtlAllocateHeap(ProcessHeap, 0, PnpEventSize); if (PnpEvent == NULL) { NtClose(hEnum); NtClose(hServices); return STATUS_NO_MEMORY; } continue; } if (!NT_SUCCESS(Status)) { DPRINT("NtPlugPlayEvent() failed (Status %lx)\n", Status); break; } /* Process the pnp event */ DPRINT("Received PnP Event\n"); if (IsEqualIID(&PnpEvent->EventGuid, (REFGUID)&GUID_DEVICE_ENUMERATED)) { DPRINT("Device arrival event: %S\n", PnpEvent->TargetDevice.DeviceIds); InstallDevice(hInf, hEnum, hServices, PnpEvent->TargetDevice.DeviceIds); } else { DPRINT("Unknown event\n"); } /* Dequeue the current pnp event and signal the next one */ NtPlugPlayControl(PlugPlayControlUserResponse, NULL, 0); } RtlFreeHeap(ProcessHeap, 0, PnpEvent); NtClose(hEnum); NtClose(hServices); return STATUS_SUCCESS; }
BOOL SaveGroup( HANDLE GroupsKey, PWSTR GroupName, PGROUP_DEF Group ) { NTSTATUS Status; UNICODE_STRING KeyName, ValueName; HANDLE Key; OBJECT_ATTRIBUTES ObjectAttributes; ULONG CreateDisposition; LONG ValueLength; RtlInitUnicodeString( &KeyName, GroupName ); InitializeObjectAttributes( &ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, GroupsKey, NULL ); Status = NtCreateKey( &Key, STANDARD_RIGHTS_WRITE | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS | KEY_SET_VALUE | KEY_CREATE_SUB_KEY, &ObjectAttributes, 0, NULL, 0, &CreateDisposition ); if (!NT_SUCCESS( Status )) { BaseSetLastNTError( Status ); return FALSE; } ValueLength = (LONG)((ULONG)Group->wReserved); Group->wReserved = 0; Group->wCheckSum = (WORD)-ValueLength; RtlInitUnicodeString( &ValueName, L"" ); Status = NtSetValueKey( Key, &ValueName, 0, REG_BINARY, Group, ValueLength ); Group->wReserved = (WORD)ValueLength; Group->wCheckSum = 0; NtClose( Key ); if (!NT_SUCCESS( Status )) { return FALSE; } else { return TRUE; } }
NTSTATUS NTAPI INIT_FUNCTION CmpInitializeRegistryNode(IN PCONFIGURATION_COMPONENT_DATA CurrentEntry, IN HANDLE NodeHandle, OUT PHANDLE NewHandle, IN INTERFACE_TYPE InterfaceType, IN ULONG BusNumber, IN PUSHORT DeviceIndexTable) { NTSTATUS Status; OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING KeyName, ValueName, ValueData; HANDLE KeyHandle, ParentHandle; ANSI_STRING TempString; CHAR TempBuffer[12]; WCHAR Buffer[12]; PCONFIGURATION_COMPONENT Component; ULONG Disposition, Length = 0; /* Get the component */ Component = &CurrentEntry->ComponentEntry; /* Set system class components to ARC system type */ if (Component->Class == SystemClass) Component->Type = ArcSystem; /* Create a key for the component */ InitializeObjectAttributes(&ObjectAttributes, &CmTypeName[Component->Type], OBJ_CASE_INSENSITIVE, NodeHandle, NULL); Status = NtCreateKey(&KeyHandle, KEY_READ | KEY_WRITE, &ObjectAttributes, 0, NULL, 0, &Disposition); if (!NT_SUCCESS(Status)) return Status; /* Check if this is anything but a system class component */ if (Component->Class != SystemClass) { /* Build the sub-component string */ RtlIntegerToChar(DeviceIndexTable[Component->Type]++, 10, 12, TempBuffer); RtlInitAnsiString(&TempString, TempBuffer); /* Convert it to Unicode */ RtlInitEmptyUnicodeString(&KeyName, Buffer, sizeof(Buffer)); Status = RtlAnsiStringToUnicodeString(&KeyName, &TempString, FALSE); if (!NT_SUCCESS(Status)) { NtClose(KeyHandle); return Status; } /* Create the key */ ParentHandle = KeyHandle; InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, ParentHandle, NULL); Status = NtCreateKey(&KeyHandle, KEY_READ | KEY_WRITE, &ObjectAttributes, 0, NULL, 0, &Disposition); NtClose(ParentHandle); /* Fail if the key couldn't be created, and make sure it's a new key */ if (!NT_SUCCESS(Status)) return Status; ASSERT(Disposition == REG_CREATED_NEW_KEY); } /* Setup the component information key */ RtlInitUnicodeString(&ValueName, L"Component Information"); Status = NtSetValueKey(KeyHandle, &ValueName, 0, REG_BINARY, &Component->Flags, FIELD_OFFSET(CONFIGURATION_COMPONENT, ConfigurationDataLength) - FIELD_OFFSET(CONFIGURATION_COMPONENT, Flags)); if (!NT_SUCCESS(Status)) { /* Fail */ NtClose(KeyHandle); return Status; } /* Check if we have an identifier */ if (Component->IdentifierLength) { /* Build the string and convert it to Unicode */ RtlInitUnicodeString(&ValueName, L"Identifier"); RtlInitAnsiString(&TempString, Component->Identifier); Status = RtlAnsiStringToUnicodeString(&ValueData, &TempString, TRUE); if (NT_SUCCESS(Status)) { /* Save the identifier in the registry */ Status = NtSetValueKey(KeyHandle, &ValueName, 0, REG_SZ, ValueData.Buffer, ValueData.Length + sizeof(UNICODE_NULL)); RtlFreeUnicodeString(&ValueData); } /* Check for failure during conversion or registry write */ if (!NT_SUCCESS(Status)) { /* Fail */ NtClose(KeyHandle); return Status; } } /* Setup the configuration data string */ RtlInitUnicodeString(&ValueName, L"Configuration Data"); /* Check if we got configuration data */ if (CurrentEntry->ConfigurationData) { /* Calculate the total length and check if it fits into our buffer */ Length = Component->ConfigurationDataLength + FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList); if (Length > CmpConfigurationAreaSize) { ASSERTMSG("Component too large -- need reallocation!", FALSE); } else { /* Copy the data */ RtlCopyMemory(&CmpConfigurationData->PartialResourceList.Version, CurrentEntry->ConfigurationData, Component->ConfigurationDataLength); } } else { /* No configuration data, setup defaults */ CmpConfigurationData->PartialResourceList.Version = 0; CmpConfigurationData->PartialResourceList.Revision = 0; CmpConfigurationData->PartialResourceList.Count = 0; Length = FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST, PartialDescriptors) + FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList); } /* Set the interface type and bus number */ CmpConfigurationData->InterfaceType = InterfaceType; CmpConfigurationData->BusNumber = BusNumber; /* Save the actual data */ Status = NtSetValueKey(KeyHandle, &ValueName, 0, REG_FULL_RESOURCE_DESCRIPTOR, CmpConfigurationData, Length); if (!NT_SUCCESS(Status)) { /* Fail */ NtClose(KeyHandle); } else { /* Return the new handle */ *NewHandle = KeyHandle; } /* Return status */ return Status; }
/****************************************************************** * create_scsi_entry * * Initializes registry to contain scsi info about the cdrom in NT. * All devices (even not real scsi ones) have this info in NT. * NOTE: programs usually read these registry entries after sending the * IOCTL_SCSI_GET_ADDRESS ioctl to the cdrom */ static void create_scsi_entry( PSCSI_ADDRESS scsi_addr, LPCSTR lpDriver, UINT uDriveType, LPSTR lpDriveName, LPSTR lpUnixDeviceName ) { static UCHAR uCdromNumber = 0; static UCHAR uTapeNumber = 0; OBJECT_ATTRIBUTES attr; UNICODE_STRING nameW; WCHAR dataW[50]; DWORD lenW; char buffer[40]; DWORD value; const char *data; HANDLE scsiKey; HANDLE portKey; HANDLE busKey; HANDLE targetKey; HANDLE lunKey; DWORD disp; attr.Length = sizeof(attr); attr.RootDirectory = 0; attr.ObjectName = &nameW; attr.Attributes = 0; attr.SecurityDescriptor = NULL; attr.SecurityQualityOfService = NULL; /* Ensure there is Scsi key */ if (!RtlCreateUnicodeStringFromAsciiz( &nameW, "Machine\\HARDWARE\\DEVICEMAP\\Scsi" ) || NtCreateKey( &scsiKey, KEY_ALL_ACCESS, &attr, 0, NULL, REG_OPTION_VOLATILE, &disp )) { ERR("Cannot create DEVICEMAP\\Scsi registry key\n" ); return; } RtlFreeUnicodeString( &nameW ); snprintf(buffer,sizeof(buffer),"Scsi Port %d",scsi_addr->PortNumber); attr.RootDirectory = scsiKey; if (!RtlCreateUnicodeStringFromAsciiz( &nameW, buffer ) || NtCreateKey( &portKey, KEY_ALL_ACCESS, &attr, 0, NULL, REG_OPTION_VOLATILE, &disp )) { ERR("Cannot create DEVICEMAP\\Scsi Port registry key\n" ); return; } RtlFreeUnicodeString( &nameW ); RtlCreateUnicodeStringFromAsciiz( &nameW, "Driver" ); RtlMultiByteToUnicodeN( dataW, sizeof(dataW), &lenW, lpDriver, strlen(lpDriver)); NtSetValueKey( portKey, &nameW, 0, REG_SZ, (BYTE*)dataW, lenW ); RtlFreeUnicodeString( &nameW ); value = 10; RtlCreateUnicodeStringFromAsciiz( &nameW, "FirstBusTimeScanInMs" ); NtSetValueKey( portKey,&nameW, 0, REG_DWORD, (BYTE *)&value, sizeof(DWORD)); RtlFreeUnicodeString( &nameW ); value = 0; if (strcmp(lpDriver, "atapi") == 0) { #ifdef HDIO_GET_DMA int fd, dma; fd = open(lpUnixDeviceName, O_RDONLY|O_NONBLOCK); if (fd != -1) { if (ioctl(fd, HDIO_GET_DMA, &dma) != -1) value = dma; close(fd); } #endif RtlCreateUnicodeStringFromAsciiz( &nameW, "DMAEnabled" ); NtSetValueKey( portKey,&nameW, 0, REG_DWORD, (BYTE *)&value, sizeof(DWORD)); RtlFreeUnicodeString( &nameW ); } snprintf(buffer, sizeof(buffer),"Scsi Bus %d", scsi_addr->PathId); attr.RootDirectory = portKey; if (!RtlCreateUnicodeStringFromAsciiz( &nameW, buffer ) || NtCreateKey( &busKey, KEY_ALL_ACCESS, &attr, 0, NULL, REG_OPTION_VOLATILE, &disp )) { ERR("Cannot create DEVICEMAP\\Scsi Port\\Scsi Bus registry key\n" ); return; } RtlFreeUnicodeString( &nameW ); attr.RootDirectory = busKey; /* FIXME: get real controller Id for SCSI */ if (!RtlCreateUnicodeStringFromAsciiz( &nameW, "Initiator Id 255" ) || NtCreateKey( &targetKey, KEY_ALL_ACCESS, &attr, 0, NULL, REG_OPTION_VOLATILE, &disp )) { ERR("Cannot create DEVICEMAP\\Scsi Port\\Scsi Bus\\Initiator Id 255 registry key\n" ); return; } RtlFreeUnicodeString( &nameW ); NtClose( targetKey ); snprintf(buffer, sizeof(buffer),"Target Id %d", scsi_addr->TargetId); attr.RootDirectory = busKey; if (!RtlCreateUnicodeStringFromAsciiz( &nameW, buffer ) || NtCreateKey( &targetKey, KEY_ALL_ACCESS, &attr, 0, NULL, REG_OPTION_VOLATILE, &disp )) { ERR("Cannot create DEVICEMAP\\Scsi Port\\Scsi Bus 0\\Target Id registry key\n" ); return; } RtlFreeUnicodeString( &nameW ); snprintf(buffer, sizeof(buffer),"Logical Unit Id %d", scsi_addr->Lun); attr.RootDirectory = targetKey; if (!RtlCreateUnicodeStringFromAsciiz( &nameW, buffer ) || NtCreateKey( &lunKey, KEY_ALL_ACCESS, &attr, 0, NULL, REG_OPTION_VOLATILE, &disp )) { ERR("Cannot create DEVICEMAP\\Scsi Port\\Scsi Bus 0\\Target Id registry key\\Logical Unit Id\n" ); return; } RtlFreeUnicodeString( &nameW ); switch (uDriveType) { case DRIVE_NO_ROOT_DIR: default: data = "OtherPeripheral"; break; case DRIVE_FIXED: data = "DiskPeripheral"; break; case DRIVE_REMOVABLE: data = "TapePeripheral"; snprintf(buffer, sizeof(buffer), "Tape%d", uTapeNumber++); break; case DRIVE_CDROM: data = "CdRomPeripheral"; snprintf(buffer, sizeof(buffer), "Cdrom%d", uCdromNumber++); break; } RtlCreateUnicodeStringFromAsciiz( &nameW, "Type" ); RtlMultiByteToUnicodeN( dataW, sizeof(dataW), &lenW, data, strlen(data)); NtSetValueKey( lunKey, &nameW, 0, REG_SZ, (BYTE*)dataW, lenW ); RtlFreeUnicodeString( &nameW ); RtlCreateUnicodeStringFromAsciiz( &nameW, "Identifier" ); RtlMultiByteToUnicodeN( dataW, sizeof(dataW), &lenW, lpDriveName, strlen(lpDriveName)); NtSetValueKey( lunKey, &nameW, 0, REG_SZ, (BYTE*)dataW, lenW ); RtlFreeUnicodeString( &nameW ); if (uDriveType == DRIVE_CDROM || uDriveType == DRIVE_REMOVABLE) { RtlCreateUnicodeStringFromAsciiz( &nameW, "DeviceName" ); RtlMultiByteToUnicodeN( dataW, sizeof(dataW), &lenW, buffer, strlen(buffer)); NtSetValueKey( lunKey, &nameW, 0, REG_SZ, (BYTE*)dataW, lenW ); RtlFreeUnicodeString( &nameW ); } RtlCreateUnicodeStringFromAsciiz( &nameW, "UnixDeviceName" ); RtlMultiByteToUnicodeN( dataW, sizeof(dataW), &lenW, lpUnixDeviceName, strlen(lpUnixDeviceName)); NtSetValueKey( lunKey, &nameW, 0, REG_SZ, (BYTE*)dataW, lenW ); RtlFreeUnicodeString( &nameW ); NtClose( lunKey ); NtClose( targetKey ); NtClose( busKey ); NtClose( portKey ); NtClose( scsiKey ); }
NTSTATUS NTAPI INIT_FUNCTION CmpInitializeHardwareConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBlock) { NTSTATUS Status; OBJECT_ATTRIBUTES ObjectAttributes; HANDLE KeyHandle; ULONG Disposition; UNICODE_STRING KeyName; /* Setup the key name */ RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\Hardware\\DeviceMap"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL); /* Create the device map key */ Status = NtCreateKey(&KeyHandle, KEY_READ | KEY_WRITE, &ObjectAttributes, 0, NULL, 0, &Disposition); if (!NT_SUCCESS(Status)) return Status; NtClose(KeyHandle); /* Nobody should've created this key yet! */ ASSERT(Disposition == REG_CREATED_NEW_KEY); /* Setup the key name */ RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\Hardware\\Description"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL); /* Create the description key */ Status = NtCreateKey(&KeyHandle, KEY_READ | KEY_WRITE, &ObjectAttributes, 0, NULL, 0, &Disposition); if (!NT_SUCCESS(Status)) return Status; /* Nobody should've created this key yet! */ ASSERT(Disposition == REG_CREATED_NEW_KEY); /* Allocate the configuration data buffer */ CmpConfigurationData = ExAllocatePoolWithTag(PagedPool, CmpConfigurationAreaSize, TAG_CM); if (!CmpConfigurationData) return STATUS_INSUFFICIENT_RESOURCES; /* Check if we got anything from NTLDR */ if (LoaderBlock->ConfigurationRoot) { /* Setup the configuration tree */ Status = CmpSetupConfigurationTree(LoaderBlock->ConfigurationRoot, KeyHandle, -1, -1); } else { /* Nothing else to do */ Status = STATUS_SUCCESS; } /* Close our handle, free the buffer and return status */ ExFreePoolWithTag(CmpConfigurationData, TAG_CM); NtClose(KeyHandle); return Status; }