Paco Zarabozo

Junctions para carpetas de red

Muchísima gente, incluyendo expertos en IT, desconoce lo que son los Junction points en Windows (NTFS). Quienes están familiarizados con Linux/Unix, saben lo que es un Symlink, pero muchísimos creen que es una funcionalidad que en Windows no existe, lo cuál es un error.

Para aquellos que no saben lo que es, es similar a un acceso directo. La diferencia radica en que el sistema no lo trata como un accceso directo, sino somo si se tratara de el archivo o la carpeta real en sí. Por ejemplo, si yo tengo la siguiente ruta:

C:\Documents and settings\Paco\Mis documentos\Proyectos\112343\Tareas

…pero quiero acceder a esa ruta desde D:\Tareas, podría crear un acceso directo a dicha carpeta en D:\Tareas. Sin embargo, hay un sinnúmero de motivos por los cuáles yo podría necesitar que el sistema crea que D:\Tareas es una carpeta real. Por ejemplo, algún programa que forzosamente busca esa carpeta, pero yo por cuestiones de espacio, necesito conservarla en su ruta original. Entonces crearía un Junction point para que D:\Tareas sea a la vista de cualquier aplicación una carpeta real. Y si algo se modifica dentro de D:\Tareas, es automáticamente modificado en C:\Documents  and Settings\Paco\Mis documentos\Proyectos\112343\Tareas, ya que en realidad es el mismo punto y ocupa el mismo espacio en el disco duro.

Lo mismo puedo hacer para crear hardlinks a archivos (tal como lo hace el comando ln en Linux). También es necesario utilizar herramientas de terceros o provistas por Microsoft en toolkits de administración. Una vez que creas un link de este tipo, puedos tener el archivo original C:\Documents  and Settings\Paco\Mis documentos\Proyectos\112343\Tareas\Notas.txt y un hardlink a ese archivo en la ruta C:\Notas.txt. Son el mismo archivo. Si modifico uno de ellos el otro se modifica también.

Ciertamente ha existido en el sistema de archivos NTFS desde antes de Windows 2000, pero Microsoft nunca creó documentación al respecto. Existen actualmente herramientas de terceros e incluso algunas provistas por Microsoft para la manipulación de este tipo de links (por ejemplo, junction.exe de SysInternals – ahora de Microsoft).

Todo esto es de gran utilidad para muchísimos fines (mover la ubicación de carpetas de sistema para distribuir el espacio en otros discos, carpetas que un servidor web puede leer, simple comodidad de acceso, etc). Pero te encuentras con un problema cuando lo que intentas hacer es un Junction hacia una carpeta de red o una unidad de red.

Esta es una limitación directa de NTFS. Sin importar la herramienta que se utilice, un Junction hacia una ubicación que no es un disco duro local (como una unidad de red o una carpeta de red) simplemente no funciona. O al menos no funcionaba, hasta la aparición de la nueva versión de NTFS que introdujo Microsoft con Windows Vista y ahora Windows 7.

Desde Windows Vista, existe una herramienta (de línea de comandos/Símbolo del sistema) llamada mklink.exe. Con esta herramienta se pueden crear symlinks, hardlinks, softlinks y junction points. Pero la verdadera novedad es que es posible crear un symlink a una carpeta de red. ¿Por qué querrías hacer esto? Bueno, hay miles de razones diferentes para cada usuario. Pero supongamos lo siguiente:

  • Tengo un equipo de programadores en mi oficina
  • Tengo un servidor de desarrollo en el que se encuentran ciertos archivos que necesito que sean los mismos siempre para todos
  • Necesito cambios en tiempo real antes de pensar en control de versiones
  • El servidor tiene los archivos en la carpeta D:\Archivos
  • Necesito que cada programador, desde su propia máquina, vea/modifique esos archivos en tiempo real como si los tuviera en su propia carpeta local C:\Archivos_del_servidor.

Al crear un symlink en cada máquina hacia esa carpeta del servidor, cada máquina podrá utilizar esos archivos como si se tratara de archivos locales. Esto es invisible para las aplicaciones en general. Cualquier programa podrá abrir esos archivos creyendo que son archivos locales. Si yo un día modifico archivos en el servidor, no tengo que avisarle nada a nadie, todos tendrán los cambios automáticamente.

El uso de la herramienta mklink es muy sencillo. Basta con escribir ese comando en el Símbolo del sistema para que aparezcan instrucciones de uso. Para hacer, por ejemplo, un symlink como el que puse de ejemplo, utilizaría el siguiente comando en cada estación de trabajo:

