win_file.cc 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. /********************************************************************** <BR>
  2. This file is part of Crack dot Com's free source code release of
  3. Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
  4. information about compiling & licensing issues visit this URL</a>
  5. <PRE> If that doesn't help, contact Jonathan Clark at
  6. golgotha_source@usa.net (Subject should have "GOLG" in it)
  7. ***********************************************************************/
  8. #include "file/file.hh"
  9. #include "memory/malloc.hh"
  10. #include "error/error.hh"
  11. #include "time/profile.hh"
  12. #include "error/error.hh"
  13. #include "file/buf_file.hh"
  14. #include "file/async.hh"
  15. #include "file/file_man.hh"
  16. #include "memory/array.hh"
  17. #include <windows.h>
  18. #include <stdio.h>
  19. #include <fcntl.h>
  20. #include <io.h>
  21. #include <sys/types.h>
  22. #include <sys/stat.h>
  23. #include <direct.h>
  24. #include "string/string.hh"
  25. i4_profile_class pf_win32_seek("Win32File::Seek");
  26. i4_profile_class pf_win32_read("Win32File::Read");
  27. i4_profile_class pf_win32_write("Win32File::Write");
  28. class i4_win32_async_reader : public i4_async_reader
  29. {
  30. public:
  31. i4_win32_async_reader(char *name) : i4_async_reader(name) {}
  32. virtual w32 read(sw32 fd, void *buffer, w32 count)
  33. {
  34. w32 res = _read(fd,buffer,count);
  35. return res;
  36. }
  37. } i4_win32_async_instance("hd_async_reader_2");
  38. ////////////////////////////////////////////////////////////////////////
  39. //
  40. // Normal Win32 File Class
  41. //
  42. class i4_win32_file_class : public i4_file_class
  43. {
  44. protected:
  45. w32 fd;
  46. public:
  47. i4_win32_file_class(w32 fd) : fd(fd) {}
  48. virtual w32 read (void *buffer, w32 size)
  49. {
  50. pf_win32_read.start();
  51. w32 res = _read(fd,buffer,size);
  52. pf_win32_read.stop();
  53. return res;
  54. }
  55. virtual w32 write(const void *buffer, w32 size)
  56. {
  57. pf_win32_write.start();
  58. w32 res = _write(fd,buffer,size);
  59. pf_win32_write.stop();
  60. return res;
  61. }
  62. virtual w32 seek (w32 offset)
  63. {
  64. pf_win32_seek.start();
  65. w32 res = lseek(fd, offset, SEEK_SET);
  66. pf_win32_seek.stop();
  67. return res;
  68. }
  69. virtual w32 size ()
  70. {
  71. w32 len = _filelength(fd);
  72. /*
  73. w32 cur = lseek(fd,0,SEEK_CUR);
  74. ] len = lseek(fd,0,SEEK_END);
  75. lseek(fd,cur,SEEK_SET);
  76. */
  77. return len;
  78. }
  79. virtual w32 tell ()
  80. {
  81. return _tell(fd);
  82. }
  83. ~i4_win32_file_class()
  84. {
  85. _close(fd);
  86. }
  87. // returns i4_F if an immediate error occured
  88. virtual i4_bool async_read (void *buffer, w32 size,
  89. async_callback call,
  90. void *context=0)
  91. {
  92. if (i4_threads_supported())
  93. return i4_win32_async_instance.start_read(fd, buffer, size, call, context);
  94. else
  95. call(read(buffer,size),context);
  96. return i4_T;
  97. }
  98. };
  99. ////////////////////////////////////////////////////////////////////////
  100. //
  101. // File Manager Methods
  102. //
  103. // see file/file.hh for a description of what each of these functions do
  104. class i4_win32_file_manager_class : public i4_file_manager_class
  105. {
  106. public:
  107. virtual i4_file_class *open(const i4_const_str &name, w32 flags)
  108. {
  109. sw32 f=0;
  110. i4_bool no_buffer=i4_F;
  111. flags &= ~I4_SUPPORT_ASYNC; // don't have to do anything special for these
  112. if (flags & I4_NO_BUFFER)
  113. {
  114. flags=(flags & (~I4_NO_BUFFER));
  115. no_buffer=i4_T;
  116. }
  117. f=O_BINARY; // open all files in binary mode
  118. char sbuf[256];
  119. switch (flags)
  120. {
  121. case I4_READ:
  122. f|=O_RDONLY;
  123. break;
  124. case I4_WRITE:
  125. f |= O_WRONLY | O_CREAT;
  126. _unlink(i4_os_string(name,sbuf,sizeof(sbuf)));
  127. break;
  128. case I4_WRITE|I4_READ:
  129. f |= O_RDWR | O_CREAT;
  130. _unlink(i4_os_string(name,sbuf,sizeof(sbuf)));
  131. break;
  132. case I4_APPEND:
  133. case I4_WRITE|I4_APPEND:
  134. f |= O_WRONLY|O_CREAT|O_APPEND;
  135. break;
  136. default:
  137. i4_warning("i4_file_class::Bad open flags!");
  138. return NULL;
  139. }
  140. int fd;
  141. fd=::_open(i4_os_string(name,sbuf,sizeof(sbuf)),f,_S_IREAD | _S_IWRITE);
  142. if (fd<0)
  143. {
  144. i4_warning("i4_file_class::open failed for %s\n",i4_os_string(name,sbuf,sizeof(sbuf)));
  145. return NULL;
  146. }
  147. i4_file_class *ret_fp;
  148. if (!no_buffer)
  149. ret_fp=new i4_buffered_file_class(new i4_win32_file_class(fd));
  150. else
  151. ret_fp=new i4_win32_file_class(fd);
  152. return ret_fp;
  153. }
  154. virtual i4_bool unlink(const i4_const_str &name)
  155. {
  156. char buf[256];
  157. return _unlink(i4_os_string(name,buf,sizeof(buf)))==0;
  158. }
  159. virtual i4_bool mkdir(const i4_const_str &name)
  160. {
  161. char buf[256];
  162. return ::_mkdir(i4_os_string(name,buf,sizeof(buf)))==0;
  163. }
  164. i4_bool get_status(const i4_const_str &filename, i4_file_status_struct &return_stat)
  165. {
  166. i4_bool error=i4_F;
  167. struct _stat times;
  168. char buf[256];
  169. return_stat.flags=0;
  170. if (_stat(i4_os_string(filename,buf,sizeof(buf)),&times)==0)
  171. {
  172. return_stat.last_modified=times.st_mtime;
  173. return_stat.last_accessed=times.st_atime;
  174. return_stat.created=times.st_ctime;
  175. if (times.st_mode & _S_IFDIR)
  176. return_stat.flags=I4_FILE_STATUS_DIRECTORY;
  177. }
  178. else
  179. error=i4_T;
  180. return (i4_bool)(!error);
  181. }
  182. virtual i4_bool get_directory(const i4_const_str &path,
  183. i4_directory_struct &dir_struct,
  184. i4_bool get_status,
  185. i4_status_class *status)
  186. {
  187. _finddata_t fdat;
  188. char os_str[255],buf[256];
  189. sprintf(os_str,"%s/*.*",i4_os_string(path,buf,sizeof(buf)));
  190. long handle=_findfirst(os_str,&fdat),done;
  191. if (handle==-1)
  192. return i4_F;
  193. i4_array<i4_file_status_struct> stats(64,64);
  194. do
  195. {
  196. if (fdat.attrib & _A_SUBDIR)
  197. {
  198. dir_struct.tdirs++;
  199. dir_struct.dirs=(i4_str **)i4_realloc(dir_struct.dirs,
  200. sizeof(i4_str *)*dir_struct.tdirs,"dir list");
  201. dir_struct.dirs[dir_struct.tdirs-1]=new i4_str(i4_const_str(fdat.name));
  202. }
  203. else
  204. {
  205. i4_file_status_struct *s=stats.add();
  206. s->last_accessed=fdat.time_access;
  207. s->last_modified=fdat.time_write;
  208. s->created=fdat.time_create;
  209. dir_struct.tfiles++;
  210. dir_struct.files=(i4_str **)i4_realloc(dir_struct.files,
  211. sizeof(i4_str *)*dir_struct.tfiles,"dir list");
  212. dir_struct.files[dir_struct.tfiles-1]=new i4_str(i4_const_str(fdat.name));
  213. }
  214. done=_findnext(handle, &fdat);
  215. } while (done!=-1);
  216. if (get_status)
  217. {
  218. if (dir_struct.tfiles)
  219. {
  220. i4_file_status_struct *sa;
  221. sa=(i4_file_status_struct *)i4_malloc(sizeof(i4_file_status_struct)*dir_struct.tfiles,"");
  222. for (int j=0; j<dir_struct.tfiles; j++)
  223. sa[j]=stats[j];
  224. dir_struct.file_status=sa;
  225. }
  226. }
  227. return i4_T;
  228. }
  229. virtual i4_str *full_path(const i4_const_str &relative_name)
  230. {
  231. char buf[256], buf2[256];
  232. ::_fullpath(i4_os_string(relative_name, buf, 256), buf2, 256);
  233. return new i4_str(i4_const_str(buf2));
  234. }
  235. i4_win32_file_manager_class()
  236. {
  237. i4_add_file_manager(this, i4_F);
  238. }
  239. ~i4_win32_file_manager_class()
  240. {
  241. i4_remove_file_manger(this);
  242. }
  243. } i4_win32_file_man;
  244. i4_bool i4_rmdir(const i4_const_str &path)
  245. {
  246. char p[256];
  247. i4_os_string(path, p, 256);
  248. if (_rmdir(p)==0)
  249. return i4_T;
  250. else return i4_F;
  251. }
  252. i4_bool i4_chdir(const i4_const_str &path)
  253. {
  254. char p[256];
  255. i4_os_string(path, p, 256);
  256. if (_chdir(p)==0)
  257. return i4_T;
  258. else return i4_F;
  259. }