Cosas que no puedes hacer en Windows: Tener PATHs de más de 256 caracteres

Existe la creencia de que Windows no soporta paths de más de 256 caracteres. Esta limitación está heredada de versiones anteriores en las que los sistemas de ficheros no permitían direccionar rutas más largas. Recordemos también que MS-DOS imponía la limitación del nombre de fichero a 8 caracteres más 3 de extensión. Por cierto, de ahí viene también la creencia de que Windows no soporta extensiones de más de 3 caracteres.

Por convenio los path en Windows no pueden superar los 260 caracteres (sí, 260, no 256). Esto puede encontrarse en la documentación de las APIs. Sin embargo, esta limitación está impuesta por la API de Win32 y no por el sistema de ficheros NTFS, que sí soporta paths de mayor longitud.

La mayoría de las aplicaciones Windows respetan el convenio de nomenclatura, lo que significa que un PATH no puede exceder los 260 caracteres y cada componente del Path tampoco puede superar los 260 caracteres. Ahora bien, hemos dicho que la limitación es un convenio que impone la API Win32. Esto no significa que no se puedan crear paths de mayor longitud, simplemente que está desaconsejado.

Algunas APIs Win32 incorporan un sistema para eliminar esta restricción. Es el caso de CreateDirectory. Con el siguiente ejemplo vamos a crear la ruta C:\<200Caracteres>\<200 Caracteres>\<200 Caracteres>.<3 caracteres>. Eso es un Path de 608 caracteres (excluyendo el marcador NULL). He parado en 608 porque me estaba haciendo un lio al copiar y pegar, pero podríamos llegar a 32767 caracteres sin despeinarnos :)

int _tmain(int argc, _TCHAR* argv[])
{
	CreateDirectory(TEXT("\\\\?\\C:\\TestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTest"),NULL);
	CreateDirectory(TEXT("\\\\?\\C:\\TestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTest\\TestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTest"),NULL);
	CreateFile(TEXT("\\\\?\\C:\\TestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTest\\TestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTest\\TestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTest.txt"),GENERIC_WRITE,0,NULL,CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
	return 0;
}

El vudú se consigue anteponiendo \\?\ al path. De esta forma le decimos a la API de Win32 que no nos imponga el límite de los 260 caracteres. Los inconvenientes que tiene esto es que todas las herramientas que se acojan al convenio de los 260 caracteres podrían no funcionar o comportarse de forma extraña con estos paths.

Un ejemplo es la inconsistencia dentro de la propia Shell de Windows. Cuando se encuentre con nuestra ruta, la visualizará adecuadamente y podremos editar nuestro fichero de texto con, digamos, Notepad, que también soporta estas rutas. Sin embargo, si copiamos la ruta que nos da Explorer, veremos que es algo así: C:\TESTTE~1\TestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTest

Es decir, 213 caracteres. El primer directorio lo acorta usando el formato MS-DOS (siempre que esté activado en Windows). Esto evita problemas a programas que no soporten paths largos.

Si intentásemos listar nuestro fichero en PowerShell, nos encontraríamos con un problemilla, ya que no soporta rutas largas y nos daría este error:

path too long

¿Por qué PowerShell no puede ver rutas largas? Porque está en .NET y sin hacer magia negra (que sí, se puede) las aplicaciones .NET no soportan paths fuera de la convención de 260 caracteres. El motivo es simple… Win32 no está pensado para paths fuera de convención y .NET se apoya en Win32.

Anteponiendo \\?\ a un path, no sólo estamos diciéndole a Win32 que elimine la restricción de 260 caracteres, sino que estamos haciendo que se envíe casi sin control al sistema de ficheros. ¿Os imagináis crear un directorio llamado C:\CON\CON? Es un nombre ilegal en Windows y la Shell nunca os permitirá crearlo pero… ¿podemos?

int _tmain(int argc, _TCHAR* argv[])
{
	CreateDirectory(TEXT("\\\\?\\C:\\CON"),NULL);
	CreateDirectory(TEXT("\\\\?\\C:\\CON\\CON"),NULL);
	return 0;
}

Esto nos crea un bollo importante, porque la Shell no nos va a dejar acceder:

SHELL CON

CMD no va a dejarnos tampoco:

CMD CON

PowerShell ni probamos porque es .NET. ¿Qué podemos hacer? Sorprendentemente RMDIR si soporta estas rutas, así que nos lo podemos cargar con “rmdir /s /q \\.\C:\CON”


rmdir con

Conclusión

El sistema de ficheros de Windows sí soporta paths de más de 260 caracteres y sí pueden usarse. Sin embargo, muchas herramientas y algunas APIs de Windows no se comportan adecuadamente con rutas largas, por lo que se recomienda evitarlas.

En general sólo suelen utilizarse rutas de más de 260 caracteres cuando estamos interoperando con otros SSOO donde estas rutas son comunes. Las herramientas destinadas para estos entornos, como podría ser una copia de un servidor remoto con RoboCopy, se comportan adecuadamente.

Poder, se puede… pero asegúrate de que las herramientas que uses estén preparadas ;)

About the Author

Me llamo Pablo Carballude González, soy graduado en computación con master en HCI y Seguridad Informática. Actualmente trabajo para Amazon en Seattle como Software Developer Engineer. Soy de esas personas que no saben si los textos autobiográficos deben ser en primera o tercera persona. Lo intenté en segunda, pero no le entendí nada :P