//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- CheckAndCreateRegistryPath -.-.-.-.-.-.-.-.-.-.-.-.-.-.-. // DtStatus CheckAndCreateRegistryPath( WDFDRIVER Driver, DtString* pItemPath) { DtStringChar* pRegistryPath; DtString RegistryPath; DtString FullKeyName; UInt PathLength; DtStatus Status; Int i; DT_STRING_DECL(ParamItemName, "\\Parameters"); // Build the full path pRegistryPath = WdfDriverGetRegistryPath(Driver); PathLength = wcslen(pRegistryPath); DT_STRING_INIT_CONST(RegistryPath, pRegistryPath, PathLength); // Allocate a new DtString buffer for the complete path inclusive a '\0' character and // extra '\' if (!DT_SUCCESS(DtStringAlloc(&FullKeyName, PathLength+ DtStringGetStringLength(&ParamItemName)+ DtStringGetStringLength(pItemPath)+2))) return STATUS_NO_MEMORY; DtStringAppendDtString(&FullKeyName, &RegistryPath); DtStringAppendDtString(&FullKeyName, &ParamItemName); if (RtlCheckRegistryKey(RTL_REGISTRY_ABSOLUTE, FullKeyName.Buffer) != STATUS_SUCCESS) RtlCreateRegistryKey(RTL_REGISTRY_ABSOLUTE, FullKeyName.Buffer); Status = DT_STATUS_OK; i = 1; // Get all subitems from pItemPath and check if the registry entry exist. // If not, create the registry entry. // This function is needed, because Wuindows only allows us to create one registry entry // at a time and not a complete path. while (Status == DT_STATUS_OK) { DtStringAppendChars(&FullKeyName, "\\"); Status = DtStringAppendSubstring(&FullKeyName, pItemPath, i, '\\'); if (DT_SUCCESS(Status)) { if (RtlCheckRegistryKey(RTL_REGISTRY_ABSOLUTE, FullKeyName.Buffer) != STATUS_SUCCESS) RtlCreateRegistryKey(RTL_REGISTRY_ABSOLUTE, FullKeyName.Buffer); } i++; } DtStringFree(&FullKeyName); return DT_STATUS_OK; }
static int create_service(WCHAR *svc, WCHAR *name, WCHAR *image) { WCHAR tmp[PATH_MAX]; DWORD dw; wcscpy(svc, SVC_BASE); if (name) { wcscat(svc, name); } else { int p = wcslen(svc); for (WCHAR *i = name = image; *i; i++) if (*i == L'\\') name = i+1; while (*name && *name != '.') svc[p++] = *name++; svc[p] = 0; } if (!NT_SUCCESS(RtlCreateRegistryKey(0, svc))) return 0; RtlWriteRegistryValue(0, svc, L"ImagePath", REG_SZ, tmp, nt_path(tmp, image)); dw = 1; RtlWriteRegistryValue(0,svc, L"Type", REG_DWORD, &dw, sizeof(dw)); DBG("created service reg=%S, image=%S", svc, image); return 1; }
NTSTATUS NTAPI IntCreateNewRegistryPath( PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension) { static UNICODE_STRING VideoIdValueName = RTL_CONSTANT_STRING(L"VideoId"); static UNICODE_STRING ControlVideoPathName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Video\\"); HANDLE DevInstRegKey, SettingsKey, NewKey; UCHAR VideoIdBuffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + GUID_STRING_LENGTH]; UNICODE_STRING VideoIdString; UUID VideoId; PKEY_VALUE_PARTIAL_INFORMATION ValueInformation ; NTSTATUS Status; ULONG ResultLength; USHORT KeyMaxLength; OBJECT_ATTRIBUTES ObjectAttributes; /* Open the hardware key: HKLM\System\CurrentControlSet\Enum\... */ Status = IoOpenDeviceRegistryKey(DeviceExtension->PhysicalDeviceObject, PLUGPLAY_REGKEY_DEVICE, KEY_ALL_ACCESS, &DevInstRegKey); if (Status != STATUS_SUCCESS) { ERR_(VIDEOPRT, "IoOpenDeviceRegistryKey failed: status 0x%lx\n", Status); return Status; } /* Query the VideoId value */ ValueInformation = (PKEY_VALUE_PARTIAL_INFORMATION)VideoIdBuffer; Status = ZwQueryValueKey(DevInstRegKey, &VideoIdValueName, KeyValuePartialInformation, ValueInformation, sizeof(VideoIdBuffer), &ResultLength); if (!NT_SUCCESS(Status)) { /* Create a new video Id */ Status = ExUuidCreate(&VideoId); if (!NT_SUCCESS(Status)) { ERR_(VIDEOPRT, "ExUuidCreate failed: status 0x%lx\n", Status); ObCloseHandle(DevInstRegKey, KernelMode); return Status; } /* Convert the GUID into a string */ Status = RtlStringFromGUID(&VideoId, &VideoIdString); if (!NT_SUCCESS(Status)) { ERR_(VIDEOPRT, "RtlStringFromGUID failed: status 0x%lx\n", Status); ObCloseHandle(DevInstRegKey, KernelMode); return Status; } /* Copy the GUID String to our buffer */ ValueInformation->DataLength = min(VideoIdString.Length, GUID_STRING_LENGTH); RtlCopyMemory(ValueInformation->Data, VideoIdString.Buffer, ValueInformation->DataLength); /* Free the GUID string */ RtlFreeUnicodeString(&VideoIdString); /* Write the VideoId registry value */ Status = ZwSetValueKey(DevInstRegKey, &VideoIdValueName, 0, REG_SZ, ValueInformation->Data, ValueInformation->DataLength); if (!NT_SUCCESS(Status)) { ERR_(VIDEOPRT, "ZwSetValueKey failed: status 0x%lx\n", Status); ObCloseHandle(DevInstRegKey, KernelMode); return Status; } } /* Initialize the VideoId string from the registry data */ VideoIdString.Buffer = (PWCHAR)ValueInformation->Data; VideoIdString.Length = (USHORT)ValueInformation->DataLength; VideoIdString.MaximumLength = VideoIdString.Length; /* Close the hardware key */ ObCloseHandle(DevInstRegKey, KernelMode); /* Calculate the size needed for the new registry path name */ KeyMaxLength = ControlVideoPathName.Length + VideoIdString.Length + sizeof(L"\\0000"); /* Allocate the path name buffer */ DeviceExtension->NewRegistryPath.Length = 0; DeviceExtension->NewRegistryPath.MaximumLength = KeyMaxLength; DeviceExtension->NewRegistryPath.Buffer = ExAllocatePoolWithTag(PagedPool, KeyMaxLength, TAG_VIDEO_PORT); if (DeviceExtension->NewRegistryPath.Buffer == NULL) { ERR_(VIDEOPRT, "Failed to allocate key name buffer.\n"); return STATUS_INSUFFICIENT_RESOURCES; } /* Copy the root key name and append the VideoId string */ RtlCopyUnicodeString(&DeviceExtension->NewRegistryPath, &ControlVideoPathName); RtlAppendUnicodeStringToString(&DeviceExtension->NewRegistryPath, &VideoIdString); /* Check if we have the key already */ Status = RtlCheckRegistryKey(RTL_REGISTRY_ABSOLUTE, DeviceExtension->NewRegistryPath.Buffer); if (Status != STATUS_SUCCESS) { /* Try to create the new key */ Status = RtlCreateRegistryKey(RTL_REGISTRY_ABSOLUTE, DeviceExtension->NewRegistryPath.Buffer); } /* Append a the instance path */ /// \todo HACK RtlAppendUnicodeToString(&DeviceExtension->NewRegistryPath, L"\\"); RtlAppendUnicodeToString(&DeviceExtension->NewRegistryPath, L"0000"); /* Check this key again */ Status = RtlCheckRegistryKey(RTL_REGISTRY_ABSOLUTE, DeviceExtension->NewRegistryPath.Buffer); if (Status != STATUS_SUCCESS) { /* Try to create the new key */ Status = RtlCreateRegistryKey(RTL_REGISTRY_ABSOLUTE, DeviceExtension->NewRegistryPath.Buffer); if (!NT_SUCCESS(Status)) { ERR_(VIDEOPRT, "Failed create key '%wZ'\n", &DeviceExtension->NewRegistryPath); return Status; } /* Open the new key */ InitializeObjectAttributes(&ObjectAttributes, &DeviceExtension->NewRegistryPath, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); Status = ZwOpenKey(&NewKey, KEY_READ, &ObjectAttributes); if (!NT_SUCCESS(Status)) { ERR_(VIDEOPRT, "Failed to open settings key. Status 0x%lx\n", Status); return Status; } /* Open the device profile key */ InitializeObjectAttributes(&ObjectAttributes, &DeviceExtension->RegistryPath, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); Status = ZwOpenKey(&SettingsKey, KEY_READ, &ObjectAttributes); if (!NT_SUCCESS(Status)) { ERR_(VIDEOPRT, "Failed to open settings key. Status 0x%lx\n", Status); ObCloseHandle(NewKey, KernelMode); return Status; } /* Copy the registry data from the legacy key */ Status = IntCopyRegistryKey(SettingsKey, NewKey); } return Status; }