|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1996 - 1996.
//
// File: FILE.C
//
// Contents: Unit test for file propagation, issues
//
// History: 14-Sep-96 MacM Created
//
// Notes:
//
//----------------------------------------------------------------------------
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <aclapi.h>
#include <seopaque.h>
#include <ntrtl.h>
#define FLAG_ON(flags,bit) ((flags) & (bit))
#define DEFAULT_ACCESS ACTRL_STD_RIGHTS_ALL | ACTRL_DIR_TRAVERSE | ACTRL_DIR_LIST
//
// The following is the list of the directory tree to possibly be created
//
PWSTR gpwszTreeList[] = {L"\\dir1", L"\\dir1\\dir2",L"\\dir1\\dir3", L"\\dir1\\dir2\\dir4", L"\\dir1\\dir3\\dir5", L"\\dir1\\dir3\\dir6", L"\\dir1\\dir2\\dir4\\dir7", L"\\dir1\\dir2\\dir4\\dir7\\dir8", L"\\dir1\\dir2\\dir4\\dir7\\dir9"}; PWSTR gpwszFileList[] = {L"\\dir1\\file1", L"\\dir1\\dir3\\dir6\\file2", L"\\dir1\\dir2\\dir4\\dir7\\dir9\\file3"};
ULONG cTree = sizeof(gpwszTreeList) / sizeof(PWSTR); ULONG cFile = sizeof(gpwszFileList) / sizeof(PWSTR);
//
// Flags for tests
//
#define FTEST_READ 0x00000001
#define FTEST_TREE 0x00000002
#define FTEST_INTERRUPT 0x00000004
#define FTEST_COMPRESS 0x00000008
#define FTEST_NOACCESS 0x00000010
#define FTEST_OPENDIR 0x00000020
#define FTEST_COMPRESS2 0x00000040
#define FTEST_PROTECT 0x00000080
#define FTEST_GET3 0x00000100
#define FTEST_GETOWNER 0x00000200
#define RandomIndex(Max) (rand() % (Max))
#define RandomIndexNotRoot(Max) (rand() % (Max - 1) + 1)
#define HANDLE_CLOSE(h) if((h) != NULL) { CloseHandle(h); (h) = NULL;}
DWORD AddAE ( IN PWSTR pwszUser, IN ACCESS_RIGHTS AccessRights, IN INHERIT_FLAGS Inherit, IN ULONG fAccess, IN PACTRL_ACCESS pExistingAccess, OUT PACTRL_ACCESS *ppNewAccess ) /*++
Routine Description:
Initialize an access entry
Arguments:
pwszUser - User to set AccessRights - Access rights to set Inherit - Any inheritance flags fAccess - Allowed or denied node? pExistingAccess - Access Entry to add to ppNewAccess - Where the new access is returned
Return Value:
ERROR_SUCCESS - Success
--*/ { DWORD dwErr = ERROR_SUCCESS; ACTRL_ACCESS_ENTRY AAE;
BuildTrusteeWithNameW(&(AAE.Trustee), pwszUser); AAE.fAccessFlags = fAccess; AAE.Access = AccessRights; AAE.ProvSpecificAccess = 0; AAE.Inheritance = Inherit; AAE.lpInheritProperty = NULL;
dwErr = SetEntriesInAccessListW(1, &AAE, GRANT_ACCESS, NULL, pExistingAccess, ppNewAccess); if(dwErr != ERROR_SUCCESS) { printf(" FAILED to add new access entry: %lu\n", dwErr); }
return(dwErr); }
DWORD BuildTree ( IN PWSTR pwszRoot ) /*++
Routine Description:
Builds the test tree
Arguments:
pwszRoot - Root directory under which to create the tree
Return Value:
ERROR_SUCCESS - Success
--*/ { DWORD dwErr = ERROR_SUCCESS; ULONG i; WCHAR wszPath[MAX_PATH + 1]; HANDLE hFile;
for(i = 0; i < cTree; i++) { swprintf(wszPath, L"%ws%ws", pwszRoot, gpwszTreeList[i]); //
// Now, create the directory...
//
if(CreateDirectory(wszPath, NULL) == FALSE) { dwErr = GetLastError(); break; } }
//
// If all of that worked, we'll create the files
//
for(i = 0; i < cFile && dwErr == ERROR_SUCCESS; i++) { swprintf(wszPath, L"%ws%ws", pwszRoot, gpwszFileList[i]); hFile = CreateFile(wszPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if(hFile == INVALID_HANDLE_VALUE) { dwErr = GetLastError(); } else { CloseHandle(hFile); } }
if(dwErr != ERROR_SUCCESS) { printf("FAILED to create %ws: %lu\n", wszPath, dwErr); } return(dwErr); }
DWORD DeleteTree ( IN PWSTR pwszRoot ) /*++
Routine Description:
Removes the test tree
Arguments:
pwszRoot - Root directory under which the tree was created
Return Value:
VOID
--*/ { ULONG i; WCHAR wszPath[MAX_PATH + 1]; DWORD dwErr = ERROR_SUCCESS;
for(i = cFile; i != 0 && dwErr == ERROR_SUCCESS; i--) { swprintf(wszPath, L"%ws%ws", pwszRoot, gpwszFileList[i - 1]); if(DeleteFile(wszPath) == FALSE) { dwErr = GetLastError(); printf("FAILED to delete %ws: 0x%lx\n", wszPath, dwErr); break; } }
for(i = cTree; i != 0 && dwErr == ERROR_SUCCESS; i--) { swprintf(wszPath, L"%ws%ws", pwszRoot, gpwszTreeList[i - 1]); if(RemoveDirectory(wszPath) == FALSE) { dwErr = GetLastError(); if(dwErr == ERROR_PATH_NOT_FOUND || dwErr == ERROR_FILE_NOT_FOUND) { dwErr = ERROR_SUCCESS; } else { printf("FAILED to remove %ws: 0x%lx\n", wszPath, GetLastError()); } } }
return(dwErr); }
VOID Usage ( IN PSTR pszExe ) /*++
Routine Description:
Displays the usage
Arguments:
pszExe - Name of the exe
Return Value:
VOID
--*/ { printf("%s path user [/C] [/O] [/I] [/P] [/test] [/H]\n", pszExe); printf(" where path is the root path to use\n"); printf(" user is the name of a user to set access for\n"); printf(" /test indicates which test to run:\n"); printf(" /READ (Simple read/write)\n"); printf(" /TREE (Propagation of entries through tree)\n"); printf(" /INTERRUPT (Propagation interruptus and continuation)\n"); printf(" /COMPRESS (Compression of access entries)\n"); printf(" /NOACCESS (Propagation across a directory w/ no traverse access)\n"); printf(" /OPENDIR (Propagation with the directory already open\n"); printf(" /COMPRESS2 (Compression of big list of access entries)\n"); printf(" /PROTECT (Protected child acls)\n"); printf(" /GET3 (Get Dacl/Owner/Group)\n"); printf(" /GETOWNER (Get Owner test)\n"); printf(" if test is not specified, all variations are run\n"); printf(" /H indicates to use the handle version of the APIs\n"); printf(" /C is Container Inherit\n"); printf(" /O is Object Inherit\n"); printf(" /I is InheritOnly\n"); printf(" /P is Inherit No Propagate\n");
return; }
//
// Conceptually, this is a companion function for GetSecurityForPath
//
#define SetSecurityForPath(path,usehandle,handle,access) \
(usehandle == TRUE ? \ SetSecurityInfoExW(handle, \ SE_FILE_OBJECT, \ DACL_SECURITY_INFORMATION, \ NULL, \ access, \ NULL, \ NULL, \ NULL, \ NULL) : \ SetNamedSecurityInfoExW(path, \ SE_FILE_OBJECT, \ DACL_SECURITY_INFORMATION, \ NULL, \ access, \ NULL, \ NULL, \ NULL, \ NULL))
DWORD GetSecurityForPath ( IN PWSTR pwszPath, IN BOOL fUseHandle, IN ULONG OpenFlags, OUT HANDLE *phObj, OUT PACTRL_ACCESSW *ppAccess ) /*++
Routine Description:
Reads the dacl off the specified path
Arguments:
pwszPath -- Path to read fUseHandle -- Use handle or path based API OpenFlags -- Flags to use if opening the object phObj -- Handle to object ppAccess -- Where the access is returned
Return Value:
ERROR_SUCCESS -- Success
--*/ { DWORD dwErr = ERROR_SUCCESS;
if(fUseHandle == TRUE) { //
// Open the object
//
if(*phObj == NULL) { *phObj = CreateFile(pwszPath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, OpenFlags | READ_CONTROL | WRITE_DAC, NULL); if(*phObj == INVALID_HANDLE_VALUE) { dwErr = GetLastError(); *phObj = NULL; } }
if(dwErr == ERROR_SUCCESS) { dwErr = GetSecurityInfoExW(*phObj, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, ppAccess, NULL, NULL, NULL); if(dwErr != ERROR_SUCCESS) { HANDLE_CLOSE(*phObj); }
}
} else { dwErr = GetNamedSecurityInfoExW(pwszPath, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, ppAccess, NULL, NULL, NULL); if(phObj != NULL) { *phObj = NULL; } }
return(dwErr); }
DWORD VerifyTreeSet ( IN PWSTR pwszPath, IN PWSTR pwszUser, IN INHERIT_FLAGS Inherit ) /*++
Routine Description:
Reads the dacl off the specified path
Arguments:
pwszPath -- Root path to verify pwszUser -- User to verify Inherit -- Expected inheritance
Return Value:
ERROR_SUCCESS -- Success
--*/ { DWORD dwErr = ERROR_SUCCESS; WCHAR rgwszPaths[3][MAX_PATH]; INT i,j; PACTRL_ACCESSW pAccess; PACTRL_ACCESS_ENTRYW pAE; BOOL fInNoP = FALSE;
if(FLAG_ON(Inherit, INHERIT_NO_PROPAGATE)) { fInNoP = TRUE; }
//
// Now, verify it...
//
if(fInNoP == TRUE) { i = rand() % 2 + 1; } else { i = RandomIndexNotRoot(cTree); } swprintf(rgwszPaths[0], L"%ws%ws", pwszPath, gpwszTreeList[i]);
if(fInNoP == TRUE) { i = 0; } else { i = RandomIndex(cFile); } swprintf(rgwszPaths[1], L"%ws%ws", pwszPath, gpwszFileList[i]);
//
// Finally, if this is an inherit, no propagate, check one of the
// leaf entries for non-compliance
//
if(fInNoP == TRUE) { i = rand() % 6 + 3; swprintf(rgwszPaths[2], L"%ws%ws", pwszPath, gpwszTreeList[i]); Inherit &= ~(SUB_CONTAINERS_AND_OBJECTS_INHERIT);
}
for(i = 0; i < (fInNoP == TRUE ? 3 : 2) && dwErr == ERROR_SUCCESS; i++) { //
// Get the security off the node, find the entry we added, and verify
// that the entry is correct
//
dwErr = GetSecurityForPath(rgwszPaths[i], FALSE, FILE_FLAG_BACKUP_SEMANTICS, NULL, &pAccess); if(dwErr != ERROR_SUCCESS) { printf(" FAILED to get the security for %ws: %lu\n", rgwszPaths[i], dwErr); break; }
pAE = NULL; for(j = 0; j < (INT)pAccess->pPropertyAccessList[0].pAccessEntryList->cEntries; j++) { if(_wcsicmp(pwszUser, pAccess->pPropertyAccessList[0].pAccessEntryList-> pAccessList[j].Trustee.ptstrName) == 0) { pAE = &(pAccess->pPropertyAccessList[0].pAccessEntryList-> pAccessList[j]); break; } }
if(pAE == NULL) { if((i == 0 && FLAG_ON(Inherit,SUB_CONTAINERS_ONLY_INHERIT)) || (i == 1 && FLAG_ON(Inherit,SUB_OBJECTS_ONLY_INHERIT))) { printf(" FAILED to find entry for %ws on path %ws\n", pwszUser, rgwszPaths[i]); dwErr = ERROR_INVALID_FUNCTION; } } else { //
// Verify that the info is correct
//
if(!FLAG_ON(pAE->Inheritance, INHERITED_ACCESS_ENTRY)) { printf(" Access entry on %ws is not inherited!\n", rgwszPaths[i]); dwErr = ERROR_INVALID_FUNCTION; }
if(i == 0) { if(FLAG_ON(Inherit, SUB_CONTAINERS_ONLY_INHERIT) && !FLAG_ON(pAE->Inheritance, SUB_CONTAINERS_ONLY_INHERIT)) { printf(" No container inherit on %ws!\n", rgwszPaths[i]); dwErr = ERROR_INVALID_FUNCTION; } } else if(i == 1) { if(FLAG_ON(Inherit, SUB_OBJECTS_ONLY_INHERIT) && FLAG_ON(pAE->Inheritance, SUB_OBJECTS_ONLY_INHERIT)) { printf(" Object inherit bit on object on %ws!\n", rgwszPaths[i]); dwErr = ERROR_INVALID_FUNCTION; } } else { printf(" Inherit No Propagate node found on child %ws\n", rgwszPaths[i]); dwErr = ERROR_INVALID_FUNCTION; }
}
if(dwErr == ERROR_SUCCESS) { printf(" Successfully verified %ws\n", rgwszPaths[i]); }
LocalFree(pAccess); }
return(dwErr); }
DWORD DoReadTest ( IN PWSTR pwszPath, IN PWSTR pwszUser, IN BOOL fDoHandle ) /*++
Routine Description:
Does the simple read test
Arguments:
pwszPath -- Root path pwszUser -- User to run with fDoHandle -- If true, use the handle based APIs
Return Value:
ERROR_SUCCESS -- Success
--*/ { DWORD dwErr = ERROR_SUCCESS; WCHAR rgwszPaths[2][MAX_PATH]; INT i; PACTRL_ACCESS pCurrent; PACTRL_ACCESS pNew; HANDLE hObj; ULONG OpenFlags[] = {FILE_FLAG_BACKUP_SEMANTICS, 0};
printf("Simple read/write test\n");
swprintf(rgwszPaths[0], L"%ws%ws", pwszPath, gpwszTreeList[RandomIndex(cTree)]);
swprintf(rgwszPaths[1], L"%ws%ws", pwszPath, gpwszFileList[RandomIndex(cFile)]);
for(i = 0; i < 2; i++) { printf(" Processing path %ws\n", rgwszPaths[i]); hObj = NULL;
dwErr = GetSecurityForPath(rgwszPaths[i], fDoHandle, OpenFlags[i], &hObj, &pCurrent); if(dwErr != ERROR_SUCCESS) { printf(" FAILED to read the DACL off %ws: %lu\n", rgwszPaths[i], dwErr); } else { //
// Ok, now add the entry for our user
//
dwErr = AddAE(pwszUser, DEFAULT_ACCESS, 0, ACTRL_ACCESS_ALLOWED, pCurrent, &pNew); if(dwErr == ERROR_SUCCESS) { //
// Set it
//
dwErr = SetSecurityForPath(rgwszPaths[i], fDoHandle, hObj,pNew);
if(dwErr != ERROR_SUCCESS) { printf(" Set FAILED: %lu\n", dwErr); } LocalFree(pNew); }
//
// If that worked, reread the new security, and see if it's correct
//
if(dwErr == ERROR_SUCCESS) { HANDLE_CLOSE(hObj);
dwErr = GetSecurityForPath(rgwszPaths[i], fDoHandle, OpenFlags[i], &hObj, &pNew); if(dwErr != ERROR_SUCCESS) { printf(" FAILED to read the 2nd DACL off %ws: %lu\n", rgwszPaths[i], dwErr); } else { //
// We should only have one property, so cheat...
//
ULONG cExpected = 1 + pCurrent->pPropertyAccessList[0]. pAccessEntryList->cEntries; ULONG cGot = pNew->pPropertyAccessList[0]. pAccessEntryList->cEntries; if(cExpected != cGot) { printf(" Expected %lu entries, got %lu\n", cExpected, cGot); dwErr = ERROR_INVALID_FUNCTION; }
LocalFree(pNew); }
//
// Restore the current security
//
SetNamedSecurityInfoExW(rgwszPaths[i], SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, pCurrent, NULL, NULL, NULL, NULL); }
LocalFree(pCurrent); }
HANDLE_CLOSE(hObj);
if(dwErr != ERROR_SUCCESS) { break; } } return(dwErr); }
DWORD DoTreeTest ( IN PWSTR pwszPath, IN PWSTR pwszUser, IN INHERIT_FLAGS Inherit, IN BOOL fDoHandle ) /*++
Routine Description:
Does the simple tree test
Arguments:
pwszPath -- Root path pwszUser -- User to run with Inherit -- Inheritance flags fDoHandle -- If true, use the handle based APIs
Return Value:
ERROR_SUCCESS -- Success
--*/ { DWORD dwErr = ERROR_SUCCESS, dwErr2; INT i,j; PACTRL_ACCESS pCurrent; PACTRL_ACCESS pNew; HANDLE hObj = NULL; WCHAR wszPath[MAX_PATH + 1]; WCHAR rgwszPaths[2][MAX_PATH]; PACTRL_ACCESS_ENTRYW pAE;
printf("Tree propagation test\n");
swprintf(wszPath, L"%ws%ws", pwszPath, gpwszTreeList[0]);
//
// Set the access on the root, and then we'll read the child and look for
// the appropratie access
//
dwErr = GetSecurityForPath(wszPath, fDoHandle, FILE_FLAG_BACKUP_SEMANTICS, &hObj, &pCurrent); if(dwErr != ERROR_SUCCESS) { printf(" FAILED to get the security for %ws: %lu\n", wszPath, dwErr); return(dwErr); }
//
// Ok, add the access
//
dwErr = AddAE(pwszUser, DEFAULT_ACCESS, Inherit, ACTRL_ACCESS_ALLOWED, pCurrent, &pNew); if(dwErr == ERROR_SUCCESS) { //
// Set it
//
dwErr = SetSecurityForPath(wszPath,fDoHandle,hObj,pNew);
if(dwErr != ERROR_SUCCESS) { printf("Set FAILED: %lu\n", dwErr); } LocalFree(pNew); }
dwErr = VerifyTreeSet(pwszPath, pwszUser, Inherit); if(dwErr != ERROR_SUCCESS) { printf(" VerifyTreeSet FAILED with %lu\n", dwErr); }
//
// Restore the current security
//
dwErr2 = SetNamedSecurityInfoExW(wszPath, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, pCurrent, NULL, NULL, NULL, NULL); if(dwErr2 != ERROR_SUCCESS) { if(dwErr == ERROR_SUCCESS) { dwErr = dwErr2; } printf("FAILED to restore the security for %ws: %lu\n", wszPath, dwErr2); } LocalFree(pCurrent);
HANDLE_CLOSE(hObj);
return(dwErr); }
DWORD DoInterruptTest ( IN PWSTR pwszPath, IN PWSTR pwszUser, IN INHERIT_FLAGS Inherit, IN BOOL fDoHandle ) /*++
Routine Description:
Does the interrupt tree/repeat tree test
Arguments:
pwszPath -- Root path pwszUser -- User to run with Inherit -- Inheritance flags fDoHandle -- If true, use the handle based APIs
Return Value:
ERROR_SUCCESS -- Success
--*/ { DWORD dwErr = ERROR_SUCCESS, dwErr2; PACTRL_ACCESS pCurrent; PACTRL_ACCESS pNew; HANDLE hObj = NULL; WCHAR wszPath[MAX_PATH + 1]; ACTRL_OVERLAPPED Overlapped;
printf("Tree propagation with interruption\n");
swprintf(wszPath, L"%ws%ws", pwszPath, gpwszTreeList[0]);
//
// Set the access on the root, and then we'll read the child and look for
// the appropratie access
//
dwErr = GetSecurityForPath(wszPath, fDoHandle, FILE_FLAG_BACKUP_SEMANTICS, &hObj, &pCurrent); if(dwErr != ERROR_SUCCESS) { printf(" FAILED to get the security for %ws: %lu\n", wszPath, dwErr); return(dwErr); }
//
// Ok, add the access
//
dwErr = AddAE(pwszUser, DEFAULT_ACCESS, Inherit, ACTRL_ACCESS_ALLOWED, pCurrent, &pNew);
if(dwErr == ERROR_SUCCESS) { //
// Set it, interrupt it, and set it again
//
if(fDoHandle == TRUE) { dwErr = SetSecurityInfoExW(hObj, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, pNew, NULL, NULL, NULL, &Overlapped); } else { dwErr = SetNamedSecurityInfoExW(wszPath, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, pNew, NULL, NULL, NULL, &Overlapped); }
//
// Immeadiately cancel it...
//
if(dwErr == ERROR_SUCCESS) { WaitForSingleObject(Overlapped.hEvent, 100); dwErr = CancelOverlappedAccess(&Overlapped); if(dwErr != ERROR_SUCCESS) { printf("Cancel FAILED with %lu\n", dwErr); } }
//
// Now, reset it and verify it
//
if(dwErr == ERROR_SUCCESS) { dwErr = SetSecurityForPath(wszPath,fDoHandle,hObj,pNew);
if(dwErr != ERROR_SUCCESS) { printf("Set FAILED: %lu\n", dwErr); } }
LocalFree(pNew); }
dwErr = VerifyTreeSet(pwszPath, pwszUser, Inherit); if(dwErr != ERROR_SUCCESS) { printf(" VerifyTreeSet FAILED with %lu\n", dwErr); }
//
// Restore the current security
//
dwErr2 = SetNamedSecurityInfoExW(wszPath, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, pCurrent, NULL, NULL, NULL, NULL); if(dwErr2 != ERROR_SUCCESS) { if(dwErr == ERROR_SUCCESS) { dwErr = dwErr2; } printf("FAILED to restore the security for %ws: %lu\n", wszPath, dwErr2); } LocalFree(pCurrent);
HANDLE_CLOSE(hObj);
return(dwErr); }
DWORD DoCompressTest ( IN PWSTR pwszPath, IN PWSTR pwszUser, IN BOOL fDoHandle ) /*++
Routine Description:
Does the entry compression test
Arguments:
pwszPath -- Root path pwszUser -- User to run with fDoHandle -- Do the handle based API
Return Value:
ERROR_SUCCESS -- Success
--*/ { DWORD dwErr = ERROR_SUCCESS; WCHAR rgwszPaths[2][MAX_PATH]; INT i,j; ULONG cOrigCnt; PACTRL_ACCESS pCurrent; PACTRL_ACCESS pNew; HANDLE hObj; ULONG OpenFlags[] = {FILE_FLAG_BACKUP_SEMANTICS, 0}; ACCESS_RIGHTS Rights[] = {ACTRL_DELETE, ACTRL_READ_CONTROL, ACTRL_CHANGE_ACCESS, ACTRL_CHANGE_OWNER, ACTRL_SYNCHRONIZE, ACTRL_STD_RIGHTS_ALL};
printf("Entry compression test\n");
swprintf(rgwszPaths[0], L"%ws%ws", pwszPath, gpwszTreeList[RandomIndex(cTree)]);
swprintf(rgwszPaths[1], L"%ws%ws", pwszPath, gpwszFileList[RandomIndex(cFile)]);
for(i = 0; i < 2; i++) { cOrigCnt = 0; printf(" Processing path %ws\n", rgwszPaths[i]);
for(j = 0; j < sizeof(Rights) / sizeof(ACCESS_RIGHTS); j++) { hObj = NULL; printf(" Processing right 0x%lx\n", Rights[j]);
dwErr = GetSecurityForPath(rgwszPaths[i], fDoHandle, OpenFlags[i], &hObj, &pCurrent); if(dwErr != ERROR_SUCCESS) { printf(" FAILED to read the DACL off %ws: %lu\n", rgwszPaths[i], dwErr); } else { if(cOrigCnt == 0) { cOrigCnt = pCurrent->pPropertyAccessList[0]. pAccessEntryList->cEntries; }
//
// Ok, now add the entry for our user
//
dwErr = AddAE(pwszUser, Rights[0] | ACTRL_DIR_TRAVERSE | ACTRL_DIR_LIST, 0, ACTRL_ACCESS_ALLOWED, pCurrent, &pNew);
if(dwErr == ERROR_SUCCESS) { //
// Set it
//
dwErr = SetSecurityForPath(rgwszPaths[i], fDoHandle, hObj, pNew); if(dwErr != ERROR_SUCCESS) { printf("Set FAILED: %lu\n", dwErr); } LocalFree(pNew); }
//
// If that worked, reread the new security, and see if it's
// correct
//
if(dwErr == ERROR_SUCCESS) { HANDLE_CLOSE(hObj); dwErr = GetSecurityForPath(rgwszPaths[i], fDoHandle, OpenFlags[i], &hObj, &pNew); if(dwErr != ERROR_SUCCESS) { printf(" FAILED to read the 2nd DACL off %ws: %lu\n", rgwszPaths[i], dwErr); } else { //
// We should only have one property, so cheat...
//
ULONG cGot = pNew->pPropertyAccessList[0]. pAccessEntryList->cEntries; if(cOrigCnt + 1 != cGot) { printf(" Expected %lu entries, got %lu\n", cOrigCnt + 1, cGot); dwErr = ERROR_INVALID_FUNCTION; }
LocalFree(pNew); }
//
// Restore the current security
//
SetNamedSecurityInfoExW(rgwszPaths[i], SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, pCurrent, NULL, NULL, NULL, NULL); }
LocalFree(pCurrent); }
HANDLE_CLOSE(hObj);
if(dwErr != ERROR_SUCCESS) { break; } } }
return(dwErr); }
DWORD DoCompress2Test ( IN PWSTR pwszPath, IN PWSTR pwszUser, IN BOOL fDoHandle ) /*++
Routine Description:
Does the big list entry compression test
Arguments:
pwszPath -- Root path pwszUser -- User to run with fDoHandle -- Do the handle based API
Return Value:
ERROR_SUCCESS -- Success
--*/ { DWORD dwErr = ERROR_SUCCESS; WCHAR rgwszPaths[2][MAX_PATH]; INT i,j; ULONG cOrigCnt; PACTRL_ACCESS pCurrent; PACTRL_ACCESS pNew; HANDLE hObj; ULONG OpenFlags[] = {FILE_FLAG_BACKUP_SEMANTICS, 0}; ACCESS_RIGHTS Rights[] = {ACTRL_DELETE, ACTRL_READ_CONTROL, ACTRL_CHANGE_ACCESS, ACTRL_CHANGE_OWNER, ACTRL_SYNCHRONIZE, ACTRL_STD_RIGHTS_ALL, ACTRL_DIR_TRAVERSE | ACTRL_DIR_LIST}; INT cItems = sizeof(Rights) / sizeof(ACCESS_RIGHTS); ACTRL_ACCESS_ENTRY AAEList[sizeof(Rights) / sizeof(ACCESS_RIGHTS)]; PACTRL_ACCESS_ENTRY pAE;
printf("Entry compression test\n");
swprintf(rgwszPaths[0], L"%ws%ws", pwszPath, gpwszTreeList[RandomIndex(cTree)]);
swprintf(rgwszPaths[1], L"%ws%ws", pwszPath, gpwszFileList[RandomIndex(cFile)]);
for(i = 0; i < 2; i++) { printf(" Processing path %ws\n", rgwszPaths[i]); cOrigCnt = 0;
hObj = NULL;
dwErr = GetSecurityForPath(rgwszPaths[i], fDoHandle, OpenFlags[i], &hObj, &pCurrent); if(dwErr != ERROR_SUCCESS) { printf(" FAILED to read the DACL off %ws: %lu\n", rgwszPaths[i], dwErr); } else { if(cOrigCnt == 0) { cOrigCnt = pCurrent->pPropertyAccessList[0]. pAccessEntryList->cEntries; }
//
// Ok, now add the entries for our user
//
for(j = 0; j < sizeof(Rights) / sizeof(ACCESS_RIGHTS); j++) { printf(" Processing right 0x%lx\n", Rights[j]);
BuildTrusteeWithNameW(&(AAEList[j].Trustee), pwszUser); AAEList[j].fAccessFlags = ACTRL_ACCESS_ALLOWED; AAEList[j].Access = Rights[j]; AAEList[j].ProvSpecificAccess = 0; AAEList[j].Inheritance = 0; AAEList[j].lpInheritProperty = NULL; }
//
// Now, add 'em
//
dwErr = SetEntriesInAccessListW(cItems, AAEList, GRANT_ACCESS, NULL, pCurrent, &pNew);
if(dwErr == ERROR_SUCCESS) { //
// Set it
//
dwErr = SetSecurityForPath(rgwszPaths[i], fDoHandle, hObj, pNew); if(dwErr != ERROR_SUCCESS) { printf("Set FAILED: %lu\n", dwErr); } LocalFree(pNew); }
//
// If that worked, reread the new security, and see if it's
// correct
//
if(dwErr == ERROR_SUCCESS) { HANDLE_CLOSE(hObj); dwErr = GetSecurityForPath(rgwszPaths[i], fDoHandle, OpenFlags[i], &hObj, &pNew); if(dwErr != ERROR_SUCCESS) { printf(" FAILED to read the 2nd DACL off %ws: %lu\n", rgwszPaths[i], dwErr); } else { //
// We should only have one property, so cheat...
//
ULONG cGot = pNew->pPropertyAccessList[0]. pAccessEntryList->cEntries; if(cOrigCnt + 1 != cGot) { printf(" Expected %lu entries, got %lu\n", cOrigCnt + 1, cGot); dwErr = ERROR_INVALID_FUNCTION; } else { //
// Find the added entry...
//
pAE = NULL; for(j = 0; j < (INT)pNew->pPropertyAccessList[0]. pAccessEntryList->cEntries; j++) { if(_wcsicmp(pwszUser, pNew->pPropertyAccessList[0]. pAccessEntryList->pAccessList[j]. Trustee.ptstrName) == 0) { pAE = &(pNew->pPropertyAccessList[0]. pAccessEntryList->pAccessList[j]); break; } }
if(pAE == NULL) { printf(" Couldn't find entry for %ws\n", pwszUser); dwErr = ERROR_INVALID_FUNCTION; } else { ACCESS_RIGHTS ExpectedAR = 0; for(j = 0; j < cItems; j++) { ExpectedAR |= Rights[j]; }
if(pAE->Access != ExpectedAR) { printf(" Expected compressed rights of 0x%lx, not 0x%lx\n", ExpectedAR, pAE->Access); dwErr = ERROR_INVALID_FUNCTION; }
} }
LocalFree(pNew); }
//
// Restore the current security
//
SetNamedSecurityInfoExW(rgwszPaths[i], SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, pCurrent, NULL, NULL, NULL, NULL); }
LocalFree(pCurrent); }
HANDLE_CLOSE(hObj);
if(dwErr != ERROR_SUCCESS) { break; } }
return(dwErr); }
DWORD DoNoAccessTest ( IN PWSTR pwszPath, IN PWSTR pwszUser, IN INHERIT_FLAGS Inherit, IN BOOL fDoHandle ) /*++
Routine Description:
Does the NoAccess tree test, where some child node does not have access to its children
Arguments:
pwszPath -- Root path pwszUser -- User to run with Inherit -- Inheritance flags fDoHandle -- If true, use the handle based APIs
Return Value:
ERROR_SUCCESS -- Success
--*/ { DWORD dwErr = ERROR_SUCCESS, dwErr2; INT i,j, iChild; PACTRL_ACCESS pCurrent; PACTRL_ACCESS pCurrentChild; PACTRL_ACCESS pNew; PACTRL_ACCESS pNewChild; HANDLE hObj = NULL; HANDLE hChildObj = NULL; WCHAR wszPath[MAX_PATH + 1]; WCHAR wszChildPath[MAX_PATH + 1]; WCHAR rgwszPaths[2][MAX_PATH]; PACTRL_ACCESS_ENTRYW pAE; PSECURITY_DESCRIPTOR pSD;
printf("NoAccess Tree test\n");
swprintf(wszPath, L"%ws%ws", pwszPath, gpwszTreeList[0]);
iChild = RandomIndexNotRoot(cTree); if(iChild == (INT)(cTree - 1)) { iChild--; }
//
// Set the access on the root, and then we'll read the child and look for
// the appropratie access
//
dwErr = GetSecurityForPath(wszPath, fDoHandle, FILE_FLAG_BACKUP_SEMANTICS, &hObj, &pCurrent); if(dwErr != ERROR_SUCCESS) { printf(" FAILED to get the security for %ws: %lu\n", wszPath, dwErr); return(dwErr); } else { swprintf(wszChildPath, L"%ws%ws", pwszPath, gpwszTreeList[iChild]);
dwErr = GetSecurityForPath(wszChildPath, fDoHandle, FILE_FLAG_BACKUP_SEMANTICS, &hChildObj, &pCurrentChild); if(dwErr != ERROR_SUCCESS) { printf(" FAILED to get the security for %ws: %lu\n", wszPath, dwErr); HANDLE_CLOSE(hObj); LocalFree(pCurrent); return(dwErr); }
}
//
// Ok, add the access to the child
//
dwErr = AddAE(L"Everyone", ACTRL_DIR_LIST | ACTRL_DIR_TRAVERSE, 0, ACTRL_ACCESS_DENIED, pCurrentChild, &pNewChild); if(dwErr == ERROR_SUCCESS) { //
// Set it
//
dwErr = SetSecurityForPath(wszChildPath,fDoHandle,hChildObj,pNewChild);
if(dwErr != ERROR_SUCCESS) { printf("Child set FAILED: %lu\n", dwErr); } LocalFree(pNewChild); }
if(dwErr == ERROR_SUCCESS) { dwErr = AddAE(pwszUser, DEFAULT_ACCESS, Inherit, ACTRL_ACCESS_ALLOWED, pCurrent, &pNew);
//
// Set it
//
if(dwErr == ERROR_SUCCESS) { dwErr = SetSecurityForPath(wszPath,fDoHandle,hObj,pNew);
if(dwErr != ERROR_SUCCESS) { printf("Set returned %lu as expected\n", dwErr); if(dwErr == ERROR_ACCESS_DENIED) { dwErr = ERROR_SUCCESS; } } else { printf("Set succeeded when it should have FAILED!\n"); dwErr = ERROR_INVALID_FUNCTION; } } LocalFree(pNew); }
//
// Restore the current child security. Use the old APIs so we don't
// end up trying to do propagation
//
dwErr2 = ConvertAccessToSecurityDescriptor(pCurrentChild, NULL, NULL, NULL, &pSD); if(dwErr2 == ERROR_SUCCESS) { if(SetFileSecurity(wszChildPath, DACL_SECURITY_INFORMATION, pSD) == FALSE) { dwErr2 = GetLastError(); printf("SetFileSecurity on %ws FAILED with %lu\n", wszChildPath, dwErr2); }
LocalFree(pSD); } else { printf("ConvertAccessToSecurityDescriptor FAILED with %lu\n", dwErr2); }
if(dwErr2 != ERROR_SUCCESS) { if(dwErr == ERROR_SUCCESS) { dwErr = dwErr2; } printf("FAILED to restore the security for %ws: %lu\n", wszChildPath, dwErr2); } LocalFree(pCurrentChild);
//
// Restore the current security
//
dwErr2 = SetNamedSecurityInfoExW(wszPath, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, pCurrent, NULL, NULL, NULL, NULL); if(dwErr2 != ERROR_SUCCESS) { if(dwErr == ERROR_SUCCESS) { dwErr = dwErr2; } printf("FAILED to restore the security for %ws: %lu\n", wszPath, dwErr2); } LocalFree(pCurrent);
HANDLE_CLOSE(hObj); HANDLE_CLOSE(hChildObj);
return(dwErr); }
DWORD DoOpenDirTest ( IN PWSTR pwszPath, IN PWSTR pwszUser, IN INHERIT_FLAGS Inherit, IN BOOL fDoHandle ) /*++
Routine Description:
Does the OpenDir tree test, where some child node has been opened
Arguments:
pwszPath -- Root path pwszUser -- User to run with Inherit -- Inheritance flags fDoHandle -- If true, use the handle based APIs
Return Value:
ERROR_SUCCESS -- Success
--*/ { DWORD dwErr = ERROR_SUCCESS, dwErr2; INT i,iChild; PACTRL_ACCESS pCurrent; PACTRL_ACCESS pNew; HANDLE hObj = NULL; HANDLE hChild = NULL; WCHAR wszPath[MAX_PATH + 1]; WCHAR wszChildPath[MAX_PATH + 1]; ULONG ShareFlags[] = {0, FILE_SHARE_WRITE, FILE_SHARE_READ}; PSTR rgszShareFlags[] = {"None", "Write", "Read"}; ULONG ExpectedReturn[] = {ERROR_SHARING_VIOLATION, ERROR_SHARING_VIOLATION, ERROR_SUCCESS};
printf("Open Directory test\n");
swprintf(wszPath, L"%ws%ws", pwszPath, gpwszTreeList[0]);
iChild = RandomIndex(cTree);
//
// Set the access on the root, and then we'll read the child and look for
// the appropratie access
//
dwErr = GetSecurityForPath(wszPath, fDoHandle, FILE_FLAG_BACKUP_SEMANTICS, &hObj, &pCurrent); if(dwErr != ERROR_SUCCESS) { printf(" FAILED to get the security for %ws: %lu\n", wszPath, dwErr); return(dwErr); } else { swprintf(wszChildPath, L"%ws%ws", pwszPath, gpwszTreeList[iChild]); }
//
// Do this through all our flags
//
for(i = 0; i < sizeof(ShareFlags) / sizeof(ULONG) && dwErr == ERROR_SUCCESS; i++) {
printf(" Opening %ws with share flags %s\n", wszChildPath, rgszShareFlags[i]);
//
// Open the child
//
hChild = CreateFile(wszChildPath, GENERIC_READ | GENERIC_WRITE, ShareFlags[i], NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); if(hChild == INVALID_HANDLE_VALUE) { dwErr = GetLastError(); }
//
// Create the new entry
//
if(dwErr == ERROR_SUCCESS) { dwErr = AddAE(pwszUser, DEFAULT_ACCESS, Inherit, ACTRL_ACCESS_ALLOWED, pCurrent, &pNew);
//
// Set it
//
if(dwErr == ERROR_SUCCESS) { dwErr = SetSecurityForPath(wszPath,fDoHandle,hObj,pNew);
if(dwErr == ExpectedReturn[i]) { printf(" Set returned %lu as expected\n", dwErr); dwErr = ERROR_SUCCESS; } else { printf(" Set returned an unexpected %lu instead of %lu!\n", dwErr, ExpectedReturn[i]); if(dwErr == ERROR_SUCCESS) { dwErr = ERROR_INVALID_FUNCTION; } } } LocalFree(pNew); } HANDLE_CLOSE(hChild); }
//
// Restore the current security
//
dwErr2 = SetNamedSecurityInfoExW(wszPath, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, pCurrent, NULL, NULL, NULL, NULL); if(dwErr2 != ERROR_SUCCESS) { if(dwErr == ERROR_SUCCESS) { dwErr = dwErr2; } printf("FAILED to restore the security for %ws: %lu\n", wszPath, dwErr2); } LocalFree(pCurrent);
HANDLE_CLOSE(hObj);
return(dwErr); }
DWORD DoProtectedTest ( IN PWSTR pwszPath, IN PWSTR pwszUser, IN INHERIT_FLAGS Inherit, IN BOOL fDoHandle ) /*++
Routine Description:
Does the protected child test.
Arguments:
pwszPath -- Root path pwszUser -- User to run with Inherit -- Inheritance flags fDoHandle -- If true, use the handle based APIs
Return Value:
ERROR_SUCCESS -- Success
--*/ { DWORD dwErr = ERROR_SUCCESS, dwErr2; WCHAR wszPath[MAX_PATH + 1]; WCHAR wszChildPath[MAX_PATH + 1]; PACTRL_ACCESS pCurrent, pCurrentChild, pNew; HANDLE hObj = NULL;
printf("Propagation with protected child test\n");
//
// Pick a file
//
swprintf(wszChildPath, L"%ws%ws", pwszPath, gpwszFileList[RandomIndex(cFile)]);
//
// Build the parent
//
wcscpy(wszPath, wszChildPath); *(wcsrchr(wszPath, L'\\')) = L'\0';
//
// Get the current security off of both
//
dwErr = GetSecurityForPath(wszPath, fDoHandle, FILE_FLAG_BACKUP_SEMANTICS, &hObj, &pCurrent); if(dwErr == ERROR_SUCCESS) { dwErr = GetSecurityForPath(wszChildPath, FALSE, 0, NULL, &pCurrentChild); if(dwErr != ERROR_SUCCESS) { LocalFree(pCurrent); } }
if(dwErr == ERROR_SUCCESS) { //
// Set a NULL security descriptor on child
//
SECURITY_DESCRIPTOR SD;
InitializeSecurityDescriptor(&SD, SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl(&SD, TRUE, NULL, FALSE); //
// Stamp it on the object directly
//
if(SetFileSecurity(wszChildPath, DACL_SECURITY_INFORMATION, &SD) == FALSE) { dwErr = GetLastError(); printf(" Setting NULL DACL on %ws FAILED with %lu\n", wszChildPath, dwErr); } } else { printf(" FAILED to read the security: %lu\n", dwErr); return(dwErr); }
//
// Ok, now we'll set on the parent, and then look at the child
//
if(dwErr == ERROR_SUCCESS) { dwErr = AddAE(pwszUser, DEFAULT_ACCESS, Inherit, ACTRL_ACCESS_ALLOWED, pCurrent, &pNew);
//
// Set it
//
if(dwErr == ERROR_SUCCESS) { dwErr = SetSecurityForPath(wszPath,fDoHandle,hObj,pNew);
if(dwErr != ERROR_SUCCESS) { printf(" Setting security on %ws FAILED with %lu\n", wszPath, dwErr); }
LocalFree(pNew); } }
//
// Now, if all of that worked, we'll read the security off the child, and make sure that
// it is correct
//
if(dwErr == ERROR_SUCCESS) { dwErr = GetSecurityForPath(wszChildPath, FALSE, 0, NULL, &pNew); if(dwErr != ERROR_SUCCESS) { printf(" GetSecurity on child %ws FAILED with %lu\n", wszChildPath, dwErr); } else { //
// We should have a protected acl and an empty list
//
ASSERT(pNew->pPropertyAccessList != NULL); if(!FLAG_ON(pNew->pPropertyAccessList[0].fListFlags, ACTRL_ACCESS_PROTECTED)) { printf(" Child list not protected\n"); dwErr = ERROR_INVALID_FUNCTION; }
if(pNew->pPropertyAccessList[0].pAccessEntryList != NULL) { printf(" Child list not NULL\n"); dwErr = ERROR_INVALID_FUNCTION; } } }
//
// Restore the current security, child first
//
dwErr2 = SetNamedSecurityInfoExW(wszChildPath, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, pCurrentChild, NULL, NULL, NULL, NULL); if(dwErr2 != ERROR_SUCCESS) { if(dwErr == ERROR_SUCCESS) { dwErr = dwErr2; } printf("FAILED to restore the security for %ws: %lu\n", wszChildPath, dwErr2); }
dwErr2 = SetNamedSecurityInfoExW(wszPath, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, pCurrent, NULL, NULL, NULL, NULL); if(dwErr2 != ERROR_SUCCESS) { if(dwErr == ERROR_SUCCESS) { dwErr = dwErr2; } printf("FAILED to restore the security for %ws: %lu\n", wszPath, dwErr2); }
LocalFree(pCurrent); LocalFree(pCurrentChild);
HANDLE_CLOSE(hObj);
return(dwErr); }
DWORD DoGet3Test ( IN PWSTR pwszPath, IN PWSTR pwszUser, IN BOOL fDoHandle ) /*++
Routine Description:
Does the simple read test
Arguments:
pwszPath -- Root path pwszUser -- User to run with fDoHandle -- If true, use the handle based APIs
Return Value:
ERROR_SUCCESS -- Success
--*/ { DWORD dwErr = ERROR_SUCCESS; WCHAR rgwszPaths[MAX_PATH]; PACTRL_ACCESS pAccessList = NULL, pAuditList = NULL; LPWSTR lpOwner = NULL, lpGroup = NULL; ULONG SeInfo = DACL_SECURITY_INFORMATION;
printf("Get3 Test\n");
swprintf(rgwszPaths, L"%ws%ws", pwszPath, gpwszTreeList[RandomIndex(cTree)]);
printf(" Processing path %ws\n", rgwszPaths);
if(rand() % 2 == 1) { SeInfo |= OWNER_SECURITY_INFORMATION; }
if(rand() % 2 == 1 || SeInfo == DACL_SECURITY_INFORMATION) { SeInfo |= GROUP_SECURITY_INFORMATION; }
dwErr = GetNamedSecurityInfoEx( rgwszPaths, SE_FILE_OBJECT, SeInfo, NULL,NULL,&pAccessList,&pAuditList, &lpOwner,&lpGroup); if(dwErr != ERROR_SUCCESS) { printf(" FAILED: %lu\n", dwErr); } else { printf(" SeInfo: %lu\n", SeInfo);
if ((SeInfo & OWNER_SECURITY_INFORMATION) != 0) {
printf(" Owner: %ws\n", lpOwner); LocalFree(lpOwner); }
if ((SeInfo & GROUP_SECURITY_INFORMATION) != 0) {
printf(" Group: %ws\n", lpGroup); LocalFree(lpGroup);
}
LocalFree(pAccessList); LocalFree(pAuditList); } return(dwErr); }
DWORD DoGetOwnerTest ( IN PWSTR pwszPath, IN PWSTR pwszUser, IN BOOL fDoHandle ) /*++
Routine Description:
Gets the owner from a file
Arguments:
pwszPath -- Root path pwszUser -- User to run with fDoHandle -- If true, use the handle based APIs
Return Value:
ERROR_SUCCESS -- Success
--*/ { DWORD dwErr = ERROR_SUCCESS; WCHAR rgwszPaths[MAX_PATH]; PACTRL_ACCESS pAccessList = NULL, pAuditList = NULL; LPWSTR lpOwner = NULL, lpGroup = NULL; ULONG SeInfo = DACL_SECURITY_INFORMATION;
printf("GetOwner Test\n");
swprintf(rgwszPaths, L"%ws%ws", pwszPath, gpwszTreeList[RandomIndex(cTree)]);
printf(" Processing path %ws\n", rgwszPaths);
dwErr = GetNamedSecurityInfoEx( rgwszPaths, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, NULL,NULL,&pAccessList,&pAuditList, &lpOwner,&lpGroup); if(dwErr != ERROR_SUCCESS) { printf(" FAILED: %lu\n", dwErr); } else { printf(" Owner: %ws\n", lpOwner); LocalFree(lpOwner); } return(dwErr); }
__cdecl main ( IN INT argc, IN CHAR *argv[]) /*++
Routine Description:
The main
Arguments:
argc -- Count of arguments argv -- List of arguments
Return Value:
0 -- Success non-0 -- Failure
--*/ {
DWORD dwErr = ERROR_SUCCESS, dwErr2; WCHAR wszPath[MAX_PATH + 1]; WCHAR wszUser[MAX_PATH + 1]; INHERIT_FLAGS Inherit = 0; ULONG Tests = 0; INT i; BOOL fHandle = FALSE;
srand((ULONG)(GetTickCount() * GetCurrentThreadId()));
if(argc < 3) { Usage(argv[0]); exit(1); }
mbstowcs(wszPath, argv[1], strlen(argv[1]) + 1); mbstowcs(wszUser, argv[2], strlen(argv[2]) + 1);
//
// process the command line
//
for(i = 3; i < argc; i++) { if(_stricmp(argv[i], "/h") == 0) { fHandle = TRUE; } else if(_stricmp(argv[i],"/C") == 0) { Inherit |= SUB_CONTAINERS_ONLY_INHERIT; } else if(_stricmp(argv[i],"/O") == 0) { Inherit |= SUB_OBJECTS_ONLY_INHERIT; } else if(_stricmp(argv[i],"/I") == 0) { Inherit |= INHERIT_ONLY; } else if(_stricmp(argv[i],"/P") == 0) { Inherit |= INHERIT_NO_PROPAGATE; } else if(_stricmp(argv[i],"/READ") == 0) { Tests |= FTEST_READ; } else if(_stricmp(argv[i],"/TREE") == 0) { Tests |= FTEST_TREE; } else if(_stricmp(argv[i],"/INTERRUPT") == 0) { Tests |= FTEST_INTERRUPT; } else if(_stricmp(argv[i],"/COMPRESS") == 0) { Tests |= FTEST_COMPRESS; } else if(_stricmp(argv[i],"/NOACCESS") == 0) { Tests |= FTEST_NOACCESS; } else if(_stricmp(argv[i],"/OPENDIR") == 0) { Tests |= FTEST_OPENDIR; } else if(_stricmp(argv[i],"/COMPRESS2") == 0) { Tests |= FTEST_COMPRESS2; } else if(_stricmp(argv[i],"/PROTECT") == 0) { Tests |= FTEST_PROTECT; } else if(_stricmp(argv[i],"/GET3") == 0) { Tests |= FTEST_GET3; } else if(_stricmp(argv[i],"/GETOWNER") == 0) { Tests |= FTEST_GETOWNER; } else { Usage(argv[0]); exit(1); break; } }
if(Tests == 0) { Tests = FTEST_READ | FTEST_TREE | FTEST_INTERRUPT | FTEST_COMPRESS | FTEST_NOACCESS | FTEST_OPENDIR | FTEST_COMPRESS2 | FTEST_PROTECT | FTEST_GET3 | FTEST_GETOWNER; }
//
// Build the tree
//
dwErr = BuildTree(wszPath); if(dwErr == ERROR_SUCCESS && FLAG_ON(Tests, FTEST_READ)) { dwErr = DoReadTest(wszPath, wszUser, fHandle); } if(dwErr == ERROR_SUCCESS && FLAG_ON(Tests, FTEST_TREE)) { dwErr = DoTreeTest(wszPath, wszUser, Inherit, fHandle); } if(dwErr == ERROR_SUCCESS && FLAG_ON(Tests, FTEST_INTERRUPT)) { dwErr = DoInterruptTest(wszPath, wszUser, Inherit, fHandle); } if(dwErr == ERROR_SUCCESS && FLAG_ON(Tests, FTEST_COMPRESS)) { dwErr = DoCompressTest(wszPath, wszUser, fHandle); } if(dwErr == ERROR_SUCCESS && FLAG_ON(Tests, FTEST_NOACCESS)) { dwErr = DoNoAccessTest(wszPath, wszUser, Inherit, fHandle); } if(dwErr == ERROR_SUCCESS && FLAG_ON(Tests, FTEST_OPENDIR)) { dwErr = DoOpenDirTest(wszPath, wszUser, Inherit, fHandle); } if(dwErr == ERROR_SUCCESS && FLAG_ON(Tests, FTEST_COMPRESS2)) { dwErr = DoCompress2Test(wszPath, wszUser, fHandle); } if(dwErr == ERROR_SUCCESS && FLAG_ON(Tests, FTEST_PROTECT)) { dwErr = DoProtectedTest(wszPath, wszUser, Inherit, fHandle); } if(dwErr == ERROR_SUCCESS && FLAG_ON(Tests, FTEST_GET3)) { dwErr = DoGet3Test(wszPath, wszUser, fHandle); } if(dwErr == ERROR_SUCCESS && FLAG_ON(Tests, FTEST_GETOWNER)) { dwErr = DoGetOwnerTest(wszPath, wszUser, fHandle); }
dwErr2 = DeleteTree(wszPath); if(dwErr2 != ERROR_SUCCESS) { printf("FAILED to delete the tree: %lu\n", dwErr);
if(dwErr == ERROR_SUCCESS) { dwErr = dwErr2; } }
printf("%s\n", dwErr == ERROR_SUCCESS ? "success" : "failed"); return(dwErr); }
|