Solved

struct dirent not reading proper file name

Posted on 2004-09-05
6
341 Views
Last Modified: 2010-04-15

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?
0
Comment
Question by:rohin1702
6 Comments
 
LVL 9

Expert Comment

by:ankuratvb
Comment Utility
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
0
 
LVL 46

Expert Comment

by:Sjef Bosman
Comment Utility
See other question http:Q_21119677

Ask for the removal and a refund on this question.
0
 
LVL 16

Expert Comment

by:PaulCaswell
Comment Utility
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
0
 
LVL 48

Expert Comment

by:AlexFM
Comment Utility
See GetShortPathName function.
0
 

Accepted Solution

by:
modulo earned 0 total points
Comment Utility
PAQed with points refunded (500)

modulo
Community Support Moderator
0

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use nested-loops in the C programming language.
The goal of this video is to provide viewers with basic examples to understand opening and reading files in the C programming language.

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now