예제 #1
0
파일: hbfsapi.c 프로젝트: jiangxilong/core
HB_BOOL hb_fsOS2QueryPathInfo( const char * pszPathName,
                               HB_FOFFSET * pnSize, HB_FATTR * pnAttr,
                               long * plJulian, long * plMillisec )
{
   HDIR hdirFindHandle = HDIR_CREATE;
   HB_FILEFINDBUF3L findBuffer;
   ULONG ulFindCount = 1;
   char * pszFree;
   APIRET ret;
   HB_BOOL fIsWSeB = hb_isWSeB();

   pszPathName = hb_fsNameConv( pszPathName, &pszFree );
   ret = DosFindFirst( ( PCSZ ) pszPathName, &hdirFindHandle,
                       FILE_ARCHIVED | FILE_DIRECTORY |
                       FILE_SYSTEM | FILE_HIDDEN | FILE_READONLY,
                       &findBuffer, sizeof( findBuffer ), &ulFindCount,
                       fIsWSeB ? FIL_STANDARDL : FIL_STANDARD );
   hb_fsSetError( ( HB_ERRCODE ) ret );
   if( hdirFindHandle != HDIR_CREATE )
      DosFindClose( hdirFindHandle );
   if( pszFree )
      hb_xfree( pszFree );

   if( ret == NO_ERROR )
   {
      if( fIsWSeB )
      {
         if( pnSize )
            *pnSize = ( HB_FOFFSET ) findBuffer.ffbl.cbFile;
         if( pnAttr )
            *pnAttr = hb_fsAttrFromRaw( ( HB_FATTR ) findBuffer.ffbl.attrFile );
         if( plJulian )
            *plJulian = hb_dateEncode( findBuffer.ffbl.fdateLastWrite.year + 1980,
                                       findBuffer.ffbl.fdateLastWrite.month,
                                       findBuffer.ffbl.fdateLastWrite.day );
         if( plMillisec )
            *plMillisec = hb_timeEncode( findBuffer.ffbl.ftimeLastWrite.hours,
                                         findBuffer.ffbl.ftimeLastWrite.minutes,
                                         findBuffer.ffbl.ftimeLastWrite.twosecs * 2, 0 );
      }
      else
      {
         if( pnSize )
            *pnSize = ( HB_FOFFSET ) findBuffer.ffb.cbFile;
         if( pnAttr )
            *pnAttr = hb_fsAttrFromRaw( ( HB_FATTR ) findBuffer.ffb.attrFile );
         if( plJulian )
            *plJulian = hb_dateEncode( findBuffer.ffb.fdateLastWrite.year + 1980,
                                       findBuffer.ffb.fdateLastWrite.month,
                                       findBuffer.ffb.fdateLastWrite.day );
         if( plMillisec )
            *plMillisec = hb_timeEncode( findBuffer.ffb.ftimeLastWrite.hours,
                                         findBuffer.ffb.ftimeLastWrite.minutes,
                                         findBuffer.ffb.ftimeLastWrite.twosecs * 2, 0 );
      }
      return HB_TRUE;
   }
   return HB_FALSE;
}
예제 #2
0
파일: hbffind.c 프로젝트: jiangxilong/core
static HB_BOOL hb_fsFindNextLow( PHB_FFIND ffind )
{
   HB_BOOL bFound;

   int iYear  = 0;
   int iMonth = 0;
   int iDay   = 0;

   int iHour = 0;
   int iMin  = 0;
   int iSec  = 0;
   int iMSec = 0;

   HB_FATTR raw_attr = 0, nAttr = 0;

   /* Set the default values in case some platforms don't
      support some of these, or they may fail on them. */

   ffind->szName[ 0 ] = '\0';
   ffind->size = 0;

   /* Do platform dependant first/next search */

   hb_vmUnlock();

#if defined( HB_OS_DOS )

   {
      PHB_FFIND_INFO info = ( PHB_FFIND_INFO ) ffind->info;

      /* Handling HB_FA_LABEL doesn't need any special tricks
         under the MS-DOS platform. */

      if( ffind->bFirst )
      {
         ffind->bFirst = HB_FALSE;

         /* tzset(); */

#if defined( __WATCOMC__ )
         bFound = ( _dos_findfirst( ffind->pszFileMask, ( HB_USHORT ) hb_fsAttrToRaw( ffind->attrmask ), &info->entry ) == 0 );
#else
         bFound = ( findfirst( ffind->pszFileMask, &info->entry, ( HB_USHORT ) hb_fsAttrToRaw( ffind->attrmask ) ) == 0 );
#endif
      }
      else
      {
#if defined( __WATCOMC__ )
         bFound = ( _dos_findnext( &info->entry ) == 0 );
#else
         bFound = ( findnext( &info->entry ) == 0 );
#endif
      }

      /* Fill Harbour found file info */

      if( bFound )
      {
         hb_strncpy( ffind->szName, info->entry.ff_name, sizeof( ffind->szName ) - 1 );
         ffind->size = info->entry.ff_fsize;

         raw_attr = info->entry.ff_attrib;

         {
            time_t ftime;
            struct tm * ft;
            struct stat sStat;

            stat( info->entry.ff_name, &sStat );

            ftime = sStat.st_mtime;
            ft = localtime( &ftime );

            iYear  = ft->tm_year + 1900;
            iMonth = ft->tm_mon + 1;
            iDay   = ft->tm_mday;

            iHour  = ft->tm_hour;
            iMin   = ft->tm_min;
            iSec   = ft->tm_sec;
         }
      }
      hb_fsSetIOError( bFound, 0 );
   }

#elif defined( HB_OS_OS2 )

   {
      #define HB_OS2_DIRCNT   16

      PHB_FFIND_INFO info = ( PHB_FFIND_INFO ) ffind->info;
      APIRET ret = NO_ERROR;

      /* TODO: HB_FA_LABEL handling */

      if( ffind->bFirst )
      {
         ffind->bFirst = HB_FALSE;

         info->isWSeB = hb_isWSeB();

         info->findSize = sizeof( FILEFINDBUF3L );
         if( info->findSize & 0x07 )
            info->findSize += 0x08 - ( info->findSize & 0x07 );
         info->findSize *= HB_OS2_DIRCNT;
         if( info->findSize > 0xF000 )
            info->findSize = 0xF000;
         info->findInitCnt = ! info->isWSeB ? info->findSize / 32 : HB_OS2_DIRCNT;

         info->hFindFile = HDIR_CREATE;
         info->findCount = info->findInitCnt;
         ret = DosAllocMem( &info->entry, info->findSize, OBJ_TILE | PAG_COMMIT | PAG_WRITE );
         if( ret == NO_ERROR )
         {
            ret = DosFindFirst( ( PCSZ ) ffind->pszFileMask,
                                &info->hFindFile,
                                ( ULONG ) hb_fsAttrToRaw( ffind->attrmask ),
                                info->entry,
                                info->findSize,
                                &info->findCount,
                                FIL_STANDARDL );
            bFound = ret == NO_ERROR && info->findCount > 0;
            if( bFound )
               info->next = info->entry;
         }
         else
         {
            info->entry = NULL;
            bFound = HB_FALSE;
         }
      }
      else if( info->findCount == 0 )
      {
         info->findCount = info->findInitCnt;
         ret = DosFindNext( info->hFindFile,
                            info->entry,
                            info->findSize,
                            &info->findCount );
         bFound = ret == NO_ERROR && info->findCount > 0;
         if( bFound )
            info->next = info->entry;
      }
      else
         bFound = HB_TRUE;

      if( bFound )
      {
         ULONG oNextEntryOffset;

         if( info->isWSeB )
         {
            PFILEFINDBUF3L pFFB = ( PFILEFINDBUF3L ) info->next;

            hb_strncpy( ffind->szName, pFFB->achName, sizeof( ffind->szName ) - 1 );
            ffind->size = ( HB_FOFFSET ) pFFB->cbFile;
            raw_attr = pFFB->attrFile;

            iYear  = pFFB->fdateLastWrite.year + 1980;
            iMonth = pFFB->fdateLastWrite.month;
            iDay   = pFFB->fdateLastWrite.day;

            iHour = pFFB->ftimeLastWrite.hours;
            iMin  = pFFB->ftimeLastWrite.minutes;
            iSec  = pFFB->ftimeLastWrite.twosecs * 2;

            oNextEntryOffset = pFFB->oNextEntryOffset;
         }
         else
         {
            PFILEFINDBUF3 pFFB = ( PFILEFINDBUF3 ) info->next;

            hb_strncpy( ffind->szName, pFFB->achName, sizeof( ffind->szName ) - 1 );
            ffind->size = ( HB_FOFFSET ) pFFB->cbFile;
            raw_attr = pFFB->attrFile;

            iYear  = pFFB->fdateLastWrite.year + 1980;
            iMonth = pFFB->fdateLastWrite.month;
            iDay   = pFFB->fdateLastWrite.day;

            iHour = pFFB->ftimeLastWrite.hours;
            iMin  = pFFB->ftimeLastWrite.minutes;
            iSec  = pFFB->ftimeLastWrite.twosecs * 2;

            oNextEntryOffset = pFFB->oNextEntryOffset;
         }

         if( oNextEntryOffset > 0 )
         {
            info->next = ( char * ) info->next + oNextEntryOffset;
            info->findCount--;
         }
         else
            info->findCount = 0;
      }

      hb_fsSetError( ( HB_ERRCODE ) ret );
   }

#elif defined( HB_OS_WIN )

   {
      PHB_FFIND_INFO info = ( PHB_FFIND_INFO ) ffind->info;

      bFound = HB_FALSE;

#if ! defined( HB_OS_WIN_CE )
      if( ( ffind->attrmask & HB_FA_LABEL ) != 0 && ! info->fLabelDone )
      {
         TCHAR lpVolName[ HB_PATH_MAX ];
         LPTSTR lpFileMask = NULL;
         char * mask = NULL;

         info->fLabelDone = HB_TRUE;

         if( ffind->pszFileMask && *ffind->pszFileMask )
         {
            PHB_FNAME pFileName = hb_fsFNameSplit( ffind->pszFileMask );
            if( pFileName->szName && pFileName->szName[ 0 ] )
               mask = hb_strdup( pFileName->szName );
            if( pFileName->szPath && pFileName->szPath[ 0 ] &&
                ( pFileName->szPath[ 1 ] ||
                  pFileName->szPath[ 0 ] != HB_OS_PATH_DELIM_CHR ) )
               lpFileMask = HB_CHARDUP( pFileName->szPath );
            hb_xfree( pFileName );
         }
         bFound = GetVolumeInformation( lpFileMask, lpVolName,
                                        HB_SIZEOFARRAY( lpVolName ),
                                        NULL, NULL, NULL, NULL, 0 ) != 0;
         if( bFound )
         {
            HB_OSSTRDUP2( lpVolName, ffind->szName, sizeof( ffind->szName ) - 1 );
            if( mask && *mask && ! hb_strMatchFile( ffind->szName, mask ) )
            {
               ffind->szName[ 0 ] = '\0';
               bFound = HB_FALSE;
            }
         }
         if( lpFileMask )
            hb_xfree( lpFileMask );
         if( mask )
            hb_xfree( mask );
      }
#endif

      if( ! bFound &&
          ( ffind->attrmask & ( HB_FA_LABEL | HB_FA_HIDDEN | HB_FA_SYSTEM |
                                HB_FA_DIRECTORY ) ) != HB_FA_LABEL )
      {
         if( ffind->bFirst )
         {
            LPTSTR lpFileMask = HB_CHARDUP( ffind->pszFileMask );
            ffind->bFirst = HB_FALSE;
            info->dwAttr    = ( DWORD ) hb_fsAttrToRaw( ffind->attrmask );
            info->hFindFile = FindFirstFile( lpFileMask, &info->pFindFileData );
            hb_xfree( lpFileMask );

            if( ( info->hFindFile != INVALID_HANDLE_VALUE ) && _HB_WIN_MATCH() )
               bFound = HB_TRUE;
         }

         if( ! bFound && info->hFindFile != INVALID_HANDLE_VALUE )
         {
            while( FindNextFile( info->hFindFile, &info->pFindFileData ) )
            {
               if( _HB_WIN_MATCH() )
               {
                  bFound = HB_TRUE;
                  break;
               }
            }
         }

         /* Fill Harbour found file info */

         if( bFound )
         {
            HB_OSSTRDUP2( info->pFindFileData.cFileName, ffind->szName, sizeof( ffind->szName ) - 1 );

            if( info->pFindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
               ffind->size = 0;
            else
            {
#if defined( __XCC__ ) || ( defined( __POCC__ ) && __POCC__ >= 500 )
               /* NOTE: PellesC 5.00.1 will go into an infinite loop if we don't
                        split this into two operations. [vszakats] */
               ffind->size  = ( HB_FOFFSET ) info->pFindFileData.nFileSizeLow;
               ffind->size += ( HB_FOFFSET ) info->pFindFileData.nFileSizeHigh << 32;
#else
               ffind->size = ( HB_FOFFSET ) info->pFindFileData.nFileSizeLow +
                           ( ( HB_FOFFSET ) info->pFindFileData.nFileSizeHigh << 32 );
#endif
            }

            raw_attr = ( HB_FATTR ) info->pFindFileData.dwFileAttributes;

            /* NOTE: One of these may fail when searching on an UNC path, I
                     don't know yet what's the reason. [vszakats] */

            {
               FILETIME ft;
               SYSTEMTIME time;

               if( FileTimeToLocalFileTime( &info->pFindFileData.ftLastWriteTime, &ft ) &&
                   FileTimeToSystemTime( &ft, &time ) )
               {
                  iYear  = time.wYear;
                  iMonth = time.wMonth;
                  iDay   = time.wDay;
                  iHour  = time.wHour;
                  iMin   = time.wMinute;
                  iSec   = time.wSecond;
                  iMSec  = time.wMilliseconds;
               }
            }
         }
      }
      hb_fsSetIOError( bFound, 0 );
   }

#elif defined( HB_OS_UNIX )

   {
      PHB_FFIND_INFO info = ( PHB_FFIND_INFO ) ffind->info;

      char dirname[ HB_PATH_MAX ];

      bFound = HB_FALSE;

      /* TODO: HB_FA_LABEL handling */

      if( ffind->bFirst )
      {
         char * pos;

         ffind->bFirst = HB_FALSE;

         hb_strncpy( dirname, ffind->pszFileMask, sizeof( dirname ) - 1 );
         pos = strrchr( dirname, HB_OS_PATH_DELIM_CHR );
         if( pos )
         {
            hb_strncpy( info->pattern, pos + 1, sizeof( info->pattern ) - 1 );
            *( pos + 1 ) = '\0';
         }
         else
         {
            hb_strncpy( info->pattern, dirname, sizeof( info->pattern ) - 1 );
            dirname[ 0 ] = '.';
            dirname[ 1 ] = HB_OS_PATH_DELIM_CHR;
            dirname[ 2 ] = '\0';
         }

         /* tzset(); */

         info->dir = opendir( dirname );
         hb_strncpy( info->path, dirname, sizeof( info->path ) - 1 );
      }

      if( info->dir && info->pattern[ 0 ] != '\0' )
      {
         while( ( info->entry = readdir( info->dir ) ) != NULL )
         {
            if( hb_strMatchFile( info->entry->d_name, info->pattern ) )
            {
               bFound = HB_TRUE;
               break;
            }
         }
      }

      /* Fill Harbour found file info */
      if( bFound )
      {
         hb_strncpy( dirname, info->path, sizeof( dirname ) - 1 );
         hb_strncat( dirname, info->entry->d_name, sizeof( dirname ) - 1 );
         {
            time_t ftime;
            struct tm lt;
#if defined( HB_USE_LARGEFILE64 )
            struct stat64 sStat, sStatL;
            if( lstat64( dirname, &sStat ) == 0 )
            {
               if( S_ISLNK( sStat.st_mode ) && ( ffind->attrmask & HB_FA_LINK ) == 0 )
               {
                  if( stat64( dirname, &sStatL ) == 0 )
                     memcpy( &sStat, &sStatL, sizeof( sStat ) );
                  nAttr |= HB_FA_LINK;
               }
#else
            struct stat sStat, sStatL;
            if( lstat( dirname, &sStat ) == 0 )
            {
               if( S_ISLNK( sStat.st_mode ) && ( ffind->attrmask & HB_FA_LINK ) == 0 )
               {
                  if( stat( dirname, &sStatL ) == 0 )
                     memcpy( &sStat, &sStatL, sizeof( sStat ) );
                  nAttr |= HB_FA_LINK;
               }
#endif
               hb_strncpy( ffind->szName, info->entry->d_name, sizeof( ffind->szName ) - 1 );
               ffind->size = sStat.st_size;

               raw_attr = sStat.st_mode;

               ftime = sStat.st_mtime;
#  if defined( HB_HAS_LOCALTIME_R )
               localtime_r( &ftime, &lt );
#  else
               lt = *localtime( &ftime );
#  endif

               iYear  = lt.tm_year + 1900;
               iMonth = lt.tm_mon + 1;
               iDay   = lt.tm_mday;

               iHour = lt.tm_hour;
               iMin  = lt.tm_min;
               iSec  = lt.tm_sec;

#  if defined( HB_OS_LINUX ) && \
      defined( __GLIBC__ ) && defined( __GLIBC_MINOR__ ) && \
      ( __GLIBC__ > 2 || ( __GLIBC__ == 2 && __GLIBC_MINOR__ >= 6 ) )
#     if defined( _BSD_SOURCE ) || defined( _SVID_SOURCE ) || \
         ( __GLIBC_MINOR__ >= 12 && \
           ( ( defined( _POSIX_C_SOURCE ) || _POSIX_C_SOURCE >= 200809L ) || \
             ( defined( _XOPEN_SOURCE ) || _XOPEN_SOURCE >= 700 ) ) )
               iMSec = sStat.st_mtim.tv_nsec / 1000000;
#     else
               iMSec = sStat.st_mtimensec / 1000000;
#     endif
#  endif
            }
            else
               bFound = HB_FALSE;
         }
      }
      hb_fsSetIOError( bFound, 0 );
   }

#else

   {
      int iTODO; /* TODO: for given platform */

      /* HB_SYMBOL_UNUSED( ffind ); */

      HB_SYMBOL_UNUSED( iYear );
      HB_SYMBOL_UNUSED( iMonth );
      HB_SYMBOL_UNUSED( iDay );
      HB_SYMBOL_UNUSED( iHour );
      HB_SYMBOL_UNUSED( iMin );
      HB_SYMBOL_UNUSED( iSec );
      HB_SYMBOL_UNUSED( iMSec );
      HB_SYMBOL_UNUSED( raw_attr );

      bFound = HB_FALSE;

      hb_fsSetIOError( bFound, 0 );
   }

#endif

   /* Fill common Harbour found file info */

   if( bFound )
   {
      /* Do the conversions common for all platforms */
      ffind->szName[ sizeof( ffind->szName ) - 1 ] = '\0';

#if ! defined( HB_OS_WIN )
      /* Convert from OS codepage */
      {
         char * pszFree = NULL;
         HB_SIZE nSize = sizeof( ffind->szName );
         const char * pszResult = hb_osDecodeCP( ffind->szName, &pszFree, &nSize );

         if( pszFree )
         {
            hb_strncpy( ffind->szName, pszResult, sizeof( ffind->szName ) - 1 );
            hb_xfree( pszFree );
         }
      }
#endif
      ffind->attr = hb_fsAttrFromRaw( raw_attr ) | nAttr;

      ffind->lDate = hb_dateEncode( iYear, iMonth, iDay );
      ffind->lTime = hb_timeEncode( iHour, iMin, iSec, iMSec );
      hb_dateStrPut( ffind->szDate, iYear, iMonth, iDay );
      ffind->szDate[ 8 ] = '\0';

      hb_snprintf( ffind->szTime, sizeof( ffind->szTime ), "%02d:%02d:%02d", iHour, iMin, iSec );
   }
   hb_vmLock();

   return bFound;
}

PHB_FFIND hb_fsFindFirst( const char * pszFileMask, HB_FATTR attrmask )
{
   PHB_FFIND ffind = ( PHB_FFIND ) hb_xgrabz( sizeof( HB_FFIND ) );

   /* Allocate platform dependent file find info storage */
   ffind->info = ( void * ) hb_xgrabz( sizeof( HB_FFIND_INFO ) );

   /* Store search parameters */
#if defined( HB_OS_WIN )
   ffind->pszFileMask = pszFileMask;
#else
   /* Convert to OS codepage */
   ffind->pszFileMask = hb_fsNameConv( pszFileMask, &ffind->pszFree );
#endif
   ffind->attrmask = attrmask;
   ffind->bFirst = HB_TRUE;

   /* Find first/next matching file */

   if( hb_fsFindNext( ffind ) )
      return ffind;

   /* If no file found at all, free stuff allocated so far and return NULL. */

   hb_fsFindClose( ffind );

   return NULL;
}
예제 #3
0
파일: filestat.c 프로젝트: xharbour/core
static BOOL hb_fsFileStats(
   BYTE * pszFileName,
   BYTE * pszAttr,
   HB_FOFFSET * llSize,
   LONG * lcDate,
   LONG * lcTime,
   LONG * lmDate,
   LONG * lmTime )
{
   BOOL fResult = FALSE;

#if defined( HB_OS_UNIX )

   struct stat statbuf;

   if( stat( ( char * ) pszFileName, &statbuf ) == 0 )
   {
      // determine if we can read/write/execute the file
      USHORT      usAttr, ushbAttr = 0;
      time_t      ftime;
#if _POSIX_C_SOURCE >= 199506L
      struct tm   tms;
#endif
      struct tm * ptms;

      /* See which attribs are applicable */
      if( statbuf.st_uid == geteuid() )
      {
         usAttr =
            ( ( statbuf.st_mode & S_IRUSR ) ? 1 << 2 : 0 ) |
            ( ( statbuf.st_mode & S_IWUSR ) ? 1 << 1 : 0 ) |
            ( ( statbuf.st_mode & S_IXUSR ) ? 1 : 0 );
      }
      else if( statbuf.st_gid == getegid() )
      {
         usAttr =
            ( ( statbuf.st_mode & S_IRGRP ) ? 1 << 2 : 0 ) |
            ( ( statbuf.st_mode & S_IWGRP ) ? 1 << 1 : 0 ) |
            ( ( statbuf.st_mode & S_IXGRP ) ? 1 : 0 );
      }
      else
      {
         usAttr =
            ( ( statbuf.st_mode & S_IROTH ) ? 1 << 2 : 0 ) |
            ( ( statbuf.st_mode & S_IWOTH ) ? 1 << 1 : 0 ) |
            ( ( statbuf.st_mode & S_IXOTH ) ? 1 : 0 );
      }

      /* Standard characters */
      if( ( usAttr & 4 ) == 0 ) /* Hidden (can't read)*/
         ushbAttr |= HB_FA_HIDDEN;

      if( ( usAttr & 2 ) == 0 ) /* read only (can't write)*/
         ushbAttr |= HB_FA_READONLY;

      if( ( usAttr & 1 ) == 1 ) /* executable?  (xbit)*/
         ushbAttr |= HB_FA_SYSTEM;

      /* Extension characters */

      if( ( statbuf.st_mode & S_IFLNK ) == S_IFLNK )
         *pszAttr++ = 'Z';  /* Xharbour extension */

      if( ( statbuf.st_mode & S_IFSOCK ) == S_IFSOCK )
         *pszAttr++ = 'K';  /* Xharbour extension */

      /* device */
      if( ( statbuf.st_mode & S_IFBLK ) == S_IFBLK ||
          ( statbuf.st_mode & S_IFCHR ) == S_IFCHR )
         ushbAttr |= HB_FA_DEVICE;  /* Xharbour extension */

      if( ( statbuf.st_mode & S_IFIFO ) == S_IFIFO )
         *pszAttr++ = 'Y';  /* Xharbour extension */

      if( S_ISDIR( statbuf.st_mode ) )
         ushbAttr |= HB_FA_DIRECTORY;  /* Xharbour extension */
      /* Give the ARCHIVE if readwrite, not executable and not special */
      else if( S_ISREG( statbuf.st_mode ) && ushbAttr == 0 )
         ushbAttr |= HB_FA_ARCHIVE;

      *llSize  = ( HB_FOFFSET ) statbuf.st_size;

      ftime    = statbuf.st_mtime;
#if _POSIX_C_SOURCE >= 199506L && ! defined( HB_OS_DARWIN_5 )
      ptms     = localtime_r( &ftime, &tms );
#else
      ptms     = localtime( &ftime );
#endif

      *lcDate  = hb_dateEncode( ptms->tm_year + 1900,
                                ptms->tm_mon + 1, ptms->tm_mday );
      *lcTime  = ptms->tm_hour * 3600 + ptms->tm_min * 60 + ptms->tm_sec;

      ftime    = statbuf.st_atime;
#if _POSIX_C_SOURCE >= 199506L && ! defined( HB_OS_DARWIN_5 )
      ptms     = localtime_r( &ftime, &tms );
#else
      ptms     = localtime( &ftime );
#endif
      *lmDate  = hb_dateEncode( ptms->tm_year + 1900,
                                ptms->tm_mon + 1, ptms->tm_mday );
      *lmTime  = ptms->tm_hour * 3600 + ptms->tm_min * 60 + ptms->tm_sec;

      hb_fsAttrDecode( ushbAttr, ( char * ) pszAttr );

      fResult = TRUE;
   }

#elif defined( HB_OS_WIN )

   {
      DWORD             dwAttribs;
      WIN32_FIND_DATAA  ffind;
      HANDLE            hFind;
      FILETIME          filetime;
      SYSTEMTIME        time;

      /* Get attributes... */
      dwAttribs = GetFileAttributesA( ( char * ) pszFileName );
      if( dwAttribs == INVALID_FILE_ATTRIBUTES )
      {
         /* return */
         return FALSE;
      }

      hb_fsAttrDecode( hb_fsAttrFromRaw( dwAttribs ), ( char * ) pszAttr );

      /* If file existed, do a findfirst */
      hFind = FindFirstFileA( ( char * ) pszFileName, &ffind );
      if( hFind != INVALID_HANDLE_VALUE )
      {
         FindClose( hFind );

         /* get file times and work them out */
         *llSize = ( HB_FOFFSET ) ffind.nFileSizeLow + ( ( HB_FOFFSET ) ffind.nFileSizeHigh << 32 );

         if( FileTimeToLocalFileTime( &ffind.ftCreationTime, &filetime ) &&
             FileTimeToSystemTime( &filetime, &time ) )
         {
            *lcDate  = hb_dateEncode( time.wYear, time.wMonth, time.wDay );
            *lcTime  = time.wHour * 3600 + time.wMinute * 60 + time.wSecond;
         }
         else
         {
            *lcDate  = hb_dateEncode( 0, 0, 0 );
            *lcTime  = 0;
         }

         if( FileTimeToLocalFileTime( &ffind.ftLastAccessTime, &filetime ) &&
             FileTimeToSystemTime( &filetime, &time ) )
         {
            *lmDate  = hb_dateEncode( time.wYear, time.wMonth, time.wDay );
            *lmTime  = time.wHour * 3600 + time.wMinute * 60 + time.wSecond;
         }
         else
         {
            *lcDate  = hb_dateEncode( 0, 0, 0 );
            *lcTime  = 0;
         }
         fResult = TRUE;
      }
   }

#else

   /* Generic algorithm based on findfirst */
   {
      PHB_FFIND findinfo = hb_fsFindFirst( ( char * ) pszFileName, HB_FA_ALL );

      if( findinfo )
      {
         hb_fsAttrDecode( findinfo->attr, ( char * ) pszAttr );
         *llSize  = ( HB_FOFFSET ) findinfo->size;
         *lcDate  = findinfo->lDate;
         *lcTime  = ( findinfo->szTime[ 0 ] - '0' ) * 36000 +
                    ( findinfo->szTime[ 1 ] - '0' ) * 3600 +
                    ( findinfo->szTime[ 3 ] - '0' ) * 600 +
                    ( findinfo->szTime[ 4 ] - '0' ) * 60 +
                    ( findinfo->szTime[ 6 ] - '0' ) * 10 +
                    ( findinfo->szTime[ 7 ] - '0' );
         *lmDate  = hb_dateEncode( 0, 0, 0 );
         *lmTime  = 0;
         hb_fsFindClose( findinfo );
         fResult  = TRUE;
      }
   }

#endif

   hb_fsSetIOError( fResult, 0 );
   return fResult;
}