iowin32.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440
  1. /* iowin32.c -- IO base function header for compress/uncompress .zip
  2. Version 1.1, February 14h, 2010
  3. part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
  4. Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
  5. Modifications for Zip64 support
  6. Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
  7. For more info read MiniZip_info.txt
  8. */
  9. #include <stdlib.h>
  10. #include "zlib.h"
  11. #include "ioapi.h"
  12. #include "iowin32.h"
  13. #ifndef INVALID_HANDLE_VALUE
  14. #define INVALID_HANDLE_VALUE (0xFFFFFFFF)
  15. #endif
  16. #ifndef INVALID_SET_FILE_POINTER
  17. #define INVALID_SET_FILE_POINTER ((DWORD)-1)
  18. #endif
  19. // see Include/shared/winapifamily.h in the Windows Kit
  20. #if defined(WINAPI_FAMILY_PARTITION) && (!(defined(IOWIN32_USING_WINRT_API)))
  21. #if !defined(WINAPI_FAMILY_ONE_PARTITION)
  22. #define WINAPI_FAMILY_ONE_PARTITION(PartitionSet, Partition) ((WINAPI_FAMILY & PartitionSet) == Partition)
  23. #endif
  24. #if WINAPI_FAMILY_ONE_PARTITION(WINAPI_FAMILY, WINAPI_PARTITION_APP)
  25. #define IOWIN32_USING_WINRT_API 1
  26. #endif
  27. #endif
  28. typedef struct
  29. {
  30. HANDLE hf;
  31. int error;
  32. } WIN32FILE_IOWIN;
  33. static void win32_translate_open_mode(int mode,
  34. DWORD* lpdwDesiredAccess,
  35. DWORD* lpdwCreationDisposition,
  36. DWORD* lpdwShareMode,
  37. DWORD* lpdwFlagsAndAttributes) {
  38. *lpdwDesiredAccess = *lpdwShareMode = *lpdwFlagsAndAttributes = *lpdwCreationDisposition = 0;
  39. if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
  40. {
  41. *lpdwDesiredAccess = GENERIC_READ;
  42. *lpdwCreationDisposition = OPEN_EXISTING;
  43. *lpdwShareMode = FILE_SHARE_READ;
  44. }
  45. else if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
  46. {
  47. *lpdwDesiredAccess = GENERIC_WRITE | GENERIC_READ;
  48. *lpdwCreationDisposition = OPEN_EXISTING;
  49. }
  50. else if (mode & ZLIB_FILEFUNC_MODE_CREATE)
  51. {
  52. *lpdwDesiredAccess = GENERIC_WRITE | GENERIC_READ;
  53. *lpdwCreationDisposition = CREATE_ALWAYS;
  54. }
  55. }
  56. static voidpf win32_build_iowin(HANDLE hFile) {
  57. voidpf ret=NULL;
  58. if ((hFile != NULL) && (hFile != INVALID_HANDLE_VALUE))
  59. {
  60. WIN32FILE_IOWIN w32fiow;
  61. w32fiow.hf = hFile;
  62. w32fiow.error = 0;
  63. ret = malloc(sizeof(WIN32FILE_IOWIN));
  64. if (ret==NULL)
  65. CloseHandle(hFile);
  66. else
  67. *((WIN32FILE_IOWIN*)ret) = w32fiow;
  68. }
  69. return ret;
  70. }
  71. voidpf ZCALLBACK win32_open64_file_func(voidpf opaque, const void* filename, int mode) {
  72. const char* mode_fopen = NULL;
  73. DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;
  74. HANDLE hFile = NULL;
  75. win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);
  76. #ifdef IOWIN32_USING_WINRT_API
  77. #ifdef UNICODE
  78. if ((filename!=NULL) && (dwDesiredAccess != 0))
  79. hFile = CreateFile2((LPCTSTR)filename, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);
  80. #else
  81. if ((filename!=NULL) && (dwDesiredAccess != 0))
  82. {
  83. WCHAR filenameW[FILENAME_MAX + 0x200 + 1];
  84. MultiByteToWideChar(CP_ACP,0,(const char*)filename,-1,filenameW,FILENAME_MAX + 0x200);
  85. hFile = CreateFile2(filenameW, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);
  86. }
  87. #endif
  88. #else
  89. if ((filename!=NULL) && (dwDesiredAccess != 0))
  90. hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
  91. #endif
  92. return win32_build_iowin(hFile);
  93. }
  94. voidpf ZCALLBACK win32_open64_file_funcA(voidpf opaque, const void* filename, int mode) {
  95. const char* mode_fopen = NULL;
  96. DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;
  97. HANDLE hFile = NULL;
  98. win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);
  99. #ifdef IOWIN32_USING_WINRT_API
  100. if ((filename!=NULL) && (dwDesiredAccess != 0))
  101. {
  102. WCHAR filenameW[FILENAME_MAX + 0x200 + 1];
  103. MultiByteToWideChar(CP_ACP,0,(const char*)filename,-1,filenameW,FILENAME_MAX + 0x200);
  104. hFile = CreateFile2(filenameW, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);
  105. }
  106. #else
  107. if ((filename!=NULL) && (dwDesiredAccess != 0))
  108. hFile = CreateFileA((LPCSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
  109. #endif
  110. return win32_build_iowin(hFile);
  111. }
  112. voidpf ZCALLBACK win32_open64_file_funcW(voidpf opaque, const void* filename, int mode) {
  113. const char* mode_fopen = NULL;
  114. DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;
  115. HANDLE hFile = NULL;
  116. win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);
  117. #ifdef IOWIN32_USING_WINRT_API
  118. if ((filename!=NULL) && (dwDesiredAccess != 0))
  119. hFile = CreateFile2((LPCWSTR)filename, dwDesiredAccess, dwShareMode, dwCreationDisposition,NULL);
  120. #else
  121. if ((filename!=NULL) && (dwDesiredAccess != 0))
  122. hFile = CreateFileW((LPCWSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
  123. #endif
  124. return win32_build_iowin(hFile);
  125. }
  126. voidpf ZCALLBACK win32_open_file_func(voidpf opaque, const char* filename, int mode) {
  127. const char* mode_fopen = NULL;
  128. DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;
  129. HANDLE hFile = NULL;
  130. win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);
  131. #ifdef IOWIN32_USING_WINRT_API
  132. #ifdef UNICODE
  133. if ((filename!=NULL) && (dwDesiredAccess != 0))
  134. hFile = CreateFile2((LPCTSTR)filename, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);
  135. #else
  136. if ((filename!=NULL) && (dwDesiredAccess != 0))
  137. {
  138. WCHAR filenameW[FILENAME_MAX + 0x200 + 1];
  139. MultiByteToWideChar(CP_ACP,0,(const char*)filename,-1,filenameW,FILENAME_MAX + 0x200);
  140. hFile = CreateFile2(filenameW, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);
  141. }
  142. #endif
  143. #else
  144. if ((filename!=NULL) && (dwDesiredAccess != 0))
  145. hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
  146. #endif
  147. return win32_build_iowin(hFile);
  148. }
  149. uLong ZCALLBACK win32_read_file_func(voidpf opaque, voidpf stream, void* buf,uLong size) {
  150. uLong ret=0;
  151. HANDLE hFile = NULL;
  152. if (stream!=NULL)
  153. hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
  154. if (hFile != NULL)
  155. {
  156. if (!ReadFile(hFile, buf, size, &ret, NULL))
  157. {
  158. DWORD dwErr = GetLastError();
  159. if (dwErr == ERROR_HANDLE_EOF)
  160. dwErr = 0;
  161. ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
  162. }
  163. }
  164. return ret;
  165. }
  166. uLong ZCALLBACK win32_write_file_func(voidpf opaque, voidpf stream, const void* buf, uLong size) {
  167. uLong ret=0;
  168. HANDLE hFile = NULL;
  169. if (stream!=NULL)
  170. hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
  171. if (hFile != NULL)
  172. {
  173. if (!WriteFile(hFile, buf, size, &ret, NULL))
  174. {
  175. DWORD dwErr = GetLastError();
  176. if (dwErr == ERROR_HANDLE_EOF)
  177. dwErr = 0;
  178. ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
  179. }
  180. }
  181. return ret;
  182. }
  183. static BOOL MySetFilePointerEx(HANDLE hFile, LARGE_INTEGER pos, LARGE_INTEGER *newPos, DWORD dwMoveMethod) {
  184. #ifdef IOWIN32_USING_WINRT_API
  185. return SetFilePointerEx(hFile, pos, newPos, dwMoveMethod);
  186. #else
  187. LONG lHigh = pos.HighPart;
  188. DWORD dwNewPos = SetFilePointer(hFile, pos.LowPart, &lHigh, dwMoveMethod);
  189. BOOL fOk = TRUE;
  190. if (dwNewPos == 0xFFFFFFFF)
  191. if (GetLastError() != NO_ERROR)
  192. fOk = FALSE;
  193. if ((newPos != NULL) && (fOk))
  194. {
  195. newPos->LowPart = dwNewPos;
  196. newPos->HighPart = lHigh;
  197. }
  198. return fOk;
  199. #endif
  200. }
  201. long ZCALLBACK win32_tell_file_func(voidpf opaque, voidpf stream) {
  202. long ret=-1;
  203. HANDLE hFile = NULL;
  204. if (stream!=NULL)
  205. hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
  206. if (hFile != NULL)
  207. {
  208. LARGE_INTEGER pos;
  209. pos.QuadPart = 0;
  210. if (!MySetFilePointerEx(hFile, pos, &pos, FILE_CURRENT))
  211. {
  212. DWORD dwErr = GetLastError();
  213. ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
  214. ret = -1;
  215. }
  216. else
  217. ret=(long)pos.LowPart;
  218. }
  219. return ret;
  220. }
  221. ZPOS64_T ZCALLBACK win32_tell64_file_func(voidpf opaque, voidpf stream) {
  222. ZPOS64_T ret= (ZPOS64_T)-1;
  223. HANDLE hFile = NULL;
  224. if (stream!=NULL)
  225. hFile = ((WIN32FILE_IOWIN*)stream)->hf;
  226. if (hFile)
  227. {
  228. LARGE_INTEGER pos;
  229. pos.QuadPart = 0;
  230. if (!MySetFilePointerEx(hFile, pos, &pos, FILE_CURRENT))
  231. {
  232. DWORD dwErr = GetLastError();
  233. ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
  234. ret = (ZPOS64_T)-1;
  235. }
  236. else
  237. ret=pos.QuadPart;
  238. }
  239. return ret;
  240. }
  241. long ZCALLBACK win32_seek_file_func(voidpf opaque, voidpf stream, uLong offset, int origin) {
  242. DWORD dwMoveMethod=0xFFFFFFFF;
  243. HANDLE hFile = NULL;
  244. long ret=-1;
  245. if (stream!=NULL)
  246. hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
  247. switch (origin)
  248. {
  249. case ZLIB_FILEFUNC_SEEK_CUR :
  250. dwMoveMethod = FILE_CURRENT;
  251. break;
  252. case ZLIB_FILEFUNC_SEEK_END :
  253. dwMoveMethod = FILE_END;
  254. break;
  255. case ZLIB_FILEFUNC_SEEK_SET :
  256. dwMoveMethod = FILE_BEGIN;
  257. break;
  258. default: return -1;
  259. }
  260. if (hFile != NULL)
  261. {
  262. LARGE_INTEGER pos;
  263. pos.QuadPart = offset;
  264. if (!MySetFilePointerEx(hFile, pos, NULL, dwMoveMethod))
  265. {
  266. DWORD dwErr = GetLastError();
  267. ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
  268. ret = -1;
  269. }
  270. else
  271. ret=0;
  272. }
  273. return ret;
  274. }
  275. long ZCALLBACK win32_seek64_file_func(voidpf opaque, voidpf stream, ZPOS64_T offset, int origin) {
  276. DWORD dwMoveMethod=0xFFFFFFFF;
  277. HANDLE hFile = NULL;
  278. long ret=-1;
  279. if (stream!=NULL)
  280. hFile = ((WIN32FILE_IOWIN*)stream)->hf;
  281. switch (origin)
  282. {
  283. case ZLIB_FILEFUNC_SEEK_CUR :
  284. dwMoveMethod = FILE_CURRENT;
  285. break;
  286. case ZLIB_FILEFUNC_SEEK_END :
  287. dwMoveMethod = FILE_END;
  288. break;
  289. case ZLIB_FILEFUNC_SEEK_SET :
  290. dwMoveMethod = FILE_BEGIN;
  291. break;
  292. default: return -1;
  293. }
  294. if (hFile)
  295. {
  296. LARGE_INTEGER pos;
  297. pos.QuadPart = offset;
  298. if (!MySetFilePointerEx(hFile, pos, NULL, dwMoveMethod))
  299. {
  300. DWORD dwErr = GetLastError();
  301. ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
  302. ret = -1;
  303. }
  304. else
  305. ret=0;
  306. }
  307. return ret;
  308. }
  309. int ZCALLBACK win32_close_file_func(voidpf opaque, voidpf stream) {
  310. int ret=-1;
  311. if (stream!=NULL)
  312. {
  313. HANDLE hFile;
  314. hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
  315. if (hFile != NULL)
  316. {
  317. CloseHandle(hFile);
  318. ret=0;
  319. }
  320. free(stream);
  321. }
  322. return ret;
  323. }
  324. int ZCALLBACK win32_error_file_func(voidpf opaque, voidpf stream) {
  325. int ret=-1;
  326. if (stream!=NULL)
  327. {
  328. ret = ((WIN32FILE_IOWIN*)stream) -> error;
  329. }
  330. return ret;
  331. }
  332. void fill_win32_filefunc(zlib_filefunc_def* pzlib_filefunc_def) {
  333. pzlib_filefunc_def->zopen_file = win32_open_file_func;
  334. pzlib_filefunc_def->zread_file = win32_read_file_func;
  335. pzlib_filefunc_def->zwrite_file = win32_write_file_func;
  336. pzlib_filefunc_def->ztell_file = win32_tell_file_func;
  337. pzlib_filefunc_def->zseek_file = win32_seek_file_func;
  338. pzlib_filefunc_def->zclose_file = win32_close_file_func;
  339. pzlib_filefunc_def->zerror_file = win32_error_file_func;
  340. pzlib_filefunc_def->opaque = NULL;
  341. }
  342. void fill_win32_filefunc64(zlib_filefunc64_def* pzlib_filefunc_def) {
  343. pzlib_filefunc_def->zopen64_file = win32_open64_file_func;
  344. pzlib_filefunc_def->zread_file = win32_read_file_func;
  345. pzlib_filefunc_def->zwrite_file = win32_write_file_func;
  346. pzlib_filefunc_def->ztell64_file = win32_tell64_file_func;
  347. pzlib_filefunc_def->zseek64_file = win32_seek64_file_func;
  348. pzlib_filefunc_def->zclose_file = win32_close_file_func;
  349. pzlib_filefunc_def->zerror_file = win32_error_file_func;
  350. pzlib_filefunc_def->opaque = NULL;
  351. }
  352. void fill_win32_filefunc64A(zlib_filefunc64_def* pzlib_filefunc_def) {
  353. pzlib_filefunc_def->zopen64_file = win32_open64_file_funcA;
  354. pzlib_filefunc_def->zread_file = win32_read_file_func;
  355. pzlib_filefunc_def->zwrite_file = win32_write_file_func;
  356. pzlib_filefunc_def->ztell64_file = win32_tell64_file_func;
  357. pzlib_filefunc_def->zseek64_file = win32_seek64_file_func;
  358. pzlib_filefunc_def->zclose_file = win32_close_file_func;
  359. pzlib_filefunc_def->zerror_file = win32_error_file_func;
  360. pzlib_filefunc_def->opaque = NULL;
  361. }
  362. void fill_win32_filefunc64W(zlib_filefunc64_def* pzlib_filefunc_def) {
  363. pzlib_filefunc_def->zopen64_file = win32_open64_file_funcW;
  364. pzlib_filefunc_def->zread_file = win32_read_file_func;
  365. pzlib_filefunc_def->zwrite_file = win32_write_file_func;
  366. pzlib_filefunc_def->ztell64_file = win32_tell64_file_func;
  367. pzlib_filefunc_def->zseek64_file = win32_seek64_file_func;
  368. pzlib_filefunc_def->zclose_file = win32_close_file_func;
  369. pzlib_filefunc_def->zerror_file = win32_error_file_func;
  370. pzlib_filefunc_def->opaque = NULL;
  371. }