158 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			158 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
** 2015 November 30
 | 
						|
**
 | 
						|
** The author disclaims copyright to this source code.  In place of
 | 
						|
** a legal notice, here is a blessing:
 | 
						|
**
 | 
						|
**    May you do good and not evil.
 | 
						|
**    May you find forgiveness for yourself and forgive others.
 | 
						|
**    May you share freely, never taking more than you give.
 | 
						|
**
 | 
						|
*************************************************************************
 | 
						|
** This file contains code to implement most of the opendir() family of
 | 
						|
** POSIX functions on Win32 using the MSVCRT.
 | 
						|
*/
 | 
						|
 | 
						|
#if defined(_WIN32) && defined(_MSC_VER)
 | 
						|
 | 
						|
#include "test_windirent.h"
 | 
						|
 | 
						|
/*
 | 
						|
** Implementation of the POSIX opendir() function using the MSVCRT.
 | 
						|
*/
 | 
						|
LPDIR opendir(
 | 
						|
  const char *dirname
 | 
						|
){
 | 
						|
  struct _finddata_t data;
 | 
						|
  LPDIR dirp = (LPDIR)sqlite3_malloc(sizeof(DIR));
 | 
						|
  SIZE_T namesize = sizeof(data.name) / sizeof(data.name[0]);
 | 
						|
 | 
						|
  if( dirp==NULL ) return NULL;
 | 
						|
  memset(dirp, 0, sizeof(DIR));
 | 
						|
 | 
						|
  /* TODO: Remove this if Unix-style root paths are not used. */
 | 
						|
  if( sqlite3_stricmp(dirname, "/")==0 ){
 | 
						|
    dirname = getenv("SystemDrive");
 | 
						|
  }
 | 
						|
 | 
						|
  _snprintf(data.name, namesize, "%s\\*", dirname);
 | 
						|
  dirp->d_handle = _findfirst(data.name, &data);
 | 
						|
 | 
						|
  if( dirp->d_handle==BAD_INTPTR_T ){
 | 
						|
    closedir(dirp);
 | 
						|
    return NULL;
 | 
						|
  }
 | 
						|
 | 
						|
  /* TODO: Remove this block to allow hidden and system files. */
 | 
						|
  if( data.attrib&_A_HIDDEN || data.attrib&_A_SYSTEM ){
 | 
						|
    if( _findnext(dirp->d_handle, &data)==-1 ){
 | 
						|
      closedir(dirp);
 | 
						|
      return NULL;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  dirp->d_first.d_attributes = data.attrib;
 | 
						|
  strncpy(dirp->d_first.d_name, data.name, NAME_MAX);
 | 
						|
  dirp->d_first.d_name[NAME_MAX] = '\0';
 | 
						|
 | 
						|
  return dirp;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
** Implementation of the POSIX readdir() function using the MSVCRT.
 | 
						|
*/
 | 
						|
LPDIRENT readdir(
 | 
						|
  LPDIR dirp
 | 
						|
){
 | 
						|
  struct _finddata_t data;
 | 
						|
 | 
						|
  if( dirp==NULL ) return NULL;
 | 
						|
 | 
						|
  if( dirp->d_first.d_ino==0 ){
 | 
						|
    dirp->d_first.d_ino++;
 | 
						|
    dirp->d_next.d_ino++;
 | 
						|
 | 
						|
    return &dirp->d_first;
 | 
						|
  }
 | 
						|
 | 
						|
next:
 | 
						|
 | 
						|
  if( _findnext(dirp->d_handle, &data)==-1 ) return NULL;
 | 
						|
 | 
						|
  /* TODO: Remove this block to allow hidden and system files. */
 | 
						|
  if( data.attrib&_A_HIDDEN ) goto next;
 | 
						|
  if( data.attrib&_A_SYSTEM ) goto next;
 | 
						|
 | 
						|
  dirp->d_next.d_ino++;
 | 
						|
  dirp->d_next.d_attributes = data.attrib;
 | 
						|
  strncpy(dirp->d_next.d_name, data.name, NAME_MAX);
 | 
						|
  dirp->d_next.d_name[NAME_MAX] = '\0';
 | 
						|
 | 
						|
  return &dirp->d_next;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
** Implementation of the POSIX readdir_r() function using the MSVCRT.
 | 
						|
*/
 | 
						|
INT readdir_r(
 | 
						|
  LPDIR dirp,
 | 
						|
  LPDIRENT entry,
 | 
						|
  LPDIRENT *result
 | 
						|
){
 | 
						|
  struct _finddata_t data;
 | 
						|
 | 
						|
  if( dirp==NULL ) return EBADF;
 | 
						|
 | 
						|
  if( dirp->d_first.d_ino==0 ){
 | 
						|
    dirp->d_first.d_ino++;
 | 
						|
    dirp->d_next.d_ino++;
 | 
						|
 | 
						|
    entry->d_ino = dirp->d_first.d_ino;
 | 
						|
    entry->d_attributes = dirp->d_first.d_attributes;
 | 
						|
    strncpy(entry->d_name, dirp->d_first.d_name, NAME_MAX);
 | 
						|
    entry->d_name[NAME_MAX] = '\0';
 | 
						|
 | 
						|
    *result = entry;
 | 
						|
    return 0;
 | 
						|
  }
 | 
						|
 | 
						|
next:
 | 
						|
 | 
						|
  if( _findnext(dirp->d_handle, &data)==-1 ){
 | 
						|
    *result = NULL;
 | 
						|
    return ENOENT;
 | 
						|
  }
 | 
						|
 | 
						|
  /* TODO: Remove this block to allow hidden and system files. */
 | 
						|
  if( data.attrib&_A_HIDDEN ) goto next;
 | 
						|
  if( data.attrib&_A_SYSTEM ) goto next;
 | 
						|
 | 
						|
  entry->d_ino = (ino_t)-1; /* not available */
 | 
						|
  entry->d_attributes = data.attrib;
 | 
						|
  strncpy(entry->d_name, data.name, NAME_MAX);
 | 
						|
  entry->d_name[NAME_MAX] = '\0';
 | 
						|
 | 
						|
  *result = entry;
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
** Implementation of the POSIX closedir() function using the MSVCRT.
 | 
						|
*/
 | 
						|
INT closedir(
 | 
						|
  LPDIR dirp
 | 
						|
){
 | 
						|
  INT result = 0;
 | 
						|
 | 
						|
  if( dirp==NULL ) return EINVAL;
 | 
						|
 | 
						|
  if( dirp->d_handle!=NULL_INTPTR_T && dirp->d_handle!=BAD_INTPTR_T ){
 | 
						|
    result = _findclose(dirp->d_handle);
 | 
						|
  }
 | 
						|
 | 
						|
  sqlite3_free(dirp);
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
#endif /* defined(WIN32) && defined(_MSC_VER) */
 |