diff options
Diffstat (limited to 'win/tclWinTest.c')
| -rw-r--r-- | win/tclWinTest.c | 632 | 
1 files changed, 242 insertions, 390 deletions
| diff --git a/win/tclWinTest.c b/win/tclWinTest.c index 6925866..b3ad626 100644 --- a/win/tclWinTest.c +++ b/win/tclWinTest.c @@ -7,40 +7,44 @@   *   * 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.16 2006/03/21 09:46:00 vincentdarley Exp $   */ -#define USE_COMPAT_CONST +#ifndef USE_TCL_STUBS +#   define USE_TCL_STUBS +#endif  #include "tclInt.h"  /*   * For TestplatformChmod on Windows   */ -#ifdef __WIN32__ +#ifdef _WIN32  #include <aclapi.h>  #endif  /* + * MinGW 3.4.2 does not define this. + */ +#ifndef INHERITED_ACE +#define INHERITED_ACE (0x10) +#endif + +/*   * Forward declarations of functions defined later in this file:   */ -int			TclplatformtestInit(Tcl_Interp *interp); -static int		TesteventloopCmd(ClientData dummy, Tcl_Interp *interp, -			    int argc, char **argv); +static int		TesteventloopCmd(ClientData dummy, Tcl_Interp* interp, +			    int objc, Tcl_Obj *const objv[]);  static int		TestvolumetypeCmd(ClientData dummy,  			    Tcl_Interp *interp, int objc, -			    Tcl_Obj *CONST objv[]); +			    Tcl_Obj *const objv[]);  static int		TestwinclockCmd(ClientData dummy, Tcl_Interp* interp, -			    int objc, Tcl_Obj *CONST objv[]); +			    int objc, Tcl_Obj *const objv[]);  static int		TestwinsleepCmd(ClientData dummy, Tcl_Interp* interp, -			    int objc, Tcl_Obj *CONST objv[]); +			    int objc, Tcl_Obj *const objv[]);  static Tcl_ObjCmdProc	TestExceptionCmd; -static int		TestwincpuidCmd(ClientData dummy, Tcl_Interp* interp, -			    int objc, Tcl_Obj *CONST objv[]); -static int		TestplatformChmod(CONST char *nativePath, int pmode); -static int		TestchmodCmd(ClientData dummy, -			    Tcl_Interp *interp, int argc, CONST char **argv); +static int		TestplatformChmod(const char *nativePath, int pmode); +static int		TestchmodCmd(ClientData dummy, Tcl_Interp* interp, +			    int objc, Tcl_Obj *const objv[]);  /*   *---------------------------------------------------------------------- @@ -67,18 +71,12 @@ 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_CreateObjCommand(interp, "testchmod", TestchmodCmd, NULL, NULL); +    Tcl_CreateObjCommand(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, "testwinsleep", TestwinsleepCmd, NULL, NULL);      Tcl_CreateObjCommand(interp, "testexcept", TestExceptionCmd, NULL, NULL);      return TCL_OK;  } @@ -105,24 +103,21 @@ static int  TesteventloopCmd(      ClientData clientData,	/* Not used. */      Tcl_Interp *interp,		/* Current interpreter. */ -    int argc,			/* Number of arguments. */ -    char **argv)		/* Argument strings. */ +    int objc,			/* Number of arguments. */ +    Tcl_Obj *const objv[])	/* Argument objects. */  {      static int *framePtr = NULL;/* Pointer to integer on stack frame of  				 * innermost invocation of the "wait"  				 * subcommand. */ -   if (argc < 2) { -	Tcl_AppendResult(interp, "wrong # arguments: should be \"", argv[0], -                " option ... \"", NULL); -        return TCL_ERROR; +    if (objc < 2) { +	Tcl_WrongNumArgs(interp, 1, objv, "option ..."); +	return TCL_ERROR;      } -    if (strcmp(argv[1], "done") == 0) { +    if (strcmp(Tcl_GetString(objv[1]), "done") == 0) {  	*framePtr = 1; -    } else if (strcmp(argv[1], "wait") == 0) { -	int *oldFramePtr; -	int done; -	MSG msg; +    } else if (strcmp(Tcl_GetString(objv[1]), "wait") == 0) { +	int *oldFramePtr, done;  	int oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL);  	/* @@ -133,19 +128,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(msg.wParam); +		PostQuitMessage((int) msg.wParam);  		break;  	    }  	    TranslateMessage(&msg); @@ -154,7 +151,7 @@ TesteventloopCmd(  	(void) Tcl_SetServiceMode(oldMode);  	framePtr = oldFramePtr;      } else { -	Tcl_AppendResult(interp, "bad option \"", argv[1], +	Tcl_AppendResult(interp, "bad option \"", Tcl_GetString(objv[1]),  		"\": must be done or wait", NULL);  	return TCL_ERROR;      } @@ -183,28 +180,29 @@ TestvolumetypeCmd(      ClientData clientData,	/* Not used. */      Tcl_Interp *interp,		/* Current interpreter. */      int objc,			/* Number of arguments. */ -    Tcl_Obj *CONST objv[])	/* Argument objects. */ +    Tcl_Obj *const objv[])	/* Argument objects. */  {  #define VOL_BUF_SIZE 32      int found;      char volType[VOL_BUF_SIZE]; -    char *path; +    const char *path;      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 \"", @@ -212,7 +210,7 @@ TestvolumetypeCmd(  	TclWinConvertError(GetLastError());  	return TCL_ERROR;      } -    Tcl_SetResult(interp, volType, TCL_VOLATILE); +    Tcl_AppendResult(interp, volType, NULL);      return TCL_OK;  #undef VOL_BUF_SIZE  } @@ -222,9 +220,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 @@ -233,9 +231,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. @@ -248,14 +246,14 @@ TestwinclockCmd(      ClientData dummy,		/* Unused */      Tcl_Interp* interp,		/* Tcl interpreter */      int objc,			/* Argument count */ -    Tcl_Obj *CONST objv[])	/* Argument vector */ +    Tcl_Obj *const objv[])	/* Argument vector */  { -    CONST static FILETIME posixEpoch = { 0xD53E8000, 0x019DB1DE }; +    static const FILETIME posixEpoch = { 0xD53E8000, 0x019DB1DE };  				/* The Posix epoch, expressed as a Windows  				 * 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; @@ -292,93 +290,15 @@ TestwinclockCmd(      return TCL_OK;  } -/* - *---------------------------------------------------------------------- - * - * TestwincpuidCmd -- - * - *	Retrieves CPU ID information. - * - * Usage: - *	testwincpuid <eax> - * - * Parameters: - *	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. - * - * Side effects: - *	None. - * - *---------------------------------------------------------------------- - */ - -static int -TestwincpuidCmd( -    ClientData dummy, -    Tcl_Interp* interp,		/* Tcl interpreter */ -    int objc,			/* Parameter count */ -    Tcl_Obj *CONST * objv)	/* Parameter vector */ -{ -    int status; -    int index; -    unsigned int regs[4]; -    Tcl_Obj * regsObjs[4]; -    int i; - -    if (objc != 2) { -	Tcl_WrongNumArgs(interp, 1, objv, "eax"); -	return TCL_ERROR; -    } -    if (Tcl_GetIntFromObj(interp, objv[1], &index) != TCL_OK) { -	return TCL_ERROR; -    } -    status = TclWinCPUID((unsigned int) index, regs); -    if (status != TCL_OK) { -	Tcl_SetObjResult(interp, -		Tcl_NewStringObj("operation not available", -1)); -	return status; -    } -    for (i=0 ; i<4 ; ++i) { -	regsObjs[i] = Tcl_NewIntObj((int) regs[i]); -    } -    Tcl_SetObjResult(interp, Tcl_NewListObj(4, regsObjs)); -    return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * TestwinsleepCmd -- - * - *	Causes this process to wait for the given number of milliseconds by - *	means of a direct call to Sleep. - * - * Usage: - *	testwinsleep <n> - * - * Parameters: - *	n - the number of milliseconds to sleep - * - * Results: - *	None. - * - * Side effects: - *	Sleeps for the requisite number of milliseconds. - * - *---------------------------------------------------------------------- - */ -  static int  TestwinsleepCmd(      ClientData clientData,	/* Unused */      Tcl_Interp* interp,		/* Tcl interpreter */      int objc,			/* Parameter count */ -    Tcl_Obj * CONST * objv)	/* Parameter vector */ +    Tcl_Obj *const * objv)	/* Parameter vector */  {      int ms; +      if (objc != 2) {  	Tcl_WrongNumArgs(interp, 1, objv, "ms");  	return TCL_ERROR; @@ -418,54 +338,28 @@ TestExceptionCmd(      ClientData dummy,			/* Unused */      Tcl_Interp* interp,			/* Tcl interpreter */      int objc,				/* Argument count */ -    Tcl_Obj *CONST objv[])		/* Argument vector */ +    Tcl_Obj *const objv[])		/* Argument vector */  { -    static 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 +    static const char *const 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      }; -    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 +    static const 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      };      int cmd; @@ -498,256 +392,210 @@ TestExceptionCmd(      return TCL_OK;  } -static int  -TestplatformChmod(CONST char *nativePath, int pmode) +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 ); - -    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; +    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; +    /* +     * References to security functions (only available on NT and later). +     */      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; -   -    DWORD userSidLen = 4096;      SID *userSid = 0; -    DWORD userDomainLen = 32; -    TCHAR *userDomain = 0; - -    DWORD attr; - +    char *userDomain = 0;      int res = 0;      /* -     * One time initialization, dynamically load Windows NT features +     * Process the chmod request.       */ -    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"); -		getFileSecurityProc = (getFileSecurityADef) -		  GetProcAddress(hInstance, "GetFileSecurityA"); -		getAceProc = (getAceDef) -		  GetProcAddress(hInstance, "GetAce"); -		addAceProc = (addAceDef) -		  GetProcAddress(hInstance, "AddAce"); -		equalSidProc = (equalSidDef) -		  GetProcAddress(hInstance, "EqualSid"); -		addAccessDeniedAceProc = (addAccessDeniedAceDef) -		  GetProcAddress(hInstance, "AddAccessDeniedAce"); -		initializeAclProc = (initializeAclDef) -		  GetProcAddress(hInstance, "InitializeAcl"); -		getLengthSidProc = (getLengthSidDef) -		  GetProcAddress(hInstance, "GetLengthSid"); -		getAclInformationProc = (getAclInformationDef) -		  GetProcAddress(hInstance, "GetAclInformation"); -		getSecurityDescriptorDaclProc = (getSecurityDescriptorDaclDef) -		  GetProcAddress(hInstance, "GetSecurityDescriptorDacl"); -		lookupAccountNameProc = (lookupAccountNameADef) -		  GetProcAddress(hInstance, "LookupAccountNameA"); -		getSidLengthRequiredProc = (getSidLengthRequiredDef) -		  GetProcAddress(hInstance, "GetSidLengthRequired"); -		initializeSidProc = (initializeSidDef) -		  GetProcAddress(hInstance, "InitializeSid"); -		getSidSubAuthorityProc = (getSidSubAuthorityDef) -		  GetProcAddress(hInstance, "GetSidSubAuthority"); -		if (setNamedSecurityInfoProc && getAceProc -		  && addAceProc && equalSidProc && addAccessDeniedAceProc -		  && initializeAclProc && getLengthSidProc -		  && getAclInformationProc && getSecurityDescriptorDaclProc -		  && lookupAccountNameProc && getFileSecurityProc -		  && getSidLengthRequiredProc && initializeSidProc -		  && getSidSubAuthorityProc) -		    initialized = 1; -	    } -	    if (!initialized) -		initialized = -1; -	} -	Tcl_MutexUnlock(&initializeMutex); -    } -    /* Process the chmod request */ -    attr = GetFileAttributes(nativePath); +    attr = GetFileAttributesA(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 nativePath is not a directory, there is no special handling.       */ -    if (initialized < 0 || !(attr & FILE_ATTRIBUTE_DIRECTORY)) { + +    if (!(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, secDesc,  -				     secDescLen, &secDescLen2)  + +    if (!GetFileSecurityA(nativePath, infoBits, NULL, 0, &secDescLen)) { +	DWORD secDescLen2 = 0; + +	if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { +	    goto done; +	} + +	secDesc = ckalloc(secDescLen); +	if (!GetFileSecurityA(nativePath, infoBits, +		(PSECURITY_DESCRIPTOR) secDesc, secDescLen, &secDescLen2)  		|| (secDescLen < secDescLen2)) { -		goto done; -	    } -	} else {  	    goto done;  	}      } -    /* Get the World SID */ -    userSid = (SID*) ckalloc(getSidLengthRequiredProc(1)); -    initializeSidProc( userSid, &userSidAuthority, 1); -    *(getSidSubAuthorityProc( userSid, 0)) = SECURITY_WORLD_RID; +    /* +     * Get the World SID. +     */ -    /* If curAclPresent == false then curAcl and curAclDefaulted not valid */ -    if (!getSecurityDescriptorDaclProc(secDesc, &curAclPresent,  -      &curAcl, &curAclDefaulted)) -	goto done; +    userSid = ckalloc(GetSidLengthRequired((UCHAR) 1)); +    InitializeSid(userSid, &userSidAuthority, (BYTE) 1); +    *(GetSidSubAuthority(userSid, 0)) = SECURITY_WORLD_RID; +    /* +     * If curAclPresent == false then curAcl and curAclDefaulted not valid. +     */ + +    if (!GetSecurityDescriptorDacl((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 (!GetAclInformation(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) +	    + GetLengthSid(userSid) - sizeof(DWORD); +    newAcl = ckalloc(newAclSize); + +    /* +     * Initialize the new ACL. +     */ + +    if (!InitializeAcl(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 && !AddAccessDeniedAce(newAcl, ACL_REVISION, +	    readOnlyMask, userSid)) {  	goto done;      } -       +      acl_readOnly_found = FALSE;      for (j = 0; j < ACLSize.AceCount; j++) { -	PACL *pACE2; +	LPVOID pACE2;  	ACE_HEADER *phACE2; -	if (! getAceProc (curAcl, j, (LPVOID*) &pACE2)) { + +	if (!GetAce(curAcl, j, &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 +		    && EqualSid(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 (!AddAce(newAcl, ACL_REVISION, MAXDWORD, (PACL *) 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 || SetNamedSecurityInfoA( +	    (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(newAcl); +    } +    if (userSid) { +	ckfree(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);  } @@ -756,10 +604,10 @@ TestplatformChmod(CONST char *nativePath, int pmode)   *   * 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. @@ -771,36 +619,32 @@ TestplatformChmod(CONST char *nativePath, int pmode)   */  static int -TestchmodCmd(dummy, interp, argc, argv) -    ClientData dummy;			/* Not used. */ -    Tcl_Interp *interp;			/* Current interpreter. */ -    int argc;				/* Number of arguments. */ -    CONST char **argv;			/* Argument strings. */ +TestchmodCmd( +    ClientData dummy,		/* Not used. */ +    Tcl_Interp *interp,		/* Current interpreter. */ +    int objc,			/* Parameter count */ +    Tcl_Obj *const * objv)	/* Parameter vector */  {      int i, mode; -    char *rest; -    if (argc < 2) { -	usage: -	Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], -		" mode file ?file ...?", NULL); +    if (objc < 2) { +	Tcl_WrongNumArgs(interp, 1, objv, "mode file ?file ...?");  	return TCL_ERROR;      } -    mode = (int) strtol(argv[1], &rest, 8); -    if ((rest == argv[1]) || (*rest != '\0')) { -	goto usage; +    if (Tcl_GetIntFromObj(interp, objv[1], &mode) != TCL_OK) { +	return TCL_ERROR;      } -    for (i = 2; i < argc; i++) { +    for (i = 2; i < objc; i++) {  	Tcl_DString buffer; -	CONST char *translated; +	const char *translated; -	translated = Tcl_TranslateFileName(interp, argv[i], &buffer); +	translated = Tcl_TranslateFileName(interp, Tcl_GetString(objv[i]), &buffer);  	if (translated == NULL) {  	    return TCL_ERROR;  	} -	if (TestplatformChmod(translated, (unsigned) mode) != 0) { +	if (TestplatformChmod(translated, mode) != 0) {  	    Tcl_AppendResult(interp, translated, ": ", Tcl_PosixError(interp),  		    NULL);  	    return TCL_ERROR; @@ -809,3 +653,11 @@ TestchmodCmd(dummy, interp, argc, argv)      }      return TCL_OK;  } + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ | 
