diff options
Diffstat (limited to 'win/tclWinTest.c')
-rw-r--r-- | win/tclWinTest.c | 504 |
1 files changed, 265 insertions, 239 deletions
diff --git a/win/tclWinTest.c b/win/tclWinTest.c index ac00411..eb3123c 100644 --- a/win/tclWinTest.c +++ b/win/tclWinTest.c @@ -8,7 +8,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclWinTest.c,v 1.19.2.1 2007/09/04 17:44:27 dgp Exp $ + * RCS: @(#) $Id: tclWinTest.c,v 1.19.2.2 2007/11/21 06:31:03 dgp Exp $ */ #include "tclInt.h" @@ -73,18 +73,13 @@ TclplatformtestInit( * Add commands for platform specific tests for Windows here. */ - Tcl_CreateCommand(interp, "testchmod", TestchmodCmd, - (ClientData) 0, NULL); - Tcl_CreateCommand(interp, "testeventloop", TesteventloopCmd, - (ClientData) 0, NULL); + Tcl_CreateCommand(interp, "testchmod", TestchmodCmd, NULL, NULL); + Tcl_CreateCommand(interp, "testeventloop", TesteventloopCmd, NULL, NULL); Tcl_CreateObjCommand(interp, "testvolumetype", TestvolumetypeCmd, - (ClientData) 0, NULL); - Tcl_CreateObjCommand(interp, "testwinclock", TestwinclockCmd, - (ClientData) 0, NULL); - Tcl_CreateObjCommand(interp, "testwincpuid", TestwincpuidCmd, - (ClientData) 0, NULL); - Tcl_CreateObjCommand(interp, "testwinsleep", TestwinsleepCmd, - (ClientData) 0, NULL); + NULL, NULL); + Tcl_CreateObjCommand(interp, "testwinclock", TestwinclockCmd, NULL, NULL); + Tcl_CreateObjCommand(interp, "testwincpuid", TestwincpuidCmd, NULL, NULL); + Tcl_CreateObjCommand(interp, "testwinsleep", TestwinsleepCmd, NULL, NULL); Tcl_CreateObjCommand(interp, "testexcept", TestExceptionCmd, NULL, NULL); return TCL_OK; } @@ -112,23 +107,21 @@ TesteventloopCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ int argc, /* Number of arguments. */ - const char **argv) /* Argument strings. */ + const char **argv) /* Argument strings. */ { static int *framePtr = NULL;/* Pointer to integer on stack frame of * innermost invocation of the "wait" * subcommand. */ - if (argc < 2) { + if (argc < 2) { Tcl_AppendResult(interp, "wrong # arguments: should be \"", argv[0], - " option ... \"", NULL); - return TCL_ERROR; + " option ... \"", NULL); + return TCL_ERROR; } if (strcmp(argv[1], "done") == 0) { *framePtr = 1; } else if (strcmp(argv[1], "wait") == 0) { - int *oldFramePtr; - int done; - MSG msg; + int *oldFramePtr, done; int oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL); /* @@ -139,19 +132,21 @@ TesteventloopCmd( framePtr = &done; /* - * Enter a standard Windows event loop until the flag changes. - * Note that we do not explicitly call Tcl_ServiceEvent(). + * Enter a standard Windows event loop until the flag changes. Note + * that we do not explicitly call Tcl_ServiceEvent(). */ done = 0; while (!done) { + MSG msg; + if (!GetMessage(&msg, NULL, 0, 0)) { /* - * The application is exiting, so repost the quit message - * and start unwinding. + * The application is exiting, so repost the quit message and + * start unwinding. */ - PostQuitMessage((int)msg.wParam); + PostQuitMessage((int) msg.wParam); break; } TranslateMessage(&msg); @@ -198,19 +193,20 @@ TestvolumetypeCmd( if (objc > 2) { Tcl_WrongNumArgs(interp, 1, objv, "?name?"); - return TCL_ERROR; + return TCL_ERROR; } if (objc == 2) { /* - * path has to be really a proper volume, but we don't - * get query APIs for that until NT5 + * path has to be really a proper volume, but we don't get query APIs + * for that until NT5 */ + path = Tcl_GetString(objv[1]); } else { path = NULL; } - found = GetVolumeInformationA(path, NULL, 0, NULL, NULL, - NULL, volType, VOL_BUF_SIZE); + found = GetVolumeInformationA(path, NULL, 0, NULL, NULL, NULL, volType, + VOL_BUF_SIZE); if (found == 0) { Tcl_AppendResult(interp, "could not get volume type for \"", @@ -228,9 +224,9 @@ TestvolumetypeCmd( * * TestwinclockCmd -- * - * Command that returns the seconds and microseconds portions of - * the system clock and of the Tcl clock so that they can be - * compared to validate that the Tcl clock is staying in sync. + * Command that returns the seconds and microseconds portions of the + * system clock and of the Tcl clock so that they can be compared to + * validate that the Tcl clock is staying in sync. * * Usage: * testclock @@ -239,9 +235,9 @@ TestvolumetypeCmd( * None. * * Results: - * Returns a standard Tcl result comprising a four-element list: - * the seconds and microseconds portions of the system clock, - * and the seconds and microseconds portions of the Tcl clock. + * Returns a standard Tcl result comprising a four-element list: the + * seconds and microseconds portions of the system clock, and the seconds + * and microseconds portions of the Tcl clock. * * Side effects: * None. @@ -261,7 +257,7 @@ TestwinclockCmd( * FILETIME */ Tcl_Time tclTime; /* Tcl clock */ FILETIME sysTime; /* System clock */ - Tcl_Obj* result; /* Result of the command */ + Tcl_Obj *result; /* Result of the command */ LARGE_INTEGER t1, t2; LARGE_INTEGER p1, p2; @@ -312,8 +308,8 @@ TestwinclockCmd( * eax - The value to pass in the EAX register to a CPUID instruction. * * Results: - * Returns a four-element list containing the values from the - * EAX, EBX, ECX and EDX registers returned from the CPUID instruction. + * Returns a four-element list containing the values from the EAX, EBX, + * ECX and EDX registers returned from the CPUID instruction. * * Side effects: * None. @@ -328,11 +324,9 @@ TestwincpuidCmd( int objc, /* Parameter count */ Tcl_Obj *const * objv) /* Parameter vector */ { - int status; - int index; + int status, index, i; unsigned int regs[4]; - Tcl_Obj * regsObjs[4]; - int i; + Tcl_Obj *regsObjs[4]; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "eax"); @@ -341,7 +335,7 @@ TestwincpuidCmd( if (Tcl_GetIntFromObj(interp, objv[1], &index) != TCL_OK) { return TCL_ERROR; } - status = TclWinCPUID((unsigned int) index, regs); + status = TclWinCPUID((unsigned) index, regs); if (status != TCL_OK) { Tcl_SetObjResult(interp, Tcl_NewStringObj("operation not available", -1)); @@ -385,6 +379,7 @@ TestwinsleepCmd( Tcl_Obj *const * objv) /* Parameter vector */ { int ms; + if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "ms"); return TCL_ERROR; @@ -427,51 +422,25 @@ TestExceptionCmd( Tcl_Obj *const objv[]) /* Argument vector */ { static const char *cmds[] = { - "access_violation", - "datatype_misalignment", - "array_bounds", - "float_denormal", - "float_divbyzero", - "float_inexact", - "float_invalidop", - "float_overflow", - "float_stack", - "float_underflow", - "int_divbyzero", - "int_overflow", - "private_instruction", - "inpageerror", - "illegal_instruction", - "noncontinue", - "stack_overflow", - "invalid_disp", - "guard_page", - "invalid_handle", - "ctrl+c", - NULL + "access_violation", "datatype_misalignment", "array_bounds", + "float_denormal", "float_divbyzero", "float_inexact", + "float_invalidop", "float_overflow", "float_stack", "float_underflow", + "int_divbyzero", "int_overflow", "private_instruction", "inpageerror", + "illegal_instruction", "noncontinue", "stack_overflow", + "invalid_disp", "guard_page", "invalid_handle", "ctrl+c", + NULL }; static DWORD exceptions[] = { - EXCEPTION_ACCESS_VIOLATION, - EXCEPTION_DATATYPE_MISALIGNMENT, - EXCEPTION_ARRAY_BOUNDS_EXCEEDED, - EXCEPTION_FLT_DENORMAL_OPERAND, - EXCEPTION_FLT_DIVIDE_BY_ZERO, - EXCEPTION_FLT_INEXACT_RESULT, - EXCEPTION_FLT_INVALID_OPERATION, - EXCEPTION_FLT_OVERFLOW, - EXCEPTION_FLT_STACK_CHECK, - EXCEPTION_FLT_UNDERFLOW, - EXCEPTION_INT_DIVIDE_BY_ZERO, - EXCEPTION_INT_OVERFLOW, - EXCEPTION_PRIV_INSTRUCTION, - EXCEPTION_IN_PAGE_ERROR, - EXCEPTION_ILLEGAL_INSTRUCTION, - EXCEPTION_NONCONTINUABLE_EXCEPTION, - EXCEPTION_STACK_OVERFLOW, - EXCEPTION_INVALID_DISPOSITION, - EXCEPTION_GUARD_PAGE, - EXCEPTION_INVALID_HANDLE, - CONTROL_C_EXIT + EXCEPTION_ACCESS_VIOLATION, EXCEPTION_DATATYPE_MISALIGNMENT, + EXCEPTION_ARRAY_BOUNDS_EXCEEDED, EXCEPTION_FLT_DENORMAL_OPERAND, + EXCEPTION_FLT_DIVIDE_BY_ZERO, EXCEPTION_FLT_INEXACT_RESULT, + EXCEPTION_FLT_INVALID_OPERATION, EXCEPTION_FLT_OVERFLOW, + EXCEPTION_FLT_STACK_CHECK, EXCEPTION_FLT_UNDERFLOW, + EXCEPTION_INT_DIVIDE_BY_ZERO, EXCEPTION_INT_OVERFLOW, + EXCEPTION_PRIV_INSTRUCTION, EXCEPTION_IN_PAGE_ERROR, + EXCEPTION_ILLEGAL_INSTRUCTION, EXCEPTION_NONCONTINUABLE_EXCEPTION, + EXCEPTION_STACK_OVERFLOW, EXCEPTION_INVALID_DISPOSITION, + EXCEPTION_GUARD_PAGE, EXCEPTION_INVALID_HANDLE, CONTROL_C_EXIT }; int cmd; @@ -504,258 +473,307 @@ TestExceptionCmd( return TCL_OK; } -static int +static int TestplatformChmod( const char *nativePath, int pmode) { - SID_IDENTIFIER_AUTHORITY userSidAuthority = - { SECURITY_WORLD_SID_AUTHORITY }; + typedef DWORD (WINAPI *getSidLengthRequiredDef)(UCHAR); + typedef BOOL (WINAPI *initializeSidDef)(PSID, PSID_IDENTIFIER_AUTHORITY, + BYTE); + typedef PDWORD (WINAPI *getSidSubAuthorityDef)(PSID, DWORD); + typedef DWORD (WINAPI *setNamedSecurityInfoADef)(IN LPSTR, + IN SE_OBJECT_TYPE, IN SECURITY_INFORMATION, IN PSID, IN PSID, + IN PACL, IN PACL); + typedef BOOL (WINAPI *getAceDef)(PACL, DWORD, LPVOID *); + typedef BOOL (WINAPI *addAceDef)(PACL, DWORD, DWORD, LPVOID, DWORD); + typedef BOOL (WINAPI *equalSidDef)(PSID, PSID); + typedef BOOL (WINAPI *addAccessDeniedAceDef)(PACL, DWORD, DWORD, PSID); + typedef BOOL (WINAPI *initializeAclDef)(PACL, DWORD, DWORD); + typedef DWORD (WINAPI *getLengthSidDef)(PSID); + typedef BOOL (WINAPI *getAclInformationDef)(PACL, LPVOID, DWORD, + ACL_INFORMATION_CLASS); + typedef BOOL (WINAPI *getSecurityDescriptorDaclDef)(PSECURITY_DESCRIPTOR, + LPBOOL, PACL *, LPBOOL); + typedef BOOL (WINAPI *lookupAccountNameADef)(LPCSTR, LPCSTR, PSID, + PDWORD, LPSTR, LPDWORD, PSID_NAME_USE); + typedef BOOL (WINAPI *getFileSecurityADef)(LPCSTR, SECURITY_INFORMATION, + PSECURITY_DESCRIPTOR, DWORD, LPDWORD); + + static const SECURITY_INFORMATION infoBits = OWNER_SECURITY_INFORMATION + | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION; + static const DWORD readOnlyMask = FILE_DELETE_CHILD | FILE_ADD_FILE + | FILE_ADD_SUBDIRECTORY | FILE_WRITE_EA | FILE_APPEND_DATA + | FILE_WRITE_DATA | DELETE; - typedef DWORD (WINAPI *getSidLengthRequiredDef) ( UCHAR ); - typedef BOOL (WINAPI *initializeSidDef) ( PSID, - PSID_IDENTIFIER_AUTHORITY, BYTE ); - typedef PDWORD (WINAPI *getSidSubAuthorityDef) ( PSID, DWORD ); + /* + * References to security functions (only available on NT and later). + */ static getSidLengthRequiredDef getSidLengthRequiredProc; static initializeSidDef initializeSidProc; static getSidSubAuthorityDef getSidSubAuthorityProc; - static const SECURITY_INFORMATION infoBits = OWNER_SECURITY_INFORMATION - | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION; - static const DWORD readOnlyMask = FILE_DELETE_CHILD | FILE_ADD_FILE - | FILE_ADD_SUBDIRECTORY | FILE_WRITE_EA | FILE_APPEND_DATA - | FILE_WRITE_DATA | DELETE; - - BYTE *secDesc = 0; - DWORD secDescLen; + static setNamedSecurityInfoADef setNamedSecurityInfoProc; + static getAceDef getAceProc; + static addAceDef addAceProc; + static equalSidDef equalSidProc; + static addAccessDeniedAceDef addAccessDeniedAceProc; + static initializeAclDef initializeAclProc; + static getLengthSidDef getLengthSidProc; + static getAclInformationDef getAclInformationProc; + static getSecurityDescriptorDaclDef getSecurityDescriptorDaclProc; + static lookupAccountNameADef lookupAccountNameProc; + static getFileSecurityADef getFileSecurityProc; + static int initialized = 0; const BOOL set_readOnly = !(pmode & 0222); - BOOL acl_readOnly_found = FALSE; - + BOOL acl_readOnly_found = FALSE, curAclPresent, curAclDefaulted; + SID_IDENTIFIER_AUTHORITY userSidAuthority = { + SECURITY_WORLD_SID_AUTHORITY + }; + BYTE *secDesc = 0; + DWORD secDescLen, attr, newAclSize; ACL_SIZE_INFORMATION ACLSize; - BOOL curAclPresent, curAclDefaulted; - PACL curAcl; - PACL newAcl = 0; - DWORD newAclSize; - + PACL curAcl, newAcl = 0; WORD j; - SID *userSid = 0; TCHAR *userDomain = 0; - - DWORD attr; - int res = 0; /* * One time initialization, dynamically load Windows NT features */ - typedef DWORD (WINAPI *setNamedSecurityInfoADef)( IN LPSTR, - IN SE_OBJECT_TYPE, IN SECURITY_INFORMATION, IN PSID, IN PSID, - IN PACL, IN PACL ); - typedef BOOL (WINAPI *getAceDef) (PACL, DWORD, LPVOID *); - typedef BOOL (WINAPI *addAceDef) ( PACL, DWORD, DWORD, LPVOID, DWORD ); - typedef BOOL (WINAPI *equalSidDef) ( PSID, PSID ); - typedef BOOL (WINAPI *addAccessDeniedAceDef) ( PACL, DWORD, DWORD, PSID ); - typedef BOOL (WINAPI *initializeAclDef) ( PACL, DWORD, DWORD ); - typedef DWORD (WINAPI *getLengthSidDef) ( PSID ); - typedef BOOL (WINAPI *getAclInformationDef) (PACL, LPVOID, DWORD, - ACL_INFORMATION_CLASS ); - typedef BOOL (WINAPI *getSecurityDescriptorDaclDef) (PSECURITY_DESCRIPTOR, - LPBOOL, PACL *, LPBOOL ); - typedef BOOL (WINAPI *lookupAccountNameADef) ( LPCSTR, LPCSTR, PSID, - PDWORD, LPSTR, LPDWORD, PSID_NAME_USE ); - typedef BOOL (WINAPI *getFileSecurityADef) ( LPCSTR, SECURITY_INFORMATION, - PSECURITY_DESCRIPTOR, DWORD, LPDWORD ); - - static setNamedSecurityInfoADef setNamedSecurityInfoProc; - static getAceDef getAceProc; - static addAceDef addAceProc; - static equalSidDef equalSidProc; - static addAccessDeniedAceDef addAccessDeniedAceProc; - static initializeAclDef initializeAclProc; - static getLengthSidDef getLengthSidProc; - static getAclInformationDef getAclInformationProc; - static getSecurityDescriptorDaclDef getSecurityDescriptorDaclProc; - static lookupAccountNameADef lookupAccountNameProc; - static getFileSecurityADef getFileSecurityProc; - static int initialized = 0; if (!initialized) { TCL_DECLARE_MUTEX(initializeMutex) Tcl_MutexLock(&initializeMutex); if (!initialized) { HINSTANCE hInstance = LoadLibrary("Advapi32"); + if (hInstance != NULL) { setNamedSecurityInfoProc = (setNamedSecurityInfoADef) - GetProcAddress(hInstance, "SetNamedSecurityInfoA"); + GetProcAddress(hInstance, "SetNamedSecurityInfoA"); getFileSecurityProc = (getFileSecurityADef) - GetProcAddress(hInstance, "GetFileSecurityA"); + GetProcAddress(hInstance, "GetFileSecurityA"); getAceProc = (getAceDef) - GetProcAddress(hInstance, "GetAce"); + GetProcAddress(hInstance, "GetAce"); addAceProc = (addAceDef) - GetProcAddress(hInstance, "AddAce"); + GetProcAddress(hInstance, "AddAce"); equalSidProc = (equalSidDef) - GetProcAddress(hInstance, "EqualSid"); + GetProcAddress(hInstance, "EqualSid"); addAccessDeniedAceProc = (addAccessDeniedAceDef) - GetProcAddress(hInstance, "AddAccessDeniedAce"); + GetProcAddress(hInstance, "AddAccessDeniedAce"); initializeAclProc = (initializeAclDef) - GetProcAddress(hInstance, "InitializeAcl"); + GetProcAddress(hInstance, "InitializeAcl"); getLengthSidProc = (getLengthSidDef) - GetProcAddress(hInstance, "GetLengthSid"); + GetProcAddress(hInstance, "GetLengthSid"); getAclInformationProc = (getAclInformationDef) - GetProcAddress(hInstance, "GetAclInformation"); + GetProcAddress(hInstance, "GetAclInformation"); getSecurityDescriptorDaclProc = (getSecurityDescriptorDaclDef) - GetProcAddress(hInstance, "GetSecurityDescriptorDacl"); + GetProcAddress(hInstance, "GetSecurityDescriptorDacl"); lookupAccountNameProc = (lookupAccountNameADef) - GetProcAddress(hInstance, "LookupAccountNameA"); + GetProcAddress(hInstance, "LookupAccountNameA"); getSidLengthRequiredProc = (getSidLengthRequiredDef) - GetProcAddress(hInstance, "GetSidLengthRequired"); + GetProcAddress(hInstance, "GetSidLengthRequired"); initializeSidProc = (initializeSidDef) - GetProcAddress(hInstance, "InitializeSid"); + GetProcAddress(hInstance, "InitializeSid"); getSidSubAuthorityProc = (getSidSubAuthorityDef) - GetProcAddress(hInstance, "GetSidSubAuthority"); - if (setNamedSecurityInfoProc && getAceProc - && addAceProc && equalSidProc && addAccessDeniedAceProc - && initializeAclProc && getLengthSidProc - && getAclInformationProc && getSecurityDescriptorDaclProc - && lookupAccountNameProc && getFileSecurityProc - && getSidLengthRequiredProc && initializeSidProc - && getSidSubAuthorityProc) + GetProcAddress(hInstance, "GetSidSubAuthority"); + + if (setNamedSecurityInfoProc && getAceProc && addAceProc + && equalSidProc && addAccessDeniedAceProc + && initializeAclProc && getLengthSidProc + && getAclInformationProc + && getSecurityDescriptorDaclProc + && lookupAccountNameProc && getFileSecurityProc + && getSidLengthRequiredProc && initializeSidProc + && getSidSubAuthorityProc) { initialized = 1; + } } - if (!initialized) + if (!initialized) { initialized = -1; + } } Tcl_MutexUnlock(&initializeMutex); } - /* Process the chmod request */ + /* + * Process the chmod request. + */ + attr = GetFileAttributes(nativePath); - /* nativePath not found */ + /* + * nativePath not found + */ + if (attr == 0xffffffff) { res = -1; goto done; } - /* If no ACL API is present or nativePath is not a directory, - * there is no special handling + /* + * If no ACL API is present or nativePath is not a directory, there is no + * special handling. */ + if (initialized < 0 || !(attr & FILE_ATTRIBUTE_DIRECTORY)) { goto done; } - - /* Set the result to error, if the ACL change is successful it will - * be reset to 0 + + /* + * Set the result to error, if the ACL change is successful it will be + * reset to 0. */ + res = -1; /* - * Read the security descriptor for the directory. Note the - * first call obtains the size of the security descriptor. + * Read the security descriptor for the directory. Note the first call + * obtains the size of the security descriptor. */ + if (!getFileSecurityProc(nativePath, infoBits, NULL, 0, &secDescLen)) { - if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { - DWORD secDescLen2 = 0; - secDesc = (BYTE *) ckalloc(secDescLen); - if (!getFileSecurityProc(nativePath, infoBits, - (PSECURITY_DESCRIPTOR)secDesc, - secDescLen, &secDescLen2) + DWORD secDescLen2 = 0; + + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { + goto done; + } + + secDesc = (BYTE *) ckalloc(secDescLen); + if (!getFileSecurityProc(nativePath, infoBits, + (PSECURITY_DESCRIPTOR) secDesc, secDescLen, &secDescLen2) || (secDescLen < secDescLen2)) { - goto done; - } - } else { goto done; } } - /* Get the World SID */ - userSid = (SID*) ckalloc(getSidLengthRequiredProc((UCHAR)1)); - initializeSidProc( userSid, &userSidAuthority, (BYTE)1); - *(getSidSubAuthorityProc( userSid, 0)) = SECURITY_WORLD_RID; + /* + * Get the World SID. + */ + + userSid = (SID *) ckalloc(getSidLengthRequiredProc((UCHAR) 1)); + initializeSidProc(userSid, &userSidAuthority, (BYTE) 1); + *(getSidSubAuthorityProc(userSid, 0)) = SECURITY_WORLD_RID; + + /* + * If curAclPresent == false then curAcl and curAclDefaulted not valid. + */ - /* If curAclPresent == false then curAcl and curAclDefaulted not valid */ - if (!getSecurityDescriptorDaclProc((PSECURITY_DESCRIPTOR)secDesc, - &curAclPresent, &curAcl, - &curAclDefaulted)) { + if (!getSecurityDescriptorDaclProc((PSECURITY_DESCRIPTOR) secDesc, + &curAclPresent, &curAcl, &curAclDefaulted)) { goto done; } if (!curAclPresent || !curAcl) { ACLSize.AclBytesInUse = 0; ACLSize.AceCount = 0; - } else if (!getAclInformationProc(curAcl, &ACLSize, sizeof(ACLSize), - AclSizeInformation)) + } else if (!getAclInformationProc(curAcl, &ACLSize, sizeof(ACLSize), + AclSizeInformation)) { goto done; + } - /* Allocate memory for the new ACL */ - newAclSize = ACLSize.AclBytesInUse + sizeof (ACCESS_DENIED_ACE) - + getLengthSidProc(userSid) - sizeof (DWORD); - newAcl = (ACL *) ckalloc (newAclSize); - - /* Initialize the new ACL */ - if(!initializeAclProc(newAcl, newAclSize, ACL_REVISION)) { + /* + * Allocate memory for the new ACL. + */ + + newAclSize = ACLSize.AclBytesInUse + sizeof(ACCESS_DENIED_ACE) + + getLengthSidProc(userSid) - sizeof(DWORD); + newAcl = (ACL *) ckalloc(newAclSize); + + /* + * Initialize the new ACL. + */ + + if (!initializeAclProc(newAcl, newAclSize, ACL_REVISION)) { goto done; } - - /* Add denied to make readonly, this will be known as a "read-only tag" */ - if (set_readOnly && !addAccessDeniedAceProc(newAcl, ACL_REVISION, - readOnlyMask, userSid)) { + + /* + * Add denied to make readonly, this will be known as a "read-only tag". + */ + + if (set_readOnly && !addAccessDeniedAceProc(newAcl, ACL_REVISION, + readOnlyMask, userSid)) { goto done; } - + acl_readOnly_found = FALSE; for (j = 0; j < ACLSize.AceCount; j++) { PACL *pACE2; ACE_HEADER *phACE2; - if (! getAceProc (curAcl, j, (LPVOID*) &pACE2)) { + + if (!getAceProc(curAcl, j, (LPVOID *) &pACE2)) { goto done; } - - phACE2 = ((ACE_HEADER *) pACE2); - /* Do NOT propagate inherited ACEs */ + phACE2 = (ACE_HEADER *) pACE2; + + /* + * Do NOT propagate inherited ACEs. + */ + if (phACE2->AceFlags & INHERITED_ACE) { continue; } - - /* Skip the "read-only tag" restriction (either added above, or it - * is being removed) + + /* + * Skip the "read-only tag" restriction (either added above, or it is + * being removed). */ + if (phACE2->AceType == ACCESS_DENIED_ACE_TYPE) { - ACCESS_DENIED_ACE *pACEd = (ACCESS_DENIED_ACE *)phACE2; - if (pACEd->Mask == readOnlyMask && equalSidProc(userSid, - (PSID)&(pACEd->SidStart))) { + ACCESS_DENIED_ACE *pACEd = (ACCESS_DENIED_ACE *) phACE2; + + if (pACEd->Mask == readOnlyMask + && equalSidProc(userSid, (PSID) &pACEd->SidStart)) { acl_readOnly_found = TRUE; continue; } } - /* Copy the current ACE from the old to the new ACL */ - if(! addAceProc (newAcl, ACL_REVISION, MAXDWORD, pACE2, - ((PACE_HEADER) pACE2)->AceSize)) { + /* + * Copy the current ACE from the old to the new ACL. + */ + + if (!addAceProc(newAcl, ACL_REVISION, MAXDWORD, pACE2, + ((PACE_HEADER) pACE2)->AceSize)) { goto done; } } - /* Apply the new ACL */ - if (set_readOnly == acl_readOnly_found - || setNamedSecurityInfoProc((LPSTR)nativePath, SE_FILE_OBJECT, - DACL_SECURITY_INFORMATION, NULL, NULL, newAcl, NULL) - == ERROR_SUCCESS ) { + /* + * Apply the new ACL. + */ + + if (set_readOnly == acl_readOnly_found || setNamedSecurityInfoProc( + (LPSTR) nativePath, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, + NULL, NULL, newAcl, NULL) == ERROR_SUCCESS) { res = 0; } - done: - if (secDesc) ckfree(secDesc); - if (newAcl) ckfree((char *)newAcl); - if (userSid) ckfree((char *)userSid); - if (userDomain) ckfree(userDomain); + done: + if (secDesc) { + ckfree(secDesc); + } + if (newAcl) { + ckfree((char *) newAcl); + } + if (userSid) { + ckfree((char *) userSid); + } + if (userDomain) { + ckfree(userDomain); + } - if (res != 0) + if (res != 0) { return res; - - /* Run normal chmod command */ + } + + /* + * Run normal chmod command. + */ + return chmod(nativePath, pmode); } @@ -764,10 +782,10 @@ TestplatformChmod( * * TestchmodCmd -- * - * Implements the "testchmod" cmd. Used when testing "file" command. - * The only attribute used by the Windows platform is the user write - * flag; if this is not set, the file is made read-only. Otehrwise, the - * file is made read-write. + * Implements the "testchmod" cmd. Used when testing "file" command. The + * only attribute used by the Windows platform is the user write flag; if + * this is not set, the file is made read-only. Otherwise, the file is + * made read-write. * * Results: * A standard Tcl result. @@ -780,16 +798,16 @@ TestplatformChmod( static int TestchmodCmd( - ClientData dummy, /* Not used. */ - Tcl_Interp *interp, /* Current interpreter. */ - int argc, /* Number of arguments. */ - const char **argv) /* Argument strings. */ + ClientData dummy, /* Not used. */ + Tcl_Interp *interp, /* Current interpreter. */ + int argc, /* Number of arguments. */ + const char **argv) /* Argument strings. */ { int i, mode; char *rest; if (argc < 2) { - usage: + usage: Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " mode file ?file ...?", NULL); return TCL_ERROR; @@ -817,3 +835,11 @@ TestchmodCmd( } return TCL_OK; } + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ |