#memory-management #unicode-string
#управление памятью #unicode-строка
Вопрос:
Я получаю очень странный (для меня) сбой при ручном управлении UNICODE_STRING
:
UNICODE_STRING ustrName;
UNICODE_STRING ustrPortName;
UNICODE_STRING linkName;
UCHAR m_COMPortName[6];
RtlInitUnicodeString(amp;ustrName, L"PortName");
status = WdfStringCreate(NULL, WDF_NO_OBJECT_ATTRIBUTES, amp;strPortName);
if(NT_SUCCESS(status)) // String created
{ status = WdfRegistryQueryString (hKey, amp;ustrName, strPortName); // strPortName is now "COM8"
if (NT_SUCCESS (status)) {
WdfStringGetUnicodeString(strPortName, amp;ustrPortName);
m_COMPortName[0] = (UCHAR)ustrPortName.Buffer[0];
m_COMPortName[1] = (UCHAR)ustrPortName.Buffer[1];
m_COMPortName[2] = (UCHAR)ustrPortName.Buffer[2];
m_COMPortName[3] = (UCHAR)ustrPortName.Buffer[3];
m_COMPortName[4] = (UCHAR)ustrPortName.Buffer[4];
m_COMPortName[5] = 0; // Force a null-termination
}
}
WdfRegistryClose(hKey);
RtlInitUnicodeString(amp;linkName, L"\??\COM123"); // Init with lets say COM123, Breakpoint here...
linkName.Buffer[7] = (USHORT)m_COMPortName[3]; // First digit in the COM-port number // ** THIS LINE CRASH **
linkName.Buffer[8] = (USHORT)m_COMPortName[4]; // Second digit in the COM-port number // (if any else NULL)
linkName.Buffer[9] = (USHORT)m_COMPortName[5]; // Third digit in the COM-port number // (if any else NULL)
Разборка:
902de533 6840072e90 push offset mydriver! ?? ::FNODOBFM::'string' (902e0740) ** Breakpoint here (same as above...) **
902de538 8d45f8 lea eax,[ebp-8]
902de53b 50 push eax
902de53c ff1528202e90 call dword ptr [mydriver!_imp__RtlInitUnicodeString (902e2028)]
902de542 660fb60d23392e90 movzx cx,byte ptr [mydriver!m_COMPortName 0x3 (902e3923)] ** Start of the crashing line **
902de54a 8b55fc mov edx,dword ptr [ebp-4] ** Seems ok **
902de54d 66894a0e mov word ptr [edx 0Eh],cx ds:0023:902e074e=0031 ** CRASH!!! **
902de551 660fb60524392e90 movzx ax,byte ptr [mydriver!m_COMPortName 0x4 (902e3924)]
902de559 8b4dfc mov ecx,dword ptr [ebp-4]
902de55c 66894110 mov word ptr [ecx 10h],ax
902de560 660fb61525392e90 movzx dx,byte ptr [mydriver!m_COMPortName 0x5 (902e3925)]
902de568 8b45fc mov eax,dword ptr [ebp-4]
902de56b 66895012 mov word ptr [eax 12h],dx
И linkName
то, и m_COMPortName
другое выглядит правильно в Часах. Что случилось?
Другое решение состоит в том , чтобы каким — то образом объединить строку юникода L"\??\"
с динамически считываемой строкой Юникода L"COMx"
. Но я не знаю, как это сделать. Я знаю MultiByteToWideChar
, но я не очень люблю его использовать, поскольку он необходим windows.h
, и когда я включаю этот файл в свой крошечный проект KMDF-драйвера, компилятор выдает мне кучу ошибок…
Весь код, созданный для Windows Vista в WinDDK 7600.16385.1 (KMDF)
Комментарии:
1. Нашел этот RtlUnicodeStringCat(amp;linkName, amp;ustrPortName) в #include <ntstrsafe.h>, все еще сбой…
Ответ №1:
Из MSDN RtlUnicodeStringInit
:
Устанавливает буферный элемент структуры UNICODE_STRING по адресу, указанному в исходном параметре.
linkName
buffer указывает на константу ( L"\??\COM123"
), поэтому она выходит из строя при попытке ее изменить.