Coverage Report

Created: 2024-05-20 06:11

/src/FreeRDP/winpr/libwinpr/path/shell.c
Line
Count
Source (jump to first uncovered line)
1
/**
2
 * WinPR: Windows Portable Runtime
3
 * Path Functions
4
 *
5
 * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6
 * Copyright 2016 David PHAM-VAN <d.phamvan@inuvika.com>
7
 *
8
 * Licensed under the Apache License, Version 2.0 (the "License");
9
 * you may not use this file except in compliance with the License.
10
 * You may obtain a copy of the License at
11
 *
12
 *     http://www.apache.org/licenses/LICENSE-2.0
13
 *
14
 * Unless required by applicable law or agreed to in writing, software
15
 * distributed under the License is distributed on an "AS IS" BASIS,
16
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
 * See the License for the specific language governing permissions and
18
 * limitations under the License.
19
 */
20
21
#include <winpr/config.h>
22
23
#include <stdio.h>
24
#include <stdlib.h>
25
#include <string.h>
26
#include <sys/stat.h>
27
28
#include <winpr/crt.h>
29
#include <winpr/platform.h>
30
#include <winpr/file.h>
31
#include <winpr/tchar.h>
32
#include <winpr/environment.h>
33
34
#include <winpr/path.h>
35
#include <winpr/wlog.h>
36
37
#include "../log.h"
38
#define TAG WINPR_TAG("path.shell")
39
40
#if defined(__IOS__)
41
#include "shell_ios.h"
42
#endif
43
44
#if defined(WIN32)
45
#include <shlobj.h>
46
#else
47
#include <errno.h>
48
#include <dirent.h>
49
#endif
50
51
static char* GetPath_XDG_CONFIG_HOME(void);
52
static char* GetPath_XDG_RUNTIME_DIR(void);
53
54
/**
55
 * SHGetKnownFolderPath function:
56
 * http://msdn.microsoft.com/en-us/library/windows/desktop/bb762188/
57
 */
58
59
/**
60
 * XDG Base Directory Specification:
61
 * http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
62
 */
63
64
char* GetEnvAlloc(LPCSTR lpName)
65
134k
{
66
134k
  DWORD nSize = 0;
67
134k
  DWORD nStatus = 0;
68
134k
  char* env = NULL;
69
70
134k
  nSize = GetEnvironmentVariableX(lpName, NULL, 0);
71
72
134k
  if (nSize > 0)
73
89.8k
  {
74
89.8k
    env = malloc(nSize);
75
76
89.8k
    if (!env)
77
0
      return NULL;
78
79
89.8k
    nStatus = GetEnvironmentVariableX(lpName, env, nSize);
80
81
89.8k
    if (nStatus != (nSize - 1))
82
0
    {
83
0
      free(env);
84
0
      return NULL;
85
0
    }
86
89.8k
  }
87
88
134k
  return env;
89
134k
}
90
91
static char* GetPath_HOME(void)
92
89.8k
{
93
89.8k
  char* path = NULL;
94
#ifdef _WIN32
95
  path = GetEnvAlloc("UserProfile");
96
#elif defined(__IOS__)
97
  path = ios_get_home();
98
#else
99
89.8k
  path = GetEnvAlloc("HOME");
100
89.8k
#endif
101
89.8k
  return path;
102
89.8k
}
103
104
static char* GetPath_TEMP(void)
105
0
{
106
0
  char* path = NULL;
107
#ifdef _WIN32
108
  path = GetEnvAlloc("TEMP");
109
#elif defined(__IOS__)
110
  path = ios_get_temp();
111
#else
112
0
  path = GetEnvAlloc("TMPDIR");
113
114
0
  if (!path)
115
0
    path = _strdup("/tmp");
116
117
0
#endif
118
0
  return path;
119
0
}
120
121
static char* GetPath_XDG_DATA_HOME(void)
122
0
{
123
0
  char* path = NULL;
124
#if defined(WIN32) || defined(__IOS__)
125
  path = GetPath_XDG_CONFIG_HOME();
126
#else
127
0
  size_t size = 0;
128
0
  char* home = NULL;
129
  /**
130
   * There is a single base directory relative to which user-specific data files should be
131
   * written. This directory is defined by the environment variable $XDG_DATA_HOME.
132
   *
133
   * $XDG_DATA_HOME defines the base directory relative to which user specific data files should
134
   * be stored. If $XDG_DATA_HOME is either not set or empty, a default equal to
135
   * $HOME/.local/share should be used.
136
   */
137
0
  path = GetEnvAlloc("XDG_DATA_HOME");
138
139
0
  if (path)
140
0
    return path;
141
142
0
  home = GetPath_HOME();
143
144
0
  if (!home)
145
0
    return NULL;
146
147
0
  size = strlen(home) + strlen("/.local/share") + 1;
148
0
  path = (char*)malloc(size);
149
150
0
  if (!path)
151
0
  {
152
0
    free(home);
153
0
    return NULL;
154
0
  }
155
156
0
  sprintf_s(path, size, "%s%s", home, "/.local/share");
157
0
  free(home);
158
0
#endif
159
0
  return path;
160
0
}
161
162
static char* GetPath_XDG_CONFIG_HOME(void)
163
44.9k
{
164
44.9k
  char* path = NULL;
165
#if defined(WIN32) && !defined(_UWP)
166
  path = calloc(MAX_PATH, sizeof(char));
167
168
  if (!path)
169
    return NULL;
170
171
  if (FAILED(SHGetFolderPathA(0, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, path)))
172
  {
173
    free(path);
174
    return NULL;
175
  }
176
177
#elif defined(__IOS__)
178
  path = ios_get_data();
179
#else
180
44.9k
  size_t size = 0;
181
44.9k
  char* home = NULL;
182
  /**
183
   * There is a single base directory relative to which user-specific configuration files should
184
   * be written. This directory is defined by the environment variable $XDG_CONFIG_HOME.
185
   *
186
   * $XDG_CONFIG_HOME defines the base directory relative to which user specific configuration
187
   * files should be stored. If $XDG_CONFIG_HOME is either not set or empty, a default equal to
188
   * $HOME/.config should be used.
189
   */
190
44.9k
  path = GetEnvAlloc("XDG_CONFIG_HOME");
191
192
44.9k
  if (path)
193
0
    return path;
194
195
44.9k
  home = GetPath_HOME();
196
197
44.9k
  if (!home)
198
0
    home = GetPath_TEMP();
199
200
44.9k
  if (!home)
201
0
    return NULL;
202
203
44.9k
  size = strlen(home) + strlen("/.config") + 1;
204
44.9k
  path = (char*)malloc(size);
205
206
44.9k
  if (!path)
207
0
  {
208
0
    free(home);
209
0
    return NULL;
210
0
  }
211
212
44.9k
  sprintf_s(path, size, "%s%s", home, "/.config");
213
44.9k
  free(home);
214
44.9k
#endif
215
44.9k
  return path;
216
44.9k
}
217
218
static char* GetPath_XDG_CACHE_HOME(void)
219
0
{
220
0
  char* path = NULL;
221
0
  char* home = NULL;
222
#if defined(WIN32)
223
  home = GetPath_XDG_RUNTIME_DIR();
224
225
  if (home)
226
  {
227
    path = GetCombinedPath(home, "cache");
228
229
    if (!winpr_PathFileExists(path))
230
      if (!CreateDirectoryA(path, NULL))
231
        path = NULL;
232
  }
233
234
  free(home);
235
#elif defined(__IOS__)
236
  path = ios_get_cache();
237
#else
238
0
  size_t size = 0;
239
  /**
240
   * There is a single base directory relative to which user-specific non-essential (cached) data
241
   * should be written. This directory is defined by the environment variable $XDG_CACHE_HOME.
242
   *
243
   * $XDG_CACHE_HOME defines the base directory relative to which user specific non-essential data
244
   * files should be stored. If $XDG_CACHE_HOME is either not set or empty, a default equal to
245
   * $HOME/.cache should be used.
246
   */
247
0
  path = GetEnvAlloc("XDG_CACHE_HOME");
248
249
0
  if (path)
250
0
    return path;
251
252
0
  home = GetPath_HOME();
253
254
0
  if (!home)
255
0
    return NULL;
256
257
0
  size = strlen(home) + strlen("/.cache") + 1;
258
0
  path = (char*)malloc(size);
259
260
0
  if (!path)
261
0
  {
262
0
    free(home);
263
0
    return NULL;
264
0
  }
265
266
0
  sprintf_s(path, size, "%s%s", home, "/.cache");
267
0
  free(home);
268
0
#endif
269
0
  return path;
270
0
}
271
272
char* GetPath_XDG_RUNTIME_DIR(void)
273
0
{
274
0
  char* path = NULL;
275
#if defined(WIN32) && !defined(_UWP)
276
  path = calloc(MAX_PATH, sizeof(char));
277
278
  if (!path)
279
    return NULL;
280
281
  if (FAILED(SHGetFolderPathA(0, CSIDL_LOCAL_APPDATA, NULL, SHGFP_TYPE_CURRENT, path)))
282
  {
283
    free(path);
284
    return NULL;
285
  }
286
287
#else
288
  /**
289
   * There is a single base directory relative to which user-specific runtime files and other file
290
   * objects should be placed. This directory is defined by the environment variable
291
   * $XDG_RUNTIME_DIR.
292
   *
293
   * $XDG_RUNTIME_DIR defines the base directory relative to which user-specific non-essential
294
   * runtime files and other file objects (such as sockets, named pipes, ...) should be stored.
295
   * The directory MUST be owned by the user, and he MUST be the only one having read and write
296
   * access to it. Its Unix access mode MUST be 0700.
297
   *
298
   * The lifetime of the directory MUST be bound to the user being logged in. It MUST be created
299
   * when the user first logs in and if the user fully logs out the directory MUST be removed. If
300
   * the user logs in more than once he should get pointed to the same directory, and it is
301
   * mandatory that the directory continues to exist from his first login to his last logout on
302
   * the system, and not removed in between. Files in the directory MUST not survive reboot or a
303
   * full logout/login cycle.
304
   *
305
   * The directory MUST be on a local file system and not shared with any other system. The
306
   * directory MUST by fully-featured by the standards of the operating system. More specifically,
307
   * on Unix-like operating systems AF_UNIX sockets, symbolic links, hard links, proper
308
   * permissions, file locking, sparse files, memory mapping, file change notifications, a
309
   * reliable hard link count must be supported, and no restrictions on the file name character
310
   * set should be imposed. Files in this directory MAY be subjected to periodic clean-up. To
311
   * ensure that your files are not removed, they should have their access time timestamp modified
312
   * at least once every 6 hours of monotonic time or the 'sticky' bit should be set on the file.
313
   *
314
   * If $XDG_RUNTIME_DIR is not set applications should fall back to a replacement directory with
315
   * similar capabilities and print a warning message. Applications should use this directory for
316
   * communication and synchronization purposes and should not place larger files in it, since it
317
   * might reside in runtime memory and cannot necessarily be swapped out to disk.
318
   */
319
0
  path = GetEnvAlloc("XDG_RUNTIME_DIR");
320
0
#endif
321
322
0
  if (path)
323
0
    return path;
324
325
0
  path = GetPath_TEMP();
326
0
  return path;
327
0
}
328
329
char* GetKnownPath(int id)
330
89.8k
{
331
89.8k
  char* path = NULL;
332
333
89.8k
  switch (id)
334
89.8k
  {
335
44.9k
    case KNOWN_PATH_HOME:
336
44.9k
      path = GetPath_HOME();
337
44.9k
      break;
338
339
0
    case KNOWN_PATH_TEMP:
340
0
      path = GetPath_TEMP();
341
0
      break;
342
343
0
    case KNOWN_PATH_XDG_DATA_HOME:
344
0
      path = GetPath_XDG_DATA_HOME();
345
0
      break;
346
347
44.9k
    case KNOWN_PATH_XDG_CONFIG_HOME:
348
44.9k
      path = GetPath_XDG_CONFIG_HOME();
349
44.9k
      break;
350
351
0
    case KNOWN_PATH_XDG_CACHE_HOME:
352
0
      path = GetPath_XDG_CACHE_HOME();
353
0
      break;
354
355
0
    case KNOWN_PATH_XDG_RUNTIME_DIR:
356
0
      path = GetPath_XDG_RUNTIME_DIR();
357
0
      break;
358
359
0
    default:
360
0
      path = NULL;
361
0
      break;
362
89.8k
  }
363
364
89.8k
  if (!path)
365
89.8k
    WLog_WARN(TAG, "Path %s is %p", GetKnownPathIdString(id), path);
366
89.8k
  return path;
367
89.8k
}
368
369
char* GetKnownSubPath(int id, const char* path)
370
44.9k
{
371
44.9k
  char* subPath = NULL;
372
44.9k
  char* knownPath = NULL;
373
44.9k
  knownPath = GetKnownPath(id);
374
375
44.9k
  if (!knownPath)
376
0
    return NULL;
377
378
44.9k
  subPath = GetCombinedPath(knownPath, path);
379
44.9k
  free(knownPath);
380
44.9k
  return subPath;
381
44.9k
}
382
383
char* GetEnvironmentPath(char* name)
384
0
{
385
0
  char* env = NULL;
386
0
  DWORD nSize = 0;
387
0
  DWORD nStatus = 0;
388
0
  nSize = GetEnvironmentVariableX(name, NULL, 0);
389
390
0
  if (nSize)
391
0
  {
392
0
    env = (LPSTR)malloc(nSize);
393
394
0
    if (!env)
395
0
      return NULL;
396
397
0
    nStatus = GetEnvironmentVariableX(name, env, nSize);
398
399
0
    if (nStatus != (nSize - 1))
400
0
    {
401
0
      free(env);
402
0
      return NULL;
403
0
    }
404
0
  }
405
406
0
  return env;
407
0
}
408
409
char* GetEnvironmentSubPath(char* name, const char* path)
410
0
{
411
0
  char* env = NULL;
412
0
  char* subpath = NULL;
413
0
  env = GetEnvironmentPath(name);
414
415
0
  if (!env)
416
0
    return NULL;
417
418
0
  subpath = GetCombinedPath(env, path);
419
0
  free(env);
420
0
  return subpath;
421
0
}
422
423
char* GetCombinedPath(const char* basePath, const char* subPath)
424
44.9k
{
425
44.9k
  size_t length = 0;
426
44.9k
  HRESULT status = 0;
427
44.9k
  char* path = NULL;
428
44.9k
  char* subPathCpy = NULL;
429
44.9k
  size_t basePathLength = 0;
430
44.9k
  size_t subPathLength = 0;
431
432
44.9k
  if (basePath)
433
44.9k
    basePathLength = strlen(basePath);
434
435
44.9k
  if (subPath)
436
44.9k
    subPathLength = strlen(subPath);
437
438
44.9k
  length = basePathLength + subPathLength + 1;
439
44.9k
  path = (char*)calloc(1, length + 1);
440
441
44.9k
  if (!path)
442
0
    goto fail;
443
444
44.9k
  if (basePath)
445
44.9k
    CopyMemory(path, basePath, basePathLength);
446
447
44.9k
  if (FAILED(PathCchConvertStyleA(path, basePathLength, PATH_STYLE_NATIVE)))
448
0
    goto fail;
449
450
44.9k
  if (!subPath)
451
0
    return path;
452
453
44.9k
  subPathCpy = _strdup(subPath);
454
455
44.9k
  if (!subPathCpy)
456
0
    goto fail;
457
458
44.9k
  if (FAILED(PathCchConvertStyleA(subPathCpy, subPathLength, PATH_STYLE_NATIVE)))
459
0
    goto fail;
460
461
44.9k
  status = NativePathCchAppendA(path, length + 1, subPathCpy);
462
44.9k
  if (FAILED(status))
463
0
    goto fail;
464
465
44.9k
  free(subPathCpy);
466
44.9k
  return path;
467
468
0
fail:
469
0
  free(path);
470
0
  free(subPathCpy);
471
0
  return NULL;
472
44.9k
}
473
474
BOOL PathMakePathA(LPCSTR path, LPSECURITY_ATTRIBUTES lpAttributes)
475
0
{
476
#if defined(_UWP)
477
  return FALSE;
478
#elif defined(_WIN32)
479
  return (SHCreateDirectoryExA(NULL, path, lpAttributes) == ERROR_SUCCESS);
480
#else
481
0
  const char delim = PathGetSeparatorA(PATH_STYLE_NATIVE);
482
0
  char* dup = NULL;
483
0
  BOOL result = TRUE;
484
  /* we only operate on a non-null, absolute path */
485
#if defined(__OS2__)
486
487
  if (!path)
488
    return FALSE;
489
490
#else
491
492
0
  if (!path || *path != delim)
493
0
    return FALSE;
494
495
0
#endif
496
497
0
  if (!(dup = _strdup(path)))
498
0
    return FALSE;
499
500
#ifdef __OS2__
501
  p = (strlen(dup) > 3) && (dup[1] == ':') && (dup[2] == delim)) ? &dup[3] : dup;
