NTSTATUS FilterWriteSetting(_In_ PMS_FILTER pFilter, uint16_t aKey, int aIndex, const uint8_t *aValue, uint16_t aValueLength) { HANDLE regKey = NULL; OBJECT_ATTRIBUTES attributes; DECLARE_UNICODE_STRING_SIZE(Name, 20); // Convert 'aKey' to a string RtlIntegerToUnicodeString((ULONG)aKey, 16, &Name); InitializeObjectAttributes( &attributes, &Name, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, pFilter->otSettingsRegKey, NULL); // Create/Open the registry key NTSTATUS status = ZwCreateKey( ®Key, KEY_ALL_ACCESS, &attributes, 0, NULL, REG_OPTION_NON_VOLATILE, NULL); NT_ASSERT(NT_SUCCESS(status)); if (!NT_SUCCESS(status)) { LogError(DRIVER_DEFAULT, "ZwCreateKey for %S key failed, %!STATUS!", Name.Buffer, status); goto error; } // Convert 'aIndex' to a string RtlIntegerToUnicodeString((ULONG)aIndex, 16, &Name); // Write the data to the registry status = ZwSetValueKey( regKey, &Name, 0, REG_BINARY, (PVOID)aValue, aValueLength); if (!NT_SUCCESS(status)) { LogError(DRIVER_DEFAULT, "ZwSetValueKey for %S value failed, %!STATUS!", Name.Buffer, status); goto error; } error: if (regKey) ZwClose(regKey); return status; }
NTSTATUS ConstructDeviceName( IN PCWSTR Path, IN UCHAR Index, OUT PUNICODE_STRING DeviceName) { UNICODE_STRING UnicodePath; UNICODE_STRING UnicodeIndex; WCHAR IndexStringBuffer[5]; USHORT Size; USHORT LastCharacterIndex; /* Check for NULL parameters */ if ( ( ! Path ) || ( ! DeviceName ) ) { DPRINT("Unexpected NULL parameter"); return STATUS_INVALID_PARAMETER; } /* Range-check */ if ( Index >= SOUND_MAX_DEVICES ) { DPRINT("Device index %d out of range", Index); return STATUS_INVALID_PARAMETER; } /* Initialise the unicode path string */ RtlInitUnicodeString(&UnicodePath, Path); /* Calculate the length to hold the full string */ Size = UnicodePath.Length + sizeof(IndexStringBuffer) + sizeof(UNICODE_NULL); /* Allocate memory for DeviceName */ DeviceName->Buffer = ExAllocatePool(PagedPool, Size); DeviceName->MaximumLength = Size; if ( ! DeviceName->Buffer ) { DPRINT("Couldn't allocate memory for device name string"); return STATUS_INSUFFICIENT_RESOURCES; } /* Copy the path */ RtlCopyUnicodeString(DeviceName, &UnicodePath); /* Convert Index to string and append */ UnicodeIndex.Buffer = IndexStringBuffer; UnicodeIndex.MaximumLength = sizeof(IndexStringBuffer); RtlIntegerToUnicodeString((ULONG)Index, 10, &UnicodeIndex); RtlAppendUnicodeStringToString(DeviceName, &UnicodeIndex); /* Terminate the string */ LastCharacterIndex = DeviceName->Length / sizeof(UNICODE_NULL); DeviceName->Buffer[LastCharacterIndex] = UNICODE_NULL; return STATUS_SUCCESS; }
BOOLEAN NTAPI IntVideoPortGetMonitorId( IN PVIDEO_PORT_CHILD_EXTENSION ChildExtension, IN OUT PWCHAR Buffer) { USHORT Manufacturer, Model; UNICODE_STRING UnicodeModelStr; /* This must be valid to call this function */ ASSERT(ChildExtension->EdidValid); /* 3 letters 5-bit ANSI manufacturer code (big endian) */ Manufacturer = *(PUSHORT)(&ChildExtension->ChildDescriptor[8]); /* Letters encoded as A=1 to Z=26 */ Buffer[0] = (WCHAR)((Manufacturer & 0x7C00) + 'A' - 1); Buffer[1] = (WCHAR)((Manufacturer & 0x03E0) + 'A' - 1); Buffer[2] = (WCHAR)((Manufacturer & 0x001F) + 'A' - 1); /* Model number (16-bit little endian) */ Model = *(PUSHORT)(&ChildExtension->ChildDescriptor[10]); /* Use Rtl helper for conversion */ UnicodeModelStr.Buffer = &Buffer[3]; UnicodeModelStr.Length = 0; UnicodeModelStr.MaximumLength = 4 * sizeof(WCHAR); RtlIntegerToUnicodeString(Model, 16, &UnicodeModelStr); /* Terminate it */ Buffer[7] = UNICODE_NULL; /* And we're done */ return TRUE; }
BOOLEAN SecMgrpSetProfileInt( LPTSTR lpAppName, LPTSTR lpKeyName, ULONG Value ) { NTSTATUS NtStatus; UNICODE_STRING IntString; WCHAR StringBuffer[20]; IntString.Buffer = StringBuffer; IntString.MaximumLength = 20; IntString.Length = 0; NtStatus = RtlIntegerToUnicodeString( Value, 10, &IntString ); return (WriteProfileString( lpAppName, lpKeyName, IntString.Buffer) ); }
uint16_t FilterCountSettings(_In_ PMS_FILTER pFilter, uint16_t aKey) { HANDLE regKey = NULL; OBJECT_ATTRIBUTES attributes; DECLARE_UNICODE_STRING_SIZE(Name, 8); UCHAR InfoBuffer[128] = {0}; PKEY_FULL_INFORMATION pInfo = (PKEY_FULL_INFORMATION)InfoBuffer; ULONG InfoLength = sizeof(InfoBuffer); // Convert 'aKey' to a string RtlIntegerToUnicodeString((ULONG)aKey, 16, &Name); InitializeObjectAttributes( &attributes, &Name, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, pFilter->otSettingsRegKey, NULL); // Open the registry key NTSTATUS status = ZwOpenKey( ®Key, KEY_ALL_ACCESS, &attributes); if (!NT_SUCCESS(status)) { // Key doesn't exist, return a count of 0 goto error; } // Query the key info from the registry status = ZwQueryKey( regKey, KeyValueFullInformation, pInfo, InfoLength, &InfoLength); if (!NT_SUCCESS(status)) { LogError(DRIVER_DEFAULT, "ZwQueryKey for %S value failed, %!STATUS!", Name.Buffer, status); goto error; } error: if (regKey) ZwClose(regKey); return (uint16_t)pInfo->Values; }
NTSTATUS SoundCreateDeviceName( PCWSTR PrePrefix, PCWSTR Prefix, UCHAR Index, PUNICODE_STRING DeviceName ) { UNICODE_STRING Number; WCHAR NumberBuffer[5]; UNICODE_STRING uPrePrefix; UNICODE_STRING uPrefix; ULONG Size; RtlInitUnicodeString(&uPrePrefix, PrePrefix); RtlInitUnicodeString(&uPrefix, Prefix); Size = uPrePrefix.Length + uPrefix.Length + sizeof(NumberBuffer) + sizeof(UNICODE_NULL); DeviceName->Buffer = ExAllocatePool(PagedPool, Size); DeviceName->MaximumLength = (USHORT)Size; if (DeviceName->Buffer == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } RtlCopyUnicodeString(DeviceName, &uPrePrefix); RtlAppendUnicodeStringToString(DeviceName, &uPrefix); if (Index != 255) { Number.Buffer = NumberBuffer; Number.MaximumLength = sizeof(NumberBuffer); RtlIntegerToUnicodeString((ULONG)Index, 10, &Number); RtlAppendUnicodeStringToString(DeviceName, &Number); } /* ** Null terminate for some uses (but don't increase the 'length' or ** the UNICODE_STRING version will have a 0 on the end. */ DeviceName->Buffer[DeviceName->Length / sizeof(UNICODE_NULL)] = UNICODE_NULL; return STATUS_SUCCESS; }
NTSTATUS MyDLPKBF_CreateDevice (IN PDRIVER_OBJECT pDriverObject, IN ULONG DeviceNumber) { PDEVICE_OBJECT pDevObj; UNICODE_STRING uniNtDeviceName, uniDosDeviceName, uniNumber; WCHAR ntDeviceNameBuffer[MYDLP_MAX_NAME_LENGTH]; WCHAR dosDeviceNameBuffer[MYDLP_MAX_NAME_LENGTH]; WCHAR numberBuffer[2]; PMYDLPKBF_DEVICE_EXTENSION pDevExt; NTSTATUS status; DbgPrint("MyDLPKBF_CreateDevice: Start\n"); status = STATUS_SUCCESS; uniNtDeviceName.Buffer = ntDeviceNameBuffer; uniNtDeviceName.MaximumLength = MYDLP_MAX_NAME_LENGTH * 2; uniNtDeviceName.Length = 0; uniDosDeviceName.Buffer = dosDeviceNameBuffer; uniDosDeviceName.MaximumLength = MYDLP_MAX_NAME_LENGTH * 2; uniDosDeviceName.Length = 0; uniNumber.Buffer = numberBuffer; uniNumber.MaximumLength = 4; uniNumber.Length = 0; RtlIntegerToUnicodeString( DeviceNumber, 10, &uniNumber); RtlAppendUnicodeToString( &uniNtDeviceName, NT_DEVICE_NAME); RtlAppendUnicodeStringToString( &uniNtDeviceName, &uniNumber); RtlAppendUnicodeToString( &uniDosDeviceName, DOS_DEVICE_NAME); RtlAppendUnicodeStringToString( &uniDosDeviceName, &uniNumber); status = IoCreateDevice(pDriverObject, sizeof(MYDLPKBF_DEVICE_EXTENSION), &uniNtDeviceName, FILE_DEVICE_UNKNOWN, 0, TRUE, &pDevObj); if(!NT_SUCCESS(status)) { DbgPrint("MyDLPKBF_CreateDevice: IoCreateDevice failed\ device no:%d\n", DeviceNumber); return status; }
NTSTATUS FilterDeleteSetting(_In_ PMS_FILTER pFilter, uint16_t aKey, int aIndex) { HANDLE regKey = NULL; OBJECT_ATTRIBUTES attributes; DECLARE_UNICODE_STRING_SIZE(Name, 20); // Convert 'aKey' to a string RtlIntegerToUnicodeString((ULONG)aKey, 16, &Name); InitializeObjectAttributes( &attributes, &Name, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, pFilter->otSettingsRegKey, NULL); // Open the registry key NTSTATUS status = ZwOpenKey( ®Key, KEY_ALL_ACCESS, &attributes); if (!NT_SUCCESS(status)) { // Key doesn't exist goto error; } // If 'aIndex' is -1 then delete the whole key, otherwise delete the individual value if (aIndex == -1) { // Delete the registry key status = ZwDeleteKey(regKey); } else { UCHAR KeyInfoBuffer[128] = { 0 }; PKEY_FULL_INFORMATION pKeyInfo = (PKEY_FULL_INFORMATION)KeyInfoBuffer; ULONG KeyInfoLength = sizeof(KeyInfoBuffer); // When deleting an individual value, since order doesn't matter, we will actually // copy the last value over the one being deleted and then delete the last value; so // we maintain a contiguous list of numbered values // Query the number of values // Note: Can't use helper function because we already have the key open status = ZwQueryKey( regKey, KeyValueFullInformation, pKeyInfo, KeyInfoLength, &KeyInfoLength); if (!NT_SUCCESS(status)) { LogError(DRIVER_DEFAULT, "ZwQueryKey for %S value failed, %!STATUS!", Name.Buffer, status); goto error; } if ((ULONG)aIndex >= pKeyInfo->Values) { // Attempt to delete beyond the end of the list status = STATUS_OBJECT_NAME_NOT_FOUND; goto error; } else if (pKeyInfo->Values == 1) { // Deleting the only value on the key, go ahead and delete the entire key status = ZwDeleteKey(regKey); } else if (pKeyInfo->Values - 1 != (ULONG)aIndex) { // We aren't deleting the last value so we need to copy the last value // over this one, and then delete the last one. PKEY_VALUE_PARTIAL_INFORMATION pValueInfo = NULL; ULONG ValueInfoLength = 0; // Convert pKeyInfo->Values-1 to a string RtlIntegerToUnicodeString(pKeyInfo->Values - 1, 16, &Name); // Query the key data buffer size status = ZwQueryValueKey( regKey, &Name, KeyValuePartialInformation, pValueInfo, 0, &ValueInfoLength); NT_ASSERT(status != STATUS_SUCCESS); if (status != STATUS_BUFFER_TOO_SMALL) { LogVerbose(DRIVER_DEFAULT, "ZwQueryValueKey for %S value failed, %!STATUS!", Name.Buffer, status); goto error; } pValueInfo = FILTER_ALLOC_MEM(pFilter->FilterHandle, ValueInfoLength); if (pValueInfo == NULL) { status = STATUS_INSUFFICIENT_RESOURCES; goto error; } // Query the data buffer status = ZwQueryValueKey( regKey, &Name, KeyValuePartialInformation, pValueInfo, ValueInfoLength, &ValueInfoLength); if (!NT_SUCCESS(status)) { LogError(DRIVER_DEFAULT, "ZwQueryValueKey for %S value failed, %!STATUS!", Name.Buffer, status); goto cleanup; } // Delete the registry value status = ZwDeleteValueKey( regKey, &Name); if (!NT_SUCCESS(status)) { LogError(DRIVER_DEFAULT, "ZwDeleteValueKey for %S value failed, %!STATUS!", Name.Buffer, status); goto cleanup; } // Convert 'aIndex' to a string RtlIntegerToUnicodeString((ULONG)aIndex, 16, &Name); // Write the data to the registry key we are deleting status = ZwSetValueKey( regKey, &Name, 0, REG_BINARY, (PVOID)pValueInfo->Data, pValueInfo->DataLength); if (!NT_SUCCESS(status)) { LogError(DRIVER_DEFAULT, "ZwSetValueKey for %S value failed, %!STATUS!", Name.Buffer, status); goto cleanup; } cleanup: if (pValueInfo) FILTER_FREE_MEM(pValueInfo); } else { // Deleting the last value in the list (but not the only value) // Just delete the value directly. No need to copy any others. // Convert 'aIndex' to a string RtlIntegerToUnicodeString((ULONG)aIndex, 16, &Name); // Delete the registry value status = ZwDeleteValueKey( regKey, &Name); } } error: if (regKey) ZwClose(regKey); return status; }
NTSTATUS FilterReadSetting(_In_ PMS_FILTER pFilter, uint16_t aKey, int aIndex, uint8_t *aValue, uint16_t *aValueLength) { HANDLE regKey = NULL; OBJECT_ATTRIBUTES attributes; DECLARE_UNICODE_STRING_SIZE(Name, 20); PKEY_VALUE_PARTIAL_INFORMATION pInfo = NULL; ULONG InfoLength = sizeof(*pInfo) + *aValueLength; // Convert 'aKey' to a string RtlIntegerToUnicodeString((ULONG)aKey, 16, &Name); InitializeObjectAttributes( &attributes, &Name, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, pFilter->otSettingsRegKey, NULL); // Open the registry key NTSTATUS status = ZwOpenKey( ®Key, KEY_ALL_ACCESS, &attributes); if (!NT_SUCCESS(status)) { // Key doesn't exist goto error; } // Convert 'aIndex' to a string RtlIntegerToUnicodeString((ULONG)aIndex, 16, &Name); // Allocate buffer for query pInfo = FILTER_ALLOC_MEM(pFilter->FilterHandle, InfoLength); if (pInfo == NULL) { status = STATUS_INSUFFICIENT_RESOURCES; goto error; } // Query the data status = ZwQueryValueKey( regKey, &Name, KeyValuePartialInformation, pInfo, InfoLength, &InfoLength); if (!NT_SUCCESS(status)) { LogVerbose(DRIVER_DEFAULT, "ZwQueryValueKey for %S value failed, %!STATUS!", Name.Buffer, status); goto error; } NT_ASSERT(*aValueLength >= pInfo->DataLength); *aValueLength = (uint16_t)pInfo->DataLength; if (aValue) { memcpy(aValue, pInfo->Data, pInfo->DataLength); } error: if (pInfo) FILTER_FREE_MEM(pInfo); if (regKey) ZwClose(regKey); return status; }
BOOLEAN ParMakeNames( IN ULONG ParallelPortNumber, OUT PUNICODE_STRING PortName, OUT PUNICODE_STRING ClassName, OUT PUNICODE_STRING LinkName ) /*++ Routine Description: This routine generates the names \Device\ParallelPortN and \Device\ParallelVdmN, \DosDevices\PARVDMN. Arguments: ParallelPortNumber - Supplies the port number. PortName - Returns the port name. ClassName - Returns the class name. LinkName - Returns the symbolic link name. Return Value: FALSE - Failure. TRUE - Success. --*/ { UNICODE_STRING prefix, digits, linkPrefix, linkDigits; WCHAR digitsBuffer[10], linkDigitsBuffer[10]; UNICODE_STRING portSuffix, classSuffix, linkSuffix; NTSTATUS status; // Put together local variables for constructing names. RtlInitUnicodeString(&prefix, L"\\Device\\"); RtlInitUnicodeString(&linkPrefix, L"\\DosDevices\\"); RtlInitUnicodeString(&portSuffix, DD_PARALLEL_PORT_BASE_NAME_U); RtlInitUnicodeString(&classSuffix, L"ParallelVdm"); RtlInitUnicodeString(&linkSuffix, L"$VDMLPT"); digits.Length = 0; digits.MaximumLength = 20; digits.Buffer = digitsBuffer; linkDigits.Length = 0; linkDigits.MaximumLength = 20; linkDigits.Buffer = linkDigitsBuffer; status = RtlIntegerToUnicodeString(ParallelPortNumber, 10, &digits); if (!NT_SUCCESS(status)) { return FALSE; } status = RtlIntegerToUnicodeString(ParallelPortNumber + 1, 10, &linkDigits); if (!NT_SUCCESS(status)) { return FALSE; } // Make the port name. PortName->Length = 0; PortName->MaximumLength = prefix.Length + portSuffix.Length + digits.Length + sizeof(WCHAR); PortName->Buffer = ExAllocatePool(PagedPool, PortName->MaximumLength); if (!PortName->Buffer) { return FALSE; } RtlZeroMemory(PortName->Buffer, PortName->MaximumLength); RtlAppendUnicodeStringToString(PortName, &prefix); RtlAppendUnicodeStringToString(PortName, &portSuffix); RtlAppendUnicodeStringToString(PortName, &digits); // Make the class name. ClassName->Length = 0; ClassName->MaximumLength = prefix.Length + classSuffix.Length + digits.Length + sizeof(WCHAR); ClassName->Buffer = ExAllocatePool(PagedPool, ClassName->MaximumLength); if (!ClassName->Buffer) { ExFreePool(PortName->Buffer); return FALSE; } RtlZeroMemory(ClassName->Buffer, ClassName->MaximumLength); RtlAppendUnicodeStringToString(ClassName, &prefix); RtlAppendUnicodeStringToString(ClassName, &classSuffix); RtlAppendUnicodeStringToString(ClassName, &digits); // Make the link name. LinkName->Length = 0; LinkName->MaximumLength = linkPrefix.Length + linkSuffix.Length + linkDigits.Length + sizeof(WCHAR); LinkName->Buffer = ExAllocatePool(PagedPool, LinkName->MaximumLength); if (!LinkName->Buffer) { ExFreePool(PortName->Buffer); ExFreePool(ClassName->Buffer); return FALSE; } RtlZeroMemory(LinkName->Buffer, LinkName->MaximumLength); RtlAppendUnicodeStringToString(LinkName, &linkPrefix); RtlAppendUnicodeStringToString(LinkName, &linkSuffix); RtlAppendUnicodeStringToString(LinkName, &linkDigits); return TRUE; }
NTSTATUS NTAPI IopQueryDeviceDescription( PIO_QUERY Query, UNICODE_STRING RootKey, HANDLE RootKeyHandle, ULONG Bus, PKEY_VALUE_FULL_INFORMATION *BusInformation) { NTSTATUS Status = STATUS_SUCCESS; /* Controller Stuff */ UNICODE_STRING ControllerString; UNICODE_STRING ControllerRootRegName = RootKey; UNICODE_STRING ControllerRegName; HANDLE ControllerKeyHandle; PKEY_FULL_INFORMATION ControllerFullInformation = NULL; PKEY_VALUE_FULL_INFORMATION ControllerInformation[3] = {NULL, NULL, NULL}; ULONG ControllerNumber; ULONG ControllerLoop; ULONG MaximumControllerNumber; /* Peripheral Stuff */ UNICODE_STRING PeripheralString; HANDLE PeripheralKeyHandle; PKEY_FULL_INFORMATION PeripheralFullInformation; PKEY_VALUE_FULL_INFORMATION PeripheralInformation[3] = {NULL, NULL, NULL}; ULONG PeripheralNumber; ULONG PeripheralLoop; ULONG MaximumPeripheralNumber; /* Global Registry Stuff */ OBJECT_ATTRIBUTES ObjectAttributes; ULONG LenFullInformation; ULONG LenKeyFullInformation; UNICODE_STRING TempString; WCHAR TempBuffer[14]; PWSTR Strings[3] = { L"Identifier", L"Configuration Data", L"Component Information" }; /* Temporary String */ TempString.MaximumLength = sizeof(TempBuffer); TempString.Length = 0; TempString.Buffer = TempBuffer; /* Add Controller Name to String */ RtlAppendUnicodeToString(&ControllerRootRegName, L"\\"); RtlAppendUnicodeToString(&ControllerRootRegName, ArcTypes[*Query->ControllerType]); /* Set the Controller Number if specified */ if (Query->ControllerNumber && *(Query->ControllerNumber)) { ControllerNumber = *Query->ControllerNumber; MaximumControllerNumber = ControllerNumber + 1; } else { /* Find out how many Controller Numbers there are */ InitializeObjectAttributes( &ObjectAttributes, &ControllerRootRegName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = ZwOpenKey(&ControllerKeyHandle, KEY_READ, &ObjectAttributes); if (NT_SUCCESS(Status)) { /* How much buffer space */ ZwQueryKey(ControllerKeyHandle, KeyFullInformation, NULL, 0, &LenFullInformation); /* Allocate it */ ControllerFullInformation = ExAllocatePoolWithTag(PagedPool, LenFullInformation, TAG_IO_RESOURCE); /* Get the Information */ Status = ZwQueryKey(ControllerKeyHandle, KeyFullInformation, ControllerFullInformation, LenFullInformation, &LenFullInformation); ZwClose(ControllerKeyHandle); ControllerKeyHandle = NULL; } /* No controller was found, go back to function. */ if (!NT_SUCCESS(Status)) { if (ControllerFullInformation != NULL) ExFreePoolWithTag(ControllerFullInformation, TAG_IO_RESOURCE); return Status; } /* Find out Controller Numbers */ ControllerNumber = 0; MaximumControllerNumber = ControllerFullInformation->SubKeys; /* Free Memory */ ExFreePoolWithTag(ControllerFullInformation, TAG_IO_RESOURCE); ControllerFullInformation = NULL; } /* Save String */ ControllerRegName = ControllerRootRegName; /* Loop through controllers */ for (; ControllerNumber < MaximumControllerNumber; ControllerNumber++) { /* Load String */ ControllerRootRegName = ControllerRegName; /* Controller Number to Registry String */ Status = RtlIntegerToUnicodeString(ControllerNumber, 10, &TempString); /* Create String */ Status |= RtlAppendUnicodeToString(&ControllerRootRegName, L"\\"); Status |= RtlAppendUnicodeStringToString(&ControllerRootRegName, &TempString); /* Something messed up */ if (!NT_SUCCESS(Status)) break; /* Open the Registry Key */ InitializeObjectAttributes( &ObjectAttributes, &ControllerRootRegName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = ZwOpenKey(&ControllerKeyHandle, KEY_READ, &ObjectAttributes); /* Read the Configuration Data... */ if (NT_SUCCESS(Status)) { for (ControllerLoop = 0; ControllerLoop < 3; ControllerLoop++) { /* Identifier String First */ RtlInitUnicodeString(&ControllerString, Strings[ControllerLoop]); /* How much buffer space */ Status = ZwQueryValueKey(ControllerKeyHandle, &ControllerString, KeyValueFullInformation, NULL, 0, &LenKeyFullInformation); if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_TOO_SMALL && Status != STATUS_BUFFER_OVERFLOW) continue; /* Allocate it */ ControllerInformation[ControllerLoop] = ExAllocatePoolWithTag(PagedPool, LenKeyFullInformation, TAG_IO_RESOURCE); /* Get the Information */ Status = ZwQueryValueKey(ControllerKeyHandle, &ControllerString, KeyValueFullInformation, ControllerInformation[ControllerLoop], LenKeyFullInformation, &LenKeyFullInformation); } /* Clean Up */ ZwClose(ControllerKeyHandle); ControllerKeyHandle = NULL; } /* Something messed up */ if (!NT_SUCCESS(Status)) goto EndLoop; /* We now have Bus *AND* Controller Information.. is it enough? */ if (!Query->PeripheralType || !(*Query->PeripheralType)) { Status = Query->CalloutRoutine( Query->Context, &ControllerRootRegName, *Query->BusType, Bus, BusInformation, *Query->ControllerType, ControllerNumber, ControllerInformation, 0, 0, NULL); goto EndLoop; } /* Not enough...caller also wants peripheral name */ Status = RtlAppendUnicodeToString(&ControllerRootRegName, L"\\"); Status |= RtlAppendUnicodeToString(&ControllerRootRegName, ArcTypes[*Query->PeripheralType]); /* Something messed up */ if (!NT_SUCCESS(Status)) goto EndLoop; /* Set the Peripheral Number if specified */ if (Query->PeripheralNumber && *Query->PeripheralNumber) { PeripheralNumber = *Query->PeripheralNumber; MaximumPeripheralNumber = PeripheralNumber + 1; } else { /* Find out how many Peripheral Numbers there are */ InitializeObjectAttributes( &ObjectAttributes, &ControllerRootRegName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = ZwOpenKey(&PeripheralKeyHandle, KEY_READ, &ObjectAttributes); if (NT_SUCCESS(Status)) { /* How much buffer space */ ZwQueryKey(PeripheralKeyHandle, KeyFullInformation, NULL, 0, &LenFullInformation); /* Allocate it */ PeripheralFullInformation = ExAllocatePoolWithTag(PagedPool, LenFullInformation, TAG_IO_RESOURCE); /* Get the Information */ Status = ZwQueryKey(PeripheralKeyHandle, KeyFullInformation, PeripheralFullInformation, LenFullInformation, &LenFullInformation); ZwClose(PeripheralKeyHandle); PeripheralKeyHandle = NULL; } /* No controller was found, go back to function but clean up first */ if (!NT_SUCCESS(Status)) { Status = STATUS_SUCCESS; goto EndLoop; } /* Find out Peripheral Number */ PeripheralNumber = 0; MaximumPeripheralNumber = PeripheralFullInformation->SubKeys; /* Free Memory */ ExFreePoolWithTag(PeripheralFullInformation, TAG_IO_RESOURCE); PeripheralFullInformation = NULL; } /* Save Name */ ControllerRegName = ControllerRootRegName; /* Loop through Peripherals */ for (; PeripheralNumber < MaximumPeripheralNumber; PeripheralNumber++) { /* Restore Name */ ControllerRootRegName = ControllerRegName; /* Peripheral Number to Registry String */ Status = RtlIntegerToUnicodeString(PeripheralNumber, 10, &TempString); /* Create String */ Status |= RtlAppendUnicodeToString(&ControllerRootRegName, L"\\"); Status |= RtlAppendUnicodeStringToString(&ControllerRootRegName, &TempString); /* Something messed up */ if (!NT_SUCCESS(Status)) break; /* Open the Registry Key */ InitializeObjectAttributes( &ObjectAttributes, &ControllerRootRegName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = ZwOpenKey(&PeripheralKeyHandle, KEY_READ, &ObjectAttributes); if (NT_SUCCESS(Status)) { for (PeripheralLoop = 0; PeripheralLoop < 3; PeripheralLoop++) { /* Identifier String First */ RtlInitUnicodeString(&PeripheralString, Strings[PeripheralLoop]); /* How much buffer space */ Status = ZwQueryValueKey(PeripheralKeyHandle, &PeripheralString, KeyValueFullInformation, NULL, 0, &LenKeyFullInformation); if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_TOO_SMALL && Status != STATUS_BUFFER_OVERFLOW) { PeripheralInformation[PeripheralLoop] = NULL; continue; } /* Allocate it */ PeripheralInformation[PeripheralLoop] = ExAllocatePoolWithTag(PagedPool, LenKeyFullInformation, TAG_IO_RESOURCE); /* Get the Information */ Status = ZwQueryValueKey(PeripheralKeyHandle, &PeripheralString, KeyValueFullInformation, PeripheralInformation[PeripheralLoop], LenKeyFullInformation, &LenKeyFullInformation); } /* Clean Up */ ZwClose(PeripheralKeyHandle); PeripheralKeyHandle = NULL; /* We now have everything the caller could possibly want */ if (NT_SUCCESS(Status)) { Status = Query->CalloutRoutine( Query->Context, &ControllerRootRegName, *Query->BusType, Bus, BusInformation, *Query->ControllerType, ControllerNumber, ControllerInformation, *Query->PeripheralType, PeripheralNumber, PeripheralInformation); } /* Free the allocated memory */ for (PeripheralLoop = 0; PeripheralLoop < 3; PeripheralLoop++) { if (PeripheralInformation[PeripheralLoop]) { ExFreePoolWithTag(PeripheralInformation[PeripheralLoop], TAG_IO_RESOURCE); PeripheralInformation[PeripheralLoop] = NULL; } } /* Something Messed up */ if (!NT_SUCCESS(Status)) break; } } EndLoop: /* Free the allocated memory */ for (ControllerLoop = 0; ControllerLoop < 3; ControllerLoop++) { if (ControllerInformation[ControllerLoop]) { ExFreePoolWithTag(ControllerInformation[ControllerLoop], TAG_IO_RESOURCE); ControllerInformation[ControllerLoop] = NULL; } } /* Something Messed up */ if (!NT_SUCCESS(Status)) break; } return Status; }
NTSTATUS SampCheckMemberUpgradedFor18471( IN ULONG AliasRid, IN ULONG MemberRid ) /*++ Routine Description: This routine checks if the SAM upgrade flag is set. The upgrade flag is: HKEY_LOCAL_MACHINE\System\CurrentControlSet\control\lsa UpgradeSam = REG_DWORD 1 Arguments: Return Value: TRUE - The flag was set FALSE - The flag was not set or the value was not present --*/ { OBJECT_ATTRIBUTES ObjectAttributes; HANDLE KeyHandle; NTSTATUS Status; WCHAR KeyName[100]; WCHAR AliasName[15]; // big enough for 4 billion UNICODE_STRING KeyNameString; UNICODE_STRING AliasString; // // Build the full key name. It is of the form: // "fix18471\alias_rid\member_rid" // wcscpy( KeyName, SAMP_FIX_18471_KEY_NAME L"\\" ); AliasString.Buffer = AliasName; AliasString.MaximumLength = sizeof(AliasName); Status = RtlIntegerToUnicodeString( AliasRid, 16, &AliasString ); ASSERT(NT_SUCCESS(Status)); wcscat( KeyName, AliasString.Buffer ); wcscat( KeyName, L"\\" ); AliasString.MaximumLength = sizeof(AliasName); Status = RtlIntegerToUnicodeString( MemberRid, 16, &AliasString ); ASSERT(NT_SUCCESS(Status)); wcscat( KeyName, AliasString.Buffer ); RtlInitUnicodeString( &KeyNameString, KeyName ); // // Open the member key in the registry // InitializeObjectAttributes( &ObjectAttributes, &KeyNameString, OBJ_CASE_INSENSITIVE, 0, NULL ); Status = NtOpenKey( &KeyHandle, KEY_READ, &ObjectAttributes ); NtClose(KeyHandle); return(Status); }
NTSTATUS SampAddMemberRidTo18471Key( IN ULONG AliasRid, IN ULONG MemberRid ) /*++ Routine Description: This routine adds a key for this member under the key for this alias to the current registry transaction. Arguments: AliasRid - the rid of the alias MemberRid - The rid of the member of the alias Returns: Errors from the RtlRXact APIs --*/ { NTSTATUS Status; WCHAR KeyName[100]; WCHAR AliasName[15]; // big enough for 4 billion UNICODE_STRING KeyNameString; UNICODE_STRING AliasString; // // Build the full key name. It is of the form: // "fix18471\alias_rid\member_rid" // wcscpy( KeyName, SAMP_FIX_18471_SHORT_KEY_NAME L"\\" ); AliasString.Buffer = AliasName; AliasString.MaximumLength = sizeof(AliasName); Status = RtlIntegerToUnicodeString( AliasRid, 16, &AliasString ); ASSERT(NT_SUCCESS(Status)); wcscat( KeyName, AliasString.Buffer ); wcscat( KeyName, L"\\" ); AliasString.MaximumLength = sizeof(AliasName); Status = RtlIntegerToUnicodeString( MemberRid, 16, &AliasString ); ASSERT(NT_SUCCESS(Status)); wcscat( KeyName, AliasString.Buffer ); RtlInitUnicodeString( &KeyNameString, KeyName ); // // Add this action to the RXact // Status = RtlAddActionToRXact( SampRXactContext, RtlRXactOperationSetValue, &KeyNameString, 0, // no value type NULL, // no value 0 // no value length ); return(Status); }
NTSTATUS SampAddAliasTo18471Key( IN ULONG AliasRid ) /*++ Routine Description: This routine creates the 18471 key used to transaction this fix. Arguments: Return Value: Codes from the NT registry APIs --*/ { NTSTATUS Status; WCHAR KeyName[100]; WCHAR AliasName[15]; // big enough for 4 billion UNICODE_STRING KeyNameString; UNICODE_STRING AliasString; // // Build the key name. It will be "fix18471\rid_in_hex" // wcscpy( KeyName, SAMP_FIX_18471_SHORT_KEY_NAME L"\\" ); AliasString.Buffer = AliasName; AliasString.MaximumLength = sizeof(AliasName); Status = RtlIntegerToUnicodeString( AliasRid, 16, &AliasString ); ASSERT(NT_SUCCESS(Status)); wcscat( KeyName, AliasString.Buffer ); RtlInitUnicodeString( &KeyNameString, KeyName ); Status = SampAcquireWriteLock(); if (!NT_SUCCESS(Status)) { return(Status); } SampSetTransactionDomain(0); SampTransactionWithinDomain = FALSE; // // Open the Lsa key in the registry // Status = RtlAddActionToRXact( SampRXactContext, RtlRXactOperationSetValue, &KeyNameString, 0, // no value type NULL, // no value 0 // no value length ); // // Commit this change // if (NT_SUCCESS(Status)) { Status = SampReleaseWriteLock( TRUE ); } else { (void) SampReleaseWriteLock( FALSE ); } return(Status); }
NTSTATUS GetStreamLocationFromFrequency(IN CEncoderDevice* EncDevice, IN DWORD dwFreq, OUT PUNICODE_STRING FileName) { // 1) Convert dword frequency to string. // 2) find matching key in registry // 3) read StreamLocation value from registry. // 4) pass key back to caller. NTSTATUS Status = STATUS_SUCCESS; UNICODE_STRING KeyName; if (!EncDevice) { return STATUS_UNSUCCESSFUL; } dwFreq /= 1000; //registry frequencies are in khz WCHAR *pczDeviceInstanceID = EncDevice->GetDeviceInstanceID(); KeyName.Buffer = (LPWSTR)ExAllocatePoolWithTag(NonPagedPool, MAX_PATH+1, MS_SAMPLE_ANALOG_POOL_TAG ); KeyName.Length = MAX_PATH; KeyName.MaximumLength = MAX_PATH; UNICODE_STRING StubName; RtlInitUnicodeString(&StubName, L"\\Registry\\Machine\\System\\PSWTuner\\"); UNICODE_STRING Seperator; RtlInitUnicodeString(&Seperator, L"\\"); UNICODE_STRING Parameters; RtlInitUnicodeString(&Parameters, L"Device Parameters\\"); UNICODE_STRING DevInstanceID; RtlInitUnicodeString(&DevInstanceID, pczDeviceInstanceID); RtlCopyUnicodeString(&KeyName,&StubName); RtlAppendUnicodeStringToString(&KeyName, &DevInstanceID); RtlAppendUnicodeStringToString(&KeyName, &Seperator); RtlAppendUnicodeStringToString(&KeyName, &Parameters); UNICODE_STRING Freq; Freq.Buffer = (LPWSTR)ExAllocatePoolWithTag(NonPagedPool, MAX_PATH+1, MS_SAMPLE_ANALOG_POOL_TAG ); if (NULL == Freq.Buffer) { ExFreePoolWithTag(KeyName.Buffer, MS_SAMPLE_ANALOG_POOL_TAG); return STATUS_UNSUCCESSFUL; } Freq.Length = MAX_PATH; Freq.MaximumLength = MAX_PATH; RtlZeroMemory(Freq.Buffer, MAX_PATH+1); if (STATUS_SUCCESS != RtlIntegerToUnicodeString(dwFreq, 10, &Freq)) { ExFreePoolWithTag(KeyName.Buffer, MS_SAMPLE_ANALOG_POOL_TAG); ExFreePoolWithTag(Freq.Buffer, MS_SAMPLE_ANALOG_POOL_TAG); return STATUS_UNSUCCESSFUL; } DbgPrint("Converted Frequency value %S\n", Freq.Buffer); if (STATUS_SUCCESS != RtlAppendUnicodeStringToString(&KeyName, &Freq)) { ExFreePoolWithTag(KeyName.Buffer, MS_SAMPLE_ANALOG_POOL_TAG); ExFreePoolWithTag(Freq.Buffer, MS_SAMPLE_ANALOG_POOL_TAG); return STATUS_UNSUCCESSFUL; } // UNICODE_STRING StreamLocation; RtlZeroMemory(&(EncDevice->StreamLocation), sizeof(EncDevice->StreamLocation)); Status = PptRegGetSz(RTL_REGISTRY_ABSOLUTE, KeyName.Buffer, L"StreamLocation", &(EncDevice->StreamLocation)); if (!NT_SUCCESS(Status)) { DetermineIfFineTuning(dwFreq); if (Freq.Buffer) { ExFreePoolWithTag(Freq.Buffer, MS_SAMPLE_ANALOG_POOL_TAG); } if (KeyName.Buffer) { ExFreePoolWithTag(KeyName.Buffer, MS_SAMPLE_ANALOG_POOL_TAG); } return Status; } RtlInitUnicodeString(FileName, EncDevice->StreamLocation.Buffer); if (Freq.Buffer) { ExFreePoolWithTag(Freq.Buffer, MS_SAMPLE_ANALOG_POOL_TAG); } if (KeyName.Buffer) { ExFreePoolWithTag(KeyName.Buffer, MS_SAMPLE_ANALOG_POOL_TAG); } return Status; }
PPCI_REGISTRY_INFO_INTERNAL NTAPI INIT_FUNCTION HalpQueryPciRegistryInfo(VOID) { #ifndef _MINIHAL_ WCHAR NameBuffer[8]; OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING KeyName, ConfigName, IdentName; HANDLE KeyHandle, BusKeyHandle, CardListHandle; NTSTATUS Status; UCHAR KeyBuffer[sizeof(CM_FULL_RESOURCE_DESCRIPTOR) + 100]; PKEY_VALUE_FULL_INFORMATION ValueInfo = (PVOID)KeyBuffer; UCHAR PartialKeyBuffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(PCI_CARD_DESCRIPTOR)]; PKEY_VALUE_PARTIAL_INFORMATION PartialValueInfo = (PVOID)PartialKeyBuffer; KEY_FULL_INFORMATION KeyInformation; ULONG ResultLength; PWSTR Tag; ULONG i, ElementCount; PCM_FULL_RESOURCE_DESCRIPTOR FullDescriptor; PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor; PPCI_REGISTRY_INFO PciRegInfo; PPCI_REGISTRY_INFO_INTERNAL PciRegistryInfo; PPCI_CARD_DESCRIPTOR CardDescriptor; /* Setup the object attributes for the key */ RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\Hardware\\Description\\" L"System\\MultiFunctionAdapter"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL); /* Open the key */ Status = ZwOpenKey(&KeyHandle, KEY_READ, &ObjectAttributes); if (!NT_SUCCESS(Status)) return NULL; /* Setup the receiving string */ KeyName.Buffer = NameBuffer; KeyName.MaximumLength = sizeof(NameBuffer); /* Setup the configuration and identifier key names */ RtlInitUnicodeString(&ConfigName, L"Configuration Data"); RtlInitUnicodeString(&IdentName, L"Identifier"); /* Keep looping for each ID */ for (i = 0; TRUE; i++) { /* Setup the key name */ RtlIntegerToUnicodeString(i, 10, &KeyName); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, KeyHandle, NULL); /* Open it */ Status = ZwOpenKey(&BusKeyHandle, KEY_READ, &ObjectAttributes); if (!NT_SUCCESS(Status)) { /* None left, fail */ ZwClose(KeyHandle); return NULL; } /* Read the registry data */ Status = ZwQueryValueKey(BusKeyHandle, &IdentName, KeyValueFullInformation, ValueInfo, sizeof(KeyBuffer), &ResultLength); if (!NT_SUCCESS(Status)) { /* Failed, try the next one */ ZwClose(BusKeyHandle); continue; } /* Get the PCI Tag and validate it */ Tag = (PWSTR)((ULONG_PTR)ValueInfo + ValueInfo->DataOffset); if ((Tag[0] != L'P') || (Tag[1] != L'C') || (Tag[2] != L'I') || (Tag[3])) { /* Not a valid PCI entry, skip it */ ZwClose(BusKeyHandle); continue; } /* Now read our PCI structure */ Status = ZwQueryValueKey(BusKeyHandle, &ConfigName, KeyValueFullInformation, ValueInfo, sizeof(KeyBuffer), &ResultLength); ZwClose(BusKeyHandle); if (!NT_SUCCESS(Status)) continue; /* We read it OK! Get the actual resource descriptors */ FullDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR) ((ULONG_PTR)ValueInfo + ValueInfo->DataOffset); PartialDescriptor = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) ((ULONG_PTR)FullDescriptor-> PartialResourceList.PartialDescriptors); /* Check if this is our PCI Registry Information */ if (PartialDescriptor->Type == CmResourceTypeDeviceSpecific) { /* It is, stop searching */ break; } } /* Close the key */ ZwClose(KeyHandle); /* Save the PCI information for later */ PciRegInfo = (PPCI_REGISTRY_INFO)(PartialDescriptor + 1); /* Assume no Card List entries */ ElementCount = 0; /* Set up for checking the PCI Card List key */ RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\System\\CurrentControlSet\\" L"Control\\PnP\\PCI\\CardList"); InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL); /* Attempt to open it */ Status = ZwOpenKey(&CardListHandle, KEY_READ, &ObjectAttributes); if (NT_SUCCESS(Status)) { /* It exists, so let's query it */ Status = ZwQueryKey(CardListHandle, KeyFullInformation, &KeyInformation, sizeof(KEY_FULL_INFORMATION), &ResultLength); if (!NT_SUCCESS(Status)) { /* Failed to query, so no info */ PciRegistryInfo = NULL; } else { /* Allocate the full structure */ PciRegistryInfo = ExAllocatePoolWithTag(NonPagedPool, sizeof(PCI_REGISTRY_INFO_INTERNAL) + (KeyInformation.Values * sizeof(PCI_CARD_DESCRIPTOR)), TAG_HAL); if (PciRegistryInfo) { /* Get the first card descriptor entry */ CardDescriptor = (PPCI_CARD_DESCRIPTOR)(PciRegistryInfo + 1); /* Loop all the values */ for (i = 0; i < KeyInformation.Values; i++) { /* Attempt to get the value */ Status = ZwEnumerateValueKey(CardListHandle, i, KeyValuePartialInformation, PartialValueInfo, sizeof(PartialKeyBuffer), &ResultLength); if (!NT_SUCCESS(Status)) { /* Something went wrong, stop the search */ break; } /* Make sure it is correctly sized */ if (PartialValueInfo->DataLength == sizeof(PCI_CARD_DESCRIPTOR)) { /* Sure is, copy it over */ *CardDescriptor = *(PPCI_CARD_DESCRIPTOR) PartialValueInfo->Data; /* One more Card List entry */ ElementCount++; /* Move to the next descriptor */ CardDescriptor = (CardDescriptor + 1); } } } } /* Close the Card List key */ ZwClose(CardListHandle); } else { /* No key, no Card List */ PciRegistryInfo = NULL; } /* Check if we failed to get the full structure */ if (!PciRegistryInfo) { /* Just allocate the basic structure then */ PciRegistryInfo = ExAllocatePoolWithTag(NonPagedPool, sizeof(PCI_REGISTRY_INFO_INTERNAL), TAG_HAL); if (!PciRegistryInfo) return NULL; } /* Save the info we got */ PciRegistryInfo->MajorRevision = PciRegInfo->MajorRevision; PciRegistryInfo->MinorRevision = PciRegInfo->MinorRevision; PciRegistryInfo->NoBuses = PciRegInfo->NoBuses; PciRegistryInfo->HardwareMechanism = PciRegInfo->HardwareMechanism; PciRegistryInfo->ElementCount = ElementCount; /* Return it */ return PciRegistryInfo; #else return NULL; #endif }
NTSTATUS NTAPI IntVideoPortChildQueryId( IN PVIDEO_PORT_CHILD_EXTENSION ChildExtension, IN PIRP Irp, IN PIO_STACK_LOCATION IrpSp) { PWCHAR Buffer = NULL, StaticBuffer; UNICODE_STRING UnicodeStr; switch (IrpSp->Parameters.QueryId.IdType) { case BusQueryDeviceID: switch (ChildExtension->ChildType) { case Monitor: if (ChildExtension->EdidValid) { StaticBuffer = L"DISPLAY\\"; Buffer = ExAllocatePool(PagedPool, (wcslen(StaticBuffer) + 8) * sizeof(WCHAR)); if (!Buffer) return STATUS_NO_MEMORY; /* Write the static portion */ RtlCopyMemory(Buffer, StaticBuffer, wcslen(StaticBuffer) * sizeof(WCHAR)); /* Add the dynamic portion */ IntVideoPortGetMonitorId(ChildExtension, &Buffer[wcslen(StaticBuffer)]); } else { StaticBuffer = L"DISPLAY\\Default_Monitor"; Buffer = ExAllocatePool(PagedPool, (wcslen(StaticBuffer) + 1) * sizeof(WCHAR)); if (!Buffer) return STATUS_NO_MEMORY; /* Copy the default id */ RtlCopyMemory(Buffer, StaticBuffer, (wcslen(StaticBuffer) + 1) * sizeof(WCHAR)); } break; default: ASSERT(FALSE); break; } break; case BusQueryInstanceID: Buffer = ExAllocatePool(PagedPool, 5 * sizeof(WCHAR)); if (!Buffer) return STATUS_NO_MEMORY; UnicodeStr.Buffer = Buffer; UnicodeStr.Length = 0; UnicodeStr.MaximumLength = 4 * sizeof(WCHAR); RtlIntegerToUnicodeString(ChildExtension->ChildId, 16, &UnicodeStr); break; case BusQueryHardwareIDs: switch (ChildExtension->ChildType) { case Monitor: if (ChildExtension->EdidValid) { StaticBuffer = L"MONITOR\\"; Buffer = ExAllocatePool(PagedPool, (wcslen(StaticBuffer) + 9) * sizeof(WCHAR)); if (!Buffer) return STATUS_NO_MEMORY; /* Write the static portion */ RtlCopyMemory(Buffer, StaticBuffer, wcslen(StaticBuffer) * sizeof(WCHAR)); /* Add the dynamic portion */ IntVideoPortGetMonitorId(ChildExtension, &Buffer[wcslen(StaticBuffer)]); /* Add the second null termination char */ Buffer[wcslen(StaticBuffer) + 8] = UNICODE_NULL; } else { StaticBuffer = L"MONITOR\\Default_Monitor"; Buffer = ExAllocatePool(PagedPool, (wcslen(StaticBuffer) + 2) * sizeof(WCHAR)); if (!Buffer) return STATUS_NO_MEMORY; /* Copy the default id */ RtlCopyMemory(Buffer, StaticBuffer, (wcslen(StaticBuffer) + 1) * sizeof(WCHAR)); /* Add the second null terminator */ Buffer[wcslen(StaticBuffer) + 1] = UNICODE_NULL; } break; default: ASSERT(FALSE); break; } break; case BusQueryCompatibleIDs: switch (ChildExtension->ChildType) { case Monitor: if (ChildExtension->EdidValid) { StaticBuffer = L"*PNP09FF"; Buffer = ExAllocatePool(PagedPool, (wcslen(StaticBuffer) + 2) * sizeof(WCHAR)); if (!Buffer) return STATUS_NO_MEMORY; RtlCopyMemory(Buffer, StaticBuffer, (wcslen(StaticBuffer) + 1) * sizeof(WCHAR)); Buffer[wcslen(StaticBuffer)+1] = UNICODE_NULL; } else { /* No PNP ID for non-PnP monitors */ return Irp->IoStatus.Status; } break; default: ASSERT(FALSE); break; } break; default: return Irp->IoStatus.Status; } INFO_(VIDEOPRT, "Reporting ID: %S\n", Buffer); Irp->IoStatus.Information = (ULONG_PTR)Buffer; return STATUS_SUCCESS; }
DWORD WINAPI LLSTopLevelExceptionHandler( struct _EXCEPTION_POINTERS *ExceptionInfo ) /*++ Routine Description: The Top Level exception filter for LLSMain.exe. This ensures the entire process will be cleaned up if any of the threads fail. Since LLSMain.exe is a distributed application, it is better to fail the entire process than allow random threads to continue executing. Arguments: ExceptionInfo - Identifies the exception that occurred. Return Values: EXCEPTION_EXECUTE_HANDLER - Terminate the process. EXCEPTION_CONTINUE_SEARCH - Continue processing as though this filter was never called. --*/ { HANDLE hModule; // // Raise an alert // hModule = LoadLibraryA("netapi32"); if ( hModule != NULL ) { NET_API_STATUS (NET_API_FUNCTION *NetAlertRaiseExFunction) (LPTSTR, LPVOID, DWORD, LPTSTR); NetAlertRaiseExFunction = (NET_API_STATUS (NET_API_FUNCTION *) (LPTSTR, LPVOID, DWORD, LPTSTR)) GetProcAddress(hModule, "NetAlertRaiseEx"); if ( NetAlertRaiseExFunction != NULL ) { NTSTATUS Status; UNICODE_STRING Strings; char message[ALERTSZ + sizeof(ADMIN_OTHER_INFO)]; PADMIN_OTHER_INFO admin = (PADMIN_OTHER_INFO) message; // // Build the variable data // admin->alrtad_errcode = ALERT_UnhandledException; admin->alrtad_numstrings = 0; Strings.Buffer = (LPWSTR) ALERT_VAR_DATA(admin); Strings.Length = 0; Strings.MaximumLength = ALERTSZ; Status = RtlIntegerToUnicodeString( (ULONG)ExceptionInfo->ExceptionRecord->ExceptionCode, 16, &Strings ); if ( NT_SUCCESS(Status) ) { if ( Strings.Length + sizeof(WCHAR) >= Strings.MaximumLength) { Status = STATUS_BUFFER_TOO_SMALL; } else { admin->alrtad_numstrings++; *(Strings.Buffer+(Strings.Length/sizeof(WCHAR))) = L'\0'; Strings.Length += sizeof(WCHAR); Status = RtlAppendUnicodeToString( &Strings, L"LLS" ); } } if ( NT_SUCCESS(Status) ) { if ( Strings.Length + sizeof(WCHAR) >= Strings.MaximumLength) { Status = STATUS_BUFFER_TOO_SMALL; } else { admin->alrtad_numstrings++; *(Strings.Buffer+(Strings.Length/sizeof(WCHAR))) = L'\0'; Strings.Buffer += (Strings.Length/sizeof(WCHAR)) + 1; Strings.MaximumLength -= Strings.Length + sizeof(WCHAR); Strings.Length = 0; Status = RtlIntegerToUnicodeString( (ULONG)ExceptionInfo->ExceptionRecord->ExceptionAddress, 16, &Strings ); } } if ( NT_SUCCESS(Status) ) { if ( Strings.Length + sizeof(WCHAR) >= Strings.MaximumLength) { Status = STATUS_BUFFER_TOO_SMALL; } else { admin->alrtad_numstrings++; *(Strings.Buffer+(Strings.Length/sizeof(WCHAR))) = L'\0'; Strings.Buffer += (Strings.Length/sizeof(WCHAR)) + 1; (VOID) (*NetAlertRaiseExFunction)( ALERT_ADMIN_EVENT, message, (DWORD)((PCHAR)Strings.Buffer - (PCHAR)message), L"LLS" ); } } } (VOID) FreeLibrary( hModule ); } // // Just continue processing the exception. // return EXCEPTION_CONTINUE_SEARCH; } // LLSTopLevelExceptionHandler