/*++ Copyright (c) 1993 Microsoft Corporation Module Name: diansicv.c Abstract: Routine to convert device installer data structures between ANSI and Unicode. The contents of this file are compiled only when UNICODE is #define'd. Author: Ted Miller (tedm) 19-July-1996 Revision History: --*/ #include "setupntp.h" #pragma hdrstop #ifdef UNICODE 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. --*/ { int i; DWORD rc; rc = NO_ERROR; try { if(AnsiDevInstParams->cbSize == sizeof(SP_DEVINSTALL_PARAMS_A)) { // // 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. // i = MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, AnsiDevInstParams->DriverPath, sizeof(AnsiDevInstParams->DriverPath), UnicodeDevInstParams->DriverPath, sizeof(UnicodeDevInstParams->DriverPath) / sizeof(WCHAR) ); if(!i) { rc = GetLastError(); } } else { rc = ERROR_INVALID_PARAMETER; } } except(EXCEPTION_EXECUTE_HANDLER) { rc = ERROR_INVALID_PARAMETER; } 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. --*/ { int i; DWORD rc; UCHAR AnsiString[MAX_PATH*2]; rc = NO_ERROR; try { if(UnicodeDevInstParams->cbSize == sizeof(SP_DEVINSTALL_PARAMS_W)) { // // 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. // i = WideCharToMultiByte( CP_ACP, 0, UnicodeDevInstParams->DriverPath, sizeof(UnicodeDevInstParams->DriverPath) / sizeof(WCHAR), AnsiString, sizeof(AnsiString), NULL, NULL ); if(i) { // // Copy converted string into caller's structure, limiting // its length to avoid overflow. // if(!lstrcpynA(AnsiDevInstParams->DriverPath,AnsiString,sizeof(AnsiDevInstParams->DriverPath))) { // // lstrcpyn faulted, a pointer must be bogus // rc = ERROR_INVALID_PARAMETER; } } else { rc = GetLastError(); } } else { rc = ERROR_INVALID_PARAMETER; } } except(EXCEPTION_EXECUTE_HANDLER) { rc = ERROR_INVALID_PARAMETER; } 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. --*/ { int i; DWORD rc; rc = NO_ERROR; try { if(AnsiSelDevParams->ClassInstallHeader.cbSize == sizeof(SP_CLASSINSTALL_HEADER)) { // // 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. // i = MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, AnsiSelDevParams->Title, sizeof(AnsiSelDevParams->Title), UnicodeSelDevParams->Title, sizeof(UnicodeSelDevParams->Title) / sizeof(WCHAR) ); if(i) { i = MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, AnsiSelDevParams->Instructions, sizeof(AnsiSelDevParams->Instructions), UnicodeSelDevParams->Instructions, sizeof(UnicodeSelDevParams->Instructions) / sizeof(WCHAR) ); if(i) { i = MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, AnsiSelDevParams->ListLabel, sizeof(AnsiSelDevParams->ListLabel), UnicodeSelDevParams->ListLabel, sizeof(UnicodeSelDevParams->ListLabel) / sizeof(WCHAR) ); if(!i) { rc = GetLastError(); } } else { rc = GetLastError(); } } else { rc = GetLastError(); } } else { rc = ERROR_INVALID_PARAMETER; } } except(EXCEPTION_EXECUTE_HANDLER) { rc = ERROR_INVALID_PARAMETER; } 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. 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. --*/ { int i; DWORD rc; UCHAR AnsiTitle[MAX_TITLE_LEN*2]; UCHAR AnsiInstructions[MAX_INSTRUCTION_LEN*2]; UCHAR AnsiListLabel[MAX_LABEL_LEN*2]; PVOID p; rc = NO_ERROR; try { if(UnicodeSelDevParams->ClassInstallHeader.cbSize == sizeof(SP_CLASSINSTALL_HEADER)) { // // 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*). // i = WideCharToMultiByte( CP_ACP, 0, UnicodeSelDevParams->Title, sizeof(UnicodeSelDevParams->Title) / sizeof(WCHAR), AnsiTitle, sizeof(AnsiTitle), NULL, NULL ); if(i) { i = WideCharToMultiByte( CP_ACP, 0, UnicodeSelDevParams->Instructions, sizeof(UnicodeSelDevParams->Instructions) / sizeof(WCHAR), AnsiInstructions, sizeof(AnsiInstructions), NULL, NULL ); if(i) { i = WideCharToMultiByte( CP_ACP, 0, UnicodeSelDevParams->ListLabel, sizeof(UnicodeSelDevParams->ListLabel) / sizeof(WCHAR), AnsiListLabel, sizeof(AnsiListLabel), NULL, NULL ); if(i) { // // Copy converted strings into caller's structure, limiting // lengths to avoid overflow. If any lstrcpynA call returns NULL // then it faulted meaning a pointer is bad. // #undef CPYANS #define CPYANS(field) lstrcpynA(AnsiSelDevParams->field,Ansi##field,sizeof(AnsiSelDevParams->field)) if(!CPYANS(Title) || !CPYANS(Instructions) || !CPYANS(ListLabel)) { rc = ERROR_INVALID_PARAMETER; } } else { rc = GetLastError(); } } else { rc = GetLastError(); } } else { rc = GetLastError(); } } else { rc = ERROR_INVALID_PARAMETER; } } except(EXCEPTION_EXECUTE_HANDLER) { rc = ERROR_INVALID_PARAMETER; } 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. --*/ { int i; DWORD rc; rc = NO_ERROR; try { if(AnsiDrvInfoData->cbSize == sizeof(SP_DRVINFO_DATA_A)) { // // Fixed part of structure. // MYASSERT(offsetof(SP_DRVINFO_DATA_A,Description) == offsetof(SP_DRVINFO_DATA_W,Description)); 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. // i = MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, AnsiDrvInfoData->Description, sizeof(AnsiDrvInfoData->Description), UnicodeDrvInfoData->Description, sizeof(UnicodeDrvInfoData->Description) / sizeof(WCHAR) ); if(i) { i = MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, AnsiDrvInfoData->MfgName, sizeof(AnsiDrvInfoData->MfgName), UnicodeDrvInfoData->MfgName, sizeof(UnicodeDrvInfoData->MfgName) / sizeof(WCHAR) ); if(i) { i = MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, AnsiDrvInfoData->ProviderName, sizeof(AnsiDrvInfoData->ProviderName), UnicodeDrvInfoData->ProviderName, sizeof(UnicodeDrvInfoData->ProviderName) / sizeof(WCHAR) ); if(!i) { rc = GetLastError(); } } else { rc = GetLastError(); } } else { rc = GetLastError(); } } else { rc = ERROR_INVALID_PARAMETER; } } except(EXCEPTION_EXECUTE_HANDLER) { rc = ERROR_INVALID_PARAMETER; } 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. --*/ { int i; DWORD rc; UCHAR AnsiDescription[LINE_LEN*2]; UCHAR AnsiMfgName[LINE_LEN*2]; UCHAR AnsiProviderName[LINE_LEN*2]; PVOID p; rc = NO_ERROR; try { if(UnicodeDrvInfoData->cbSize == sizeof(SP_DRVINFO_DATA_W)) { // // Fixed part of structure. // MYASSERT(offsetof(SP_DRVINFO_DATA_A,Description) == offsetof(SP_DRVINFO_DATA_W,Description)); CopyMemory( AnsiDrvInfoData, UnicodeDrvInfoData, offsetof(SP_DRVINFO_DATA_W,Description) ); AnsiDrvInfoData->cbSize = sizeof(SP_DRVINFO_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*). // i = WideCharToMultiByte( CP_ACP, 0, UnicodeDrvInfoData->Description, sizeof(UnicodeDrvInfoData->Description) / sizeof(WCHAR), AnsiDescription, sizeof(AnsiDescription), NULL, NULL ); if(i) { i = WideCharToMultiByte( CP_ACP, 0, UnicodeDrvInfoData->MfgName, sizeof(UnicodeDrvInfoData->MfgName) / sizeof(WCHAR), AnsiMfgName, sizeof(AnsiMfgName), NULL, NULL ); if(i) { i = WideCharToMultiByte( CP_ACP, 0, UnicodeDrvInfoData->ProviderName, sizeof(UnicodeDrvInfoData->ProviderName) / sizeof(WCHAR), AnsiProviderName, sizeof(AnsiProviderName), NULL, NULL ); if(i) { // // Copy converted strings into caller's structure, limiting // lengths to avoid overflow. If any lstrcpynA call returns NULL // then it faulted meaning a pointer is bad. // #undef CPYANS #define CPYANS(field) lstrcpynA(AnsiDrvInfoData->field,Ansi##field,sizeof(AnsiDrvInfoData->field)) if(!CPYANS(Description) || !CPYANS(MfgName) || !CPYANS(ProviderName)) { rc = ERROR_INVALID_PARAMETER; } } else { rc = GetLastError(); } } else { rc = GetLastError(); } } else { rc = GetLastError(); } } else { rc = ERROR_INVALID_PARAMETER; } } except(EXCEPTION_EXECUTE_HANDLER) { rc = ERROR_INVALID_PARAMETER; } return(rc); } #endif // def UNICODE