]> cygwin.com Git - cygwin-apps/setup.git/blame - mkdir.cc
Added dpiAwareness element to manifest
[cygwin-apps/setup.git] / mkdir.cc
CommitLineData
23c9e63c
DD
1/*
2 * Copyright (c) 2000, Red Hat, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * A copy of the GNU General Public License can be found at
10 * http://www.gnu.org/
11 *
12 * Written by DJ Delorie <dj@cygnus.com>
13 *
14 */
15
16/* see mkdir.h */
17
18#include "win32.h"
6dcfeb7d 19#include "ntdll.h"
89cc2408
CV
20
21#include <sys/stat.h>
23c9e63c
DD
22
23#include "mkdir.h"
2f0315ad 24#include "filemanip.h"
781a9555 25#include "LogSingleton.h"
23c9e63c 26
70e4bf04 27/* Return 0 on success.
a5104a04 28 A mode of 0 means no POSIX perms. */
23c9e63c 29int
b41c2908 30mkdir_p (int isadir, const char *in_path, mode_t mode)
23c9e63c
DD
31{
32 char saved_char, *slash = 0;
33 char *c;
2f0315ad
CV
34 const size_t len = strlen (in_path) + 1;
35 char path[len];
aa1e3b4d 36 DWORD d, gse;
2f0315ad
CV
37 WCHAR wpath[len + 6];
38
85b43844 39 strcpy (path, in_path);
1e029da2 40 mklongpath (wpath, path, len + 6);
23c9e63c 41
1e029da2 42 d = GetFileAttributesW (wpath);
2f0315ad 43 if (d != INVALID_FILE_ATTRIBUTES && d & FILE_ATTRIBUTE_DIRECTORY)
23c9e63c
DD
44 return 0;
45
46 if (isadir)
47 {
1e029da2
YS
48 NTSTATUS status;
49 HANDLE dir;
50 UNICODE_STRING upath;
51 OBJECT_ATTRIBUTES attr;
52 IO_STATUS_BLOCK io;
53 SECURITY_DESCRIPTOR sd;
54 acl_t acl;
55
56 wpath[1] = '?';
57 upath.Length = wcslen (wpath) * sizeof (WCHAR);
58 upath.MaximumLength = upath.Length + sizeof (WCHAR);
59 upath.Buffer = wpath;
60 InitializeObjectAttributes (&attr, &upath, OBJ_CASE_INSENSITIVE, NULL,
61 mode == 0 ? NULL
62 : nt_sec.GetPosixPerms (path, NULL, NULL,
63 S_IFDIR | mode,
64 sd, acl));
65 status = NtCreateFile (&dir, SYNCHRONIZE | READ_CONTROL
66 | FILE_LIST_DIRECTORY,
67 &attr, &io, NULL, FILE_ATTRIBUTE_DIRECTORY,
68 FILE_SHARE_VALID_FLAGS, FILE_CREATE,
69 FILE_DIRECTORY_FILE
70 | FILE_SYNCHRONOUS_IO_NONALERT
71 | FILE_OPEN_FOR_BACKUP_INTENT, NULL, 0);
72 if (NT_SUCCESS (status))
73 {
74 NtClose (dir);
75 return 0;
76 }
77 else
78 SetLastError (RtlNtStatusToDosError (status));
23c9e63c 79 gse = GetLastError ();
89725f30 80 if (gse != ERROR_PATH_NOT_FOUND && gse != ERROR_FILE_NOT_FOUND)
23c9e63c
DD
81 {
82 if (gse == ERROR_ALREADY_EXISTS)
83 {
781a9555
JT
84 Log (LOG_TIMESTAMP) << "warning: deleting \"" << path
85 << "\" so I can make a directory there" << endLog;
1e029da2 86 if (DeleteFileW (wpath))
d2a5fdfb 87 return mkdir_p (isadir, path, mode ? 0755 : 0);
23c9e63c
DD
88 }
89 return 1;
90 }
91 }
92
85b43844 93 for (c = path; *c; c++)
23c9e63c 94 {
23c9e63c
DD
95 if (*c == '/' || *c == '\\')
96 slash = c;
97 }
98
99 if (!slash)
100 return 0;
101
f2e49cf8
RC
102 // Trying to create a drive... It's time to give up.
103 if (((slash - path) == 2) && (path[1] == ':'))
104 return 1;
105
23c9e63c
DD
106 saved_char = *slash;
107 *slash = 0;
d2a5fdfb 108 if (mkdir_p (1, path, mode ? 0755 : 0))
23c9e63c
DD
109 {
110 *slash = saved_char;
111 return 1;
112 }
f2e49cf8 113
23c9e63c
DD
114 *slash = saved_char;
115
116 if (!isadir)
117 return 0;
118
b41c2908 119 return mkdir_p (isadir, path, mode);
23c9e63c 120}
This page took 0.1589 seconds and 6 git commands to generate.