Link to home
Start Free TrialLog in
Avatar of rohin1702
rohin1702

asked on

struct dirent not reading proper file name


hi..
i am using struct dirent to  search for a given file in a directory.the trouble is that if the name of the file is LP36-3_27FP.phd.1 it is reading it as LP-3~1.1 (and some are taking hexadecimal value) and hence strcmpi is not working.Can anyone help me solve my problem?
Avatar of ankuratvb
ankuratvb
Flag of United States of America image

Yeah.struct dirent reads in the dos filenames.

What compiler are you on?

You could try system("dir/b >>dir.txt"); if on windows platform.

and read from that text file.One filename on one line.

dir/b gives you the bare filenames without the size etc. details and i redirect the output to a file dir.txt
Avatar of Sjef Bosman
See other question http:Q_21119677

Ask for the removal and a refund on this question.
This is clearly Windoze. Are you running as a DOS only tool or full Win32?

Under Win32 you can use FindFirstFile etc. Under DOS you can use the equivalent under assembly:

// Windows structures for long file name handling.
#ifndef WIN32
// Look for '714e' in MSDN to find the descriptions.
typedef struct FILETIME
{
      ulong dwLowDateTime;
      ulong dwHighDateTime;
}FILETIME;

typedef struct WIN32_FIND_DATA
{
      ulong            dwFileAttributes;
      FILETIME      ftCreationTime;
      FILETIME      ftLastAccessTime;
      FILETIME      ftLastWriteTime;
      ulong            nFileSizeHigh;
      ulong            nFileSizeLow;
      ulong            dwReserved0;
      ulong            dwReserved1;
      char            cFileName[ _MAX_PATH ];
      char            cAlternateFileName[ 14 ];
} WIN32_FIND_DATA;

// The possible file attributes (from WINNT.H).
#define FILE_ATTRIBUTE_READONLY         0x00000001
#define FILE_ATTRIBUTE_HIDDEN           0x00000002
#define FILE_ATTRIBUTE_SYSTEM           0x00000004
#define FILE_ATTRIBUTE_DIRECTORY        0x00000010
#define FILE_ATTRIBUTE_ARCHIVE          0x00000020
#define FILE_ATTRIBUTE_NORMAL           0x00000080
#define FILE_ATTRIBUTE_TEMPORARY        0x00000100

#endif

// The windows (long names) versions;
static unsigned WIN_findfirst(const char * name, unsigned flags, WildFindT * found, long * handle);
static unsigned WIN_findnext(WildFindT * found, long * handle);
static void WIN_findclose(long handle);

// Translate the long found structure into the short.
void WIN_TranslateFileDetails ( WIN32_FIND_DATA * longFound, WildFindT * found);
// Get the short version of a long file name.
void WIN_ShortName ( char * longName, char * shortName );

// The windows (long names) versions;
unsigned WIN_findfirst(const char * name, unsigned flags, WildFindT * found, long * handle)
{
      WIN32_FIND_DATA longFound;
      bool noMore = true;

#ifdef WIN32
      *handle = (long)FindFirstFile ( name, &longFound );

      if ( *handle != -1 )
      {
            // Fill in the found structure.
            WIN_TranslateFileDetails ( &longFound, found );
            noMore = false;
#ifdef _DEBUG
            Finds += 1;
//            TFPRINT(("WIN_findfirst '%s'->'%s' (%d) [%d]", name, longFound.cFileName, outregs.x.ax, Finds));
//            DBG(Finds);
#endif
      }
#else
      WIN32_FIND_DATA far * farFound = &longFound;
      char far * farName = (char far *)name;
      union  REGS inregs, outregs;
      struct SREGS segregs;

/*
mov ax, 714Eh             ; Find First File
mov ch, MustMatchAttrs    ; see below
mov cl, SearchAttrs       ; see below
mov dx, seg Filename      ; see below
mov ds, dx
mov dx, offset Filename
mov di, seg FindData      ; see below
mov es, di
mov di, offset FindData
mov si, DateTimeFormat    ; see below
int 21h

jc  error
mov [Handle], ax          ; search handle
mov [ConversionCode], cx  ; Unicode to OEM/ANSI conversion OK?

*/
       // Start them clear.
      Clear (inregs);
      Clear (segregs);
      // Setup the parameters.
      inregs.x.ax = 0x714E;            // Find First File
      inregs.h.ch = 0;                  // Match all.
      inregs.h.cl = (uchar)flags;

      segregs.ds  = FP_SEG( farName );
      inregs.x.dx  = FP_OFF( farName );
      segregs.es  = FP_SEG( farFound );
      inregs.x.di  = FP_OFF( farFound );
      inregs.x.si  = 1;                  // Date/Time format
      
      intdosx( &inregs, &outregs, &segregs );      // DoIt
      
      if ( outregs.x.cflag == 0 )
      {
            // Fill in the found structure.
            WIN_TranslateFileDetails ( &longFound, found );
            // Save the handle.
            *handle = outregs.x.ax;
            noMore = false;
#ifdef _DEBUG
            Finds += 1;
//            TFPRINT(("WIN_findfirst '%s'->'%s' (%d) [%d]", name, longFound.cFileName, outregs.x.ax, Finds));
//            DBG(Finds);
#endif
      }
#endif

      return ( noMore );
}

