Path to long

Ein Benutzer klagt darüber, dass er auf Dateien nicht zugreifen kann, die ein anderer Kollege erstellt hat.
Zugangsrechte sind vorhanden aber die Dateien können nicht geöffnet werden.
Grund:
Der erste Kollege hat die Dateien über ein separates Programm erstellt oder hat ein anderes Mapping verwendet.
Die Windowsshell hat (auch noch in W7) die Beschränkung, dass keine Dateien mit einem Pfadnamen länger als 255 Zeichen verwaltet werden können.
Windows und NTFS an sich haben diese Beschränkung nicht. Sie können bis 32767 Byte Pfadlänge verwalten.
Das Problem liegt darin , dass viele Programme (Explorer,Shell32.dll) noch alte Funktionen verwenden, die gegen die alten ANSI-Funktionen gelinkt sind.
Manche 3rdParty-Programme sind gegen UNICODE gelinkt und können deshalb weit längere Pfade verwalten.
Die lapidare Antwort von MS ist dann immer man soll sich tiefer in den Pfad einmappen und dann die Verzeichniss- und Dateinamen kürzen.
Um diese Leichen zu finden, kann dass beigefügte Programm benutzt werden nachdem es mit dem LCC-Compiler erstellt wurde.

(zum Löschen der Dateien siehe auch die Erweiterung : Delete all Files that Path are longer than 255... )

getLongPath.c
/*  Liste alle Pfade länger als 255 auf!
**  Kompilierung: lc getLongPath.c
**  getLongPath.exe -r -n H:\ 
**  siehe auch http://en.literateprograms.org/Directory_listing_%28C,_Windows%29
*/
#ifndef UNICODE
#define UNICODE
#endif
 
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <wchar.h>
#include <tchar.h>
 
//------------------------------------------------------------------------------
// Globals...
//------------------------------------------------------------------------------
WIN32_FIND_DATA *fd;
UINT i= 1;
#define LINUX_PATH 4096  // UNICODELänge sonst Pfad schnell zu kurz    32767
 
//------------------------------------------------------------------------------
int     showdir(WCHAR *path, BOOL recursive, BOOL nummerierung);
int     fixpath(WCHAR *inpath, WCHAR *outpath);
//------------------------------------------------------------------------------
// showdir()
//------------------------------------------------------------------------------
int showdir(TCHAR *_path,BOOL recursive,BOOL nummerierung)
{
  HANDLE fh;
 
  int    filecnt=0;
  int    length;
  TCHAR	 path[LINUX_PATH];
  TCHAR	 tmppath[LINUX_PATH];
  TCHAR	 pathlength[LINUX_PATH];
 
  fd = malloc(sizeof(WIN32_FIND_DATA));
 
  fixpath(_path,path);
  wcscat(path,L "*");
 
  fh = FindFirstFileW( path,fd);
 
  if(fh != INVALID_HANDLE_VALUE)
  {
    do
    {
      filecnt++;
      if(fd->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
      {
        if((0 != wcscmp(fd->cFileName,L".")) && (0 != wcscmp(fd->cFileName,L"..")))
        {
          fixpath(_path,tmppath);
          wcscat(tmppath,fd->cFileName);
          fixpath(tmppath,tmppath);
          if(recursive)
            showdir(tmppath,recursive,nummerierung);
        }
      }
      else
      {
       length = wsprintf(pathlength,L "%s%s",_path,fd->cFileName); //Pfadlänge ermitteln
       if  (length > 255){
        if(nummerierung)
          {wprintf(L "%d %d %s%s\n",i,length,_path,fd->cFileName) && i++;} 
        else  
          {wprintf(L "%d %s%s\n",length,_path,fd->cFileName) && i++;}
      }
     }
   }
    while(FindNextFile(fh,fd));
  }
 
  FindClose(fh);
 
  return 1;
}
//------------------------------------------------------------------------------
// fixpath() - Adds \ to the end of a path if not present.
//------------------------------------------------------------------------------
int fixpath(TCHAR *inpath, TCHAR *outpath)
{
  int   n=0;
 
  wcscpy(outpath,inpath);
 
  while(inpath[n]) n++;
 
  if(inpath[n-1] != '\\')
  {
    wcscat(outpath,L "\\");
    return 1;
  }
 
  return 0;
}
//------------------------------------------------------------------------------
// Entry point...
//------------------------------------------------------------------------------
int main(int argc, char *argv[])
{
  unsigned int recursive=0;
  unsigned int ndirs=0;
  unsigned int nummerierung=0; 
  TCHAR tPfad[LINUX_PATH];
 
  printf("Programm zut Anzeige von langen Pfaden auf NTFS-Dateisystemen : %s\n",argv[0]);
  printf("richard@borwinius.de / 2011\n\n");
  if((argc == 1) || (argc > 4) )
    {
    printf("Nutzung von : %s \n",argv[0]);
    printf("Schalter /n oder -n \t Anzeige einer fortlaufenden Nummerierung\n");
    printf("Schalter /r oder -r \t Anzeige rekursiv auch der Unterverzeichnisse\n");
    printf("Beispiel : %s -n -r h:\\meineDateien\\\n",argv[0]);
    printf("  oder   : %s -n -r \\\\meinUNCServer\\meineDateien\\\n",argv[0]);
    printf("Ausgabe: lfdNr. Pfadlänge LangerPfad\\datei.ext");
    return 1;
    }
 
  while(*++argv)
  {
    if(!strcmp(*argv,"-r") || !strcmp(*argv,"/r"))
      recursive=1;
    if(!strcmp(*argv,"-n") || !strcmp(*argv,"/n"))
      nummerierung=1;
    else
    {
      MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,*argv,-1,tPfad,LINUX_PATH); //Umwandlung von char in TCHAR
      showdir(tPfad, recursive,nummerierung);
      ++ndirs;
    }
  }
  if(!ndirs) showdir(L".", recursive,nummerierung);
 
  return 0;
}