Cómo cambiar un icono fotorrealista de dispositivo en Windows 7

Una de las novedades de Windows 7 con respecto a sistemas anteriores es su nuevo centro de dispositivos e impresoras, donde podemos visualizar rápidamente un listado de los dispositivos que tenemos conectados a nuestra máquina, así como información de utilidad sobre ellos (fabricante, descripción, página de soporte, etc.). Además, algunos dispositivos pueden acompañarse de un icono fotorrealista que hace que los identifiquemos mucho más rápidamente. Esta información sobre los dispositivos la genera el fabricante y la pone a disposición de los usuarios a través de Windows Metadata and Internet Services (WMIS). Windows 7 incorpora un componente cliente que contacta con este servicio y descarga información actualizada sobre los dispositivos conectados sin que el usuario tenga que hacer nada.

A pesar de que esta información está pensada para que la proporcione el fabricante, puede que nos apetezca cambiar alguno de los iconos por otro de más calidad, o bien más apropiado para el dispositivo en cuestión. En este artículo explicaré cómo usar una herramienta de Microsoft, Device and Printers Metadata Authoring Wizard, que permite crear paquetes de "metadatos” sobre cualquier dispositivo conectado a la máquina. Estos paquetes incluyen información sobre el dispositivo (modelo, fabricante, descripción, etc.), así como un icono fotorrealista que se mostrará en el centro de dispositivos e impresoras. Es la aplicación que usan los fabricantes de dispositivos para crear y probar localmente los paquetes de información e iconos, antes de publicarlos en los servicios web de Microsoft.

Podemos descargar este asistente desde la siguiente dirección: http://download.microsoft.com/download/F/5/4/F54F4AF9-737A-4EE6-B3F8-BEF68990CB62/Devices-and-Printers-Metadata-Authoring-Wizard.msi Una vez instalada la aplicación, abrimos Inicio, Dispositivos e impresoras y seleccionamos con el botón derecho el dispositivo en cuestión. Veremos una nueva opción en el menú contextual, Create metadata package, tal y como se muestra en la siguiente captura:

Create_Metadata

Esta opción abre un asistente como el que se muestra en la siguiente imagen:

Wizard_Device

El asistente tiene diversas pestañas para poder rellenar, entre otras cosas, el icono del dispositivo, su descripción, el ID de hardware asociado, la categoría a la que pertenece o los idiomas en los que mostrar la información. En este artículo vamos a centrarnos en cambiar el icono sin entrar en detalle sobre el resto de información; sin embargo, recomiendo que experimente con el resto de campos por su cuenta.

En la pestaña Icon podemos agregar el icono fotorrealista que hayamos creado para nuestro dispositivo. Para crear un icono fotorrealista hay que seguir ciertas pautas para que sea considerado válido (a este tipo de iconos se les conoce como iconos “estilo Windows Aero”). Estas pautas se citan en el propio asistente (formato .ico, número de formatos de imagen requeridos), así como de manera ampliada en esta dirección web: http://msdn.microsoft.com/en-us/library/aa511280.aspx En la documentación de prácticamente cualquier herramienta de diseño gráfico hay información paso a paso sobre cómo crear iconos con estilo Windows Aero. Por ejemplo, si se usa Axialis IconWorkShop se puede usar esta documentación para crear el icono fácilmente a partir de una imagen: http://www.axialis.com/docs/iw/Introducing_Vista_Icons.htm

En la pestaña Associations debemos seleccionar aquellos ID de hardware que queremos asociar con el paquete de “metadatos”. Puede ver los ID de hardware en Administrador de disposivos, haciendo doble clic sobre el dispositivo, pestaña Detalles, propiedad Id. de hardware. Otra pestaña importante es la pestaña Options, donde tendremos que seleccionar el idioma que queremos asociar con este paquete. Podemos crear varios paquetes de información, cada uno asociado con un idioma, y el sistema operativo decidirá automáticamente cuál utilizar en cada caso.

Para concluir, en la pestaña Finish deberemos seleccionar la casilla correspondiente para almacenar el paquete en el almacén de Windows:

Copy_to_Store

Al pulsar sobre Finish, si todo ha ido bien, aparecerá un cuadro de Control de cuentas de usuario pidiéndonos confirmación o privilegios administrativos y el icono del dispositivo cambiará inmediatamente. Además de en el almacén de “metadatos” sobre dispositivos (%ProgramData%\Microsoft\Windows\DeviceMetadata\Idioma), se guarda también una copia del fichero .devicemetadata-ms en la carpeta que hayamos seleccionado en la pestaña Finish (por defecto, la carpeta Documentos). Conviene tener una copia de seguridad por si en algún momento un nuevo controlador o el propio servicio web WMIS “machacan” esta información que hemos personalizado localmente.

Configurar la opción de abrir ítems con un simple clic a través de la API de Windows y de un script VBS

Un usuario del foro preguntaba si es posible cambiar a la opción de abrir archivos o carpetas con un simple clic, que está situada en Explorador de Windows, menú Organizar, Opciones de carpeta y búsqueda, pestaña General. El objetivo principal era incluir este automatismo como parte del proceso de instalación de un programa.

