martes, 19 de junio de 2012

Archivos MUI (Multilanguage User Interface)

Todos los que nos dedicamos a este complejo mundo del desarrollo de software, nos hemos topado en alguna ocasión con la necesidad de hacer que nuestras aplicaciones estén localizadas, es decir, que estén disponibles en varios idiomas.

Para conseguir esto existen multitud de técnicas, pero en esta ocasión quiero comentaros una que utiliza Microsoft en el desarrollo de sus sistemas operativos Windows Vista, 7, 8, etc Se trata de los archivos MUI (Multilanguage User Interface).

La idea es muy simple, pero bastante eficaz. Consiste en compilar las aplicaciones como binarios independientes de los recursos utilizados por las mismas, de tal forma que tengamos por un lado nuestros ejecutables o librerías (EXEs, DLLs) y por otro lado los recursos (en un archivo de tipo .MUI).

En este escenario, una aplicación que necesita hacer uso de un recurso (cadena de texto, diálogo, icono, etc. ), lo que debe hacer es cargarlo desde el archivo .MUI correspondiente a la aplicación y en el "idioma establecido en el sistema operativo". Para tal fin se hace uso de llamadas a las APIs:

LoadLibrary, FreeLibrary, FindResource, LoadString, LoadIcon, LoadMenu, LoadCursor, LoadBitmap, LoadAccelerators, FormatMessage, etc

Por ejemplo, la calculadora de windows se encuentra en la carpeta %SystemRoot%\system32\calc.exe y su archivo 'MUI' correspondiente está alojado en C:\Windows\System32\idioma_es_ES_fr_FR_etc\calc.exe.mui

Ejemplo de uso: cuando intentamos hacer una división entre '0' la calculadora muestra en pantalla el mensaje de error:

Error: división por cero.

Se trata de una cadena de texto que está alojada en el archivo calc.exe.mui y su identificador es el nº 71. En el pedazo de código siguiente veremos cómo se puede tener acceso a esa cadena de texto (se trata de un fragmento de código como prueba de concepto y muy simplificado, para utilizarlo en un escenario real hay que comprobar que los identificadores devueltos no sean nulos, etc. ):

// En primer lugar obtenemos un handle a la librería de recursos (el archivo mui de la calculadora)

HMODULE resLibrary = LoadLibraryExW(L"C:\\Windows\\System32\\es-ES\\calc.exe.mui", NULL, LOAD_LIBRARY_AS_IMAGE_RESOURCE | LOAD_LIBRARY_AS_DATAFILE);

// A continuación cargamos el recurso de tipo 'cadena de texto' cuyo identificador es 71 correspondiente a "Error: división por cero."

WCHAR szCadena[MAX_PATH * 2];
LoadStringW(resLibrary, 71, szCadena, MAX_PATH * 2);

// Y por último liberamos la librería de recursos

FreeLibrary(resLibrary);

NOTA AL MARGEN:

Desde el punto de vista de la seguridad, he encontrado multitud de archivos de tipo MUI, en cuyo interior se encuentran cadenas de texto que contienen información sensible (ej. contraseñas, sentencias SQL para acceso a base de datos, etc), cuidado con esto, es muy fácil inyectar código SQL en un MUI por ejemplo, o acceder/extraer cualquier tipo de recurso.

2 comentarios: