win32.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. /*
  2. * Unix support routines for PhysicsFS.
  3. *
  4. * Please see the file LICENSE in the source's root directory.
  5. *
  6. * This file written by Ryan C. Gordon.
  7. */
  8. #if (defined __STRICT_ANSI__)
  9. #define __PHYSFS_DOING_STRICT_ANSI__
  10. #endif
  11. #include <windows.h>
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <ctype.h>
  16. #include <pthread.h>
  17. #include <unistd.h>
  18. #include <sys/types.h>
  19. #include <pwd.h>
  20. #include <sys/stat.h>
  21. #include <sys/param.h>
  22. #include <dirent.h>
  23. #include <time.h>
  24. #include <errno.h>
  25. #define __PHYSICSFS_INTERNAL__
  26. #include "physfs_internal.h"
  27. const char *__PHYSFS_platformDirSeparator = "\\";
  28. static const char *win32strerror(void)
  29. {
  30. static char msgbuf[255];
  31. FormatMessage(
  32. FORMAT_MESSAGE_FROM_SYSTEM |
  33. FORMAT_MESSAGE_IGNORE_INSERTS,
  34. NULL,
  35. GetLastError(),
  36. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  37. &msgbuf,
  38. 0,
  39. NULL
  40. );
  41. return(msgbuf);
  42. } /* win32strerror */
  43. char **__PHYSFS_platformDetectAvailableCDs(void)
  44. {
  45. char **retval = (char **) malloc(sizeof (char *));
  46. int cd_count = 1; /* We count the NULL entry. */
  47. char drive_str[4] = "x:\\";
  48. int i;
  49. for (drive_str[0] = 'A'; drive_str[0] <= 'Z'; drive_str[0]++)
  50. {
  51. if (GetDriveType(drive_str) == DRIVE_CDROM)
  52. {
  53. char **tmp = realloc(retval, sizeof (char *) * cd_count + 1);
  54. if (tmp)
  55. {
  56. retval = tmp;
  57. retval[cd_count-1] = (char *) malloc(4);
  58. if (retval[cd_count-1])
  59. {
  60. strcpy(retval[cd_count-1], drive_str);
  61. cd_count++;
  62. } /* if */
  63. } /* if */
  64. } /* if */
  65. } /* for */
  66. retval[cd_count - 1] = NULL;
  67. return(retval);
  68. } /* __PHYSFS_detectAvailableCDs */
  69. static char *copyEnvironmentVariable(const char *varname)
  70. {
  71. const char *envr = getenv(varname);
  72. char *retval = NULL;
  73. if (envr != NULL)
  74. {
  75. retval = malloc(strlen(envr) + 1);
  76. if (retval != NULL)
  77. strcpy(retval, envr);
  78. } /* if */
  79. return(retval);
  80. } /* copyEnvironmentVariable */
  81. char *__PHYSFS_platformCalcBaseDir(const char *argv0)
  82. {
  83. DWORD buflen = 0;
  84. char *retval = NULL;
  85. char *filepart = NULL;
  86. if (strchr(argv0, '\\') != NULL) /* default behaviour can handle this. */
  87. return(NULL);
  88. SearchPath(NULL, argv0, NULL, &buflen, NULL, NULL);
  89. retval = (char *) malloc(buflen);
  90. BAIL_IF_MACRO(!retval, ERR_OUT_OF_MEMORY, NULL);
  91. SearchPath(NULL, argv0, NULL, &buflen, retval, &filepart);
  92. return(retval);
  93. } /* __PHYSFS_platformCalcBaseDir */
  94. char *__PHYSFS_platformGetUserName(void)
  95. {
  96. LPDWORD bufsize = 0;
  97. LPTSTR retval = NULL;
  98. if (GetUserName(NULL, &bufsize) == 0) /* This SHOULD fail. */
  99. {
  100. retval = (LPTSTR) malloc(bufsize);
  101. BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
  102. if (GetUserName(retval, &bufsize) == 0) /* ?! */
  103. {
  104. free(retval);
  105. retval = NULL;
  106. } /* if */
  107. } /* if */
  108. return((char *) retval);
  109. } /* __PHYSFS_platformGetUserName */
  110. char *__PHYSFS_platformGetUserDir(void)
  111. {
  112. return(NULL); /* no user dir on win32. */
  113. } /* __PHYSFS_platformGetUserDir */
  114. int __PHYSFS_platformGetThreadID(void)
  115. {
  116. return((int) GetCurrentThreadId());
  117. } /* __PHYSFS_platformGetThreadID */
  118. int __PHYSFS_platformStricmp(const char *x, const char *y)
  119. {
  120. return(stricmp(x, y));
  121. } /* __PHYSFS_platformStricmp */
  122. int __PHYSFS_platformExists(const char *fname)
  123. {
  124. return(GetFileAttributes(fname) != 0xffffffff);
  125. } /* __PHYSFS_platformExists */
  126. int __PHYSFS_platformIsSymLink(const char *fname)
  127. {
  128. return(0); /* no symlinks on win32. */
  129. } /* __PHYSFS_platformIsSymlink */
  130. int __PHYSFS_platformIsDirectory(const char *fname)
  131. {
  132. return((GetFileAttributes(fname) & FILE_ATTRIBUTE_DIRECTORY) != 0);
  133. } /* __PHYSFS_platformIsDirectory */
  134. char *__PHYSFS_platformCvtToDependent(const char *prepend,
  135. const char *dirName,
  136. const char *append)
  137. {
  138. int len = ((prepend) ? strlen(prepend) : 0) +
  139. ((append) ? strlen(append) : 0) +
  140. strlen(dirName) + 1;
  141. char *retval = malloc(len);
  142. BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
  143. if (prepend)
  144. strcpy(retval, prepend);
  145. else
  146. retval[0] = '\0';
  147. strcat(retval, dirName);
  148. if (append)
  149. strcat(retval, append);
  150. for (p = strchr(retval, '/'); p != NULL; p = strchr(p + 1, '/'))
  151. *p = '\\';
  152. return(retval);
  153. } /* __PHYSFS_platformCvtToDependent */
  154. /* Much like my college days, try to sleep for 10 milliseconds at a time... */
  155. void __PHYSFS_platformTimeslice(void)
  156. {
  157. Sleep(10);
  158. } /* __PHYSFS_platformTimeslice */
  159. LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname,
  160. int omitSymLinks)
  161. {
  162. LinkedStringList *retval = NULL;
  163. LinkedStringList *l = NULL;
  164. LinkedStringList *prev = NULL;
  165. HANDLE dir;
  166. WIN32_FIND_DATA ent;
  167. dir = FindFirstFile(dirname, &ent);
  168. BAIL_IF_MACRO(dir == INVALID_HANDLE_VALUE, win32strerror(), NULL);
  169. for (; FineNextFile(dir, &ent) != 0; )
  170. {
  171. if (strcmp(ent.cFileName, ".") == 0)
  172. continue;
  173. if (strcmp(ent.cFileName, "..") == 0)
  174. continue;
  175. l = (LinkedStringList *) malloc(sizeof (LinkedStringList));
  176. if (l == NULL)
  177. break;
  178. l->str = (char *) malloc(strlen(ent.cFileName) + 1);
  179. if (l->str == NULL)
  180. {
  181. free(l);
  182. break;
  183. } /* if */
  184. strcpy(l->str, ent.cFileName);
  185. if (retval == NULL)
  186. retval = l;
  187. else
  188. prev->next = l;
  189. prev = l;
  190. l->next = NULL;
  191. } /* while */
  192. FindClose(dir);
  193. return(retval);
  194. } /* __PHYSFS_platformEnumerateFiles */
  195. int __PHYSFS_platformFileLength(FILE *handle)
  196. {
  197. fpos_t curpos;
  198. int retval;
  199. fgetpos(handle, &curpos);
  200. fseek(handle, 0, SEEK_END);
  201. retval = ftell(handle);
  202. fsetpos(handle, &curpos);
  203. return(retval);
  204. } /* __PHYSFS_platformFileLength */
  205. char *__PHYSFS_platformCurrentDir(void)
  206. {
  207. LPTSTR *retval;
  208. DWORD buflen = 0;
  209. GetCurrentDirectory(&buflen, NULL);
  210. retval = (LPTSTR) malloc(buflen);
  211. GetCurrentDirectory(&buflen, retval);
  212. return((char *) retval);
  213. } /* __PHYSFS_platformCurrentDir */
  214. char *__PHYSFS_platformRealPath(const char *path)
  215. {
  216. return(_fullpath(NULL, path, _MAX_PATH));
  217. } /* __PHYSFS_platformRealPath */
  218. int __PHYSFS_platformMkDir(const char *path)
  219. {
  220. rc = CreateDirectory(path, NULL);
  221. BAIL_IF_MACRO(rc == 0, win32strerror(), 0);
  222. return(1);
  223. } /* __PHYSFS_platformMkDir */
  224. /* end of win32.c ... */