// The windows (long names) versions;
unsigned WIN_findnext(WildFindT * found, long * handle)
{
      WIN32_FIND_DATA longFound;
      bool noMore = true;

#ifdef WIN32
      if ( FindNextFile ( (HANDLE)*handle, &longFound ) )
      {
            // Fill in the found structure.
            WIN_TranslateFileDetails ( &longFound, found );
            noMore = false;
      }
      else
      {
            // Done with that one.
            WIN_findclose(*handle);
            // Fill in an invalid handle.
            *handle = 0;
      }
#else
      union  REGS inregs, outregs;
      struct SREGS segregs;
      WIN32_FIND_DATA far * farFound = &longFound;

/*
mov ax, 714Fh            ; Find Next File
mov bx, Handle           ; see below
mov di, seg FindData     ; see below
mov es, di
mov di, offset FindData
mov si, DateTimeFormat   ; see below
int 21h

jc error
mov [ConversionCode], cx  ; Unicode to OEM/ANSI conversion OK?
*/
       // Start them clear.
      Clear (inregs);
      Clear (segregs);
      // Setup the parameters.
      inregs.x.ax = 0x714F;            // Find First File
      inregs.x.bx = (ushort)*handle;            // The handle.
      segregs.es  = FP_SEG( farFound );
      inregs.x.di  = FP_OFF( farFound );
      inregs.x.si  = 1;                  // Date/Time format
      
      intdosx( &inregs, &outregs, &segregs );      // DoIt
      
      if ( outregs.x.cflag == 0 )
      {
//            TFPRINT(("\tWIN_findnext -> '%s' (%d)", longFound.cFileName, *handle ));
            // Fill in the found structure.
            WIN_TranslateFileDetails ( &longFound, found );
            noMore = false;
      }
      else
      {
            // Done with that one.
            WIN_findclose(*handle);
            // Fill in an invalid handle.
            *handle = 0;
      }
#endif

      return ( noMore );
}

// The windows (long names) versions;
void WIN_findclose(long handle)
{
#ifdef WIN32
      FindClose ((HANDLE)handle);
#else
      union  REGS inregs, outregs;
/*
mov ax, 71A1h   ; Find Close
mov bx, Handle  ; see below
int 21h
*/
      if ( handle != 0 )
      {
             // Start them clear.
            Clear (inregs);
            // Setup the parameters.
            inregs.x.ax = 0x71A1;            // Find close
            inregs.x.bx = (ushort)handle;            // The handle.
            intdos( &inregs, &outregs );      // DoIt
#ifdef _DEBUG
            Finds -= 1;
//            TFPRINT(("WIN_findclose (%d) [%d]", handle, Finds));
//            DBG(Finds);
#endif
      }
      else
      {
            TFPRINT(("WIN_findclose BAD!!!"));
      }
#endif
}

