home *** CD-ROM | disk | FTP | other *** search
- /* DISKUSE
-
- This program will list the filename, file owner and file size of every file in
- a specified directory.
-
- AUTHOR:
- Mike Frederick, University of Houston, May 11, 1994
-
- NOTES:
- To get the file owner information, a call to the API GetFileSecurity should be
- used. However, there is a bug in the Windows NT 3.1 version of the API which
- causes the request to fail if the owner of the file has denied access to the
- calling user. The API should check to see if the calling user has the
- SE_BACKUP_NAME privilege enabled, but it does not.
-
- The work-around (supplied by MS PSS) is to enable SE_BACKUP_NAME, open the
- file with the CreateFile API (with FILE_FLAG_BACKUP_SEMANTICS) and then call
- GetKernelObjectSecurity on the open handle.
-
- LIMITS:
- This program cannot report on files or directory totals greater than 2**32
- bytes in size.
-
- */
-
- #include <stdio.h>
- #include <windows.h>
- #include <string.h>
- #include <malloc.h>
- #include <memory.h>
- #include <process.h>
-
- #define CopyPathFile lstrcpy(downPath,FindPath);downPath [lstrlen(downPath)-3]=0;lstrcat(downPath,FileData.cFileName);
- #define SID_SIZE 100
- #define SD_SIZE 512
- #define PATH_SIZE 1024
-
- /* Called routines */
-
- dirtotal (const char *);
- void usage (void);
- BOOL AdjustProcessPrivs (LPTSTR PrivString, BOOL fEnable);
- BOOL GetFileOwner (const char * path, PSECURITY_DESCRIPTOR pSD);
-
- DWORD GrandTotal = 0;
- int depth = -1;
-
- /* Main routine */
-
- UINT main (int argc, char *argv[]) {
-
- /* Check ARGs */
-
- if (argc < 2) usage ();
-
- /* Enable privs to allow bypassing file system protections */
-
- AdjustProcessPrivs (SE_BACKUP_NAME, TRUE);
-
- /* Call the directory scanner */
-
- dirtotal (argv [1]);
-
- /* Turn off privileges */
-
- AdjustProcessPrivs (NULL, FALSE);
-
- /* Print the total results */
-
- printf ("\n\nGrand Total is: %luK\n", GrandTotal);
- return (0);
-
- }
-
- /* Tell the user the correct invocation syntax */
-
- void usage (void)
- {
- printf ("Usage: FILES path\n");
- exit (0);
- }
-
- /* Workhorse routine. This routine is called recursively with the name of
- every subdirectory. */
-
- dirtotal (const char * path)
- {
-
- WIN32_FIND_DATA
- FileData;
-
- HANDLE
- hSearch;
-
- BOOL
- fFinished = FALSE,
- od,
- status;
-
- DWORD
- SizeTotal = 0,
- usersize,
- domainsize;
-
- UCHAR
- FindPath [PATH_SIZE],
- downPath [PATH_SIZE],
- SD [SD_SIZE],
- sid [SID_SIZE],
- LastSid [SID_SIZE],
- userid [20],
- domain [20];
-
- PSECURITY_DESCRIPTOR
- pSD = (PSECURITY_DESCRIPTOR) &SD;
-
- PSID
- psid = &sid,
- LastSidPtr = &LastSid;
-
- SID_NAME_USE
- SNU;
-
- PSID_NAME_USE
- pSNU = &SNU;
-
- int
- i;
-
-
- depth++;
-
- /* Make a working copy of the input path */
-
- lstrcpy (FindPath, path); lstrcat (FindPath, "*.*");
- printf ("%s\n\n", path);
-
- /* Start the wildcard search */
-
- hSearch = FindFirstFile (FindPath, &FileData);
- if ((int) hSearch == -1)
- {
- printf ("Cannot access any of these files or subdirectories\n");
- return (0);
- }
-
- while (!fFinished) {
-
- /* If the found file is not a directory, report its size */
-
- if (!(FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
- CopyPathFile;
- if (GetFileOwner (downPath, pSD))
- {
- status = GetSecurityDescriptorOwner (pSD, &psid, &od);
-
- /* If this file is owned by the same SID as the previous file examined, don't
- go through the overhead of the LookupAccountSid again. */
-
- if (!EqualSid (psid, LastSid))
- {
- usersize = sizeof (userid);
- domainsize = sizeof (domain);
- if (!LookupAccountSid ("", psid, userid, &usersize, domain, &domainsize, pSNU))
- {
- status = GetLastError ();
- }
- CopySid (sizeof (LastSid), LastSid, psid);
- }
- }
- else
- {
-
- /* Use dummy values when the real owner cannot be determined */
-
- lstrcpy (domain, "Unknown");
- lstrcpy (userid, "No_file_access");
-
- /* Clear the "LastSid" to force a lookup after a file access is not allowed */
-
- for (i = 0; i < SID_SIZE; i++) LastSid [i] = 0;
- }
- printf ("+ %12lu %s\\%s %s\n", FileData.nFileSizeLow, domain, userid, FileData.cFileName);
- SizeTotal += FileData.nFileSizeLow / 1024;
- }
- else
- {
-
- /* If the found file is a directory, call this routine with the new path.
- Ignore the directories "." and "..". */
-
- if (lstrcmp (FileData.cFileName, TEXT (".")) != 0 &&
- lstrcmp (FileData.cFileName, TEXT ("..")) != 0)
- {
- CopyPathFile;
- lstrcat (downPath, "\\");
- dirtotal (downPath);
- }
- }
-
- /* Look for more files */
-
- if (!FindNextFile (hSearch, &FileData)) {
- if (GetLastError () == ERROR_NO_MORE_FILES) fFinished = TRUE;
- }
- }
-
- /* Close the wildcard search */
-
- FindClose (hSearch);
-
- /* Print the directory totals */
-
- printf ("\nTotal size: %luK (%luM)\n", SizeTotal, SizeTotal / 1024);
- GrandTotal += SizeTotal;
- depth--;
-
- }
-
- BOOL GetFileOwner (const char * path, PSECURITY_DESCRIPTOR pSD)
-
- /* GetFileOwner
-
- Because of a problem with the GetFileSecurity API, you must this kludge to
- get the ownership of a file to which you have no file access permissions.
-
- */
-
- {
-
- HANDLE
- hFile;
-
- DWORD
- status,
- SizeRequired;
-
- hFile = CreateFile (
- path,
- GENERIC_READ,
- FILE_SHARE_WRITE,
- NULL,
- OPEN_EXISTING,
- FILE_FLAG_BACKUP_SEMANTICS,
- NULL);
- status = GetLastError ();
-
- if (status == ERROR_SUCCESS)
- {
- status = GetKernelObjectSecurity (
- hFile,
- OWNER_SECURITY_INFORMATION,
- pSD,
- SID_SIZE,
- &SizeRequired
- );
- if (status)
- {
- CloseHandle (hFile);
- return TRUE;
- }
- else
- {
- printf ("Error calling API GetKernelObjectSecurity = %d\n", status);
- printf ("GetLastError = %d\n", GetLastError ());
- }
- }
- else
- printf ("Error calling API CreateFile = %d\n", status);
- return FALSE;
- }
-
-
-