502
503
  while (p)
504
#else
505
0
  for (char* p = dup; p;)
506
0
#endif
507
0
  {
508
0
    if ((p = strchr(p + 1, delim)))
509
0
      *p = '\0';
510
511
0
    if (mkdir(dup, 0777) != 0)
512
0
      if (errno != EEXIST)
513
0
      {
514
0
        result = FALSE;
515
0
        break;
516
0
      }
517
518
0
    if (p)
519
0
      *p = delim;
520
0
  }
521
522
0
  free(dup);
523
0
  return (result);
524
0
#endif
525
0
}
526
527
BOOL PathMakePathW(LPCWSTR path, LPSECURITY_ATTRIBUTES lpAttributes)
528
0
{
529
#if defined(_UWP)
530
  return FALSE;
531
#elif defined(_WIN32)
532
  return (SHCreateDirectoryExW(NULL, path, lpAttributes) == ERROR_SUCCESS);
533
#else
534
0
  const WCHAR wdelim = PathGetSeparatorW(PATH_STYLE_NATIVE);
535
0
  const char delim = PathGetSeparatorA(PATH_STYLE_NATIVE);
536
0
  char* dup = NULL;
537
0
  BOOL result = TRUE;
538
  /* we only operate on a non-null, absolute path */
539
#if defined(__OS2__)
540
541
  if (!path)
542
    return FALSE;
543
544
#else
545
546
0
  if (!path || *path != wdelim)
547
0
    return FALSE;
548
549
0
#endif
550
551
0
  dup = ConvertWCharToUtf8Alloc(path, NULL);
552
0
  if (!dup)
553
0
    return FALSE;
554
555
#ifdef __OS2__
556
  p = (strlen(dup) > 3) && (dup[1] == ':') && (dup[2] == delim)) ? &dup[3] : dup;
557
558
  while (p)
559
#else
560
0
  for (char* p = dup; p;)
561
0
#endif
562
0
  {
563
0
    if ((p = strchr(p + 1, delim)))
564
0
      *p = '\0';
565
566
0
    if (mkdir(dup, 0777) != 0)
567
0
      if (errno != EEXIST)
568
0
      {
569
0
        result = FALSE;
570
0
        break;
571
0
      }
572
573
0
    if (p)
574
0
      *p = delim;
575
0
  }
576
577
0
  free(dup);
578
0
  return (result);
579
0
#endif
580
0
}
581
582
#if !defined(_WIN32) || defined(_UWP)
583
584
BOOL PathIsRelativeA(LPCSTR pszPath)
585
0
{
586
0
  if (!pszPath)
587
0
    return FALSE;
588
589
0
  return pszPath[0] != '/';
590
0
}
591
592
BOOL PathIsRelativeW(LPCWSTR pszPath)
593
0
{
594
0
  LPSTR lpFileNameA = NULL;
595
0
  BOOL ret = FALSE;
596
597
0
  if (!pszPath)
598
0
    goto fail;
599
600
0
  lpFileNameA = ConvertWCharToUtf8Alloc(pszPath, NULL);
601
0
  if (!lpFileNameA)
602
0
    goto fail;
603
0
  ret = PathIsRelativeA(lpFileNameA);
604
0
fail:
605
0
  free(lpFileNameA);
606
0
  return ret;
607
0
}
608
609
BOOL PathFileExistsA(LPCSTR pszPath)
610
0
{
611
0
  struct stat stat_info;
612
613
0
  if (stat(pszPath, &stat_info) != 0)
614
0
    return FALSE;
615
616
0
  return TRUE;
617
0
}
618
619
BOOL PathFileExistsW(LPCWSTR pszPath)
620
0
{
621
0
  LPSTR lpFileNameA = NULL;
622
0
  BOOL ret = FALSE;
623
624
0
  if (!pszPath)
625
0
    goto fail;
626
0
  lpFileNameA = ConvertWCharToUtf8Alloc(pszPath, NULL);
627
0
  if (!lpFileNameA)
628
0
    goto fail;
629
630
0
  ret = winpr_PathFileExists(lpFileNameA);
631
0
fail:
632
0
  free(lpFileNameA);
633
0
  return ret;
634
0
}
635
636
BOOL PathIsDirectoryEmptyA(LPCSTR pszPath)
637
0
{
638
0
  struct dirent* dp = NULL;
639
0
  int empty = 1;
640
0
  DIR* dir = opendir(pszPath);
641
642
0
  if (dir == NULL) /* Not a directory or doesn't exist */
643
0
    return 1;
644
645
0
  while ((dp = readdir(dir)) != NULL)
646
0
  {
647
0
    if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0)
648
0
      continue; /* Skip . and .. */
649
650
0
    empty = 0;
651
0
    break;
652
0
  }
653
654
0
  closedir(dir);
655
0
  return empty;
656
0
}
657
658
BOOL PathIsDirectoryEmptyW(LPCWSTR pszPath)
659
0
{
660
0
  LPSTR lpFileNameA = NULL;
661
0
  BOOL ret = FALSE;
662
0
  if (!pszPath)
663
0
    goto fail;
664
0
  lpFileNameA = ConvertWCharToUtf8Alloc(pszPath, NULL);
665
0
  if (!lpFileNameA)
666
0
    goto fail;
667
0
  ret = PathIsDirectoryEmptyA(lpFileNameA);
668
0
fail:
669
0
  free(lpFileNameA);
670
0
  return ret;
671
0
}
672
673
#endif
674
675
BOOL winpr_MoveFile(LPCSTR lpExistingFileName, LPCSTR lpNewFileName)
676
0
{
677
0
#ifndef _WIN32
678
0
  return MoveFileA(lpExistingFileName, lpNewFileName);
679
#else
680
  BOOL result = FALSE;
681
  LPWSTR lpExistingFileNameW = NULL;
682
  LPWSTR lpNewFileNameW = NULL;
683
684
  if (!lpExistingFileName || !lpNewFileName)
685
    return FALSE;
686
687
  lpExistingFileNameW = ConvertUtf8ToWCharAlloc(lpExistingFileName, NULL);
688
  if (!lpExistingFileNameW)
689
    goto cleanup;
690
  lpNewFileNameW = ConvertUtf8ToWCharAlloc(lpNewFileName, NULL);
691
  if (!lpNewFileNameW)
692
    goto cleanup;
693
694
  result = MoveFileW(lpExistingFileNameW, lpNewFileNameW);
695
696
cleanup:
697
  free(lpExistingFileNameW);
698
  free(lpNewFileNameW);
699
  return result;
700
#endif
701
0
}
702
703
BOOL winpr_MoveFileEx(LPCSTR lpExistingFileName, LPCSTR lpNewFileName, DWORD dwFlags)
704
0
{
705
0
#ifndef _WIN32
706
0
  return MoveFileExA(lpExistingFileName, lpNewFileName, dwFlags);
707
#else
708
  BOOL result = FALSE;
709
  LPWSTR lpExistingFileNameW = NULL;
710
  LPWSTR lpNewFileNameW = NULL;
711
712
  if (!lpExistingFileName || !lpNewFileName)
713
    return FALSE;
714
715
  lpExistingFileNameW = ConvertUtf8ToWCharAlloc(lpExistingFileName, NULL);
716
  if (!lpExistingFileNameW)
717
    goto cleanup;
718
  lpNewFileNameW = ConvertUtf8ToWCharAlloc(lpNewFileName, NULL);
719
  if (!lpNewFileNameW)
720
    goto cleanup;
721
722
  result = MoveFileExW(lpExistingFileNameW, lpNewFileNameW, dwFlags);
723
724
cleanup:
725
  free(lpExistingFileNameW);
726
  free(lpNewFileNameW);
727
  return result;
728
#endif
729
0
}
730
731
BOOL winpr_DeleteFile(const char* lpFileName)
732
0
{
733
0
#ifndef _WIN32
734
0
  return DeleteFileA(lpFileName);
735
#else
736
  LPWSTR lpFileNameW = NULL;
737
  BOOL result = FALSE;
738
739
  if (lpFileName)
740
  {
741
    lpFileNameW = ConvertUtf8ToWCharAlloc(lpFileName, NULL);
742
    if (!lpFileNameW)
743
      goto cleanup;
744
  }
745
746
  result = DeleteFileW(lpFileNameW);
747
748
cleanup:
749
  free(lpFileNameW);
750
  return result;
751
#endif
752
0
}
753
754
BOOL winpr_RemoveDirectory(LPCSTR lpPathName)
755
0
{
756
0
#ifndef _WIN32
757
0
  return RemoveDirectoryA(lpPathName);
758
#else
759
  LPWSTR lpPathNameW = NULL;
760
  BOOL result = FALSE;
761
762
  if (lpPathName)
763
  {
764
    lpPathNameW = ConvertUtf8ToWCharAlloc(lpPathName, NULL);
765
    if (!lpPathNameW)
766
      goto cleanup;
767
  }
768
769
  result = RemoveDirectoryW(lpPathNameW);
770
771
cleanup:
772
  free(lpPathNameW);
773
  return result;
774
#endif
775
0
}
776
777
BOOL winpr_PathFileExists(const char* pszPath)
778
0
{
779
0
  if (!pszPath)
780
0
    return FALSE;
781
0
#ifndef _WIN32
782
0
  return PathFileExistsA(pszPath);
783
#else
784
  WCHAR* pathW = ConvertUtf8ToWCharAlloc(pszPath, NULL);
785
  BOOL result = FALSE;
786
787
  if (!pathW)
788
    return FALSE;
789
790
  result = PathFileExistsW(pathW);
791
  free(pathW);
792
793
  return result;
794
#endif
795
0
}
796
797
BOOL winpr_PathMakePath(const char* path, LPSECURITY_ATTRIBUTES lpAttributes)
798
0
{
799
0
  if (!path)
800
0
    return FALSE;
801
0
#ifndef _WIN32
802
0
  return PathMakePathA(path, lpAttributes);
803
#else
804
  WCHAR* pathW = ConvertUtf8ToWCharAlloc(path, NULL);
805
  BOOL result = FALSE;
806
807
  if (!pathW)
808
    return FALSE;
809
810
  result = SHCreateDirectoryExW(NULL, pathW, lpAttributes) == ERROR_SUCCESS;
811
  free(pathW);
812
813
  return result;
814
#endif
815
0
}