pastebin - collaborative debugging tool
rovema.kpaste.net RSS


winfsinfo1.c - print Windows filesystem info in ksh93 compound variable format (suiteable for ksh93 $ read -C varnname #)
Posted by Anonymous on Sat 11th May 2024 12:20
raw | new post

  1. /*
  2.  * MIT License
  3.  *
  4.  * Copyright (c) 2023-2024 Roland Mainz <roland.mainz@nrubsig.org>
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a copy
  7.  * of this software and associated documentation files (the "Software"), to deal
  8.  * in the Software without restriction, including without limitation the rights
  9.  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10.  * copies of the Software, and to permit persons to whom the Software is
  11.  * furnished to do so, subject to the following conditions:
  12.  *
  13.  * The above copyright notice and this permission notice shall be included in all
  14.  * copies or substantial portions of the Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19.  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21.  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  22.  * SOFTWARE.
  23.  */
  24.  
  25. /*
  26.  * winfsinfo1.c - print Windows filesystem info in ksh93 compound
  27.  * variable format (suiteable for ksh93 $ read -C varnname #)
  28.  *
  29.  * Written by Roland Mainz <roland.mainz@nrubsig.org>
  30.  */
  31.  
  32. #define UNICODE 1
  33. #define _UNICODE 1
  34.  
  35. #include <stdio.h>
  36. #include <windows.h>
  37. #include <stdlib.h>
  38. #include <stdbool.h>
  39.  
  40. static
  41. bool getvolumeinfo(const char *progname, const char *filename)
  42. {
  43.     int res = EXIT_FAILURE;
  44.     bool ok;
  45.  
  46.     HANDLE fileHandle = CreateFileA(filename,
  47.         GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
  48.         FILE_FLAG_BACKUP_SEMANTICS, NULL);
  49.     if (fileHandle == INVALID_HANDLE_VALUE) {
  50.         (void)fprintf(stderr,
  51.             "%s: Error opening file '%s'. Last error was %d.\n",
  52.             progname,
  53.             filename,
  54.             GetLastError());
  55.         return EXIT_FAILURE;
  56.     }
  57.  
  58.     DWORD volumeFlags = 0;
  59.     ok = GetVolumeInformationByHandleW(fileHandle, NULL, 0,
  60.         NULL, NULL, &volumeFlags, NULL, 0);
  61.  
  62.     if (!ok) {
  63.         (void)fprintf(stderr, "%s: GetVolumeInformationByHandleW() "
  64.             "error. GetLastError()==%d.\n",
  65.             progname,
  66.             GetLastError());
  67.         res = EXIT_FAILURE;
  68.         goto done;
  69.     }
  70.  
  71.     (void)printf("(\n");
  72.     (void)printf("\tfilename='%s'\n", filename);
  73.     (void)printf("\ttypeset -a volumeflags=(\n");
  74.  
  75. #define TESTVOLFLAG(s) \
  76.     if (volumeFlags & (s)) { \
  77.         (void)puts("\t\t"#s); \
  78.         volumeFlags &= ~(s); \
  79.     }
  80.  
  81.     TESTVOLFLAG(FILE_SUPPORTS_USN_JOURNAL);
  82.     TESTVOLFLAG(FILE_SUPPORTS_OPEN_BY_FILE_ID);
  83.     TESTVOLFLAG(FILE_SUPPORTS_EXTENDED_ATTRIBUTES);
  84.     TESTVOLFLAG(FILE_SUPPORTS_HARD_LINKS);
  85.     TESTVOLFLAG(FILE_SUPPORTS_TRANSACTIONS);
  86.     TESTVOLFLAG(FILE_SEQUENTIAL_WRITE_ONCE);
  87.     TESTVOLFLAG(FILE_READ_ONLY_VOLUME);
  88.     TESTVOLFLAG(FILE_NAMED_STREAMS);
  89.     TESTVOLFLAG(FILE_SUPPORTS_ENCRYPTION);
  90.     TESTVOLFLAG(FILE_SUPPORTS_OBJECT_IDS);
  91.     TESTVOLFLAG(FILE_VOLUME_IS_COMPRESSED);
  92.     TESTVOLFLAG(FILE_SUPPORTS_REMOTE_STORAGE);
  93.     TESTVOLFLAG(FILE_RETURNS_CLEANUP_RESULT_INFO);
  94.     TESTVOLFLAG(FILE_SUPPORTS_POSIX_UNLINK_RENAME);
  95.     TESTVOLFLAG(FILE_SUPPORTS_REPARSE_POINTS);
  96.     TESTVOLFLAG(FILE_SUPPORTS_SPARSE_FILES);
  97.     TESTVOLFLAG(FILE_VOLUME_QUOTAS);
  98.     TESTVOLFLAG(FILE_FILE_COMPRESSION);
  99.     TESTVOLFLAG(FILE_PERSISTENT_ACLS);
  100.     TESTVOLFLAG(FILE_UNICODE_ON_DISK);
  101.     TESTVOLFLAG(FILE_CASE_PRESERVED_NAMES);
  102.     TESTVOLFLAG(FILE_CASE_SENSITIVE_SEARCH);
  103.     TESTVOLFLAG(FILE_SUPPORTS_INTEGRITY_STREAMS);
  104. #ifdef FILE_SUPPORTS_BLOCK_REFCOUNTING
  105.     TESTVOLFLAG(FILE_SUPPORTS_BLOCK_REFCOUNTING);
  106. #endif
  107. #ifdef FILE_SUPPORTS_SPARSE_VDL
  108.     TESTVOLFLAG(FILE_SUPPORTS_SPARSE_VDL);
  109. #endif
  110. #ifdef FILE_DAX_VOLUME
  111.     TESTVOLFLAG(FILE_DAX_VOLUME);
  112. #endif
  113. #ifdef FILE_SUPPORTS_GHOSTING
  114.     TESTVOLFLAG(FILE_SUPPORTS_GHOSTING);
  115. #endif
  116.  
  117.     (void)printf("\t)\n");
  118.  
  119.     /*
  120.      * print any leftover flags not covered by |TESTVOLFLAG(FILE_*)|
  121.      * above
  122.      */
  123.     if (volumeFlags) {
  124.         (void)printf("\tattr=0x%lx\n", (long)volumeFlags);
  125.     }
  126.     (void)printf(")\n");
  127.     res = EXIT_SUCCESS;
  128.  
  129. done:
  130.     CloseHandle(fileHandle);
  131.     return res;
  132. }
  133.  
  134.  
  135. static
  136. bool get_file_basic_info(const char *progname, const char *filename)
  137. {
  138.     int res = EXIT_FAILURE;
  139.     bool ok;
  140.     FILE_BASIC_INFO finfo = { 0 };
  141.  
  142.     HANDLE fileHandle = CreateFileA(filename,
  143.         GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
  144.         FILE_FLAG_BACKUP_SEMANTICS, NULL);
  145.     if (fileHandle == INVALID_HANDLE_VALUE) {
  146.         (void)fprintf(stderr,
  147.             "%s: Error opening file '%s'. Last error was %d.\n",
  148.             progname,
  149.             filename,
  150.             GetLastError());
  151.         return EXIT_FAILURE;
  152.     }
  153.  
  154.     ok = GetFileInformationByHandleEx(fileHandle, FileBasicInfo, &finfo,
  155.         sizeof(finfo));
  156.  
  157.     if (!ok) {
  158.         (void)fprintf(stderr, "%s: GetFileInformationByHandleEx() "
  159.             "error. GetLastError()==%d.\n",
  160.             progname,
  161.             GetLastError());
  162.         res = EXIT_FAILURE;
  163.         goto done;
  164.     }
  165.  
  166.     (void)printf("(\n");
  167.     (void)printf("\tfilename='%s'\n", filename);
  168.  
  169.     (void)printf("\tCreationTime=%lld\n", (long long)finfo.CreationTime.QuadPart);
  170.     (void)printf("\tLastAccessTime=%lld\n", (long long)finfo.LastAccessTime.QuadPart);
  171.     (void)printf("\tLastWriteTime=%lld\n", (long long)finfo.LastWriteTime.QuadPart);
  172.     (void)printf("\tChangeTime=%lld\n", (long long)finfo.ChangeTime.QuadPart);
  173.     DWORD fattr = finfo.FileAttributes;
  174.  
  175.     (void)printf("\ttypeset -a FileAttributes=(\n");
  176.  
  177. #define TESTFBIA(s) \
  178.     if (fattr & (s)) { \
  179.         (void)puts("\t\t"#s); \
  180.         fattr &= ~(s); \
  181.     }
  182.     TESTFBIA(FILE_ATTRIBUTE_READONLY);
  183.     TESTFBIA(FILE_ATTRIBUTE_HIDDEN);
  184.     TESTFBIA(FILE_ATTRIBUTE_SYSTEM);
  185.     TESTFBIA(FILE_ATTRIBUTE_DIRECTORY);
  186.     TESTFBIA(FILE_ATTRIBUTE_ARCHIVE);
  187.     TESTFBIA(FILE_ATTRIBUTE_DEVICE);
  188.     TESTFBIA(FILE_ATTRIBUTE_NORMAL);
  189.     TESTFBIA(FILE_ATTRIBUTE_TEMPORARY);
  190.     TESTFBIA(FILE_ATTRIBUTE_SPARSE_FILE);
  191.     TESTFBIA(FILE_ATTRIBUTE_REPARSE_POINT);
  192.     TESTFBIA(FILE_ATTRIBUTE_COMPRESSED);
  193.     TESTFBIA(FILE_ATTRIBUTE_OFFLINE);
  194.     TESTFBIA(FILE_ATTRIBUTE_NOT_CONTENT_INDEXED);
  195.     TESTFBIA(FILE_ATTRIBUTE_ENCRYPTED);
  196.     TESTFBIA(FILE_ATTRIBUTE_INTEGRITY_STREAM);
  197.     TESTFBIA(FILE_ATTRIBUTE_VIRTUAL);
  198.     TESTFBIA(FILE_ATTRIBUTE_NO_SCRUB_DATA);
  199.     TESTFBIA(FILE_ATTRIBUTE_EA);
  200.     TESTFBIA(FILE_ATTRIBUTE_PINNED);
  201.     TESTFBIA(FILE_ATTRIBUTE_UNPINNED);
  202.     TESTFBIA(FILE_ATTRIBUTE_RECALL_ON_OPEN);
  203.     TESTFBIA(FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS);
  204.  
  205.     (void)printf("\t)\n");
  206.  
  207.     /*
  208.      * print any leftover flags not covered by |TESTFBIA(FILE_*)|
  209.      * above
  210.      */
  211.     if (fattr) {
  212.         (void)printf("\tfattr=0x%lx\n", (long)fattr);
  213.     }
  214.     (void)printf(")\n");
  215.     res = EXIT_SUCCESS;
  216.  
  217. done:
  218.     CloseHandle(fileHandle);
  219.     return res;
  220. }
  221.  
  222.  
  223. static
  224. bool get_file_standard_info(const char *progname, const char *filename)
  225. {
  226.     int res = EXIT_FAILURE;
  227.     bool ok;
  228.     FILE_STANDARD_INFO finfo = { 0 };
  229.  
  230.     HANDLE fileHandle = CreateFileA(filename,
  231.         GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
  232.         FILE_FLAG_BACKUP_SEMANTICS, NULL);
  233.     if (fileHandle == INVALID_HANDLE_VALUE) {
  234.         (void)fprintf(stderr,
  235.             "%s: Error opening file '%s'. Last error was %d.\n",
  236.             progname,
  237.             filename,
  238.             GetLastError());
  239.         return EXIT_FAILURE;
  240.     }
  241.  
  242.     ok = GetFileInformationByHandleEx(fileHandle, FileStandardInfo, &finfo,
  243.         sizeof(finfo));
  244.  
  245.     if (!ok) {
  246.         (void)fprintf(stderr, "%s: GetFileInformationByHandleEx() "
  247.             "error. GetLastError()==%d.\n",
  248.             progname,
  249.             GetLastError());
  250.         res = EXIT_FAILURE;
  251.         goto done;
  252.     }
  253.  
  254.     (void)printf("(\n");
  255.     (void)printf("\tfilename='%s'\n", filename);
  256.  
  257.     (void)printf("\tAllocationSize=%lld\n", (long long)finfo.AllocationSize.QuadPart);
  258.     (void)printf("\tEndOfFile=%lld\n",      (long long)finfo.EndOfFile.QuadPart);
  259.     (void)printf("\tNumberOfLinks=%ld\n",   (long)finfo.NumberOfLinks);
  260.     (void)printf("\tDeletePending=%s\n",    finfo.DeletePending?"true":"false");
  261.     (void)printf("\tDirectory=%s\n",        finfo.Directory?"true":"false");
  262.     (void)printf(")\n");
  263.     res = EXIT_SUCCESS;
  264.  
  265. done:
  266.     CloseHandle(fileHandle);
  267.     return res;
  268. }
  269.  
  270. /*
  271.  * |FILE_NAME_INFORMATION| variation with 4096 bytes, matching
  272.  * Linux |PATH_MAX| value of 4096
  273.  */
  274. typedef struct _FILE_NAME_INFORMATION4096 {
  275.   ULONG FileNameLength;
  276.   WCHAR FileName[4096];
  277. } FILE_NAME_INFORMATION4096, *PFILE_NAME_INFORMATION4096;
  278.  
  279.  
  280. static
  281. bool get_filenormalizednameinfo(const char *progname, const char *filename)
  282. {
  283.     int res = EXIT_FAILURE;
  284.     bool ok;
  285.     FILE_NAME_INFORMATION4096 finfo = { 0 };
  286.  
  287.     HANDLE fileHandle = CreateFileA(filename,
  288.         GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
  289.         FILE_FLAG_BACKUP_SEMANTICS, NULL);
  290.     if (fileHandle == INVALID_HANDLE_VALUE) {
  291.         (void)fprintf(stderr,
  292.             "%s: Error opening file '%s'. Last error was %d.\n",
  293.             progname,
  294.             filename,
  295.             GetLastError());
  296.         return EXIT_FAILURE;
  297.     }
  298.  
  299.     ok = GetFileInformationByHandleEx(fileHandle, 24/*FileNormalizedNameInfo*/,
  300.         &finfo, sizeof(finfo));
  301.  
  302.     if (!ok) {
  303.         (void)fprintf(stderr, "%s: GetFileInformationByHandleEx() "
  304.             "error. GetLastError()==%d.\n",
  305.             progname,
  306.             GetLastError());
  307.         res = EXIT_FAILURE;
  308.         goto done;
  309.     }
  310.  
  311.     (void)printf("(\n");
  312.     (void)printf("\tfilename='%s'\n", filename);
  313.  
  314.     (void)printf("\tFileNameLength=%ld\n",  (long)finfo.FileNameLength);
  315.     (void)printf("\tFileName='%S'\n",       finfo.FileName);
  316.     (void)printf(")\n");
  317.     res = EXIT_SUCCESS;
  318.  
  319. done:
  320.     CloseHandle(fileHandle);
  321.     return res;
  322. }
  323.  
  324. static
  325. void usage(void)
  326. {
  327.     (void)fprintf(stderr, "winfsinfo <"
  328.         "getvolumeinfo|"
  329.         "filebasicinfo|"
  330.         "filestandardinfo|"
  331.         "filenormalizednameinfo"
  332.         "> path\n");
  333. }
  334.  
  335. int main(int ac, char *av[])
  336. {
  337.     const char *subcmd;
  338.  
  339.     if (ac < 3) {
  340.         usage();
  341.         return 2;
  342.     }
  343.  
  344.     subcmd = av[1];
  345.  
  346.     if (!strcmp(subcmd, "getvolumeinfo")) {
  347.         return getvolumeinfo(av[0], av[2]);
  348.     }
  349.     else if (!strcmp(subcmd, "filebasicinfo")) {
  350.         return get_file_basic_info(av[0], av[2]);
  351.     }
  352.     else if (!strcmp(subcmd, "filestandardinfo")) {
  353.         return get_file_standard_info(av[0], av[2]);
  354.     }
  355.     else if (!strcmp(subcmd, "filenormalizednameinfo")) {
  356.         return get_filenormalizednameinfo(av[0], av[2]);
  357.     }
  358.     else {
  359.         (void)fprintf(stderr, "%s: Unknown subcmd '%s'\n", av[0], subcmd);
  360.         return EXIT_FAILURE;
  361.     }
  362.  
  363.     return EXIT_SUCCESS;
  364. }

Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:

To highlight particular lines, prefix each line with {%HIGHLIGHT}




All content is user-submitted.
The administrators of this site (kpaste.net) are not responsible for their content.
Abuse reports should be emailed to us at