Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

845 lines
26 KiB

/*++
Copyright (c) Microsoft Corporation. All rights reserved.
Module Name:
diansicv.c
Abstract:
Routine to convert device installer data structures between
ANSI and Unicode.
Author:
Ted Miller (tedm) 19-July-1996
Revision History:
--*/
#include "precomp.h"
#pragma hdrstop
DWORD
pSetupDiDevInstParamsAnsiToUnicode(
IN PSP_DEVINSTALL_PARAMS_A AnsiDevInstParams,
OUT PSP_DEVINSTALL_PARAMS_W UnicodeDevInstParams
)
/*++
Routine Description:
This routine converts an SP_DEVINSTALL_PARAMS_A structure to
an SP_DEVINSTALL_PARAMS_W, guarding against bogus pointers
passed in the by the caller.
Arguments:
AnsiDevInstParams - supplies ANSI device installation parameters
to be converted to unicode.
UnicodeDevInstParams - if successful, receives Unicode equivalent of
AnsiDevInstParams.
Return Value:
NO_ERROR - conversion successful.
ERROR_INVALID_PARAMETER - one of the arguments was not a valid pointer.
It is not believed that, given valid arguments, text conversion itself
can fail, since all ANSI chars always have Unicode equivalents.
--*/
{
DWORD rc;
try {
if(AnsiDevInstParams->cbSize != sizeof(SP_DEVINSTALL_PARAMS_A)) {
rc = ERROR_INVALID_USER_BUFFER;
leave;
}
//
// Fixed part of structure.
//
MYASSERT(offsetof(SP_DEVINSTALL_PARAMS_A,DriverPath) == offsetof(SP_DEVINSTALL_PARAMS_W,DriverPath));
CopyMemory(UnicodeDevInstParams,
AnsiDevInstParams,
offsetof(SP_DEVINSTALL_PARAMS_W,DriverPath)
);
UnicodeDevInstParams->cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
//
// Convert the single string in the structure. To make things easier
// we'll just convert the entire buffer. There's no potential for
// overflow.
//
rc = GLE_FN_CALL(0,
MultiByteToWideChar(
CP_ACP,
MB_PRECOMPOSED,
AnsiDevInstParams->DriverPath,
sizeof(AnsiDevInstParams->DriverPath),
UnicodeDevInstParams->DriverPath,
SIZECHARS(UnicodeDevInstParams->DriverPath))
);
} except(pSetupExceptionFilter(GetExceptionCode())) {
pSetupExceptionHandler(GetExceptionCode(), ERROR_INVALID_PARAMETER, &rc);
}
return rc;
}
DWORD
pSetupDiDevInstParamsUnicodeToAnsi(
IN PSP_DEVINSTALL_PARAMS_W UnicodeDevInstParams,
OUT PSP_DEVINSTALL_PARAMS_A AnsiDevInstParams
)
/*++
Routine Description:
This routine converts an SP_DEVINSTALL_PARAMS_W structure to
an SP_DEVINSTALL_PARAMS_A, guarding against bogus pointers
passed in the by the caller.
Arguments:
UnicodeDevInstParams - supplies Unicode device installation parameters
to be converted to ANSI.
AnsiDevInstParams - if successful, receives Ansi equivalent of
UnicodeDevInstParams.
Return Value:
NO_ERROR - conversion successful.
ERROR_INVALID_PARAMETER - one of the arguments was not a valid pointer.
Unicode chars that can't be represented in the current system ANSI codepage
will be replaced with a system default in the ANSI structure.
--*/
{
DWORD rc;
UCHAR AnsiString[MAX_PATH*2];
HRESULT hr;
MYASSERT(UnicodeDevInstParams->cbSize == sizeof(SP_DEVINSTALL_PARAMS_W));
try {
if(AnsiDevInstParams->cbSize != sizeof(SP_DEVINSTALL_PARAMS_A)) {
rc = ERROR_INVALID_USER_BUFFER;
leave;
}
//
// Fixed part of structure.
//
MYASSERT(offsetof(SP_DEVINSTALL_PARAMS_A,DriverPath) == offsetof(SP_DEVINSTALL_PARAMS_W,DriverPath));
CopyMemory(AnsiDevInstParams,
UnicodeDevInstParams,
offsetof(SP_DEVINSTALL_PARAMS_W,DriverPath)
);
AnsiDevInstParams->cbSize = sizeof(SP_DEVINSTALL_PARAMS_A);
//
// Convert the single string in the structure. Unfortunately there is
// potential for overflow because some Unicode chars could convert to
// double-byte ANSI characters -- but the string in the ANSI structure
// is only MAX_PATH *bytes* (not MAX_PATH double-byte *characters*)
// long.
//
rc = GLE_FN_CALL(0,
WideCharToMultiByte(
CP_ACP,
0,
UnicodeDevInstParams->DriverPath,
SIZECHARS(UnicodeDevInstParams->DriverPath),
AnsiString,
sizeof(AnsiString),
NULL,
NULL)
);
if(rc != NO_ERROR) {
leave;
}
//
// Copy converted string into caller's structure, limiting
// its length to avoid overflow.
//
hr = StringCchCopyA(AnsiDevInstParams->DriverPath,
sizeof(AnsiDevInstParams->DriverPath),
AnsiString
);
if(FAILED(hr)) {
rc = HRESULT_CODE(hr);
}
} except(pSetupExceptionFilter(GetExceptionCode())) {
pSetupExceptionHandler(GetExceptionCode(), ERROR_INVALID_PARAMETER, &rc);
}
return rc;
}
DWORD
pSetupDiSelDevParamsAnsiToUnicode(
IN PSP_SELECTDEVICE_PARAMS_A AnsiSelDevParams,
OUT PSP_SELECTDEVICE_PARAMS_W UnicodeSelDevParams
)
/*++
Routine Description:
This routine converts an SP_SELECTDEVICE_PARAMS_A structure to
an SP_SELECTDEVICE_PARAMS_W, guarding against bogus pointers
passed in the by the caller.
Arguments:
AnsiSelDevParams - supplies ANSI device selection parameters
to be converted to unicode.
UnicodeSelDevParams - if successful, receives Unicode equivalent of
AnsiSelDevParams.
Return Value:
NO_ERROR - conversion successful.
ERROR_INVALID_PARAMETER - one of the arguments was not a valid pointer.
It is not believed that, given valid arguments, text conversion itself
can fail, since all ANSI chars always have Unicode equivalents.
--*/
{
DWORD rc;
try {
if(AnsiSelDevParams->ClassInstallHeader.cbSize != sizeof(SP_CLASSINSTALL_HEADER)) {
rc = ERROR_INVALID_USER_BUFFER;
leave;
}
//
// Fixed part of structure.
//
MYASSERT(offsetof(SP_SELECTDEVICE_PARAMS_A,Title) == offsetof(SP_SELECTDEVICE_PARAMS_W,Title));
CopyMemory(
UnicodeSelDevParams,
AnsiSelDevParams,
offsetof(SP_SELECTDEVICE_PARAMS_W,Title)
);
//
// Convert the strings in the structure. To make things easier
// we'll just convert the entire buffers. There's no potential for
// overflow.
//
rc = GLE_FN_CALL(0,
MultiByteToWideChar(
CP_ACP,
MB_PRECOMPOSED,
AnsiSelDevParams->Title,
sizeof(AnsiSelDevParams->Title),
UnicodeSelDevParams->Title,
SIZECHARS(UnicodeSelDevParams->Title))
);
if(rc != NO_ERROR) {
leave;
}
rc = GLE_FN_CALL(0,
MultiByteToWideChar(
CP_ACP,
MB_PRECOMPOSED,
AnsiSelDevParams->Instructions,
sizeof(AnsiSelDevParams->Instructions),
UnicodeSelDevParams->Instructions,
SIZECHARS(UnicodeSelDevParams->Instructions))
);
if(rc != NO_ERROR) {
leave;
}
rc = GLE_FN_CALL(0,
MultiByteToWideChar(
CP_ACP,
MB_PRECOMPOSED,
AnsiSelDevParams->ListLabel,
sizeof(AnsiSelDevParams->ListLabel),
UnicodeSelDevParams->ListLabel,
SIZECHARS(UnicodeSelDevParams->ListLabel))
);
if(rc != NO_ERROR) {
leave;
}
rc = GLE_FN_CALL(0,
MultiByteToWideChar(
CP_ACP,
MB_PRECOMPOSED,
AnsiSelDevParams->SubTitle,
sizeof(AnsiSelDevParams->SubTitle),
UnicodeSelDevParams->SubTitle,
SIZECHARS(UnicodeSelDevParams->SubTitle))
);
} except(pSetupExceptionFilter(GetExceptionCode())) {
pSetupExceptionHandler(GetExceptionCode(), ERROR_INVALID_PARAMETER, &rc);
}
return rc;
}
DWORD
pSetupDiSelDevParamsUnicodeToAnsi(
IN PSP_SELECTDEVICE_PARAMS_W UnicodeSelDevParams,
OUT PSP_SELECTDEVICE_PARAMS_A AnsiSelDevParams
)
/*++
Routine Description:
This routine converts an SP_SELECTDEVICE_PARAMS_W structure to
an SP_SELECTDEVICE_PARAMS_A, guarding against bogus pointers
passed in the by the caller. It is assumed that the ANSI output buffer is
of sufficient size, and that its ClassInstallHeader.cbSize field is
initialized correctly.
Arguments:
UnicodeSelDevParams - supplies Unicode device selection parameters
to be converted to ANSI.
AnsiSelDevParams - if successful, receives Ansi equivalent of
UnicodeSelDevParams.
Return Value:
NO_ERROR - conversion successful.
ERROR_INVALID_PARAMETER - one of the arguments was not a valid pointer.
Unicode chars that can't be represented in the current system ANSI codepage
will be replaced with a system default in the ANSI structure.
--*/
{
DWORD rc;
UCHAR AnsiTitle[MAX_TITLE_LEN*2];
UCHAR AnsiInstructions[MAX_INSTRUCTION_LEN*2];
UCHAR AnsiListLabel[MAX_LABEL_LEN*2];
UCHAR AnsiSubTitle[MAX_SUBTITLE_LEN*2];
HRESULT hr;
MYASSERT(UnicodeSelDevParams->ClassInstallHeader.cbSize == sizeof(SP_CLASSINSTALL_HEADER));
MYASSERT(AnsiSelDevParams->ClassInstallHeader.cbSize == sizeof(SP_CLASSINSTALL_HEADER));
try {
//
// Fixed part of structure.
//
MYASSERT(offsetof(SP_SELECTDEVICE_PARAMS_A,Title) == offsetof(SP_SELECTDEVICE_PARAMS_W,Title));
CopyMemory(
AnsiSelDevParams,
UnicodeSelDevParams,
offsetof(SP_SELECTDEVICE_PARAMS_W,Title)
);
ZeroMemory(AnsiSelDevParams->Reserved,sizeof(AnsiSelDevParams->Reserved));
//
// Convert the strings in the structure. Unfortunately there is
// potential for overflow because some Unicode chars could convert to
// double-byte ANSI characters -- but the strings in the ANSI structure
// are sized in *bytes* (not double-byte *characters*).
//
rc = GLE_FN_CALL(0,
WideCharToMultiByte(
CP_ACP,
0,
UnicodeSelDevParams->Title,
SIZECHARS(UnicodeSelDevParams->Title),
AnsiTitle,
sizeof(AnsiTitle),
NULL,
NULL)
);
if(rc != NO_ERROR) {
leave;
}
rc = GLE_FN_CALL(0,
WideCharToMultiByte(
CP_ACP,
0,
UnicodeSelDevParams->Instructions,
SIZECHARS(UnicodeSelDevParams->Instructions),
AnsiInstructions,
sizeof(AnsiInstructions),
NULL,
NULL)
);
if(rc != NO_ERROR) {
leave;
}
rc = GLE_FN_CALL(0,
WideCharToMultiByte(
CP_ACP,
0,
UnicodeSelDevParams->ListLabel,
SIZECHARS(UnicodeSelDevParams->ListLabel),
AnsiListLabel,
sizeof(AnsiListLabel),
NULL,
NULL)
);
if(rc != NO_ERROR) {
leave;
}
rc = GLE_FN_CALL(0,
WideCharToMultiByte(
CP_ACP,
0,
UnicodeSelDevParams->SubTitle,
SIZECHARS(UnicodeSelDevParams->SubTitle),
AnsiSubTitle,
sizeof(AnsiSubTitle),
NULL,
NULL)
);
if(rc != NO_ERROR) {
leave;
}
//
// Copy converted strings into caller's structure, limiting lengths to
// avoid overflow.
//
#undef CPYANS
#define CPYANS(field) StringCchCopyA(AnsiSelDevParams->field, \
sizeof(AnsiSelDevParams->field), \
Ansi##field)
if(FAILED(hr = CPYANS(Title)) ||
FAILED(hr = CPYANS(Instructions)) ||
FAILED(hr = CPYANS(ListLabel)) ||
FAILED(hr = CPYANS(SubTitle))) {
rc = HRESULT_CODE(hr);
}
} except(pSetupExceptionFilter(GetExceptionCode())) {
pSetupExceptionHandler(GetExceptionCode(), ERROR_INVALID_PARAMETER, &rc);
}
return rc;
}
DWORD
pSetupDiDrvInfoDataAnsiToUnicode(
IN PSP_DRVINFO_DATA_A AnsiDrvInfoData,
OUT PSP_DRVINFO_DATA_W UnicodeDrvInfoData
)
/*++
Routine Description:
This routine converts an SP_DRVINFO_DATA_A structure to
an SP_DRVINFO_DATA_W, guarding against bogus pointers
passed in the by the caller.
Arguments:
AnsiDrvInfoData - supplies ANSI structure to be converted to unicode.
UnicodeDrvInfoData - if successful, receives Unicode equivalent of
AnsiDrvInfoData.
Return Value:
NO_ERROR - conversion successful.
ERROR_INVALID_PARAMETER - one of the arguments was not a valid pointer.
It is not believed that, given valid arguments, text conversion itself
can fail, since all ANSI chars always have Unicode equivalents.
--*/
{
DWORD rc;
try {
if((AnsiDrvInfoData->cbSize != sizeof(SP_DRVINFO_DATA_A)) &&
(AnsiDrvInfoData->cbSize != sizeof(SP_DRVINFO_DATA_V1_A))) {
rc = ERROR_INVALID_USER_BUFFER;
leave;
}
//
// Fixed part of structure.
//
MYASSERT(offsetof(SP_DRVINFO_DATA_A,Description) == offsetof(SP_DRVINFO_DATA_W,Description));
ZeroMemory(UnicodeDrvInfoData, sizeof(SP_DRVINFO_DATA_W));
CopyMemory(
UnicodeDrvInfoData,
AnsiDrvInfoData,
offsetof(SP_DRVINFO_DATA_W,Description)
);
UnicodeDrvInfoData->cbSize = sizeof(SP_DRVINFO_DATA_W);
//
// Convert the strings in the structure. To make things easier we'll
// just convert the entire buffers. There's no potential for overflow.
//
rc = GLE_FN_CALL(0,
MultiByteToWideChar(
CP_ACP,
MB_PRECOMPOSED,
AnsiDrvInfoData->Description,
sizeof(AnsiDrvInfoData->Description),
UnicodeDrvInfoData->Description,
SIZECHARS(UnicodeDrvInfoData->Description))
);
if(rc != NO_ERROR) {
leave;
}
rc = GLE_FN_CALL(0,
MultiByteToWideChar(
CP_ACP,
MB_PRECOMPOSED,
AnsiDrvInfoData->MfgName,
sizeof(AnsiDrvInfoData->MfgName),
UnicodeDrvInfoData->MfgName,
SIZECHARS(UnicodeDrvInfoData->MfgName))
);
if(rc != NO_ERROR) {
leave;
}
rc = GLE_FN_CALL(0,
MultiByteToWideChar(
CP_ACP,
MB_PRECOMPOSED,
AnsiDrvInfoData->ProviderName,
sizeof(AnsiDrvInfoData->ProviderName),
UnicodeDrvInfoData->ProviderName,
SIZECHARS(UnicodeDrvInfoData->ProviderName))
);
if(rc != NO_ERROR) {
leave;
}
//
// Successfully converted all strings to unicode. Set the final two
// fields (DriverDate and DriverVersion) unless the caller supplied us
// with a version 1 structure.
//
if(AnsiDrvInfoData->cbSize == sizeof(SP_DRVINFO_DATA_A)) {
UnicodeDrvInfoData->DriverDate = AnsiDrvInfoData->DriverDate;
UnicodeDrvInfoData->DriverVersion = AnsiDrvInfoData->DriverVersion;
}
} except(pSetupExceptionFilter(GetExceptionCode())) {
pSetupExceptionHandler(GetExceptionCode(), ERROR_INVALID_PARAMETER, &rc);
}
return rc;
}
DWORD
pSetupDiDrvInfoDataUnicodeToAnsi(
IN PSP_DRVINFO_DATA_W UnicodeDrvInfoData,
OUT PSP_DRVINFO_DATA_A AnsiDrvInfoData
)
/*++
Routine Description:
This routine converts an SP_DRVINFO_DATA_W structure to
an SP_DRVINFO_DATA_A, guarding against bogus pointers
passed in the by the caller.
Arguments:
UnicodeDrvInfoData - supplies Unicode structure to be converted
to ANSI.
AnsiDrvInfoData - if successful, receives Ansi equivalent of
UnicodeDrvInfoData.
Return Value:
NO_ERROR - conversion successful.
ERROR_INVALID_PARAMETER - one of the arguments was not a valid pointer.
Unicode chars that can't be represented in the current system ANSI codepage
will be replaced with a system default in the ANSI structure.
--*/
{
DWORD rc;
UCHAR AnsiDescription[LINE_LEN*2];
UCHAR AnsiMfgName[LINE_LEN*2];
UCHAR AnsiProviderName[LINE_LEN*2];
HRESULT hr;
MYASSERT(UnicodeDrvInfoData->cbSize == sizeof(SP_DRVINFO_DATA_W));
try {
if((AnsiDrvInfoData->cbSize != sizeof(SP_DRVINFO_DATA_A)) &&
(AnsiDrvInfoData->cbSize != sizeof(SP_DRVINFO_DATA_V1_A))) {
rc = ERROR_INVALID_USER_BUFFER;
leave;
}
//
// Copy over the DriverType and the Reserved field.
//
AnsiDrvInfoData->DriverType = UnicodeDrvInfoData->DriverType;
AnsiDrvInfoData->Reserved = UnicodeDrvInfoData->Reserved;
//
// Convert the strings in the structure. Unfortunately there is
// potential for overflow because some Unicode chars could convert
// to double-byte ANSI characters -- but the strings in the ANSI
// structure are sized in *bytes* (not double-byte *characters*).
//
rc = GLE_FN_CALL(0,
WideCharToMultiByte(
CP_ACP,
0,
UnicodeDrvInfoData->Description,
SIZECHARS(UnicodeDrvInfoData->Description),
AnsiDescription,
sizeof(AnsiDescription),
NULL,
NULL)
);
if(rc != NO_ERROR) {
leave;
}
rc = GLE_FN_CALL(0,
WideCharToMultiByte(
CP_ACP,
0,
UnicodeDrvInfoData->MfgName,
SIZECHARS(UnicodeDrvInfoData->MfgName),
AnsiMfgName,
sizeof(AnsiMfgName),
NULL,
NULL)
);
if(rc != NO_ERROR) {
leave;
}
rc = GLE_FN_CALL(0,
WideCharToMultiByte(
CP_ACP,
0,
UnicodeDrvInfoData->ProviderName,
SIZECHARS(UnicodeDrvInfoData->ProviderName),
AnsiProviderName,
sizeof(AnsiProviderName),
NULL,
NULL)
);
if(rc != NO_ERROR) {
leave;
}
//
// Copy converted strings into caller's structure, limiting lengths to
// avoid overflow.
//
#undef CPYANS
#define CPYANS(field) StringCchCopyA(AnsiDrvInfoData->field, \
sizeof(AnsiDrvInfoData->field), \
Ansi##field)
if(FAILED(hr = CPYANS(Description)) ||
FAILED(hr = CPYANS(MfgName)) ||
FAILED(hr = CPYANS(ProviderName))) {
rc = HRESULT_CODE(hr);
leave;
}
//
// Successfully converted/transferred all the unicode strings back to
// ANSI. Now, set the final two fields (DriverDate and DriverVersion)
// unless the caller supplied us with a version 1 structure.
//
if(AnsiDrvInfoData->cbSize == sizeof(SP_DRVINFO_DATA_A)) {
AnsiDrvInfoData->DriverDate = UnicodeDrvInfoData->DriverDate;
AnsiDrvInfoData->DriverVersion = UnicodeDrvInfoData->DriverVersion;
}
} except(pSetupExceptionFilter(GetExceptionCode())) {
pSetupExceptionHandler(GetExceptionCode(), ERROR_INVALID_PARAMETER, &rc);
}
return rc;
}
DWORD
pSetupDiDevInfoSetDetailDataUnicodeToAnsi(
IN PSP_DEVINFO_LIST_DETAIL_DATA_W UnicodeDevInfoSetDetails,
OUT PSP_DEVINFO_LIST_DETAIL_DATA_A AnsiDevInfoSetDetails
)
/*++
Routine Description:
This routine converts an SP_DEVINFO_LIST_DETAIL_DATA_W structure
to an SP_DEVINFO_LIST_DETAIL_DATA_A, guarding against bogus pointers
passed in the by the caller.
Arguments:
UnicodeDevInfoSetDetails - supplies Unicode structure to be converted
to ANSI.
AnsiDevInfoSetDetails - if successful, receives Ansi equivalent of
UnicodeDevInfoSetDetails.
Return Value:
NO_ERROR - conversion successful.
ERROR_INVALID_PARAMETER - one of the arguments was not a valid pointer.
Unicode chars that can't be represented in the current system ANSI codepage
will be replaced with a system default in the ANSI structure.
--*/
{
DWORD rc;
UCHAR AnsiRemoteMachineName[SP_MAX_MACHINENAME_LENGTH * 2];
HRESULT hr;
MYASSERT(UnicodeDevInfoSetDetails->cbSize == sizeof(SP_DEVINFO_LIST_DETAIL_DATA_W));
rc = NO_ERROR;
try {
if(AnsiDevInfoSetDetails->cbSize != sizeof(SP_DEVINFO_LIST_DETAIL_DATA_A)) {
rc = ERROR_INVALID_USER_BUFFER;
leave;
}
//
// Fixed part of structure.
//
MYASSERT(offsetof(SP_DEVINFO_LIST_DETAIL_DATA_A, RemoteMachineName) ==
offsetof(SP_DEVINFO_LIST_DETAIL_DATA_W, RemoteMachineName)
);
CopyMemory(AnsiDevInfoSetDetails,
UnicodeDevInfoSetDetails,
offsetof(SP_DEVINFO_LIST_DETAIL_DATA_W, RemoteMachineName)
);
AnsiDevInfoSetDetails->cbSize = sizeof(SP_DEVINFO_LIST_DETAIL_DATA_A);
//
// Convert the strings in the structure. Unfortunately there is
// potential for overflow because some Unicode chars could convert to
// double-byte ANSI characters -- but the strings in the ANSI structure
// are sized in *bytes* (not double-byte *characters*).
//
rc = GLE_FN_CALL(0,
WideCharToMultiByte(
CP_ACP,
0,
UnicodeDevInfoSetDetails->RemoteMachineName,
SIZECHARS(UnicodeDevInfoSetDetails->RemoteMachineName),
AnsiRemoteMachineName,
sizeof(AnsiRemoteMachineName),
NULL,
NULL)
);
if(rc != NO_ERROR) {
leave;
}
//
// Copy converted string into caller's structure, limiting lengths to
// avoid overflow.
//
hr = StringCchCopyA(AnsiDevInfoSetDetails->RemoteMachineName,
sizeof(AnsiDevInfoSetDetails->RemoteMachineName),
AnsiRemoteMachineName
);
if(FAILED(hr)) {
rc = HRESULT_CODE(hr);
}
} except(pSetupExceptionFilter(GetExceptionCode())) {
pSetupExceptionHandler(GetExceptionCode(), ERROR_INVALID_PARAMETER, &rc);
}
return rc;
}