Cuando se plantean este tipo de preguntas, siempre pienso inmediatamente en el usuario de esa aplicación y en cómo tras instalarla considero que ha perdido parte del control de su máquina. No es buena idea que un programa tome la decisión unilateral de modificar configuraciones personales del usuario. En primer lugar habría que volver a pensar en por qué esa aplicación requiere un cambio en una configuración personal para funcionar correctamente. Si el cambio fuese estrictamente necesario y justificado, lo ideal sería indicarle esto al usuario a través de un mensaje y seguidamente dirigirle al panel de Opciones de carpeta (control.exe folders) para sea él personalmente el que cambie la configuración requerida. De esta manera, el usuario es consciente del cambio que ha realizado en su configuración personal, si es que finalmente decide llevarla a cabo.

Microsoft es consciente de que muchas aplicaciones interfieren con la configuración personal del usuario y por ello, especialmente desde Windows 7, ha ido restringiendo ciertas partes del sistema para que no dispongan de acceso a través de la interfaz de programación de Windows. Para el caso que nos ocupa, aún disponemos del acceso a una API que nos sirve para lo que estamos busando: SHGetSetSettings. Como se indica en la página de documentación, si la llamamos con el segundo parámetro establecido en SSF_DOUBLECLICKINWEBVIEW podremos cambiar esta configuración del explorador.

El resultado final de la llamada anterior es la modificación del valor binario ShellState de la clave de registro HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer. A simple vista este valor de registro tiene un aspecto un tanto críptico, pero voy a detallar a continuación su estructura para verlo todo más claro.

¿Cómo interpretar el valor de registro ShellState?

El primer parámetro de la función SHGetSetSettings es una estructura de nombre SHELLSTATE, documentada en MSDN, y presente en el fichero de cabecera Shlobj.h. Esta estructura está formada por un conjunto de flags binarios, cada uno de los cuales controla un determinado aspecto de la configuración del explorador. SHELLSTATE es una estructura bastante antigua, ciertos campos ya no se aplican a versiones recientes de Windows, y además es una estructura propensa a cambios (cada versión de Windows suele introducir un par de nuevos flags y algunos de sus valores se han transladado a otros sitios del registro, más fácilmente controlables mediante directivas). Por esta razón, tanto el valor de registro como su API asociada podrían dejar de funcionar en un futuro sin previo aviso.

Para que esta información persista en el tiempo, la estructura SHELLSTATE junto con su tamaño se almacenan en el valor de registro ShellState antes mencionado. Si lo abrimos en Editor del Registro veremos que comienza por 24 00 00 00. Estos primeros 4 bytes (un entero sin signo) indican el tamaño total, es decir, 36 bytes (nótese que el editor nos está mostrando el dato en hexadecimal). Después del tamaño, le sigue la estructura SHELLSTATE en sí, escrita en bloques de 1 byte de derecha a izquierda. Como vemos en la documentación de MSDN, el flag que nos interesa modificar es fDoubleClickInWebView, el sexto bit. Si lo establecemos en cero, activaremos la opción de abrir ítems con un simple clic; si lo establecemos en 1, los abriremos con un doble clic (comportamiento por defecto).

Por tanto, para respetar el resto de bits de la estructura ShellState lo que podemos hacer es anotar el valor hexadecimal del quinto byte del valor de registro (recuerde que los bytes del primero al cuarto inclusive expresan el tamaño del valor de registro). Con dicho valor anotado, abrimos la calculadora de Windows y la configuramos en modo “Programador” y “hexadecimal”. Introducimos el valor que hemos anotado en el paso anterior y pulsamos “And”, “20”, “Not”, “=”. (20 es el valor hexadecimal correspondiente a poner un 1 binario en la sexta posición). Si en vez de poner el correspondiente bit a 1, queremos ponerlo a 0, la operación que hay que hacer es “Or”, “20”, “=”. Hay más información sobre cómo hacer operaciones a nivel de bit en Wikipedia, por ejemplo.

Para terminar, dejo una posible implementación en lenguaje Visual Basic Script:

