KEY_VALUE_PARTIAL_INFORMATION::Data is not a pointer to the data, it IS the data, so to get at the string you need to simply cast it
PCWSTR CHR = (PCWSTR) pkey_partial_info->Data;
but you have bigger problems.
the string that is returned is not guaranteed to be null terminated, so you must use the DataLength field to initialize the UNICODE_STRING structure
you are not making a deep copy of the buffer with RtlInitUnicodeString, you are just copying the pointer value. You are freeing the pointer in the next line (ExFreePoolWithTag), so the pointer value in buffer (buffer::Buffer) is no longer valid.
IS there a reason you are not using WDF to query the registry value ? it will take care of everything for you and manage all the validation, buffer lifetime, etc correctly.
Hey, the reason i dont use wdf is because im in KMDF and, being a beginner in kernelmode, i thought that we cant use WDF functions in KMDF. A quick look into msdn and i found that we can, amazing Thanks for the infos man.
KMDF is WDF (two names for the same thing). Or perhaps you are misusing the term KMDF to mean purely a kernel mode driver independent of programming model
Also, i proceed to use my WDF to create a key, but it constantly give me a BSoD with SYSTEM_THREAD_EXCEPTION_NOT_HANDLED and c0000005 (STATUS_ACCESS_VIOLATION)
But it dont seems like im doing anything wrong on my side, there is the code i used :
`WDFKEY WDF_CreateKey() {
UNICODE_STRING keyName;
RtlInitUnicodeString(&keyName, L"\\Registry\\Machine\\SOFTWARE\\KernelRetry");
WDFKEY key;
auto status = WdfRegistryCreateKey(NULL, &keyName, KEY_READ || KEY_WRITE, REG_OPTION_VOLATILE, NULL, WDF_NO_OBJECT_ATTRIBUTES, &key);
if (status == STATUS_INVALID_DEVICE_REQUEST) {
DbgPrintEx(0, 0, "STATUS_INVALID_DEVICE_REQUEST on Create Key \n");
}
else if (status == STATUS_INVALID_PARAMETER) {
DbgPrintEx(0, 0, "STATUS_INVALID_PARAMETER on Create Key \n");
}
else if(status == STATUS_INSUFFICIENT_RESOURCES){
DbgPrintEx(0, 0, "STATUS_INSUFFICIENT_RESOURCES on Create Key\n");
}
else if (status == STATUS_ACCESS_DENIED) {
DbgPrintEx(0, 0, "STATUS_ACCESS_DENIED on CreateKey \n");
}
else if (status == STATUS_OBJECT_NAME_NOT_FOUND) {
DbgPrintEx(0, 0, "STATUS_OBJECT_NAME_NOT_FOUND on CreateKey \n");
}
else if (status == STATUS_ACCESS_VIOLATION) {
DbgPrintEx(0, 0, "STATUS_ACCESS_VIOLATION on CreateKey\n");
}
return key;
Hello thanks for your responses. It still crashing but i think it might come from my call of the function. When they are asking for the keyName im setting it to this → L"\Registry\Machine\SOFTWARE\KernelRetry" . Maybe thats the reason why its crashing ?
Assuming the code you posted actually is your code, I don’t see a problem there. You used double backslashes in the string literal. Have you analyzed the dump? Are you absolutely sure the crash is coming from that call, or are you just guessing?
Actually, the code sample in question is a pretty interesting example of the situation when using .c and .cpp file extensions interchangingly may play a really nasty trick on you…
If you write such code in a file with .cpp extension and compile it as C++11 code, the variable type is going to be automatically inferred from WdfRegistryCreateKey()'s return type, i.e. is going to be assumed of NTSTATUS type, and, hence, the code will work exactly the way it is meant to. So far, so good.
However, if you do it in a .c file and compile it as C89 code, the target variable’s type is going to be implicitly assumed as ‘int’,
i.e. as a signed type. It is understandable that a signed int will never ever be evaluated to 0xC0000xyz - instead, it will evaluate to a negative number every time the most significant bit is set. Therefore, no statement in the subsequent ‘if’ blocks has a slightest chance of ever getting executed, no matter what WdfRegistryCreateKey() returns…
Hello, i tried to execute the exact same function, the exact same code on another kmdf project. It worked, no crash and the key has been created. But on my actual project if i call this function it make my project crash and i have actually no clue of why since the code is the exact same