mklink /d C:\Archivos_del_servidor \\SERVIDOR\d$\Archivos

La respuesta del comando sería la siguiente:

vínculo simbólico creado para C:\Archivos_del_servidor <<===>> \\DEV\d$\Archivos

Utilizando el modificador /J en lugar de /D, se crean Junction points normales, accesibles en versiones anteriores a Windows Vista. Con el modificador /H se crea un hardlink. Si el link que se quiere crear es de un archivo y no de una carpeta, entonces no se aplica ningún modificador en el comando, sólo la ruta del link a crear seguida de la ruta real al archivo.

Si no tienes experiencia con este tipo de cosas, te recomiendo fuertemente que investigues sobre el problema al eliminar Junction points desde el explorador de Windows. Puedes perder la carpeta original al vaciar tu papelera de reciclaje. Para eliminar Junctions hay que tener cuidado. Herramientas como junction.exe de SysInternals permiten la eliminación correcta. Hay muchas herramientas de terceros que lo hacen correctamente también.

Espero les sea de utilidad. 🙂

Windows 7 – Solución a Error 0x80070490 al instalar SP1 (Service Pack 1)

Decidí crear un artículo sobre esto después de pasar muchas horas tratando de solucionar este problema, ya que entre muchas búsquedas que hice, me dí cuenta de que es un problema bastante común.

Yo intentaba actualizar el Service Pack 1 de Windows 7 a través de Windows Update (actualizaciones automáticas) y el error no era muy claro. Lo intenté eventualmente a lo largo de una semana y finalmente decidí descargar el instalador directo de Service Pack 1. Fue ahí donde pude ver el error más claramente: Error 0x80070490 después de reiniciar – la actualización no se realizaba. Las muchas búsquedas que hice no me ayudaron mucho, hablaban de problemas de permisos y reparaciones desde DVD de instalación, lo cuál no me parecía algo correcto para una instalación perfectamente limpia de Windows.

Fue entonces que me puse a revisar los logs de la instalación. Entre varios archivos, hubo uno que es el que interesa en este caso: c:\Windows\inf\setupapi.dev.log (no confundir con c:\Windows\inf\setupapi.log).

Dicho archivo contiene información sobre todo lo que intenta hacer la actualización. Son miles de líneas (que además se acumulan en cada intento fallido), así que recomiendo lo siguiente:

  1. Abrir el archivo en un editor de texto (como Notepad)
  2. Buscar (automáticamente) primero la fecha de el último intento que se hizo con el siguiente formato: yyyy/mm/dd (ejemplo: 2011/04/30).
  3. Una vez localizada la línea de la fecha, buscar ahora el siguiente texto: Failed to find driver update

Esto debería llevar a una línea similar a la siguiente:

!!!  sto: Failed to find driver update ‘C:\Windows\WinSxS\amd64_usbvideo.inf_31bf3856ad364e35_6.1.7600.16543_none_8a1a2513d42628c3\usbvideo.inf’ in Driver Store. Error = 0x00000490

En dicha línea se puede ver el driver cuya carga está fallando y provocando el error en la actualización, así como su ruta completa. En el ejemplo de la línea, el dato que nos interesa es: C:\Windows\WinSxS\amd64_usbvideo.inf_31bf3856ad364e35_6.1.7600.16543_none_8a1a2513d42628c3\usbvideo.inf.

Esta clase de error podría existir para más de un driver, de modo que lo que sigue deberá hacerse con cada driver diferente. No confundir esto con el hecho de que este error puede aparecer con el mismo driver en repetidas ocasiones. Sólo hay que ejecutar la solución 1 vez para cada driver diferente.

Bien, sabiendo la ruta del driver causante de la falla, necesitamos abrir una ventana de Símbolo de sistema como administrador (dando click derecho en el ícono se puede elegir dicha opción). Una vez abierto, ejecutaremos el siguiente comando con la ruta que obtuvimos (en este caso uso la de mi ejemplo):

pnputil -a C:\Windows\WinSxS\amd64_usbvideo.inf_31bf3856ad364e35_6.1.7600.16543_none_8a1a2513d42628c3\usbvideo.inf

A continuación podría abrirse una ventana advirtiendo que el driver no tiene firma digital (y probablemente es la razón por la que no está cargado en la librería de drivers). Es necesario aceptar la instalación de dicho driver. La respuesta de pnputil entonces será algo como esto:

