file_win32.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:9k
源码类别:

Windows CE

开发平台:

C/C++

  1. /*****************************************************************************
  2.  *
  3.  * This program is free software ; you can redistribute it and/or modify
  4.  * it under the terms of the GNU General Public License as published by
  5.  * the Free Software Foundation; either version 2 of the License, or
  6.  * (at your option) any later version.
  7.  *
  8.  * This program is distributed in the hope that it will be useful,
  9.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11.  * GNU General Public License for more details.
  12.  *
  13.  * You should have received a copy of the GNU General Public License
  14.  * along with this program; if not, write to the Free Software
  15.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  16.  *
  17.  * $Id: file_win32.c 543 2006-01-07 22:06:24Z picard $
  18.  *
  19.  * The Core Pocket Media Player
  20.  * Copyright (c) 2004-2005 Gabor Kovacs
  21.  *
  22.  ****************************************************************************/
  23. #include "../common.h"
  24. #if defined(TARGET_WIN32) || defined(TARGET_WINCE)
  25. #ifndef STRICT
  26. #define STRICT
  27. #endif
  28. #define WIN32_LEAN_AND_MEAN
  29. #include <windows.h>
  30. #ifndef ERROR_INVALID_DRIVE_OBJECT
  31. #define ERROR_INVALID_DRIVE_OBJECT 4321L
  32. #endif
  33. #ifndef ERROR_DEVICE_NOT_AVAILABLE
  34. #define ERROR_DEVICE_NOT_AVAILABLE 4319L
  35. #endif
  36. #ifndef ERROR_DEVICE_REMOVED
  37. #define ERROR_DEVICE_REMOVED            1617L
  38. #endif
  39. typedef struct filestream
  40. {
  41. stream Stream;
  42. tchar_t URL[MAXPATH];
  43. HANDLE Handle;
  44. filepos_t Length;
  45. filepos_t Pos;
  46. bool_t Silent;
  47. bool_t Create;
  48. HANDLE Find;
  49. const tchar_t* Exts;
  50. bool_t ExtFilter;
  51. WIN32_FIND_DATA FindData;
  52. } filestream;
  53. static int Get(filestream* p, int No, void* Data, int Size)
  54. {
  55. int Result = ERR_INVALID_PARAM;
  56. switch (No)
  57. {
  58. case STREAM_URL: GETSTRING(p->URL); break;
  59. case STREAM_SILENT: GETVALUE(p->Silent,bool_t); break;
  60. case STREAM_LENGTH: GETVALUECOND(p->Length,int,p->Length>=0); break;
  61. case STREAM_CREATE: GETVALUE(p->Create,bool_t); break;
  62. }
  63. return Result;
  64. }
  65. static int Open(filestream* p, const tchar_t* URL, bool_t ReOpen)
  66. {
  67. if (p->Handle)
  68. CloseHandle(p->Handle);
  69. p->Handle = 0;
  70. p->Length = -1;
  71. if (!ReOpen)
  72. p->URL[0] = 0;
  73. else
  74. Sleep(200);
  75. if (URL && URL[0])
  76. {
  77. HANDLE Handle;
  78. Handle = CreateFile(URL,p->Create?GENERIC_WRITE:GENERIC_READ,
  79. FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,p->Create?CREATE_ALWAYS:OPEN_EXISTING,
  80. FILE_ATTRIBUTE_NORMAL,NULL);
  81. if (Handle == INVALID_HANDLE_VALUE)
  82. {
  83. if (!ReOpen && !p->Silent)
  84. ShowError(0,ERR_ID,ERR_FILE_NOT_FOUND,URL);
  85. return ERR_FILE_NOT_FOUND;
  86. }
  87. tcscpy_s(p->URL,TSIZEOF(p->URL),URL);
  88. p->Handle = Handle;
  89. p->Length = GetFileSize(Handle,NULL);
  90. if (ReOpen)
  91. p->Pos = SetFilePointer(p->Handle,p->Pos,NULL,FILE_BEGIN);
  92. else
  93. {
  94. p->Pos = 0;
  95. #if defined(TARGET_WINCE)
  96. // wince shortcut handling
  97. if (p->Length < MAXPATH && !p->Create)
  98. {
  99. uint32_t Readed;
  100. char ShortCut[MAXPATH];
  101. tchar_t URL[MAXPATH];
  102. char* ch;
  103. if (ReadFile(p->Handle,ShortCut,p->Length,&Readed,NULL))
  104. {
  105. ShortCut[Readed] = 0;
  106. for (ch=ShortCut;*ch && *ch!='#';++ch)
  107. if (!IsDigit(*ch))
  108. break;
  109. if (ch[0] == '#' && ch[1]!=':')
  110. {
  111. char* Head = ++ch;
  112. char* Tail;
  113. if (*ch == '"')
  114. {
  115. Head++;
  116. ch = strchr(ch+1,'"');
  117. if (ch)
  118. *(ch++) = 0;
  119. }
  120. if (ch)
  121. {
  122. Tail = strchr(ch,13);
  123. if (Tail)
  124. {
  125. *Tail = 0;
  126. ch = Tail+1;
  127. }
  128. if (!strchr(ch,13))
  129. {
  130. ch = strchr(ch,10);
  131. if (!ch || !strchr(ch+1,10))
  132. {
  133. if (ch) *ch = 0;
  134. StrToTcs(URL,TSIZEOF(URL),Head);
  135. return Open(p,URL,0);
  136. }
  137. }
  138. }
  139. }
  140. p->Pos = SetFilePointer(p->Handle,0,NULL,FILE_BEGIN);
  141. }
  142. }
  143. #endif
  144. }
  145. }
  146. return ERR_NONE;
  147. }
  148. static int Set(filestream* p, int No, const void* Data, int Size)
  149. {
  150. int Result = ERR_INVALID_PARAM;
  151. switch (No)
  152. {
  153. case STREAM_SILENT: SETVALUE(p->Silent,bool_t,ERR_NONE); break;
  154. case STREAM_CREATE: SETVALUE(p->Create,bool_t,ERR_NONE); break;
  155. case STREAM_URL:
  156. Result = Open(p,(const tchar_t*)Data,0);
  157. break;
  158. }
  159. return Result;
  160. }
  161. static int Read(filestream* p,void* Data,int Size)
  162. {
  163. uint32_t Readed;
  164. DWORD Error;
  165. //Sleep(100); 
  166. //DEBUG_MSG3(-1,"FileRead: %08x %08x %d",p->Pos,SetFilePointer(p->Handle,0,NULL,FILE_CURRENT),Size);
  167. if (ReadFile(p->Handle,Data,Size,&Readed,NULL))
  168. {
  169. //DEBUG_MSG2(T("READ pos:%d len:%d"),p->Pos,Readed);
  170. p->Pos += Readed;
  171. return Readed;
  172. }
  173. Error = GetLastError();
  174. //DEBUG_MSG2(T("READ pos:%d error:%d"),p->Pos,Error);
  175. if (Error == ERROR_DEVICE_REMOVED || 
  176. Error == ERROR_DEVICE_NOT_AVAILABLE ||
  177. Error == ERROR_INVALID_HANDLE || 
  178. Error == ERROR_INVALID_DRIVE_OBJECT ||
  179. Error == ERROR_DEV_NOT_EXIST ||
  180. Error == ERROR_GEN_FAILURE)
  181. Open(p,p->URL,1);
  182. return -1;
  183. }
  184. static int ReadBlock(filestream* p,block* Block,int Ofs,int Size)
  185. {
  186. return Read(p,(char*)(Block->Ptr+Ofs),Size);
  187. }
  188. static int Seek(filestream* p,int Pos,int SeekMode)
  189. {
  190. int ReTry=3;
  191. int Result;
  192. DWORD Error;
  193. switch (SeekMode)
  194. {
  195. default:
  196. case SEEK_SET: SeekMode = FILE_BEGIN; break;
  197. case SEEK_CUR: SeekMode = FILE_CURRENT; break;
  198. case SEEK_END: SeekMode = FILE_END; break;
  199. }
  200. do
  201. {
  202. //DEBUG_MSG3(-1,"FileSeek: %08x %08x %d",SetFilePointer(p->Handle,0,NULL,FILE_CURRENT),Pos,SeekMode);
  203. Result = SetFilePointer(p->Handle,Pos,NULL,SeekMode);
  204. if (Result != -1)
  205. {
  206. p->Pos = Result;
  207. break;
  208. }
  209. Error = GetLastError();
  210. if (Error != ERROR_DEVICE_REMOVED && Error != ERROR_INVALID_HANDLE)
  211. break;
  212. Open(p,p->URL,1);
  213. }
  214. while (--ReTry>0);
  215. return Result;
  216. }
  217. static int Write(filestream* p,const void* Data,int Size)
  218. {
  219. DWORD Written;
  220. if (WriteFile(p->Handle,Data,Size,&Written,NULL))
  221. {
  222. p->Pos += Written;
  223. return Written;
  224. }
  225. return -1;
  226. }
  227. static int EnumDir(filestream* p,const tchar_t* URL,const tchar_t* Exts,bool_t ExtFilter,streamdir* Item)
  228. {
  229. if (URL)
  230. {
  231. DWORD Attrib;
  232. tchar_t Path[MAXPATH];
  233. p->Exts = Exts;
  234. p->ExtFilter = ExtFilter;
  235. if (p->Find != INVALID_HANDLE_VALUE)
  236. {
  237. FindClose(p->Find);
  238. p->Find = INVALID_HANDLE_VALUE;
  239. }
  240. stprintf_s(Path,TSIZEOF(Path),T("%s\*.*"),URL);
  241. Attrib = GetFileAttributes(URL);
  242. if (URL[0] && Attrib == (DWORD)-1)
  243. return ERR_FILE_NOT_FOUND;
  244. if (!(Attrib & FILE_ATTRIBUTE_DIRECTORY))
  245. return ERR_NOT_DIRECTORY;
  246. p->Find = FindFirstFile(Path, &p->FindData);
  247. }
  248. Item->FileName[0] = 0;
  249. Item->DisplayName[0] = 0;
  250. while (!Item->FileName[0] && p->Find != INVALID_HANDLE_VALUE)
  251. {
  252. if (p->FindData.cFileName[0]!='.') // skip unix/mac hidden files and . .. directory entries
  253. {
  254. FILETIME Local;
  255. tcscpy_s(Item->FileName,TSIZEOF(Item->FileName),p->FindData.cFileName);
  256. if (FileTimeToLocalFileTime(&p->FindData.ftLastWriteTime,&Local))
  257. Item->Date = ((int64_t)Local.dwHighDateTime << 32)|Local.dwLowDateTime;
  258. else
  259. Item->Date = -1;
  260. if (p->FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
  261. Item->Size = -1;
  262. else
  263. {
  264. Item->Size = p->FindData.nFileSizeLow;
  265. Item->Type = CheckExts(Item->FileName,p->Exts);
  266. if (!Item->Type && p->ExtFilter)
  267. Item->FileName[0] = 0; // skip
  268. }
  269. }
  270. if (!FindNextFile(p->Find,&p->FindData))
  271. {
  272. FindClose(p->Find);
  273. p->Find = INVALID_HANDLE_VALUE;
  274. }
  275. }
  276. if (!Item->FileName[0])
  277. {
  278. if (p->Find != INVALID_HANDLE_VALUE)
  279. {
  280. FindClose(p->Find);
  281. p->Find = INVALID_HANDLE_VALUE;
  282. }
  283. return ERR_END_OF_FILE;
  284. }
  285. return ERR_NONE;
  286. }
  287. static int Create(filestream* p)
  288. {
  289. p->Stream.Get = (nodeget)Get,
  290. p->Stream.Set = (nodeset)Set,
  291. p->Stream.Read = Read;
  292. p->Stream.ReadBlock = ReadBlock;
  293. p->Stream.Write = Write;
  294. p->Stream.Seek = Seek;
  295. p->Stream.EnumDir = EnumDir;
  296. p->Find = INVALID_HANDLE_VALUE;
  297. return ERR_NONE;
  298. }
  299. static void Delete(filestream* p)
  300. {
  301. Open(p,NULL,0);
  302. if (p->Find != INVALID_HANDLE_VALUE)
  303. FindClose(p->Find);
  304. }
  305. static const nodedef File =
  306. {
  307. sizeof(filestream),
  308. FILE_ID,
  309. STREAM_CLASS,
  310. PRI_MINIMUM,
  311. (nodecreate)Create,
  312. (nodedelete)Delete,
  313. };
  314. void File_Init()
  315. {
  316. NodeRegisterClass(&File);
  317. }
  318. void File_Done()
  319. {
  320. NodeUnRegisterClass(FILE_ID);
  321. }
  322. stream* FileCreate(const tchar_t* Path)
  323. {
  324. // create fake stream
  325. filestream* p = (filestream*)malloc(sizeof(filestream));
  326. memset(p,0,sizeof(filestream));
  327. p->Stream.Class = FILE_ID;
  328. p->Stream.Enum = (nodeenum)StreamEnum;
  329. Create(p);
  330. return &p->Stream;
  331. }
  332. void FileRelease(stream* p)
  333. {
  334. if (p)
  335. {
  336. Delete((filestream*)p);
  337. free(p);
  338. }
  339. }
  340. bool_t FileExits(const tchar_t* Path)
  341. {
  342. return GetFileAttributes(Path) != (DWORD)-1;
  343. }
  344. int64_t FileDate(const tchar_t* Path)
  345. {
  346. int64_t Date = -1;
  347. HANDLE Find;
  348. SYSTEMTIME Time;
  349. WIN32_FIND_DATA FindData;
  350. Find = FindFirstFile(Path, &FindData);
  351. if (Find != INVALID_HANDLE_VALUE)
  352. {
  353. if (FileTimeToSystemTime(&FindData.ftLastWriteTime,&Time))
  354. Date = ((((((int64_t)Time.wYear*100+(int64_t)Time.wMonth)*100+(int64_t)Time.wDay)*100+
  355.        (int64_t)Time.wHour)*100+(int64_t)Time.wMinute)*100+(int64_t)Time.wSecond)*1000+(int64_t)Time.wMilliseconds;
  356. FindClose(Find);
  357. }
  358. return Date;
  359. }
  360. #endif