'
' Small example of VBScript code that switches between "double click to open items" and "single click to open
' items" by editing the ShellState binary value in the registry.
' It depends on the layout of the SHELLSTATE structure, so it might cease to work in future versions of
' Windows.
'
' For unmanaged code, the best way to achieve this is using the SHGetSetSettings function with the
' second parameter set to SSF_DOUBLECLICKINWEBVIEW
'
' (c) Daniel Martín
'
Const HKEY_CURRENT_USER = &H80000001
strComputer = "."
Set objRegistry = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
Set objWMIService = GetObject("winmgmts:"& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set objShell = CreateObject("Wscript.Shell")

strPath = "Software\Microsoft\Windows\CurrentVersion\Explorer"
strBinValue = "ShellState"

objRegistry.GetBinaryValue HKEY_CURRENT_USER, strPath, strBinValue, uBinaryShellState
uBinaryNewShellState = uBinaryShellState ' Keep user settings
uBinaryNewShellState(4) = uBinaryShellState(4) Xor 32 ' But toggle the fDoubleClickInWebView bit
objRegistry.SetBinaryValue HKEY_CURRENT_USER, strPath, strBinValue, uBinaryNewShellState

If (Return = 0) And (Err.Number = 0) Then
    If ((uBinaryShellState(4) Or 32) = uBinaryShellState(4)) Then
        MsgBox "Single click to open items was applied successfully. Restarting Explorer..."
    Else
        MsgBox "Double click to open items was applied successfully. Restarting Explorer..."
    End If
    Set colProcessList = objWMIService.ExecQuery("SELECT * FROM Win32_Process WHERE Name = 'explorer.exe'")
    For Each objProcess in colProcessList
        objProcess.Terminate(1)
    Next
    objShell.Run "explorer.exe"
Else
    MsgBox "An error occurred: " + Err.Number
End If

¿Qué hacer en caso de que alguna actualización de Windows nos impida arrancar el equipo?

Pese a que Microsoft dedica bastante tiempo a probar sus actualizaciones en un enorme número de configuraciones diferentes, es posible que nos encontremos con un sistema al que le hemos intentado instalar una actualización pero el proceso falla por algún motivo, entrando el sistema en un bucle sin fín y por lo tanto no se puede arrancar el equipo.

Para solucionar este tipo de problemas, debemos tener en cuenta que lo más complicado no es conseguir arrancar el equipo, sino dejarlo en un estado consistente. Básicamente esto quiere decir que la información que mantiene el sistema operativo sobre cada uno de sus componentes se corresponda con lo que existe en realidad, números de versión incluidos. Así pues, lo primero que recomiendo si nos encontramos con un problema de este tipo es intentar restaurar el sistema. Para ello, arrancamos con el DVD de Windows 7 en la unidad y seleccionamos la opción “Reparar el equipo”. Cuando se nos presente el cuadro de diálogo con las opciones de reparación, seleccionamos Restaurar sistema y seleccionamos un punto anterior a la instalación de la actualización problemática. Este procedimiento deja el sistema en un estado consistente.

¿Qué hacer si Restaurar sistema no consigue solucionar el problema o bien no hay un punto de restauración disponible (Windows crea un punto de restauración automático antes de cada instalación de actualización)?

En esta situación mi consejo es que, debido al diseño actual y la arquitectura de componentes de Windows, pese a que consigamos arrancar el sistema va a ser tarea casi imposible dejarlo en un estado consistente. Este hecho probablemente causará problemas similares con actualizaciones futuras. Por tanto, debemos centrarnos en conseguir arrancar el sistema y salvaguardar los datos de importancia antes de proceder a reinstalar el sistema operativo.

Para conseguir iniciar el sistema, podemos probar a arrancar nuevamente con el DVD de Windows 7, seleccionamos “Reparar el equipo” y abrimos una ventana de comandos. En ella, teclearemos el siguiente comando:

Dism.exe /Image:X:\ /Cleanup-Image /RevertPendingActions

(Donde “X” es la unidad del sistema que no puede arrancar).

Este comando lo que hace es revertir todas las acciones pendientes que se hayan generado durante la instalación de la actualización. Estas acciones pendientes se ejecutan tras el reinicio de la máquina y los eventos relacionados quedan registrados en los ficheros %windir%\winsxs\poqexec.log, %windir%\winsxs\pending.xml y %windir%\winsxs\pending.xml.bad. Para que un paquete de actualización se instale correctamente, deben ejecutarse y finalizar con éxito todas las acciones que tenga pendientes, por lo que si alguna falla podemos encontrarnos en una situación de bucle infinito. En actualizaciones grandes como puede ser un service pack, hay un periodo de la instalación durante el cual no puede producirse ningún fallo o corte de energía. Si ocurriera, casi con total probabilidad el sistema entrará en un bucle infinito tras el reinicio. En Windows 7 esta “ventana fatídica” de tiempo se ha reducido bastante, lo que unido a la estabilidad del servicio de componentes y del instalador de actualizaciones han conseguido reducir enormemente este tipo de problemas. Si nos enfrentamos a un equipo con estos síntomas deberíamos sospechar siempre de alguna inconsistencia de base en el servicio de componentes de Windows, corrupción en el disco o algún otro tipo de fallo de hardware.

Actualización (15/6/2011): Si se quiere evitar reinstalar el sistema una vez recuperado el arranque correcto de la máquina, el Windows Server Core Team de Microsoft nos presenta un método para devolver el sistema a un estado consistente de nuevo, usando la herramienta Dism.exe para instalar y posteriormente desinstalar el paquete fallido. Aquí puede encontrar más información (en inglés): http://blogs.technet.com/b/askcore/archive/2011/05/10/supported-workaround-for-torn-state-installations-on-windows-7-sp1.aspx

Qué formas hay de ocultar una acción (verbo) del menú contextual

Al hacer clic con el botón derecho del ratón sobre cualquier ítem del shell (ya sea un fichero o no), el sistema nos muestra un menú contextual formado por una serie de acciones (verbos) entre las que se incluyen un cierto número de acciones por defecto (cortar, copiar, pegar, renombrar, propiedades, etc.), así como ciertas acciones añadidas por programas de terceros. Puesto que un requisito para lograr una buena usabilidad podría ser un menú contextual simple y organizado, un usuario preguntaba cómo se pueden ocultar selectivamente estas acciones de la interfaz de usuario, pero sin eliminarlas del sistema.

Hay unas cuantas formas para lograr esto, agregando algunos valores al registro de Windows:

Valor de registro “Extended”

Si se agrega al registro, justo en la sección donde se define el verbo, un valor de tipo cadena de nombre “Extended” y contenido vacío, el sistema entiende que se trata de una acción que o bien raramente se usa, o bien solo suelen usarla los usuarios avanzados. De tal forma que para mostrarla es necesario mantener pulsada la tecla Mayúsculas mientras se abre el menú contextual. Un ejemplo de esto es la acción “Abrir consola de comandos aquí” del menú contextual de Windows 7 (HKEY_CLASSES_ROOT\Directory\shell\cmd).

Valor de registro “ProgrammaticAccessOnly”

Este valor es nuevo en Windows Vista. Sirve para indicar que dicha acción no está pensada para que la ejecuten los usuarios a través de la interfaz gráfica. Solamente se puede invocar mediante programación. Un ejemplo de ello es el verbo “explorar” (explore), que está presente en el registro, por ejemplo en la clave HKEY_CLASSES_ROOT\Folder\shell\explore, pero que no aparece en el menú contextual.

Valor de registro “LegacyDisable”

Este valor indica que la acción está presente simplemente por motivos de compatibilidad con algún programa antiguo y no debería usarse de ahora en adelante.

Valor de registro “SuppressionPolicy”

Esta opción oculta el verbo si se ha aplicado al sistema una determinada directiva. Las directivas pueden ser de dos tipos: una restricción de licencia o una directiva de grupo de toda la vida. Podemos ver una ejemplo de esto en la clave de registro HKEY_CLASSES_ROOT\CLSID\{20D04FE0-3AEA-1069-A2D8-08002B30309D}\shell\Manage. Ahí encontramos un valor de nombre “SuppressionPolicy” con contenido a 0x4000003c. ¿Qué quiere decir esto? El valor SuppressionPolicy contiene un valor de 32 bits que representa la restricción que, de estar aplicada, queremos que oculte el verbo del menú contextual. Es un valor del tipo enumerado RESTRICTIONS que se le pasa como parámetro a la API SHRestricted. Para ver la correspondencia entre restricciones y códigos hexadecimales, podemos abrir el fichero del SDK de Windows ShlObj.h y posicionarnos en la definición del tipo enumerado RESTRICTIONS (typedef enum RESTRICTIONS). Esta es la línea para el ejemplo que estamos desarrollando:

REST_NOMANAGEMYCOMPUTERVERB     = 0x4000003C,   // No Manage verb on My Computer

A partir de Windows Vista, Microsoft está usando un modelo distinto de restricciones. La primera diferencia la encontramos en la clave de registro donde se activan dichas restricciones. Anteriormente se agregaban a la clave de registro Software\Policies\Microsoft\Windows (ya sea dentro de HKCU o HKLM), pero recientemente toda nueva restricción se agrega a la clave Software\Microsoft\Windows\CurrentVersion\Policies. La segunda diferencia reside en el formato de representación de la restricción: En lugar de usar un valor de 32 bits, se da preferencia a un nuevo formato basado en un GUID de 128 bits. Para agregar una restricción a un verbo usando este nuevo formato debemos crear un valor de nombre “SuppressionPolicyEx” (nótese el “Ex” final) cuyo contenido sea el GUID correspondiente a la restricción. Podemos ver un ejemplo en la clave de registro HKEY_CLASSES_ROOT\batfile\shell\runasuser. Lamentablemente, Microsoft no ha documentado esta información, lo que hace pensar que pueda ser algo transitorio y propenso a cambios. Para el lector interesado, en esta página se recoge información adicional: http://www.geoffchappell.com/viewer.htm?doc=studies/windows/shell/shlwapi/api/winpolicy/policies.htm

De manera análoga podemos restringir la aparición de una acción en el menú contextual en función de una consulta al servicio de licencias de Windows. En este caso el valor de registro se denominaría “SuppressionSlapiPolicy” y el contenido sería la licencia a consultar, correspondiéndose con el primer parámetro de la función SLGetWindowsInformationDWORD. Si la directiva de licencia que se consulta no está disponible, se ocultará la acción del menú contextual.

Valor de registro “HideInSafeMode”

Si la acción que hemos agregado solamente tiene sentido si el sistema ha arrancado en modo seguro, podemos añadir este valor de cadena (con contenido vacío) para que Windows solo lo muestre en ese escenario.

Estas son las posibles formas de ocultar un verbo del menú contextual de Windows. La extensión del menú contextual y las asociaciones de archivos es un tema bastante amplio, en algunas ocasiones complejo y que generan bastantes dudas no solo entre desarrolladores de aplicaciones, también entre usuarios finales. Un buen punto de partida para comprender mejor el menú contextual es la documentación oficial de MSDN: http://msdn.microsoft.com/en-us/library/cc144169(v=vs.85).aspx

¿Por qué aparece el fatídico mensaje “No hay disco en la unidad”?

Es posible que en alguna ocasión le aparezca un mensaje de error bastante curioso que, sin motivo aparente, le advierte de que no hay disco en la unidad. Suele aparecer al trabajar con alguna aplicación, o bien al iniciar el sistema, y tiene un aspecto similar a la siguiente imagen:

Inserte_disco_unidad

¿Por qué ocurre este mensaje de error?

La representación de un proceso en Windows es una estructura de datos que internamente se denomina EPROCESS (que viene de executive process) y que reside en espacio de memoria de núcleo. Este bloque contiene numerosos campos y apuntadores a estructuras de datos auxiliares (entre otras, el PEB o bloque de entorno de proceso). Es uno de estos campos el que le dice a Windows si el proceso es quien va a manejar los errores graves de sistema, tales como errores de E/S, fallos de alineamiento, etc. y cómo va a hacerlo. Vemos esto de forma práctica usando Windbg como depurador, habiendo iniciado una sesión de depuración de núcleo y escribiendo este comando:

lkd> dt _eprocess

[…]

+0x284 ImagePathHash : Uint4B
+0x288 DefaultHardErrorProcessing : Uint4B
+0x28c LastThreadExitStatus : Int4B
+0x290 Peb : Ptr64 _PEB
+0x298 PrefetchTrace : _EX_FAST_REF
+0x2a0 ReadOperationCount : _LARGE_INTEGER
+0x2a8 WriteOperationCount : _LARGE_INTEGER
+0x2b0 OtherOperationCount : _LARGE_INTEGER
+0x2b8 ReadTransferCount : _LARGE_INTEGER

[…]

El campo “DefaultHardErrorProcessing” está marcado en negrita porque es el que nos interesa para este artículo. Cuando Windows crea un proceso, como podrá intuir, una de las fases de inicialización implica rellenar la estructura EPROCESS. Una vez que se rellena la estructura EPROCESS esta se inserta en la lista de procesos activos y en el espacio de nombres del administrador de objetos de Windows (Object Manager), el cual devuelve un handle único que permite que el proceso sea accesible tanto para el sistema como para el resto de aplicaciones. El valor inicial del campo “DefaultHardErrorProcessing” generalmente se hereda del proceso padre, y por defecto hace que el sistema muestre todos los errores graves de sistema que ocurran. La ventana de error aparece cuando ocurre un error grave y el proceso o hilo en cuestión no lo ha gestionado.

¿Cómo cambiar el contenido del atributo de proceso DefaultHardErrorProcessing para que en vez de mostrar una ventana de error se le envíe el error al proceso para que lo trate?

Se puede usar la API pública SetErrorMode, que admite diferentes parámetros según el tipo de error grave que queramos delegar al proceso en cuestión. De esta manera evitaremos que aparezcan crípticas ventanas de error (como la que aparece al comienzo del artículo), y que nuestra aplicación quede a la espera de que interactuemos con dicha ventana para proseguir con su funcionamiento. En Windows Vista se añadió al bloque de entorno de hilo (TEB) un nuevo campo de control de errores graves, como puede comprobar si ejecuta el comando !teb en una sesión de depuración de núcleo en Windbg (en Windows Vista o Windows 7):

kd> !teb

[…]

HardErrorMode:        0`

[…]

Si bien este campo está presente desde Windows Vista, no fue hasta la llegada de Windows 7 cuando se creó una API pública para que los desarrolladores pudieran modificarlo en sus programas: SetThreadErrorMode. Esta API surgió de la necesidad por parte de las aplicaciones multi-hilo de cambiar este valor sin afectar al valor por proceso (que automáticamente es heredado por cada nuevo hilo).

Así pues, es recomendable que las aplicaciones hagan uso de la siguiente llamada a función para evitar que la experiencia de usuario sea poco agradable en caso de que ocurran errores graves:

SetErrorMode(SEM_FAILCRITICALERRORS);

o bien, en Windows 7:

SetThreadErrorMode(SEM_FAILCRITICALERRORS);

Esta es la causa por la cual aparecen mensajes del tipo “No hay disco en la unidad” en los momentos más inoportunos. Por suerte Windows ofrece a los desarrolladores la posibilidad de manejar apropiadamente estas circunstancias excepcionales para así proporcionar una experiencia de usuario más agradable. Espero que este artículo haga más visibles estas posibilidades y todos disfrutemos de un mejor ecosistema.

¿Qué cuentas de usuario se muestran en la pantalla de bienvenida de Windows?

Una pregunta que se hacen muchos usuarios de Windows es qué cuentas de usuario se muestran en la pantalla de bienvenida, puesto que no hay una relación de uno a uno entre las cuentas existentes en el sistema y las cuentas que aparecen al iniciar el equipo. Este artículo intentará aclarar esta duda.

Winlogon.exe, el proceso encargado del inicio de sesión en Windows, es quien realiza la enumeración y filtrado de las cuentas de usuario para mostrarlas en la pantalla de bienvenida ejecutando para ello, en Windows Vista y 7, un proceso auxiliar, LogonUI.exe. El hecho de separar esta tarea en dos procesos sirve para garantizar la estabilidad del sistema en caso de que código de autenticación de terceros (por ejemplo, el software de un lector de huellas) hiciera fallar a Winlogon.exe, un proceso que es crítico para el buen funcionamiento del sistema operativo. Al mostrar cuentas en la pantalla de bienvenida se examina antes una lista de cuentas “especiales” que, o bien siempre deben incluirse, o bien siempre deben ocultarse de dicha pantalla. La lista de cuentas “especiales” reside en el registro, concretamente en la clave HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\SpecialAccounts\UserList. Allí, un valor de registro de tipo DWORD y con nombre igual al nombre de la cuenta de usuario “especial” decide si la cuenta siempre se incluye en la pantalla de bienvenida (contenido a 1), o bien siempre queda oculta (contenido a 0). Esta lista de cuentas especiales se almacena en una caché en memoria, así que si modificamos el registro es conveniente que reiniciemos el equipo para que los cambios surtan efecto.

Además del listado de cuentas “especiales” que el usuario puede editar desde el registro, Windows automáticamente excluye ciertas cuentas de usuario que no interesa que aparezcan en la pantalla de bienvenida, puesto que causarían bastante confusión al usuario. Se trata de cuentas de usuario que instalan entre otros Microsoft IIS (Internet Information Server) o Visual Studio y que no están pensadas para que el usuario inicie sesión con ellas. Concretamente, nunca aparecerán en la pantalla de bienvenida aquellas cuentas de usuario que empiecen con los prefijos “IWAM_”, “IUSR_”, “VUSR_”, entre otros posibles. Otro tipo de cuentas que obviamente siempre se ocultan son aquellas que están deshabilitadas o bloqueadas. Es importante comentar que en la pantalla de bienvenida solo aparecen las cuentas que pertenezcan a los grupos de usuarios creados durante la instalación de Windows, a saber, “administradores”, “usuarios avanzados”, “usuarios” e “invitados”. Por este motivo, por ejemplo la cuenta de usuario que crea VMWare Workstation dentro del grupo “__vmware__” no se muestra en la pantalla de bienvenida.

Pasamos a analizar en detalle lo que ocurre en la pantalla de bienvenida con un cuenta de usuario que, por recibir un tratamiento especial por parte del sistema, merece un apartado para ella sola: la cuenta “Administrador”.

La cuenta “Administrador”

Esta cuenta es especial en el sentido de que es la primera cuenta que se crea al instalar Windows. Es similar a la cuenta root de GNU/Linux y, como esta, solo debería usarse en casos de emergencia. Microsoft hace patente esto al deshabilitarla por defecto y no asignarle una contraseña. Lo que diferencia a esta cuenta del resto de cuentas con privilegios administrativos es que la cuenta “Administrador” tiene por defecto desactivado Control de cuentas de usuario, lo que quiere decir que si iniciamos sesión con ella gozaremos de verdaderos privilegios administrativos todo el rato. Ahí reside el principal peligro de esta cuenta y por lo cual yo siempre desaconsejo su manipulación, salvo en casos justificados.

El comportamiento de esta cuenta en la pantalla de bienvenida depende del sistema operativo en el que estemos trabajando. En Windows XP, la cuenta “Administrador” no aparece en la pantalla de bienvenida si ya se ha creado con anterioridad otra cuenta con privilegios administrativos. En Windows Vista y Windows 7, a diferencia de sistemas anteriores, la cuenta “Administrador” no se oculta nunca de la pantalla de bienvenida, siempre y cuando esté activada.

¿Qué ocurre con la cuenta “Administrador” en modo seguro?

En Windows XP al iniciar el equipo en modo seguro podremos tener acceso a la cuenta “Administrador”, de hecho tendremos acceso a todas las cuentas del equipo que pertenezcan al grupo de administradores (el resto de cuentas no serán mostradas).

En Windows Vista y Windows 7 el estado habilitado o deshabilitado de la cuenta “Administrador” (y por consiguiente, la capacidad para iniciar sesión con ella o no) puede variar en modo seguro. Esto se debe a que aunque Microsoft no quiere que los usuarios inicien sesión con el usuario “Administrador” sí quiere proporcionar un método de inicio de sesión “de emergencia” para cuando se han deshabilitado o borrado todas las cuentas administrativas del equipo. El hecho de que en modo seguro la cuenta “Administrador” se considere habilitada o deshabilitada depende de si el sistema operativo es cliente o servidor y de si está unido a un dominio. Resumo las posibilidades en esta tabla:

¿Cuándo está habilitada o deshabilitada la cuenta “Administrador” en modo seguro? (Windows Vista/7)

  No unido a dominio Unido a dominio
S.O. cliente Habilitada en caso de emergencia* Se respeta el estado de la cuenta
S.O. servidor Siempre habilitada Siempre habilitada

*: El caso de emergencia ocurre cuando no hay ninguna cuenta administrativa habilitada para el inicio de sesión.

En este artículo he descrito a grandes rasgos las cuentas de usuario que aparecen en la pantalla de bienvenida de Windows, aspecto que depende entre otras cosas del sistema operativo, del tipo de cuenta y de si se ha iniciado en modo seguro o no. Si desea ocultar cuentas de la pantalla de bienvenida puede usar mi herramienta HideUserAccounts7, que lo que hace es incluirlas dentro del grupo de cuentas “especiales”, ya comentado al principio, marcándolas como siempre ocultas. Debe tener especial cuidado a la hora de ocultarlas puesto que accidentalmente podría impedirse completamente el inicio de sesión en la máquina.

Sorteo de dos licencias de Diskeeper entre los participantes de mi foro

En mis foros estoy sorteando dos licencias de Diskeeper (http://www.diskeeper.com/), un partner de Microsoft dedicado a la desfragmentación de discos, y cuyos productos ofrecen un valor añadido al software de desfragmentación incluido en Windows. Aquí puede ver las características de este software: http://www.diskeeper.com/business/diskeeper/

Si le interesa, para participar solamente hay que publicar en el foro General de Wintecnico.com un pequeño artículo, truco o tip sobre Windows, cuanto más original mejor. Aquí hay más información sobre el concurso: http://www.wintecnico.com/foros/default.aspx?g=posts&t=77  Los ganadores los publicaré en dicho foro y serán contactados por correo electrónico.

¡Suerte!

¿Cómo automatizar la eliminación de temporales de Internet Explorer?

Una forma sencilla de eliminar temporales en Internet Explorer consiste en abrir el menú Herramientas, Opciones de Internet y hacer clic sobre el botón Eliminar del apartado Historial de exploración. Sin embargo, a casi todo el mundo nos gusta automatizar ciertas tareas, y algo como eliminar la cache de navegación se realiza asiduamente así que bastante beneficio podríamos obtener si logramos automatizarla en la forma de un script o algo similar.

En Internet circulan scripts que eliminan temporales de Internet similares al siguiente:

rem Eliminar Archivos temporales de Internet
start RunDll32 InetCpl.cpl,ClearMyTracksByProcess 8
@exit

Pese a que el script funciona correctamente, hay que tener en cuenta que en Windows Vista y Windows 7 está accediendo y borrando ficheros que tienen un nivel de integridad bajo (los temporales creados por IE con modo protegido activado) desde un proceso con un nivel de integridad medio (por defecto en Windows 7 y Windows Vista).

Una posible mejora consiste en crear un nuevo proceso que tenga un nivel de integridad bajo y ejecutar el comando RunDll32 InetCpl.cpl,ClearMyTracksByProcess en él. Para ejemplizar mi solución, he creado una pequeña utilidad que hace esto mismo. La puede descargar desde aquí. La herramienta admite una serie de parámetros de configuración para eliminar todo, solo temporales (-t), solo historial (-h), solo cookies (-c), o sin mostrar interfaz de usuario (-q). Básicamente el algoritmo que he seguido es: Duplicar el manejador del proceso que ejecuta la aplicación, usar la API SetTokenInformation para rebajar el nivel de integridad a “bajo” y finalmente usar CreateProcessAsUser para crear un nuevo proceso con este nuevo token de seguridad. Este proceso ejecuta el comando RunDll32 InetCpl.cpl,ClearMyTracksByProcess normalmente.

Como se hace uso de una función implementada en el sistema operativo, personalmente prefiero esta solución a eliminar manualmente los directorios de temporales. Eliminar temporales no es solamente limpiar una carpeta y es bueno que el equipo de producto de Microsoft nos abstraiga de esta tarea mediante una función. A pesar de todo, no podemos contar con que esta función siga en versiones sucesivas de Internet Explorer.

Para concluir, comprobamos en Process Explorer cómo mi herramienta ha creado dos procesos que ejecutan el comando de limpieza, uno con nivel de integridad bajo y otro con nivel de integridad medio, cada una ocupándose de su correspondiente caché:

Rundll

¿Cuáles son los posibles flags de la función ClearMyTracksByProcess?

Ya tenemos una solución, ahora bien, es posible que necesitemos hacer uso de la función ClearMyTracksByProcess en algún otro momento, así que vendría bien tener a modo de referencia los posibles flags que se le pueden pasar. Según mis pruebas, esta es una lista más o menos detallada:

  • Historial: 1
  • Cookies: 2
  • Temporales de Internet: 4
  • Temporales incluyendo favoritos offline: 8
  • Formularios: 16
  • Contraseñas: 32
  • Filtro de phising: 64
  • Ejecutar sin ventana de progreso: 256

Los valores se pueden combinar mediante una simple OR. En una próxima actualización de mi herramienta iré incluyendo mejoras en la granularidad de limpieza.

Cómo eliminar la información de desinstalación del SP1 de Windows 7 y así ahorrar espacio en disco

Una vez instalado Windows 7 Service Pack 1 (en el momento de confeccionar este artículo, aún en versión RC), es posible que queramos ahorrar cierto espacio en disco quitando aquellas versiones antiguas de los componentes que hayan sido reemplazados por el service pack. Esto evita que se pueda desinstalar en un futuro, pero si tras un periodo de prueba todo funciona correctamente, raramente es necesario desinstalar un service pack. El hecho de impedir la desinstalación del service pack tiene todo el sentido del mundo cuando hemos procedido a integrarlo en una imagen original de Windows 7/Windows Server 2008 R2, tal y como explico en este artículo.

Hay tres formas de eliminar la información de desinstalación del SP1 de Windows 7:

Usando Liberador de espacio en disco

Al abrir la herramienta Liberador de espacio en disco (Cleanmgr.exe), si se selecciona la opción de Limpiar archivos de sistema (o lo que es lo mismo, ejecutándola con privilegios administrativos), nos dará la opción de eliminar los archivos de desinstalación del service pack, tal y como se ve en la captura siguiente:

SP1_Cleanup

Esta es quizá la opción más simple para la mayoría de usuarios.

Desde la línea de comandos, con el sistema arrancado

Si ejecutamos una ventana de línea de comandos (Cmd.exe) con privilegios administrativos y tecleamos lo siguiente podremos eliminar los archivos de desinstalación:

dism /online /Cleanup-Image /spsuperseded

Desde la línea de comandos, con el sistema no arrancado

Si el sistema no está arrancado, o bien si estamos integrando el service pack, podemos usar este comando desde otro sistema operativo que tengamos instalado en la misma máquina:

dism /Image:D: /Cleanup-Image /spsuperseded

(Donde D: es la unidad donde está instalado el sistema operativo con SP1).

Es indiferente la opción que usemos, el resultado es el mismo. Las dos últimas opciones tienen la ventaja de la automatización que se puede lograr usando baterías de comandos o similares.

¿Por qué Windows Registry Editor Version 5.00 y no REGEDIT5?

En Internet es común encontrarnos con ficheros .reg que contienen datos que se pueden importar en el registro del sistema operativo. Si nos fijamos en la cabecera de estos ficheros .reg, nos podemos encontrar con dos tipos diferentes:

REGEDIT4

Windows Registry Editor Version 5.00

Existe un tercer tipo que quizá no haya visto nunca, REGEDIT, que se corresponde con ficheros de registro para Windows 3.1, sistema operativo en el que apareció la primera versión de lo que conocemos como registro. Que recuerde, en esa primera versión solamente existía la raíz HKEY_CLASSES_ROOT.

¿Cuál es la diferencia entre ambas cabeceras? La respuesta a esta pregunta da pie a un breve artículo sobre la historia de Windows, particularmente de Editor del Registro.

En los inicios de Windows, Editor del Registro no soportaba todos los tipos de valores que soporta hoy en día. Entre otros, no entendía de forma nativa valores de tipo cadena expandible (REG_EXPAND_SZ). Por este motivo, estos valores debían ser exportados a un fichero de texto de forma “cruda”, es decir, como una cadena ANSI de valores hexadecimales, terminada por un carácter nulo. He aquí un ejemplo. Al exportar una clave de registro que contiene un valor de tipo cadena expandible queda algo como esto:

REGEDIT4

[HKEY_CURRENT_USER\Prueba]
"Prueba"=hex(2):25,53,79,73,74,65,6d,52,6f,6f,74,25,00

Cuando nació Windows 2000, la compatibilidad con Unicode hizo que Editor del Registro exportara ficheros de registro de una forma un tanto diferente. Ahora los valores de cadena expandible no eran exportados como flujos hexadecimales en formato ANSI, sino Unicode, y la misma clave de registro quedaría exportada de la siguiente forma:

REGEDIT4

[HKEY_CURRENT_USER\Prueba]
"Prueba"=hex(2):25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,00,74,\
  00,25,00,00,00

El caos que se formó fue importante, porque de pronto Editor del Registro podría dejar de importar correctamente millones de archivos de registro.

El primer intento de solución por parte de Microsoft fue el de crear una nueva cabecera para los archivos de registro, la versión 5, REGEDIT5. El problema que tiene esta cabecera es que tampoco era interpretada correctamente porque el parser de Editor del Registro no tenía en cuenta correctamente el número de versión. Si lo que viene después de “REGEDIT” es un número 4, entonces interpreta que se trata de un archivo de registro de tipo Windows 9x. Si no, interpreta que se trata de un fichero de registro de tipo Windows 3.1. ¡Desde Microsoft no pensaban que Editor del Registro fuese a necesitar una nueva versión!

Así pues, la única solución posible fue reescribir completamente la cabecera, y aprovechando la experiencia adquirida, hacerla más robusta ante futuras versiones de Editor del Registro. La nueva cabecera resultante quedó como “Windows Registry Editor Version 5.00” y ahora el parser sí interpreta correctamente que se trata de la versión 5.00. Si en un futuro Microsoft desarrollara una versión posterior, los editores antiguos descartarán adecuadamente el fichero en vez de importarlo. Las versiones recientes de Editor del Registro pueden importar archivos de registro de tipo Windows 9x y Windows 3.1. También ofrecen la posibilidad de exportar archivos de registro en formato de cadena ANSI para garantizar su compatibilidad con sistemas Windows 9x. Para ello basta con seleccionar la correspondiente opción Archivos de Registro de Win9x/NT4 (REGEDIT4) en la lista desplegable Tipo del cuadro de diálogo Exportar.

Just another Microsoft MVPs site