Microsoft PnP Utility
Processing inf :            usbvideo.inf
Driver package added successfully.
Published name :            oem32.inf
Total attempted:              1
Number successfully imported: 1

Hecho esto, intenté nuevamente la instalación de Serrvice Pack 1 y al reiniciar se completó exitosamente.

Espero que esta información le sea de utilidad a más de uno.

 

Desactivar y eliminar archivo de hibernación en Windows 7 y Windows Vista

Es común que la gente desee eliminar el archivo de hibernación en Windows. Es un archivo que llega a medir varios gigas y no es muy útil para quienes realmente no utilizan la función de hibernación. Este archivo normalmente está ligado en tamaño a la cantidad de memoria RAM del equipo. En mi caso, tengo 24 GB de memoria en mi PC de escritorio y tengo deshabilitado el uso de archivo de paginación. La hibernación por lo tanto, aunque me encanta utilizarla en mi laptop, en mi máquina de escritorio resulta muy lenta (el sistema manda a dicho archivo todo lo que se encuentre en memoria en ese momento). Tengo además muy buen equipo UPS (no-break) y puedo entrar en suspensión sin problemas por muy largo tiempo si llego a tener fallas de energía. Tengo además el sistema operativo en un SSD (disco duro de estado sólido) que no es muy grande y el resto de mis archivos en un Velociraptor de 600 GB a 10,000 RPM y el espacio que ocupaba en el SSD era simplemente un desperdicio de espacio.

En el caso de Windows XP, eliminar este archivo era tan simple como abrir la herramienta “Librador de espacio” y seleccionar entre sus opciones la eliminación de dicho archivo. Pero en Windows Vista y Windows 7 esa opción no aparece más en dicha herramienta. Pero no hay que temer, la solución es muy sencilla.

  1. Abre una ventana de Símbolo de sistema como administrador (dando click derecho en el ícono del programa puedes elegir esa opción).
  2. Ejecuta el siguiente comando: powercfg -h off

Hecho esto, la hibernación queda deshabilitada y el archivo se elimina automáticamente. Si en cualquier momento deseas activarla de nuevo y que el archivo aparezca nuevamente, sigue los mismos pasos, pero cambiando la palabra off por la palabra on.

Espero sea de ayuda a muchos. 🙂

Habilitar recursos compartidos (shares) administrativos en Windows 7

Esta es una de las situaciónes que más me frustró por un buen rato sobre Windows 7. Mucha gente está acostumbrada a compartir carpetas en red, compartiendo sólo la carpeta que desean compartir. Esto sigue siendo una fuincionalidad normal en Windows 7.

Pero para quienes no quieren compartir carpetas específicamente, o para los adminsitradores de red/equipos que necesitan acceder a cualquier punto de los discos duros sin importar si el usuario ha compartido o no una carpeta, están los recursos administrativos compartidos.

El problema con el que yo y muchos más se han encontrado, es el poder acceder a recursos administrativos compartidos. Esto es algo que hasta Windows Vista podía hacer sin mayor problema, pero que en Wiondows 7 parece estar limitado (gracias Microsoft) sólo para equipos que se encuentren dentro de un dominio de red. Para quienes no saben qué es esto, es la forma en la que un administrador de red puede acceder a todos los archivos de cualquier PC en la red. El formato es muy simple: \\NOMBRE_EQUIPO_O_IP\RECURSO$. Por ejemplo, si el equipo al que quiero entrar se llama “recepcion” y el disco que quiero leer es la unidad C, entonces lo hago con la siguiente ruta desde mi equipo: \\recepcion\c$. Esto me da acceso (siendo administrador y teniendo la contraseña de administrador) a todo lo que hay en el disco C de ese equipo.

Como siempre, hay trucos en el sistema que nos permiten habilitar funcionalidades bloqueadas. Lo que tuve que hacer después de investigar más al respecto, fue editar el registro. Es necesario ir a la siguiente ruta:

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System

Ahí, hay que crear una nueva llave  de tipo DWORD (de 32 bits, aún cuando tu sistema sea de 64 bits) con el nombre LocalAccountTokenFilterPolicy y el valor hexadecimal 1.

Hecho esto, sin necesidad de reiniciar, te permite acceder a este tipo de recursos tal como lo puedes hacer en Windows XP o Windows Vista.

A esto habría que agregar el revisar que “Compartir archivos e impresoras” esté habilitado en el Firewall de Windows.

Espero sea de ayuda a más de uno. 🙂

Time::Anytime

