ioutil.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643
  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP Version 7 |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997-2018 The PHP Group |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 3.01 of the PHP license, |
  8. | that is bundled with this package in the file LICENSE, and is |
  9. | available through the world-wide-web at the following url: |
  10. | http://www.php.net/license/3_01.txt |
  11. | If you did not receive a copy of the PHP license and are unable to |
  12. | obtain it through the world-wide-web, please send a note to |
  13. | license@php.net so we can mail you a copy immediately. |
  14. +----------------------------------------------------------------------+
  15. | Author: Anatol Belski <ab@php.net> |
  16. +----------------------------------------------------------------------+
  17. */
  18. /* This file integrates several modified parts from the libuv project, which
  19. * is copyrighted to
  20. *
  21. * Copyright Joyent, Inc. and other Node contributors. All rights reserved.
  22. *
  23. * Permission is hereby granted, free of charge, to any person obtaining a copy
  24. * of this software and associated documentation files (the "Software"), to
  25. * deal in the Software without restriction, including without limitation the
  26. * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  27. * sell copies of the Software, and to permit persons to whom the Software is
  28. * furnished to do so, subject to the following conditions:
  29. *
  30. * The above copyright notice and this permission notice shall be included in
  31. * all copies or substantial portions of the Software.
  32. *
  33. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  34. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  35. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  36. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  37. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  38. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  39. * IN THE SOFTWARE.
  40. */
  41. #ifndef PHP_WIN32_IOUTIL_H
  42. #define PHP_WIN32_IOUTIL_H
  43. #include <fcntl.h>
  44. #include <sys/types.h>
  45. #include <sys/stat.h>
  46. #include <io.h>
  47. #include <stdio.h>
  48. #include <stdlib.h>
  49. #include "win32/winutil.h"
  50. #include "win32/codepage.h"
  51. #ifdef __cplusplus
  52. extern "C" {
  53. #endif
  54. #ifdef PHP_EXPORTS
  55. # define PW32IO __declspec(dllexport)
  56. #else
  57. # define PW32IO __declspec(dllimport)
  58. #endif
  59. #define PHP_WIN32_IOUTIL_MAXPATHLEN 2048
  60. #if !defined(MAXPATHLEN) || MAXPATHLEN < PHP_WIN32_IOUTIL_MAXPATHLEN
  61. # undef MAXPATHLEN
  62. # define MAXPATHLEN PHP_WIN32_IOUTIL_MAXPATHLEN
  63. #endif
  64. #ifndef mode_t
  65. typedef unsigned short mode_t;
  66. #endif
  67. /* these are not defined in win32 headers */
  68. #ifndef W_OK
  69. #define W_OK 0x02
  70. #endif
  71. #ifndef R_OK
  72. #define R_OK 0x04
  73. #endif
  74. #ifndef X_OK
  75. #define X_OK 0x01
  76. #endif
  77. #ifndef F_OK
  78. #define F_OK 0x00
  79. #endif
  80. typedef struct {
  81. DWORD access;
  82. DWORD share;
  83. DWORD disposition;
  84. DWORD attributes;
  85. } php_ioutil_open_opts;
  86. typedef enum {
  87. PHP_WIN32_IOUTIL_IS_ASCII,
  88. PHP_WIN32_IOUTIL_IS_ANSI,
  89. PHP_WIN32_IOUTIL_IS_UTF8
  90. } php_win32_ioutil_encoding;
  91. typedef enum {
  92. PHP_WIN32_IOUTIL_NORM_OK,
  93. PHP_WIN32_IOUTIL_NORM_PARTIAL,
  94. PHP_WIN32_IOUTIL_NORM_FAIL,
  95. } php_win32_ioutil_normalization_result;
  96. #define PHP_WIN32_IOUTIL_FW_SLASHW L'/'
  97. #define PHP_WIN32_IOUTIL_FW_SLASH '/'
  98. #define PHP_WIN32_IOUTIL_BW_SLASHW L'\\'
  99. #define PHP_WIN32_IOUTIL_BW_SLASH '\\'
  100. #define PHP_WIN32_IOUTIL_DEFAULT_SLASHW PHP_WIN32_IOUTIL_BW_SLASHW
  101. #define PHP_WIN32_IOUTIL_DEFAULT_SLASH PHP_WIN32_IOUTIL_BW_SLASH
  102. #define PHP_WIN32_IOUTIL_DEFAULT_DIR_SEPARATORW L';'
  103. #define PHP_WIN32_IOUTIL_IS_SLASHW(c) ((c) == PHP_WIN32_IOUTIL_BW_SLASHW || (c) == PHP_WIN32_IOUTIL_FW_SLASHW)
  104. #define PHP_WIN32_IOUTIL_IS_LETTERW(c) (((c) >= L'a' && (c) <= L'z') || ((c) >= L'A' && (c) <= L'Z'))
  105. #define PHP_WIN32_IOUTIL_JUNCTION_PREFIXW L"\\??\\"
  106. #define PHP_WIN32_IOUTIL_JUNCTION_PREFIX_LENW 4
  107. #define PHP_WIN32_IOUTIL_LONG_PATH_PREFIXW L"\\\\?\\"
  108. #define PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW 4
  109. #define PHP_WIN32_IOUTIL_UNC_PATH_PREFIXW L"\\\\?\\UNC\\"
  110. #define PHP_WIN32_IOUTIL_UNC_PATH_PREFIX_LENW 8
  111. #define PHP_WIN32_IOUTIL_IS_LONG_PATHW(pathw, path_lenw) (path_lenw >= PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW \
  112. && 0 == wcsncmp((pathw), PHP_WIN32_IOUTIL_LONG_PATH_PREFIXW, PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW))
  113. #define PHP_WIN32_IOUTIL_IS_UNC_PATHW(pathw, path_lenw) (path_lenw >= PHP_WIN32_IOUTIL_UNC_PATH_PREFIX_LENW \
  114. && 0 == wcsncmp((pathw), PHP_WIN32_IOUTIL_UNC_PATH_PREFIXW, PHP_WIN32_IOUTIL_UNC_PATH_PREFIX_LENW))
  115. #define PHP_WIN32_IOUTIL_IS_JUNCTION_PATHW(pathw, path_lenw) (path_lenw >= PHP_WIN32_IOUTIL_JUNCTION_PREFIX_LENW \
  116. && 0 == wcsncmp((pathw), PHP_WIN32_IOUTIL_JUNCTION_PREFIXW, PHP_WIN32_IOUTIL_JUNCTION_PREFIX_LENW))
  117. #define PHP_WIN32_IOUTIL_IS_ABSOLUTEW(pathw, path_lenw) (PHP_WIN32_IOUTIL_IS_LONG_PATHW(pathw, path_lenw) \
  118. || path_lenw >= 3 && PHP_WIN32_IOUTIL_IS_LETTERW(pathw[0]) && L':' == pathw[1] && PHP_WIN32_IOUTIL_IS_SLASHW(pathw[2]))
  119. #define PHP_WIN32_IOUTIL_IS_UNC(pathw, path_lenw) (path_lenw >= 2 && PHP_WIN32_IOUTIL_IS_SLASHW(pathw[0]) && PHP_WIN32_IOUTIL_IS_SLASHW(pathw[1]) \
  120. || path_lenw >= PHP_WIN32_IOUTIL_UNC_PATH_PREFIX_LENW && 0 == wcsncmp((pathw), PHP_WIN32_IOUTIL_UNC_PATH_PREFIXW, PHP_WIN32_IOUTIL_UNC_PATH_PREFIX_LENW))
  121. #define PHP_WIN32_IOUTIL_DEFAULT_SHARE_MODE (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE)
  122. #define PHP_WIN32_IOUTIL_INIT_W(path) \
  123. wchar_t *pathw = php_win32_ioutil_any_to_w(path); \
  124. #define PHP_WIN32_IOUTIL_CLEANUP_W() do { \
  125. free(pathw); \
  126. pathw = NULL; \
  127. } while (0);
  128. #define PHP_WIN32_IOUTIL_REINIT_W(path) do { \
  129. PHP_WIN32_IOUTIL_CLEANUP_W() \
  130. pathw = php_win32_ioutil_any_to_w(path); \
  131. } while (0);
  132. #define PHP_WIN32_IOUTIL_PATH_IS_OK_W(pathw, len) \
  133. (!((len) >= 1 && L' ' == pathw[(len)-1] || \
  134. (len) > 1 && !PHP_WIN32_IOUTIL_IS_SLASHW(pathw[(len)-2]) && L'.' != pathw[(len)-2] && L'.' == pathw[(len)-1]))
  135. #define PHP_WIN32_IOUTIL_CHECK_PATH_W(pathw, ret, dealloc) do { \
  136. size_t _len = wcslen(pathw); \
  137. if (!PHP_WIN32_IOUTIL_PATH_IS_OK_W(pathw, _len)) { \
  138. if (dealloc) { \
  139. free((void *)pathw); \
  140. } \
  141. SET_ERRNO_FROM_WIN32_CODE(ERROR_ACCESS_DENIED); \
  142. return ret; \
  143. } \
  144. } while (0);
  145. PW32IO php_win32_ioutil_normalization_result php_win32_ioutil_normalize_path_w(wchar_t **buf, size_t len, size_t *new_len);
  146. #ifdef PHP_EXPORTS
  147. /* This symbols are needed only for the DllMain, but should not be exported
  148. or be available when used with PHP binaries. */
  149. BOOL php_win32_ioutil_init(void);
  150. #endif
  151. /* Keep these functions aliased for case some additional handling
  152. is needed later. */
  153. __forceinline static wchar_t *php_win32_ioutil_conv_any_to_w(const char* in, size_t in_len, size_t *out_len)
  154. {/*{{{*/
  155. wchar_t *mb, *ret;
  156. size_t mb_len;
  157. mb = php_win32_cp_conv_any_to_w(in, in_len, &mb_len);
  158. if (!mb) {
  159. return NULL;
  160. }
  161. /* Only prefix with long if it's needed. */
  162. if (mb_len >= _MAX_PATH) {
  163. size_t new_mb_len;
  164. ret = (wchar_t *) malloc((mb_len + PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW + 1) * sizeof(wchar_t));
  165. if (!ret) {
  166. free(mb);
  167. return NULL;
  168. }
  169. if (PHP_WIN32_IOUTIL_NORM_FAIL == php_win32_ioutil_normalize_path_w(&mb, mb_len, &new_mb_len)) {
  170. free(ret);
  171. free(mb);
  172. return NULL;
  173. }
  174. if (new_mb_len > mb_len) {
  175. wchar_t *tmp = (wchar_t *) realloc(ret, (new_mb_len + 1) * sizeof(wchar_t));
  176. if (!tmp) {
  177. free(ret);
  178. free(mb);
  179. return NULL;
  180. }
  181. ret = tmp;
  182. mb_len = new_mb_len;
  183. }
  184. if (PHP_WIN32_IOUTIL_IS_LONG_PATHW(mb, mb_len) || PHP_WIN32_IOUTIL_IS_JUNCTION_PATHW(mb, mb_len) || PHP_WIN32_IOUTIL_IS_UNC_PATHW(mb, mb_len)) {
  185. memmove(ret, mb, mb_len * sizeof(wchar_t));
  186. ret[mb_len] = L'\0';
  187. } else {
  188. wchar_t *src = mb, *dst = ret + PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW;
  189. memmove(ret, PHP_WIN32_IOUTIL_LONG_PATH_PREFIXW, PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW * sizeof(wchar_t));
  190. while (src < mb + mb_len) {
  191. if (*src == PHP_WIN32_IOUTIL_FW_SLASHW) {
  192. *dst++ = PHP_WIN32_IOUTIL_DEFAULT_SLASHW;
  193. src++;
  194. } else {
  195. *dst++ = *src++;
  196. }
  197. }
  198. ret[mb_len + PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW] = L'\0';
  199. mb_len += PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW;
  200. }
  201. free(mb);
  202. } else {
  203. ret = mb;
  204. }
  205. if (PHP_WIN32_CP_IGNORE_LEN_P != out_len) {
  206. *out_len = mb_len;
  207. }
  208. return ret;
  209. }/*}}}*/
  210. #define php_win32_ioutil_any_to_w(in) php_win32_ioutil_conv_any_to_w(in, PHP_WIN32_CP_IGNORE_LEN, PHP_WIN32_CP_IGNORE_LEN_P)
  211. #define php_win32_ioutil_ascii_to_w php_win32_cp_ascii_to_w
  212. #define php_win32_ioutil_utf8_to_w php_win32_cp_utf8_to_w
  213. #define php_win32_ioutil_cur_to_w php_win32_cp_cur_to_w
  214. #define php_win32_ioutil_w_to_any php_win32_cp_w_to_any
  215. #define php_win32_ioutil_conv_w_to_any php_win32_cp_conv_w_to_any
  216. /*__forceinline static char *php_win32_ioutil_w_to_any(wchar_t* w_source_ptr)
  217. {
  218. return php_win32_cp_w_to_any(w_source_ptr);
  219. }*/
  220. #define php_win32_ioutil_w_to_utf8 php_win32_cp_w_to_utf8
  221. #define php_win32_ioutil_w_to_thread php_win32_cp_w_to_thread
  222. PW32IO int php_win32_ioutil_close(int fd);
  223. PW32IO BOOL php_win32_ioutil_posix_to_open_opts(int flags, mode_t mode, php_ioutil_open_opts *opts);
  224. PW32IO size_t php_win32_ioutil_dirname(char *buf, size_t len);
  225. PW32IO int php_win32_ioutil_open_w(const wchar_t *path, int flags, ...);
  226. PW32IO int php_win32_ioutil_chdir_w(const wchar_t *path);
  227. PW32IO int php_win32_ioutil_rename_w(const wchar_t *oldname, const wchar_t *newname);
  228. PW32IO wchar_t *php_win32_ioutil_getcwd_w(wchar_t *buf, size_t len);
  229. PW32IO int php_win32_ioutil_unlink_w(const wchar_t *path);
  230. PW32IO int php_win32_ioutil_access_w(const wchar_t *path, mode_t mode);
  231. PW32IO int php_win32_ioutil_mkdir_w(const wchar_t *path, mode_t mode);
  232. PW32IO FILE *php_win32_ioutil_fopen_w(const wchar_t *path, const wchar_t *mode);
  233. PW32IO wchar_t *php_win32_ioutil_realpath_w(const wchar_t *path, wchar_t *resolved);
  234. PW32IO wchar_t *php_win32_ioutil_realpath_w_ex0(const wchar_t *path, wchar_t *resolved, PBY_HANDLE_FILE_INFORMATION info);
  235. __forceinline static int php_win32_ioutil_access(const char *path, mode_t mode)
  236. {/*{{{*/
  237. PHP_WIN32_IOUTIL_INIT_W(path)
  238. int ret, err;
  239. if (!pathw) {
  240. SET_ERRNO_FROM_WIN32_CODE(ERROR_INVALID_PARAMETER);
  241. return -1;
  242. }
  243. PHP_WIN32_IOUTIL_CHECK_PATH_W(pathw, -1, 1)
  244. ret = php_win32_ioutil_access_w(pathw, mode);
  245. if (0 > ret) {
  246. err = GetLastError();
  247. }
  248. PHP_WIN32_IOUTIL_CLEANUP_W()
  249. if (0 > ret) {
  250. SET_ERRNO_FROM_WIN32_CODE(err);
  251. }
  252. return ret;
  253. }/*}}}*/
  254. __forceinline static int php_win32_ioutil_open(const char *path, int flags, ...)
  255. {/*{{{*/
  256. mode_t mode = 0;
  257. PHP_WIN32_IOUTIL_INIT_W(path)
  258. int ret = -1;
  259. DWORD err;
  260. if (!pathw) {
  261. SET_ERRNO_FROM_WIN32_CODE(ERROR_INVALID_PARAMETER);
  262. return -1;
  263. }
  264. PHP_WIN32_IOUTIL_CHECK_PATH_W(pathw, -1, 1)
  265. if (flags & O_CREAT) {
  266. va_list arg;
  267. va_start(arg, flags);
  268. mode = (mode_t) va_arg(arg, int);
  269. va_end(arg);
  270. }
  271. ret = php_win32_ioutil_open_w(pathw, flags, mode);
  272. if (0 > ret) {
  273. err = GetLastError();
  274. }
  275. PHP_WIN32_IOUTIL_CLEANUP_W()
  276. if (0 > ret) {
  277. SET_ERRNO_FROM_WIN32_CODE(err);
  278. }
  279. return ret;
  280. }/*}}}*/
  281. __forceinline static int php_win32_ioutil_unlink(const char *path)
  282. {/*{{{*/
  283. PHP_WIN32_IOUTIL_INIT_W(path)
  284. int ret = -1;
  285. DWORD err;
  286. if (!pathw) {
  287. SET_ERRNO_FROM_WIN32_CODE(ERROR_INVALID_PARAMETER);
  288. return -1;
  289. }
  290. ret = php_win32_ioutil_unlink_w(pathw);
  291. if (0 > ret) {
  292. err = GetLastError();
  293. }
  294. PHP_WIN32_IOUTIL_CLEANUP_W()
  295. if (0 > ret) {
  296. SET_ERRNO_FROM_WIN32_CODE(err);
  297. }
  298. return ret;
  299. }/*}}}*/
  300. __forceinline static int php_win32_ioutil_rmdir(const char *path)
  301. {/*{{{*/
  302. PHP_WIN32_IOUTIL_INIT_W(path)
  303. int ret = 0;
  304. DWORD err = 0;
  305. if (!pathw) {
  306. SET_ERRNO_FROM_WIN32_CODE(ERROR_INVALID_PARAMETER);
  307. return -1;
  308. }
  309. PHP_WIN32_IOUTIL_CHECK_PATH_W(pathw, -1, 1)
  310. if (!RemoveDirectoryW(pathw)) {
  311. err = GetLastError();
  312. ret = -1;
  313. }
  314. PHP_WIN32_IOUTIL_CLEANUP_W()
  315. if (0 > ret) {
  316. SET_ERRNO_FROM_WIN32_CODE(err);
  317. }
  318. return ret;
  319. }/*}}}*/
  320. __forceinline static FILE *php_win32_ioutil_fopen(const char *patha, const char *modea)
  321. {/*{{{*/
  322. FILE *ret;
  323. wchar_t modew[16] = {0};
  324. int i = 0;
  325. PHP_WIN32_IOUTIL_INIT_W(patha)
  326. if (!pathw) {
  327. SET_ERRNO_FROM_WIN32_CODE(ERROR_INVALID_PARAMETER);
  328. return NULL;
  329. }
  330. PHP_WIN32_IOUTIL_CHECK_PATH_W(pathw, NULL, 1)
  331. while (i < (sizeof(modew)-1)/sizeof(wchar_t) && modea[i]) {
  332. modew[i] = (wchar_t)modea[i];
  333. i++;
  334. }
  335. ret = php_win32_ioutil_fopen_w(pathw, modew);
  336. if (!ret) {
  337. int err = GetLastError();
  338. PHP_WIN32_IOUTIL_CLEANUP_W()
  339. SET_ERRNO_FROM_WIN32_CODE(err);
  340. return NULL;
  341. }
  342. PHP_WIN32_IOUTIL_CLEANUP_W()
  343. return ret;
  344. }/*}}}*/
  345. __forceinline static int php_win32_ioutil_rename(const char *oldnamea, const char *newnamea)
  346. {/*{{{*/
  347. wchar_t *oldnamew;
  348. wchar_t *newnamew;
  349. int ret;
  350. DWORD err = 0;
  351. oldnamew = php_win32_ioutil_any_to_w(oldnamea);
  352. if (!oldnamew) {
  353. SET_ERRNO_FROM_WIN32_CODE(ERROR_INVALID_PARAMETER);
  354. return -1;
  355. }
  356. PHP_WIN32_IOUTIL_CHECK_PATH_W(oldnamew, -1, 1)
  357. newnamew = php_win32_ioutil_any_to_w(newnamea);
  358. if (!newnamew) {
  359. free(oldnamew);
  360. SET_ERRNO_FROM_WIN32_CODE(ERROR_INVALID_PARAMETER);
  361. return -1;
  362. } else {
  363. size_t newnamew_len = wcslen(newnamew);
  364. if (!PHP_WIN32_IOUTIL_PATH_IS_OK_W(newnamew, newnamew_len)) {
  365. free(oldnamew);
  366. free(newnamew);
  367. SET_ERRNO_FROM_WIN32_CODE(ERROR_ACCESS_DENIED);
  368. return -1;
  369. }
  370. }
  371. ret = php_win32_ioutil_rename_w(oldnamew, newnamew);
  372. if (0 > ret) {
  373. err = GetLastError();
  374. }
  375. free(oldnamew);
  376. free(newnamew);
  377. if (0 > ret) {
  378. SET_ERRNO_FROM_WIN32_CODE(err);
  379. }
  380. return ret;
  381. }/*}}}*/
  382. __forceinline static int php_win32_ioutil_chdir(const char *patha)
  383. {/*{{{*/
  384. int ret;
  385. wchar_t *pathw = php_win32_ioutil_any_to_w(patha);
  386. DWORD err = 0;
  387. if (!pathw) {
  388. SET_ERRNO_FROM_WIN32_CODE(ERROR_INVALID_PARAMETER);
  389. return -1;
  390. }
  391. ret = php_win32_ioutil_chdir_w(pathw);
  392. if (0 > ret) {
  393. err = GetLastError();
  394. }
  395. free(pathw);
  396. if (0 > ret) {
  397. SET_ERRNO_FROM_WIN32_CODE(err);
  398. }
  399. return ret;
  400. }/*}}}*/
  401. __forceinline static char *php_win32_ioutil_getcwd(char *buf, size_t len)
  402. {/*{{{*/
  403. wchar_t tmp_bufw[PHP_WIN32_IOUTIL_MAXPATHLEN];
  404. char *tmp_bufa = NULL;
  405. size_t tmp_bufa_len;
  406. DWORD err = 0;
  407. if (php_win32_ioutil_getcwd_w(tmp_bufw, len ? len : PHP_WIN32_IOUTIL_MAXPATHLEN) == NULL) {
  408. err = GetLastError();
  409. SET_ERRNO_FROM_WIN32_CODE(err);
  410. return NULL;
  411. }
  412. tmp_bufa = php_win32_cp_conv_w_to_any(tmp_bufw, wcslen(tmp_bufw), &tmp_bufa_len);
  413. if (!tmp_bufa) {
  414. err = GetLastError();
  415. SET_ERRNO_FROM_WIN32_CODE(err);
  416. return NULL;
  417. } else if (tmp_bufa_len + 1 > PHP_WIN32_IOUTIL_MAXPATHLEN) {
  418. free(tmp_bufa);
  419. SET_ERRNO_FROM_WIN32_CODE(ERROR_BAD_LENGTH);
  420. return NULL;
  421. } else if (tmp_bufa_len + 1 > len) {
  422. free(tmp_bufa);
  423. SET_ERRNO_FROM_WIN32_CODE(ERROR_INSUFFICIENT_BUFFER);
  424. return NULL;
  425. }
  426. if (!buf && !len) {
  427. /* If buf was NULL, the result has to be freed outside here. */
  428. buf = tmp_bufa;
  429. } else {
  430. memmove(buf, tmp_bufa, tmp_bufa_len + 1);
  431. free(tmp_bufa);
  432. }
  433. return buf;
  434. }/*}}}*/
  435. /* TODO improve with usage of native APIs, split for _a and _w. */
  436. __forceinline static int php_win32_ioutil_chmod(const char *patha, int mode)
  437. {/*{{{*/
  438. wchar_t *pathw = php_win32_ioutil_any_to_w(patha);
  439. int err = 0;
  440. int ret;
  441. if (!pathw) {
  442. SET_ERRNO_FROM_WIN32_CODE(ERROR_INVALID_PARAMETER);
  443. return -1;
  444. }
  445. PHP_WIN32_IOUTIL_CHECK_PATH_W(pathw, -1, 1)
  446. ret = _wchmod(pathw, mode);
  447. if (0 > ret) {
  448. _get_errno(&err);
  449. }
  450. free(pathw);
  451. if (0 > ret) {
  452. _set_errno(err);
  453. }
  454. return ret;
  455. }/*}}}*/
  456. __forceinline static int php_win32_ioutil_mkdir(const char *path, mode_t mode)
  457. {/*{{{*/
  458. int ret;
  459. DWORD err = 0;
  460. PHP_WIN32_IOUTIL_INIT_W(path)
  461. if (!pathw) {
  462. SET_ERRNO_FROM_WIN32_CODE(ERROR_INVALID_PARAMETER);
  463. return -1;
  464. }
  465. ret = php_win32_ioutil_mkdir_w(pathw, mode);
  466. if (0 > ret) {
  467. err = GetLastError();
  468. }
  469. PHP_WIN32_IOUTIL_CLEANUP_W()
  470. if (0 > ret) {
  471. SET_ERRNO_FROM_WIN32_CODE(err);
  472. }
  473. return ret;
  474. }/*}}}*/
  475. #define HAVE_REALPATH 1
  476. PW32IO char *realpath(const char *path, char *resolved);
  477. __forceinline static char *php_win32_ioutil_realpath_ex0(const char *path, char *resolved, PBY_HANDLE_FILE_INFORMATION info)
  478. {/*{{{*/
  479. wchar_t retw[PHP_WIN32_IOUTIL_MAXPATHLEN];
  480. char *reta;
  481. size_t reta_len;
  482. PHP_WIN32_IOUTIL_INIT_W(path)
  483. if (!pathw) {
  484. SET_ERRNO_FROM_WIN32_CODE(ERROR_INVALID_PARAMETER);
  485. return NULL;
  486. }
  487. if (NULL == php_win32_ioutil_realpath_w_ex0(pathw, retw, info)) {
  488. DWORD err = GetLastError();
  489. PHP_WIN32_IOUTIL_CLEANUP_W()
  490. SET_ERRNO_FROM_WIN32_CODE(err);
  491. return NULL;
  492. }
  493. reta = php_win32_cp_conv_w_to_any(retw, PHP_WIN32_CP_IGNORE_LEN, &reta_len);
  494. if (!reta || reta_len > PHP_WIN32_IOUTIL_MAXPATHLEN) {
  495. DWORD err = GetLastError();
  496. PHP_WIN32_IOUTIL_CLEANUP_W()
  497. SET_ERRNO_FROM_WIN32_CODE(err);
  498. return NULL;
  499. }
  500. if (NULL == resolved) {
  501. /* ret is expected to be either NULL or a buffer of capable size. */
  502. resolved = (char *) malloc(reta_len + 1);
  503. if (!resolved) {
  504. free(reta);
  505. PHP_WIN32_IOUTIL_CLEANUP_W()
  506. SET_ERRNO_FROM_WIN32_CODE(ERROR_NOT_ENOUGH_MEMORY);
  507. return NULL;
  508. }
  509. }
  510. memmove(resolved, reta, reta_len+1);
  511. PHP_WIN32_IOUTIL_CLEANUP_W()
  512. free(reta);
  513. return resolved;
  514. }/*}}}*/
  515. __forceinline static char *php_win32_ioutil_realpath(const char *path, char *resolved)
  516. {/*{{{*/
  517. return php_win32_ioutil_realpath_ex0(path, resolved, NULL);
  518. }/*}}}*/
  519. #ifdef __cplusplus
  520. }
  521. #endif
  522. #endif /* PHP_WIN32_IOUTIL_H */
  523. /*
  524. * Local variables:
  525. * tab-width: 4
  526. * c-basic-offset: 4
  527. * End:
  528. * vim600: sw=4 ts=4 fdm=marker
  529. * vim<600: sw=4 ts=4
  530. */