A local copy of OpenSSL from GitHub
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

154 lines
4.3 KiB

  1. /*
  2. * Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the OpenSSL license (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. #include <windows.h>
  10. #include <tchar.h>
  11. #ifndef LPDIR_H
  12. # include "LPdir.h"
  13. #endif
  14. /*
  15. * We're most likely overcautious here, but let's reserve for broken WinCE
  16. * headers and explicitly opt for UNICODE call. Keep in mind that our WinCE
  17. * builds are compiled with -DUNICODE [as well as -D_UNICODE].
  18. */
  19. #if defined(LP_SYS_WINCE) && !defined(FindFirstFile)
  20. # define FindFirstFile FindFirstFileW
  21. #endif
  22. #if defined(LP_SYS_WINCE) && !defined(FindNextFile)
  23. # define FindNextFile FindNextFileW
  24. #endif
  25. #ifndef NAME_MAX
  26. # define NAME_MAX 255
  27. #endif
  28. struct LP_dir_context_st {
  29. WIN32_FIND_DATA ctx;
  30. HANDLE handle;
  31. char entry_name[NAME_MAX + 1];
  32. };
  33. const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory)
  34. {
  35. if (ctx == NULL || directory == NULL) {
  36. errno = EINVAL;
  37. return 0;
  38. }
  39. errno = 0;
  40. if (*ctx == NULL) {
  41. const char *extdir = directory;
  42. char *extdirbuf = NULL;
  43. size_t dirlen = strlen(directory);
  44. if (dirlen == 0) {
  45. errno = ENOENT;
  46. return 0;
  47. }
  48. *ctx = malloc(sizeof(**ctx));
  49. if (*ctx == NULL) {
  50. errno = ENOMEM;
  51. return 0;
  52. }
  53. memset(*ctx, 0, sizeof(**ctx));
  54. if (directory[dirlen - 1] != '*') {
  55. extdirbuf = (char *)malloc(dirlen + 3);
  56. if (extdirbuf == NULL) {
  57. free(*ctx);
  58. *ctx = NULL;
  59. errno = ENOMEM;
  60. return 0;
  61. }
  62. if (directory[dirlen - 1] != '/' && directory[dirlen - 1] != '\\')
  63. extdir = strcat(strcpy(extdirbuf, directory), "/*");
  64. else
  65. extdir = strcat(strcpy(extdirbuf, directory), "*");
  66. }
  67. if (sizeof(TCHAR) != sizeof(char)) {
  68. TCHAR *wdir = NULL;
  69. /* len_0 denotes string length *with* trailing 0 */
  70. size_t index = 0, len_0 = strlen(extdir) + 1;
  71. wdir = (TCHAR *)calloc(len_0, sizeof(TCHAR));
  72. if (wdir == NULL) {
  73. if (extdirbuf != NULL) {
  74. free(extdirbuf);
  75. }
  76. free(*ctx);
  77. *ctx = NULL;
  78. errno = ENOMEM;
  79. return 0;
  80. }
  81. #ifdef LP_MULTIBYTE_AVAILABLE
  82. if (!MultiByteToWideChar
  83. (CP_ACP, 0, extdir, len_0, (WCHAR *)wdir, len_0))
  84. #endif
  85. for (index = 0; index < len_0; index++)
  86. wdir[index] = (TCHAR)extdir[index];
  87. (*ctx)->handle = FindFirstFile(wdir, &(*ctx)->ctx);
  88. free(wdir);
  89. } else {
  90. (*ctx)->handle = FindFirstFile((TCHAR *)extdir, &(*ctx)->ctx);
  91. }
  92. if (extdirbuf != NULL) {
  93. free(extdirbuf);
  94. }
  95. if ((*ctx)->handle == INVALID_HANDLE_VALUE) {
  96. free(*ctx);
  97. *ctx = NULL;
  98. errno = EINVAL;
  99. return 0;
  100. }
  101. } else {
  102. if (FindNextFile((*ctx)->handle, &(*ctx)->ctx) == FALSE) {
  103. return 0;
  104. }
  105. }
  106. if (sizeof(TCHAR) != sizeof(char)) {
  107. TCHAR *wdir = (*ctx)->ctx.cFileName;
  108. size_t index, len_0 = 0;
  109. while (wdir[len_0] && len_0 < (sizeof((*ctx)->entry_name) - 1))
  110. len_0++;
  111. len_0++;
  112. #ifdef LP_MULTIBYTE_AVAILABLE
  113. if (!WideCharToMultiByte
  114. (CP_ACP, 0, (WCHAR *)wdir, len_0, (*ctx)->entry_name,
  115. sizeof((*ctx)->entry_name), NULL, 0))
  116. #endif
  117. for (index = 0; index < len_0; index++)
  118. (*ctx)->entry_name[index] = (char)wdir[index];
  119. } else
  120. strncpy((*ctx)->entry_name, (const char *)(*ctx)->ctx.cFileName,
  121. sizeof((*ctx)->entry_name) - 1);
  122. (*ctx)->entry_name[sizeof((*ctx)->entry_name) - 1] = '\0';
  123. return (*ctx)->entry_name;
  124. }
  125. int LP_find_file_end(LP_DIR_CTX **ctx)
  126. {
  127. if (ctx != NULL && *ctx != NULL) {
  128. FindClose((*ctx)->handle);
  129. free(*ctx);
  130. *ctx = NULL;
  131. return 1;
  132. }
  133. errno = EINVAL;
  134. return 0;
  135. }