1 /********************************************************************/
2 /* */
3 /* cmd_win.c Command functions which call the Windows API. */
4 /* Copyright (C) 1989 - 2016, 2020 Thomas Mertes */
5 /* */
6 /* This file is part of the Seed7 Runtime Library. */
7 /* */
8 /* The Seed7 Runtime Library is free software; you can */
9 /* redistribute it and/or modify it under the terms of the GNU */
10 /* Lesser General Public License as published by the Free Software */
11 /* Foundation; either version 2.1 of the License, or (at your */
12 /* option) any later version. */
13 /* */
14 /* The Seed7 Runtime Library is distributed in the hope that it */
15 /* will be useful, but WITHOUT ANY WARRANTY; without even the */
16 /* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR */
17 /* PURPOSE. See the GNU Lesser General Public License for more */
18 /* details. */
19 /* */
20 /* You should have received a copy of the GNU Lesser General */
21 /* Public License along with this program; if not, write to the */
22 /* Free Software Foundation, Inc., 51 Franklin Street, */
23 /* Fifth Floor, Boston, MA 02110-1301, USA. */
24 /* */
25 /* Module: Seed7 Runtime Library */
26 /* File: seed7/src/cmd_win.c */
27 /* Changes: 2010 - 2016, 2020 Thomas Mertes */
28 /* Content: Command functions which call the Windows API. */
29 /* */
30 /********************************************************************/
31
32 #define LOG_FUNCTIONS 0
33 #define VERBOSE_EXCEPTIONS 0
34
35 #include "version.h"
36
37 #include "stdlib.h"
38 #include "stdio.h"
39 #include "windows.h"
40 #if ACLAPI_H_PRESENT
41 #include "aclapi.h"
42 #endif
43 #include "io.h"
44 #include "fcntl.h"
45 #ifdef OS_STRI_WCHAR
46 #include "wchar.h"
47 #endif
48
49 #include "common.h"
50 #include "data_rtl.h"
51 #include "heaputl.h"
52 #include "striutl.h"
53 #include "str_rtl.h"
54 #include "rtl_err.h"
55
56 #undef EXTERN
57 #define EXTERN
58 #include "cmd_drv.h"
59
60
61 #ifndef PATH_MAX
62 #define PATH_MAX 2048
63 #endif
64
65 #if !ACLAPI_H_PRESENT
66 #define SE_FILE_OBJECT 1
67 DWORD GetNamedSecurityInfoW (LPCWSTR pObjectName,
68 int objectType, SECURITY_INFORMATION securityInfo,
69 PSID *ppsidOwner, PSID *ppsidGroup,
70 PACL *ppDacl, PACL *ppSacl,
71 PSECURITY_DESCRIPTOR *ppSecurityDescriptor);
72 DWORD SetNamedSecurityInfoW (LPWSTR pObjectName,
73 int objectType, SECURITY_INFORMATION securityInfo,
74 PSID psidOwner, PSID psidGroup,
75 PACL pDacl, PACL pSacl);
76 #endif
77
78
79
80 #if defined OS_STRI_WCHAR && !defined USE_WMAIN
81 #ifdef DEFINE_COMMAND_LINE_TO_ARGV_W
82 #define CommandLineToArgvW MyCommandLineToArgvW
83 /**
84 * Special handling of backslash characters for CommandLineToArgvW.
85 * CommandLineToArgvW reads arguments in two modes. Inside and
86 * outside quotation mode. The following rules apply if a
87 * backslash is encountered:
88 * - 2n backslashes followed by a quotation mark produce
89 * n backslashes and a switch from inside to outside quotation
90 * mode and vice versa. In this case the quotation mark is not
91 * added to the argument.
92 * - (2n) + 1 backslashes followed by a quotation mark produce
93 * n backslashes followed by a quotation mark. In this case the
94 * quotation mark is added to the argument and the quotation mode
95 + is not changed.
96 * - n backslashes not followed by a quotation mark simply produce
97 * n backslashes.
98 */
processBackslash(const_os_striType * sourcePos,os_striType * destPos)99 static void processBackslash (const_os_striType *sourcePos, os_striType *destPos)
100
101 {
102 memSizeType backslashCount;
103 memSizeType count;
104
105 /* processBackslash */
106 backslashCount = 1;
107 (*sourcePos)++;
108 while (**sourcePos == '\\') {
109 backslashCount++;
110 (*sourcePos)++;
111 } /* while */
112 if (**sourcePos == '"') {
113 /* Backslashes in the result: backslashCount / 2 */
114 for (count = backslashCount >> 1; count > 0; count--) {
115 **destPos = '\\';
116 (*destPos)++;
117 } /* for */
118 if (backslashCount & 1) {
119 /* Add a quotation mark (") to the result. */
120 **destPos = '"';
121 (*destPos)++;
122 /* Stay in current quotation mode */
123 (*sourcePos)++;
124 } else {
125 /* Ignore the quotation mark ("). */
126 /* Switch from inside to outside quotation mode */
127 /* and vice versa. */
128 } /* if */
129 } else {
130 /* N backslashes not followed by a quotation mark */
131 /* simply produce n backslashes. */
132 for (count = backslashCount; count > 0; count--) {
133 **destPos = '\\';
134 (*destPos)++;
135 } /* for */
136 } /* if */
137 } /* processBackslash */
138
139
140
141 /**
142 * Parse commandLine and generate an array of pointers to the arguments.
143 * The parameter w_argc and the returned array of pointers (w_argv)
144 * correspond to the parameters argc and argv of main().
145 * The rules to recognize the first argument (the command) are
146 * different from the rules to recognize the other (normal) arguments.
147 * Arguments can be quoted or unquoted. Normal arguments (all except
148 * the first argument) can consist of quoted and unquoted parts. The
149 * quoted and unquoted parts that are concatenated to form one argument.
150 * To handle quoted and unquoted parts the function works with two
151 * modes: Inside and outside quotation mode.
152 * @param w_argc Address to which the argument count is copied.
153 * @return an array of pointers to the arguments of commandLine.
154 */
CommandLineToArgvW(const_os_striType commandLine,int * w_argc)155 static os_striType *CommandLineToArgvW (const_os_striType commandLine, int *w_argc)
156
157 {
158 size_t command_line_size;
159 const_os_striType sourcePos;
160 os_striType destPos;
161 os_striType destBuffer;
162 memSizeType argumentCount;
163 os_striType *w_argv;
164
165 /* CommandLineToArgvW */
166 command_line_size = os_stri_strlen(commandLine);
167 argumentCount = 0;
168 w_argv = (os_striType *) malloc(command_line_size * sizeof(os_striType *));
169 if (w_argv != NULL) {
170 sourcePos = commandLine;
171 while (*sourcePos == ' ') {
172 sourcePos++;
173 } /* while */
174 if (*sourcePos == 0) {
175 w_argv[0] = NULL;
176 } else {
177 if (unlikely(!os_stri_alloc(destBuffer, command_line_size))) {
178 free(w_argv);
179 w_argv = NULL;
180 } else {
181 /* Set pointer to first char of first argument */
182 w_argv[0] = destBuffer;
183 argumentCount = 1;
184 destPos = destBuffer;
185 if (*sourcePos == '"') {
186 sourcePos++;
187 while (*sourcePos != '"' && *sourcePos != 0) {
188 *destPos = *sourcePos;
189 sourcePos++;
190 destPos++;
191 } /* if */
192 } else {
193 while (*sourcePos != ' ' && *sourcePos != 0) {
194 *destPos = *sourcePos;
195 sourcePos++;
196 destPos++;
197 } /* if */
198 } /* if */
199 if (*sourcePos != 0) {
200 do {
201 sourcePos++;
202 } while (*sourcePos == ' ');
203 if (*sourcePos != 0) {
204 /* Terminate the current argument */
205 *destPos = 0;
206 destPos++;
207 /* Set pointer to first char of next argument */
208 w_argv[argumentCount] = destPos;
209 argumentCount++;
210 } /* if */
211 } /* if */
212 while (*sourcePos != 0) {
213 /* printf("source char: %d\n", *sourcePos); */
214 if (*sourcePos == '"') {
215 /* Inside quotation mode */
216 sourcePos++;
217 while (*sourcePos != '"' && *sourcePos != 0) {
218 if (*sourcePos == '\\') {
219 processBackslash(&sourcePos, &destPos);
220 } else {
221 *destPos = *sourcePos;
222 sourcePos++;
223 destPos++;
224 } /* if */
225 } /* while */
226 if (*sourcePos == '"') {
227 /* Consume the terminating quotation mark */
228 sourcePos++;
229 } /* if */
230 } /* if */
231 if (*sourcePos != ' ' && *sourcePos != 0) {
232 /* Outside quotation mode */
233 do {
234 if (*sourcePos == '\\') {
235 processBackslash(&sourcePos, &destPos);
236 } else {
237 *destPos = *sourcePos;
238 sourcePos++;
239 destPos++;
240 } /* if */
241 } while (*sourcePos != ' ' && *sourcePos != '"' && *sourcePos != 0);
242 } /* if */
243 if (*sourcePos == ' ') {
244 do {
245 sourcePos++;
246 } while (*sourcePos == ' ');
247 if (*sourcePos != 0) {
248 /* Terminate the current argument */
249 *destPos = 0;
250 destPos++;
251 /* Set pointer to first char of next argument */
252 w_argv[argumentCount] = destPos;
253 argumentCount++;
254 } /* if */
255 } /* if */
256 } /* while */
257 /* Terminate the last argument */
258 *destPos = 0;
259 w_argv[argumentCount] = NULL;
260 } /* if */
261 } /* if */
262 } /* if */
263 *w_argc = argumentCount;
264 return w_argv;
265 } /* CommandLineToArgvW */
266
267
268
freeUtf16Argv(os_striType * w_argv)269 void freeUtf16Argv (os_striType *w_argv)
270
271 { /* freeUtf16Argv */
272 if (w_argv != NULL) {
273 os_stri_free(w_argv[0]);
274 free(w_argv);
275 } /* if */
276 } /* freeUtf16Argv */
277
278 #else
279
280
281
freeUtf16Argv(os_striType * w_argv)282 void freeUtf16Argv (os_striType *w_argv)
283
284 { /* freeUtf16Argv */
285 LocalFree(w_argv);
286 } /* freeUtf16Argv */
287 #endif
288
289
290
getUtf16Argv(int * w_argc)291 os_striType *getUtf16Argv (int *w_argc)
292
293 {
294 os_striType commandLine;
295 os_striType *w_argv;
296
297 /* getUtf16Argv */
298 commandLine = GetCommandLineW();
299 w_argv = CommandLineToArgvW(commandLine, w_argc);
300 return w_argv;
301 } /* getUtf16Argv */
302 #endif
303
304
305
306 /**
307 * Get the absolute path of the executable of the current process.
308 * @param arg_0 Parameter argv[0] from the function main() as string.
309 * @return the absolute path of the current process.
310 */
getExecutablePath(const const_striType arg_0)311 striType getExecutablePath (const const_striType arg_0)
312
313 {
314 os_charType buffer[PATH_MAX];
315 errInfoType err_info = OKAY_NO_ERROR;
316 striType executablePath;
317
318 /* getExecutablePath */
319 if (unlikely(GetModuleFileNameW(NULL, buffer, PATH_MAX) == 0)) {
320 raise_error(FILE_ERROR);
321 executablePath = NULL;
322 } else {
323 executablePath = cp_from_os_path(buffer, &err_info);
324 if (unlikely(executablePath == NULL)) {
325 raise_error(err_info);
326 } /* if */
327 } /* if */
328 return executablePath;
329 } /* getExecutablePath */
330
331
332
333 #if USE_GET_ENVIRONMENT
getEnvironment(void)334 os_striType *getEnvironment (void)
335
336 {
337 os_striType envBuffer;
338 os_striType currPos;
339 memSizeType length;
340 memSizeType numElems = 0;
341 memSizeType currIdx = 0;
342 os_striType *env;
343
344 /* getEnvironment */
345 logFunction(printf("getEnvironment()"););
346 envBuffer = GetEnvironmentStringsW();
347 if (envBuffer == NULL) {
348 env = NULL;
349 } else {
350 /* printf("envBuffer: \"" FMT_S_OS "\"\n", envBuffer); */
351 currPos = envBuffer;
352 do {
353 length = os_stri_strlen(currPos);
354 currPos = &currPos[length + 1];
355 numElems++;
356 } while (length != 0);
357 /* printf("numElems: " FMT_U_MEM "\n", numElems); */
358 env = (os_striType *) malloc(numElems * sizeof(os_striType));
359 if (env != NULL) {
360 currPos = envBuffer;
361 do {
362 env[currIdx] = currPos;
363 length = os_stri_strlen(currPos);
364 currPos = &currPos[length + 1];
365 currIdx++;
366 } while (length != 0);
367 env[currIdx - 1] = NULL;
368 /* for (currIdx = 0; env[currIdx] != NULL; currIdx++) {
369 printf("env[" FMT_U_MEM "]: \"" FMT_S_OS "\"\n", currIdx, env[currIdx]);
370 } */
371 } /* if */
372 if (env == NULL || env[0] == NULL) {
373 if (FreeEnvironmentStringsW(envBuffer) == 0) {
374 logError(printf("getEnvironment: FreeEnvironmentStrings() failed.\n"););
375 } /* if */
376 } /* if */
377 } /* if */
378 return env;
379 } /* getEnvironment */
380
381
382
freeEnvironment(os_striType * environment)383 void freeEnvironment (os_striType *environment)
384
385 { /* freeEnvironment */
386 if (environment != NULL) {
387 if (environment[0] != NULL) {
388 if (FreeEnvironmentStringsW(environment[0]) == 0) {
389 logError(printf("getEnvironment: FreeEnvironmentStrings() failed.\n"););
390 } /* if */
391 } /* if */
392 free(environment);
393 } /* if */
394 } /* freeEnvironment */
395 #endif
396
397
398
399 #ifdef DEFINE_WGETENV
wgetenv(const const_os_striType name)400 os_striType wgetenv (const const_os_striType name)
401
402 {
403 memSizeType value_size;
404 os_striType value;
405
406 /* wgetenv */
407 value_size = GetEnvironmentVariableW(name, NULL, 0);
408 if (value_size == 0) {
409 value = NULL;
410 } else {
411 if (ALLOC_WSTRI(value, value_size - 1)) {
412 if (GetEnvironmentVariableW(name, value, value_size) != value_size - 1) {
413 FREE_OS_STRI(value);
414 value = NULL;
415 } /* if */
416 } /* if */
417 } /* if */
418 return value;
419 } /* wgetenv */
420 #endif
421
422
423
424 #ifdef DEFINE_WSETENV
wsetenv(const const_os_striType name,const const_os_striType value,int overwrite)425 int wsetenv (const const_os_striType name, const const_os_striType value,
426 int overwrite)
427
428 {
429 int result;
430
431 /* wsetenv */
432 logFunction(printf("wsetenv(\"" FMT_S_OS "\", \"" FMT_S_OS "\", &d)\n",
433 name, value, overwrite););
434 result = !SetEnvironmentVariableW(name, value);
435 return result;
436 } /* wsetenv */
437 #endif
438
439
440
441 #ifdef DEFINE_WUNSETENV
wunsetenv(const const_os_striType name)442 int wunsetenv (const const_os_striType name)
443
444 {
445 int result;
446
447 /* wunsetenv */
448 logFunction(printf("wunsetenv(\"" FMT_S_OS "\")\n", name););
449 result = !SetEnvironmentVariableW(name, NULL);
450 return result;
451 } /* wunsetenv */
452 #endif
453
454
455
getNameFromSid(PSID sid)456 static striType getNameFromSid (PSID sid)
457
458 {
459 LPWSTR AcctName;
460 DWORD dwAcctName = 0;
461 LPWSTR DomainName;
462 DWORD dwDomainName = 0;
463 SID_NAME_USE eUse = SidTypeUnknown;
464 errInfoType err_info = OKAY_NO_ERROR;
465 striType name;
466
467 /* getNameFromSid */
468 LookupAccountSidW(NULL, sid,
469 NULL, (LPDWORD) &dwAcctName,
470 NULL, (LPDWORD) &dwDomainName, &eUse);
471 AcctName = (LPWSTR) GlobalAlloc(GMEM_FIXED, dwAcctName * sizeof(os_charType));
472 DomainName = (LPWSTR) GlobalAlloc(GMEM_FIXED, dwDomainName * sizeof(os_charType));
473 if (unlikely(AcctName == NULL || DomainName == NULL)) {
474 logError(printf("getNameFromSid: GlobalAlloc() failed:\n"
475 "lastError=" FMT_U32 "\n",
476 (uint32Type) GetLastError()););
477 if (AcctName != NULL) {
478 GlobalFree(AcctName);
479 } /* if */
480 raise_error(MEMORY_ERROR);
481 name = NULL;
482 } else if (unlikely(
483 LookupAccountSidW(NULL, sid,
484 AcctName, (LPDWORD) &dwAcctName,
485 DomainName, (LPDWORD) &dwDomainName,
486 &eUse) == FALSE)) {
487 logError(printf("getNameFromSid: LookupAccountSidW() failed:\n"
488 "lastError=" FMT_U32 "\n",
489 (uint32Type) GetLastError()););
490 GlobalFree(AcctName);
491 GlobalFree(DomainName);
492 raise_error(FILE_ERROR);
493 name = NULL;
494 } else {
495 name = os_stri_to_stri(AcctName, &err_info);
496 GlobalFree(AcctName);
497 GlobalFree(DomainName);
498 if (unlikely(name == NULL)) {
499 raise_error(err_info);
500 } /* if */
501 } /* if */
502 return name;
503 } /* getNameFromSid */
504
505
506
getSidFromName(const const_striType name,errInfoType * err_info)507 static PSID getSidFromName (const const_striType name, errInfoType *err_info)
508
509 {
510 os_striType accountName;
511 DWORD numberOfBytesForSid = 0;
512 DWORD numberOfCharsForDomainName = 0;
513 os_striType domainName;
514 SID_NAME_USE sidNameUse = SidTypeInvalid;
515 PSID sid = NULL;
516
517 /* getSidFromName */
518 logFunction(printf("getSidFromName(\"%s\", %d)\n",
519 striAsUnquotedCStri(name), *err_info););
520 accountName = stri_to_os_stri(name, err_info);
521 if (likely(accountName != NULL)) {
522 LookupAccountNameW(NULL, accountName, NULL, &numberOfBytesForSid,
523 NULL, &numberOfCharsForDomainName, &sidNameUse);
524 sid = (PSID) malloc(numberOfBytesForSid);
525 if (unlikely(sid == NULL)) {
526 *err_info = MEMORY_ERROR;
527 } else if (unlikely(!ALLOC_OS_STRI(domainName, numberOfCharsForDomainName))) {
528 free(sid);
529 *err_info = MEMORY_ERROR;
530 sid = NULL;
531 } else {
532 if (unlikely(LookupAccountNameW(NULL, accountName, sid, &numberOfBytesForSid,
533 domainName, &numberOfCharsForDomainName, &sidNameUse) == 0)) {
534 logError(printf("getSidFromName: LookupAccountNameW failed:\n"
535 "lastError=" FMT_U32 "\n",
536 (uint32Type) GetLastError()););
537 free(sid);
538 *err_info = FILE_ERROR;
539 sid = NULL;
540 } /* if */
541 FREE_OS_STRI(domainName);
542 } /* if */
543 os_stri_free(accountName);
544 } /* if */
545 return sid;
546 } /* getSidFromName */
547
548
549
cmdGetGroup(const const_striType filePath)550 striType cmdGetGroup (const const_striType filePath)
551
552 {
553 os_striType os_path;
554 int path_info = PATH_IS_NORMAL;
555 errInfoType err_info = OKAY_NO_ERROR;
556 PSECURITY_DESCRIPTOR pSD = NULL;
557 PSID pSidGroup = NULL;
558 striType group;
559
560 /* cmdGetGroup */
561 logFunction(printf("cmdGetGroup(\"%s\")", striAsUnquotedCStri(filePath));
562 fflush(stdout););
563 os_path = cp_to_os_path(filePath, &path_info, &err_info);
564 if (unlikely(os_path == NULL)) {
565 logError(printf("cmdGetGroup: cp_to_os_path(\"%s\", *, *) failed:\n"
566 "path_info=%d, err_info=%d\n",
567 striAsUnquotedCStri(filePath), path_info, err_info););
568 raise_error(err_info);
569 group = NULL;
570 } else if (unlikely(
571 GetNamedSecurityInfoW(os_path, SE_FILE_OBJECT,
572 GROUP_SECURITY_INFORMATION, NULL,
573 &pSidGroup, NULL, NULL, &pSD) != ERROR_SUCCESS)) {
574 logError(printf("cmdGetGroup: "
575 "GetNamedSecurityInfoW(\"" FMT_S_OS "\", ...) failed:\n"
576 "lastError=" FMT_U32 "\n",
577 os_path, (uint32Type) GetLastError()););
578 os_stri_free(os_path);
579 raise_error(FILE_ERROR);
580 group = NULL;
581 } else {
582 os_stri_free(os_path);
583 group = getNameFromSid(pSidGroup);
584 /* The SID referenced by pSidOwner is located */
585 /* inside of the PSECURITY_DESCRIPTOR pSD. */
586 /* Therefore it is freed together with pSD. */
587 LocalFree(pSD);
588 } /* if */
589 logFunctionResult(printf("\"%s\"\n", striAsUnquotedCStri(group)););
590 return group;
591 } /* cmdGetGoup */
592
593
594
cmdGetOwner(const const_striType filePath)595 striType cmdGetOwner (const const_striType filePath)
596
597 {
598 os_striType os_path;
599 int path_info = PATH_IS_NORMAL;
600 errInfoType err_info = OKAY_NO_ERROR;
601 PSECURITY_DESCRIPTOR pSD = NULL;
602 PSID pSidOwner = NULL;
603 striType owner;
604
605 /* cmdGetOwner */
606 logFunction(printf("cmdGetOwner(\"%s\")", striAsUnquotedCStri(filePath));
607 fflush(stdout););
608 os_path = cp_to_os_path(filePath, &path_info, &err_info);
609 if (unlikely(os_path == NULL)) {
610 logError(printf("cmdGetOwner: cp_to_os_path(\"%s\", *, *) failed:\n"
611 "path_info=%d, err_info=%d\n",
612 striAsUnquotedCStri(filePath), path_info, err_info););
613 raise_error(err_info);
614 owner = NULL;
615 } else if (unlikely(
616 GetNamedSecurityInfoW(os_path, SE_FILE_OBJECT,
617 OWNER_SECURITY_INFORMATION, &pSidOwner,
618 NULL, NULL, NULL, &pSD) != ERROR_SUCCESS)) {
619 logError(printf("cmdGetOwner: "
620 "GetNamedSecurityInfoW(\"" FMT_S_OS "\", ...) failed:\n"
621 "lastError=" FMT_U32 "\n",
622 os_path, (uint32Type) GetLastError()););
623 os_stri_free(os_path);
624 raise_error(FILE_ERROR);
625 owner = NULL;
626 } else {
627 os_stri_free(os_path);
628 owner = getNameFromSid(pSidOwner);
629 /* The SID referenced by pSidOwner is located */
630 /* inside of the PSECURITY_DESCRIPTOR pSD. */
631 /* Therefore it is freed together with pSD. */
632 LocalFree(pSD);
633 } /* if */
634 logFunctionResult(printf("\"%s\"\n", striAsUnquotedCStri(owner)););
635 return owner;
636 } /* cmdGetOwner */
637
638
639
cmdSetGroup(const const_striType filePath,const const_striType group)640 void cmdSetGroup (const const_striType filePath, const const_striType group)
641
642 {
643 os_striType os_path;
644 int path_info = PATH_IS_NORMAL;
645 errInfoType err_info = OKAY_NO_ERROR;
646 PSID pSidGroup;
647
648 /* cmdSetGroup */
649 logFunction(printf("cmdSetGroup(\"%s\", ", striAsUnquotedCStri(filePath));
650 printf("\"%s\")\n", striAsUnquotedCStri(group)));
651 os_path = cp_to_os_path(filePath, &path_info, &err_info);
652 if (unlikely(os_path == NULL)) {
653 logError(printf("cmdSetGroup: cp_to_os_path(\"%s\", *, *) failed:\n"
654 "path_info=%d, err_info=%d\n",
655 striAsUnquotedCStri(filePath), path_info, err_info););
656 raise_error(err_info);
657 } else {
658 pSidGroup = getSidFromName(group, &err_info);
659 if (unlikely(pSidGroup == NULL)) {
660 os_stri_free(os_path);
661 raise_error(err_info);
662 } else {
663 SetNamedSecurityInfoW(os_path, SE_FILE_OBJECT,
664 GROUP_SECURITY_INFORMATION, NULL,
665 pSidGroup, NULL, NULL);
666 free(pSidGroup);
667 os_stri_free(os_path);
668 } /* if */
669 } /* if */
670 } /* cmdSetGroup */
671
672
673
cmdSetOwner(const const_striType filePath,const const_striType owner)674 void cmdSetOwner (const const_striType filePath, const const_striType owner)
675
676 {
677 os_striType os_path;
678 int path_info = PATH_IS_NORMAL;
679 errInfoType err_info = OKAY_NO_ERROR;
680 PSID pSidOwner;
681
682 /* cmdSetOwner */
683 logFunction(printf("cmdSetOwner(\"%s\", ", striAsUnquotedCStri(filePath));
684 printf("\"%s\")\n", striAsUnquotedCStri(owner)));
685 os_path = cp_to_os_path(filePath, &path_info, &err_info);
686 if (unlikely(os_path == NULL)) {
687 logError(printf("cmdSetOwner: cp_to_os_path(\"%s\", *, *) failed:\n"
688 "path_info=%d, err_info=%d\n",
689 striAsUnquotedCStri(filePath), path_info, err_info););
690 raise_error(err_info);
691 } else {
692 pSidOwner = getSidFromName(owner, &err_info);
693 if (unlikely(pSidOwner == NULL)) {
694 os_stri_free(os_path);
695 raise_error(err_info);
696 } else {
697 SetNamedSecurityInfoW(os_path, SE_FILE_OBJECT,
698 OWNER_SECURITY_INFORMATION, pSidOwner,
699 NULL, NULL, NULL);
700 free(pSidOwner);
701 os_stri_free(os_path);
702 } /* if */
703 } /* if */
704 } /* cmdSetOwner */
705
706
707
cmdUser(void)708 striType cmdUser (void)
709
710 {
711 HANDLE hToken = NULL;
712 TOKEN_USER *ptu = NULL;
713 DWORD dwSize = 0;
714 striType user;
715
716 /* cmdUser */
717 if (unlikely(OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken) == 0 &&
718 OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken) == 0)) {
719 logError(printf("cmdUser: OpenThreadToken() and OpenProcessToken() failed."););
720 raise_error(FILE_ERROR);
721 user = NULL;
722 } else {
723 if (unlikely(GetTokenInformation(hToken, TokenUser, NULL, 0, &dwSize) != 0 ||
724 ERROR_INSUFFICIENT_BUFFER != GetLastError())) {
725 logError(printf("cmdUser: GetTokenInformation() "
726 "should fail with ERROR_INSUFFICIENT_BUFFER.\n"
727 "lastError=" FMT_U32 "\n",
728 (uint32Type) GetLastError()););
729 raise_error(FILE_ERROR);
730 user = NULL;
731 } else {
732 ptu = (TOKEN_USER *) LocalAlloc(LPTR, dwSize);
733 if (unlikely(ptu == NULL)) {
734 raise_error(MEMORY_ERROR);
735 user = NULL;
736 } else {
737 if (GetTokenInformation(hToken, TokenUser, ptu, dwSize, &dwSize) == 0) {
738 logError(printf("cmdUser: GetNamedSecurityInfoW() failed:\n"
739 "lastError=" FMT_U32 "\n",
740 (uint32Type) GetLastError()););
741 LocalFree((HLOCAL) ptu);
742 raise_error(FILE_ERROR);
743 user = NULL;
744 } else {
745 user = getNameFromSid(ptu->User.Sid);
746 LocalFree((HLOCAL) ptu);
747 } /* if */
748 } /* if */
749 } /* if */
750 } /* if */
751 return user;
752 } /* cmdUser */
753