|
|
/*--------------------------------------------------------------------------
* * Copyright (C) Cyclades Corporation, 2000-2001. * All rights reserved. * * Cyclades-Z Enumerator Driver * * This file: string.c * * Description: This module contains the functions used to parse the * PNP COM ID and save it in the appropriate * UNICODE STRINGS. The main function that is called * is Cycladz_ParseData. All other functions are called * by this main function. * * Notes: This code supports Windows 2000 and Windows XP, * x86 and ia64 processors. * * Complies with Cyclades SW Coding Standard rev 1.3. * *-------------------------------------------------------------------------- */
/*-------------------------------------------------------------------------
* * Change History * *-------------------------------------------------------------------------- * Initial implementation based on Microsoft sample code. * *-------------------------------------------------------------------------- */
#include "pch.h"
#define MAX_DEVNODE_NAME 256 // Total size of Device ID
#ifdef ALLOC_PRAGMA
#pragma alloc_text (PAGE, Cycladz_InitMultiString)
#endif
NTSTATUS Cycladz_InitMultiString(PFDO_DEVICE_DATA FdoData, PUNICODE_STRING MultiString, ...) /*++
This routine will take a null terminated list of ascii strings and combine them together to generate a unicode multi-string block
Arguments:
MultiString - a unicode structure in which a multi-string will be built ... - a null terminated list of narrow strings which will be combined together. This list must contain at least a trailing NULL
Return Value:
NTSTATUS
--*/ { ANSI_STRING ansiString; NTSTATUS status; PCSTR rawString; PWSTR unicodeLocation; ULONG multiLength = 0; UNICODE_STRING unicodeString; va_list ap; ULONG i;
PAGED_CODE();
#if !DBG
UNREFERENCED_PARAMETER(FdoData); #endif
Cycladz_KdPrint(FdoData, SER_DBG_SS_TRACE, ("Entering Cycladz_InitMultiString\n"));
va_start(ap,MultiString);
//
// Make sure that we won't leak memory
//
ASSERT(MultiString->Buffer == NULL);
rawString = va_arg(ap, PCSTR);
while (rawString != NULL) { RtlInitAnsiString(&ansiString, rawString); multiLength += RtlAnsiStringToUnicodeSize(&(ansiString)); rawString = va_arg(ap, PCSTR); }
va_end( ap );
if (multiLength == 0) { //
// Done
//
RtlInitUnicodeString(MultiString, NULL); Cycladz_KdPrint(FdoData, SER_DBG_SS_TRACE, ("Leaving Cycladz_InitMultiString (1)\n"));
return STATUS_SUCCESS; }
//
// We need an extra null
//
multiLength += sizeof(WCHAR);
MultiString->MaximumLength = (USHORT)multiLength; MultiString->Buffer = ExAllocatePool(PagedPool, multiLength); MultiString->Length = 0;
if (MultiString->Buffer == NULL) { Cycladz_KdPrint(FdoData, SER_DBG_SS_TRACE, ("Leaving Cycladz_InitMultiString (2)\n"));
return STATUS_INSUFFICIENT_RESOURCES; }
Cycladz_KdPrint(FdoData, SER_DBG_SS_TRACE, ("Allocated %lu bytes for buffer\n", multiLength));
#if DBG
RtlFillMemory(MultiString->Buffer, multiLength, 0xff); #endif
unicodeString.Buffer = MultiString->Buffer; unicodeString.MaximumLength = (USHORT) multiLength;
va_start(ap, MultiString); rawString = va_arg(ap, PCSTR);
while (rawString != NULL) {
RtlInitAnsiString(&ansiString,rawString); status = RtlAnsiStringToUnicodeString(&unicodeString, &ansiString, FALSE);
//
// We don't allocate memory, so if something goes wrong here,
// its the function that's at fault
//
ASSERT(NT_SUCCESS(status));
//
// Check for any commas and replace them with NULLs
//
ASSERT(unicodeString.Length % sizeof(WCHAR) == 0);
for (i = 0; i < (unicodeString.Length / sizeof(WCHAR)); i++) { if (unicodeString.Buffer[i] == L'\x2C' || unicodeString.Buffer[i] == L'\x0C' ) { unicodeString.Buffer[i] = L'\0'; } }
Cycladz_KdPrint(FdoData, SER_DBG_SS_TRACE, ("unicode buffer: %ws\n", unicodeString.Buffer));
//
// Move the buffers along
//
unicodeString.Buffer += ((unicodeString.Length / sizeof(WCHAR)) + 1); unicodeString.MaximumLength -= (unicodeString.Length + sizeof(WCHAR)); unicodeString.Length = 0;
//
// Next
//
rawString = va_arg(ap, PCSTR); } // while
va_end(ap);
ASSERT(unicodeString.MaximumLength == sizeof(WCHAR));
//
// Stick the final null there
//
Cycladz_KdPrint(FdoData, SER_DBG_SS_TRACE, ("unicode buffer last addr: " "%x\n", unicodeString.Buffer));
unicodeString.Buffer[0] = L'\0';
//
// Include the nulls in the length of the string
//
MultiString->Length = (USHORT)multiLength; MultiString->MaximumLength = MultiString->Length;
Cycladz_KdPrint(FdoData, SER_DBG_SS_TRACE, ("Leaving Cycladz_InitMultiString (3)\n"));
return STATUS_SUCCESS; }
|