This fixes bug 18059.  If this one is not acceptable, feel free to take it and 
clean it up, I am abandoning this effort from here forward.

_________________________________________________________________
Windows Live: Keep your friends up to date with what you do online.
http://windowslive.com/Campaign/SocialNetworking?ocid=PID23285::T:WLMTAGL:ON:WL:en-US:SI_SB_online:082009
From 358bc34d6b400eef5200364cb2b6162a656c2c1a Mon Sep 17 00:00:00 2001
From: EA Durbin <ead1...@hotmail.com>
Date: Mon, 17 Aug 2009 18:33:37 -0500
Subject: attrib.exe: add new application attrib.exe

---
 programs/attrib/Makefile.in |   13 +++
 programs/attrib/attrib.c    |  181 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 194 insertions(+), 0 deletions(-)
 create mode 100644 programs/attrib/Makefile.in
 create mode 100644 programs/attrib/attrib.c

diff --git a/programs/attrib/Makefile.in b/programs/attrib/Makefile.in
new file mode 100644
index 0000000..3be4d21
--- /dev/null
+++ b/programs/attrib/Makefile.in
@@ -0,0 +1,13 @@
+TOPSRCDIR = @top_srcdir@
+TOPOBJDIR = ../..
+SRCDIR    = @srcdir@
+VPATH     = @srcdir@
+MODULE    = attrib.exe
+APPMODE   = -municode
+IMPORTS   = kernel32
+
+C_SRCS = attrib.c
+
+...@make_prog_rules@
+
+...@dependencies@  # everything below this line is overwritten by make depend
diff --git a/programs/attrib/attrib.c b/programs/attrib/attrib.c
new file mode 100644
index 0000000..4fbdeb3
--- /dev/null
+++ b/programs/attrib/attrib.c
@@ -0,0 +1,181 @@
+/*
+ * File Attributes
+ *
+ * Copyright 2009 EA Durbin
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/debug.h"
+#include <stdarg.h>
+#include "windef.h"
+#include "winbase.h"
+#include "winnt.h"
+#include "winnls.h"
+#include <stdio.h>
+WINE_DEFAULT_DEBUG_CHANNEL(attrib);
+#define IsAttrib(x, y)  ((INVALID_FILE_ATTRIBUTES != (x)) && ((x) & (y)))
+
+static void usage(void)
+{
+    printf("Usage: attrib [+R|-R][+A|-A][+S|-S][+H|-H][+C|-C][[drive:][path]filename] [/S][/D]...\n"
+           "    +  Sets an attribute\n"
+           "    -  Clears an attribute\n"
+           "    R  Read-only file attribute\n"
+           "    A  Archive file attribute\n"
+           "    S  System file attribute\n"
+           "    H  Hidden file attribute\n"
+           "    C  Compressed file attribute\n"
+           "    /S Process files in all directories in the specified path.\n"
+           "    /D  Process folders as well.\n");
+}
+
+void recurseattr(LPWSTR filename, DWORD clrAttr, DWORD setAttr, BOOL folders)
+{
+    HANDLE hFindFile = INVALID_HANDLE_VALUE;
+    WIN32_FIND_DATAW w32fd;
+    BOOL done = TRUE;
+    int len = lstrlenW(filename);
+    static const WCHAR asterisk[] = {'*',0};
+    static const WCHAR dot[] = {'.',0};
+    static const WCHAR dotdot[] = {'.','.',0};
+    /*  add wildcard */
+    if (len && filename[len-1] != '\\') filename[len++] = '\\';
+    lstrcpyW(filename + len, asterisk);
+    if((hFindFile = FindFirstFileW(filename, &w32fd)) != INVALID_HANDLE_VALUE)
+    {
+        for(done = FALSE; !done; done = !FindNextFileW(hFindFile, &w32fd))
+        {
+            WINE_TRACE("Processing: %s\n", wine_dbgstr_w(w32fd.cFileName));
+            if (lstrcmpW(dot, w32fd.cFileName) != 0 &&
+                lstrcmpW(dotdot, w32fd.cFileName) != 0)
+            {
+                lstrcpyW(filename + len, w32fd.cFileName);
+                if(w32fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+                {
+                    if(folders == TRUE)
+                    {
+                        if(!IsAttrib(w32fd.dwFileAttributes, setAttr))
+                            SetFileAttributesW(filename, (w32fd.dwFileAttributes | setAttr));
+                        if(IsAttrib(w32fd.dwFileAttributes, clrAttr))
+                            SetFileAttributesW(filename, w32fd.dwFileAttributes & ~clrAttr);
+                    }
+                    recurseattr(filename, clrAttr, setAttr, folders);
+                }
+                if(!IsAttrib(w32fd.dwFileAttributes, setAttr))
+                    SetFileAttributesW(filename, (w32fd.dwFileAttributes | setAttr));
+                if(IsAttrib(w32fd.dwFileAttributes, clrAttr))
+                    SetFileAttributesW(filename, w32fd.dwFileAttributes & ~clrAttr);
+            }
+        }
+        FindClose(hFindFile);
+    }
+}
+
+int wmain(int argc, WCHAR *argv[])
+{
+    int i = 0;
+    BOOL allfiles = FALSE;
+    BOOL folders = FALSE;
+    DWORD dwAttr = 0;
+    DWORD clrAttr = 0;
+    DWORD setAttr = 0;
+    LPWSTR path = NULL;
+    for(i = 1; i < argc; i++)
+    {
+        WINE_TRACE("Processing argument: %s\n", wine_dbgstr_w(argv[i]));
+        switch(argv[i][0])
+        {
+            case '+':
+                switch(toupper(argv[i][1]))
+                {
+                    case 'C':
+                        setAttr |= FILE_ATTRIBUTE_COMPRESSED;
+                        break;
+                    case 'R':
+                        setAttr |= FILE_ATTRIBUTE_READONLY;
+                        break;
+                    case 'A':
+                        setAttr |= FILE_ATTRIBUTE_ARCHIVE;
+                    break;
+                    case 'S':
+                        setAttr |= FILE_ATTRIBUTE_SYSTEM;
+                        break;
+                    case 'H':
+                        setAttr |= FILE_ATTRIBUTE_HIDDEN;
+                        break;
+                    default:
+                        fprintf(stderr, "invalid attribute: %s\n", wine_dbgstr_w(argv[i]));
+                        usage();
+                }
+            case '-':
+                switch(argv[i][1])
+                {
+                    case 'C':
+                        clrAttr |= FILE_ATTRIBUTE_COMPRESSED;
+                        break;
+                    case 'R':
+                        clrAttr |= FILE_ATTRIBUTE_READONLY;
+                        break;
+                    case 'A':
+                        clrAttr |= FILE_ATTRIBUTE_ARCHIVE;
+                        break;
+                    case 'S':
+                        clrAttr |= FILE_ATTRIBUTE_SYSTEM;
+                        break;
+                    case 'H':
+                        clrAttr |= FILE_ATTRIBUTE_HIDDEN;
+                        break;
+                    default:
+                        fprintf(stderr, "invalid attribute: %s\n", wine_dbgstr_w(argv[i]));
+                        usage();
+                }
+                break;
+            case '/': /* recurse directory or apply attributes to a folder */
+                switch(argv[i][1])
+                {
+                    case 'D':
+                        folders = TRUE;
+                        break;
+                    case 'S':
+                        allfiles = TRUE;
+                        break;
+                }
+                break;
+            default: /* file path */
+                path = argv[i];
+        }
+    }
+    dwAttr = GetFileAttributesW(path);
+    if(dwAttr == INVALID_FILE_ATTRIBUTES) /* file doesn't exist or GetFileAttributes failed */
+        return 1;
+    if(allfiles == TRUE)
+    {
+        if(!(dwAttr & FILE_ATTRIBUTE_DIRECTORY))
+            return 1; /* must be a directory */
+        recurseattr(path, clrAttr, setAttr, folders);
+    }
+    else
+    {
+        if((folders != TRUE) && (dwAttr & FILE_ATTRIBUTE_DIRECTORY))
+            return 1;
+        if(!(IsAttrib(dwAttr, setAttr)))
+            SetFileAttributesW(path, dwAttr | setAttr);
+        if(IsAttrib(dwAttr, clrAttr))
+            SetFileAttributesW(path, dwAttr & ~clrAttr);
+    }
+    return 0;
+}
-- 
1.6.0.4



Reply via email to