Here's a piece of code.
code.c:
#include <Windows.h>
#include <SubAuth.h>
char* unicodeStringToPChar(UNICODE_STRING *pUS) {
size_t wcLen = 0, cLen = 0;
wchar_t *pWBuf = NULL;
char *pBuf = NULL;
errno_t res = 0;
if (!pUS || !pUS->Length) {
return NULL;
}
wcLen = pUS->Length / sizeof(wchar_t) + 1;
pWBuf = calloc(1, wcLen * sizeof(wchar_t));
if (!pWBuf) {
return NULL;
}
if (wcsncpy_s(pWBuf, wcLen, pUS->Buffer, wcLen - 1)) {
free(pWBuf);
return NULL;
}
wcstombs_s(&cLen, NULL, 0, pWBuf, 0);
if (!cLen) {
free(pWBuf);
return NULL;
}
pBuf = calloc(1, cLen);
if (!pBuf) {
free(pWBuf);
return NULL;
}
res = wcstombs_s(NULL, pBuf, cLen, pWBuf, cLen - 1);
free(pWBuf);
if (res) {
free(pBuf);
return NULL;
}
return pBuf;
}
Notes:
- Function receives a pointer to an UNICODE_STRING (don't forget to reference if you have a plain structure)
- Returns a
char*
, NULL if it can't convert the string (whether it's empty, or some error occurred)
- You can add some output messages (e.g. printf) before
return NULL;
statements
- Don't forget to free the returned value once you're done with it to avoid memory leaks (in the caller)
There are 2 steps:
I didn't test the function thoroughly, let me know how it works out for you.
After more clarification, I understood that none of the above is usable in a driver. However on [CodeGuru]: ZwCreatefile/ ZwReadfile, there's an example of using ZwCreatefile and UNICODE_STRING (via RtlInitUnicodeString and InitializeObjectAttributes) that I'm going to paste from below (didn't test anything):
#include <ntddk.h>
HANDLE handle;
NTSTATUS ntstatus;
UNICODE_STRING uniName;
OBJECT_ATTRIBUTES objAttr;
RtlInitUnicodeString(&uniName, L"\\SystemRoot\\native.txt");
InitializeObjectAttributes(&objAttr, &uniName,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL, NULL);
ntstatus = ZwCreateFile(&handle,
GENERIC_READ,
&objAttr, &ioStatusBlock,
NULL,
FILE_ATTRIBUTE_NORMAL,
0,
FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL, 0);