Este es un proyecto personal en Perl, que deseo compartir con quien desee participar. Me agradaría mucho ver que algo como esto es tomado por manos hispanoparlantes y llevado de forma exitosa a CPAN como tal.

La idea es muy simple: extender el rango de fechas de las funciones nativas localtime y gmtime, así como el conocido módulo Time::Local.

Mi idea es lograr que las funciones en cuestión funcionen sin ninguna otra limitación que el tamaño de dígitos manejables por el propio Perl. Esto quiere decir que la idea es que sea posible pasar como argumentos a localtime y gmtime tiempos mayores a 2147483647  (fecha dentro del año 2038, máximo valor admitido por perl en sistemas de 32 bits), así como tiempos en números negativos que permitan utilizar fechas menores a 1970.

Actualmente, el módulo es funcional, pero tiene algunos raros bugs que no he tenido mucho tiempo de analizar totalmente a fondo. Básicamente, se equivoca en ciertos momentos de fecha, casi siempre con error por 1 día. Es el mínimo de los casos y sólo sucede con fechas más allá de lo normal (ejemplo: fechas en 1814 o en 3023, años fuera del rango normal). Esos errores ocasionales ocurren básicamente cuando es mal calculado el ISDST o se agrega antes de tiempo un día extra a un año bisiesto (por ejemplo, durante algún loop que agrega el día extra antes de pasar por febrero).

Actualmente funciona bien (excepto por los raros momentos de error mínimo de tiempo). Es capaz de dar fechas en millones de años adelante y atrás de 1970. Cuando una fecha baja del año 1 (año -1, no existe el año cero), scalar localtime deja el año positivo y agrega un BC  al final, refiriéndose a años antes de Cristo.

 

Explicando la idea

La idea realmente es muy simple y no debería costar tanto trabajo, sólo cálculos bien pensados.  Estas son las bases:

1) Sólo existen 14 años diferentes. Todos los años son iguales a uno de esos 14 años: 7 normales y 7 bisiestos, cada uno comenzando en un día distinto de la semana. Basándose en esto, el módulo comienza por definir 14 fechas distintas que representan el inicio de un año entendible por CORE::localtime y posteriormente copia sus características modificando únicamente el año solicitado.

2) Para poder decidir qué tipo de año es un año en cuestión, hace falta saber qué año es basado únicamente en segundos, sean positivos o negativos.

3) Para poder decidir qué tipo de año es (una vez encontrado el año), es necesario saber en qué día de la semana comienza ese año.

4) Deben tenerse en cuenta en todos los cálculos, los años que tienen 366 días (bisiestos) y el momento en el que se está procesando una fecha (antes o después del posible febrero 29).

5) Una vez determinado el año de acuerdo a los segundos, y el día de la semana en que comienza el año, basta con tomar la fecha predefinida que tiene un año del mismo tipo (ya está definido en las variables del módulo) y pasarlo ya sea por CORE::localtime o CORE::gmtime para posteriormente cambiar el año por el que se pidió en la función original.

6) Están implementadas dentro del mismo módulo las funciones timelocal y timegm del módulo Time::Local. Procesan los datos de forma similar, calculando el tiempo sobre el tipo de año similar predefinido y posteriormente agregando o restando al valor de tiempo que se devolverá, el tiempo correspondiente al año que realmente se solicitó.

Instalación

Puedes descargar el módulo aquí:  Time::Anytime

Cualquier comentario, será bien recibido. Si deseas sólo probar el módulo, basta con que lo copies en la carpeta de módulos de tu instalación de Perl (ejemplo: /usr/site/lib/Time/Anytime.pm).

No está documentado aún. Pero una vez instalado, basta con poner lo siguiente en cualquier script:

#!/usr/bin/perl
use Time::Anytime;print scalar localtime(time) . “\n”;

my @localtime = localtime(60 * 60 * 24 * 365 * 3000); # Obtiene el año 3000

# Desde aquí podrás hacer uso normal de localtime, gmtime, timelocal y timegm:

print localtime; 

# Para obtener localtime de sistema sin pasar por este módulo (tal vez para comparar la salida):

@localtime = CORE::localtime(time);

 

Altamente bienvenidos los testers. Sólo pido por favor me informen de cualquier bug encontrado.

Altamente bienvenidos los colaboradores. Hace falta cualquier programador de Perl con buena experiencia y buenas prácticas de código.

Sé que será difícil encontrar respuestas a este proyecto; pero no imposible. Yo continuaré trabajando en el módulo para desaparecer en lo posible los márgenes de error que pueda tener.

Saludos. 🙂