Hi there.
I am fairly new to driver development and have been fighting with this problem for a few days now…Might be really obvious and probably is in my experience but I cannot get a complete UNICODE string to be displayed. Every time I try to output the data I only get the first character ?
I am retreiving a value from the registry and then checking to see what the value contains. The PKEY_VALUE_PARTIAL_INFORMATION structure that I am returning indicates that the data length is 10 but only 1 character of the unicode string is being displayed…
Code snippet…The function below will return the number of the port eg COM1 number returned is 1 and is used in a filter driver but I have now added the driver as a class driver and the port can now be an LPT port or a COM port and so I want to check the full string and if the first 3 chars are COM I know I have a COM port and similarly if they equal LPT I have an LPT port…as a result of this I can return the PortType to the calling function…so I know what I am dealing with…
static NTSTATUS GetPortNumber( PDEVICE_OBJECT pdo, PULONG PortNr, PULONG PortType )
{
NTSTATUS nts = STATUS_SUCCESS;
HANDLE hkey;
*PortNr = -1;
/*
* Open the device registry key for the PDO.
*/
nts = IoOpenDeviceRegistryKey( pdo,
PLUGPLAY_REGKEY_DEVICE,
STANDARD_RIGHTS_READ,
&hkey );
if( NT_SUCCESS( nts ) )
{
UNICODE_STRING us;
ULONG i, size;
/*
* Get size required to store the data.
*/
RtlInitUnicodeString( &us, L"PortName" );
nts = ZwQueryValueKey( hkey,
&us,
KeyValuePartialInformation,
&i,
0,
&size );
if( nts == STATUS_BUFFER_TOO_SMALL )
{
char *sTmp=NULL;
/*
* Allocate the buffer now.
*/
PKEY_VALUE_PARTIAL_INFORMATION pvp =
(PKEY_VALUE_PARTIAL_INFORMATION)ExAllocatePoolWithTag( PagedPool,
size,
TAG );
if( pvp )
{
/*
* Get the data.
*/
nts = ZwQueryValueKey( hkey,
&us,
KeyValuePartialInformation,
pvp,
size,
&size );
if( NT_SUCCESS( nts ) )
{
if( pvp->DataLength > 6 )
{
KdPrint((“In getPortNo, data length is %d\n”, pvp->DataLength));
******** THIS next call always displays the first char only of the UNICODE string. “L” or “C”.
KdPrint((“%s - PORT NAME is %wZ\n”, DRIVERNAME, pvp->Data ));
/*
* Extract the number element from the port name. “COMnnn”
*/
us.Length = us.MaximumLength = (USHORT)pvp->DataLength - 6;
us.Buffer = (PWSTR)(pvp->Data + 6);
RtlUnicodeStringToInteger( &us, 10, PortNr );
/*
* Temp debug code…??? trying to work out why UNICODE string not being displayed correcly.
*/
sTmp = (char*)ExAllocatePoolWithTag( PagedPool,
pvp->DataLength+1,
TAG );
strncpy(sTmp, (char*)&pvp->Data[0], pvp->DataLength);
KdPrint((“%s - PORT NAME is %c%c%c \n”, DRIVERNAME, sTmp[0],sTmp[1],sTmp[2] ));
if( strncmp( sTmp, “LPT”, 3 ) == 0 )
{
KdPrint((“Got an LPT port!!!\n”));
*PortType = LPT_PORT;
}
else
{
*PortType = COM_PORT;
KdPrint((“Got a COM port !!!\n”));
}
}/* if */
}/* if - NT_SUCCESS( nts ) */
/*
* Free any memory used.
*/
ExFreePool( pvp );
}/* if - pvp */
}/* if - nts == STATUS_BUFFER_TOO_SMALL */
/*
* Close the file handle.
*/
ZwClose( hkey );
}/* if - NT_SUCCESS( nts ) */
/*
* If we didn’t have success along the way…
*/
if( nts != STATUS_SUCCESS )
{
KdPrint( ( “%s - GetPortNumber(%u) 0x%X.\n”, DRIVERNAME, *PortNr, nts ) );
}
return nts;
}/* End of GetPortNumber */
Much apprectiate for any ideas why this is not displaying the string correctly…
and apologies if I have done something really stupid ! I just can’t see it …! Doh.
Regards