// Get the short version of a long file name.
void WIN_ShortName ( char * longName, char * shortName )
{
#ifdef WIN32
      GetShortPathName( longName, shortName, _MAX_PATH );
#else
      union  REGS inregs, outregs;
      struct SREGS segregs;
      char far * farName = longName;
      char far * farShortName = shortName;
/*
mov ax, 7160h
mov cl, 1                  ; Get Short Path Name
mov ch, SubstExpand        ; see below
mov si, seg SourcePath     ; see below
mov ds, si
mov si, offset SourcePath
mov di, seg DestPath       ; see below
mov es, di
mov di, offset DestPath
int 21h
jc  error
*/
       // Start them clear.
      Clear (inregs);
      Clear (segregs);
      // Setup the parameters.
      inregs.x.ax = 0x7160;            // Get Short Path Name
      inregs.h.ch = 0x80;                  // Dont translate SUBST.
      inregs.h.cl = 1;                  // Get Short Path Name (subcode)
      segregs.ds  = FP_SEG( farName );
      inregs.x.si  = FP_OFF( farName );
      segregs.es  = FP_SEG( farShortName );
      inregs.x.di  = FP_OFF( farShortName );

      intdosx( &inregs, &outregs, &segregs );      // DoIt

      if ( outregs.x.cflag != 0 )
      {
            // Bad!
            shortName[0] = '\0';
      }
#endif
}

// Are long names available?
static bool LongNamesAvailable ( void )
{
#ifdef WIN32
      return true;
#else
      bool available = true;
      // First check dos version (must be >= 7.1).
      int dosVer = bdos( 0x30, 0, 0 );
      int major = dosVer & 0xff;
      int minor = dosVer >> 8;

      // Dos version must be >= 7.1
      if ( major < 7 || ( major == 7 && minor < 1 ) )
      {
            // NO!
            available = false;
      }

/*
      Later use 71a0 too.
      union  REGS inregs, outregs;

  But not like this!!! This is dangerous!
  _asm {
         mov  ax,71A0h
        int  21h
        mov  [OurError],al
  }
*/
      return available;
#endif
}

// Translate the long found structure into the short.
void WIN_TranslateFileDetails ( WIN32_FIND_DATA * longFound, WildFindT * found)
{
      //struct tm time;
      // Translate the attributes.
      found->attrib = (char)(longFound->dwFileAttributes & 0xff);

      // Translate the date and time.
      found->wr_date = (ushort)(longFound->ftLastWriteTime.dwLowDateTime >> 16);
      found->wr_time = (ushort)(longFound->ftLastWriteTime.dwLowDateTime & 0xffffL);

      // The file size.
      if ( longFound->nFileSizeHigh == 0 )
      {
            // Give them the low file size.
            found->size = longFound->nFileSizeLow;
      }
      else
      {
            // Give them max.
            found->size = 0x7fffffffL;
      }
      // The name.
      strcpy ( found->name, longFound->cFileName );
}

// Find the first/next file.
bool FindFile ( bool first, Wild * stack, bool longNames, int findFlags )
{
      bool noMore = true;

#ifndef WIN32
      if ( longNames )
      {
#endif
            // Windows one ( if we can ).
            noMore = (first ? WIN_findfirst( stack->fullName,
                                                                  findFlags,
                                                                  &stack->search[stack->depth].found,
                                                                  &stack->search[stack->depth].handle):
                                    WIN_findnext( &stack->search[stack->depth].found,
                                                            &stack->search[stack->depth].handle)) != 0;
#ifndef WIN32
      }
      else
      {
            // Normal DOS one.
            noMore = (first ? _dos_findfirst( stack->fullName,
                                                                  findFlags,
                                                                  (struct find_t *)&stack->search[stack->depth].found ):
                                    _dos_findnext( (struct find_t *)&stack->search[stack->depth].found )) != 0;
            // Short name is same as long name.
            strcpy ( stack->search[stack->depth].found.shortName,
                              stack->search[stack->depth].found.name );
      }
#endif
      return noMore;
}

Sorry but there is more code here than I intended but I hope some of it is of use. Note that this process will still not work under NT ore XP or 2K. Only the standard 32bit calls will work there as this functionality is provided by DLLs which are not available under dos. It will work fine under 95/98/Me.

Paul
Avatar of AlexFM
AlexFM

See GetShortPathName function.
ASKER CERTIFIED SOLUTION
Avatar of modulo
modulo

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial