/*++ Copyright (c) 1990 Microsoft Corporation Module Name: setlink.c Abstract: Utility to display or change the value of a symbolic link. Author: Darryl E. Havens (DarrylH) 9-Nov-1990 Revision History: --*/ #include #include #include #include #include #include BOOLEAN __cdecl main( IN ULONG argc, IN PCHAR argv[] ) { NTSTATUS Status; STRING AnsiString; UNICODE_STRING LinkName; UNICODE_STRING LinkValue; HANDLE Handle; OBJECT_ATTRIBUTES ObjectAttributes; WCHAR Buffer[256]; PWSTR s; ULONG ReturnedLength; // // Check to see whether or not this utility was invoked with the correct // number of parameters. If not, bail out now. // ConvertAppToOem( argc, argv ); if (argc < 2 || argc > 3) { printf( "Useage: setlink symbolic-link-name [symbolic-link-value]\n" ); return FALSE; } // // Begin by attempting to open the existing symbolic link name specified. // RtlInitString( &AnsiString, argv[1] ); Status = RtlAnsiStringToUnicodeString( &LinkName, &AnsiString, TRUE ); ASSERT( NT_SUCCESS( Status ) ); InitializeObjectAttributes( &ObjectAttributes, &LinkName, OBJ_CASE_INSENSITIVE, (HANDLE) NULL, (PSECURITY_DESCRIPTOR) NULL ); Status = NtOpenSymbolicLinkObject( &Handle, argc == 2 ? SYMBOLIC_LINK_QUERY : SYMBOLIC_LINK_ALL_ACCESS, &ObjectAttributes ); // // Determine what should be done based on the number of parameters that // were given to the program. // if (argc == 2) { // // Only one parameter was specified, so display the value of the // symbolic link if it exists. // if (!NT_SUCCESS( Status )) { printf( "Symbolic link %wZ does not exist\n", &LinkName ); return FALSE; } else { LinkValue.Length = 0; LinkValue.MaximumLength = sizeof( Buffer ); LinkValue.Buffer = Buffer; ReturnedLength = 0; Status = NtQuerySymbolicLinkObject( Handle, &LinkValue, &ReturnedLength ); NtClose( Handle ); if (!NT_SUCCESS( Status )) { printf( "Error reading symbolic link %wZ\n", &LinkName ); printf( "Error status was: %X\n", Status ); return FALSE; } else { printf( "Value of %wZ => %wZ", &LinkName, &LinkValue ); s = LinkValue.Buffer + ((LinkValue.Length / sizeof( WCHAR )) + 1); while (ReturnedLength > LinkValue.MaximumLength) { printf( " ; %ws", s ); while (*s++) { ReturnedLength -= 2; } ReturnedLength -= 2; } printf( "\n", s ); return TRUE; } } } else { // // Three parameters were supplied, so assign a new value to the // symbolic link if it exists by first deleting the existing link // (mark it temporary and close the handle). If it doesn't exist // yet, then it will simply be created. // if (NT_SUCCESS( Status )) { Status = NtMakeTemporaryObject( Handle ); if (NT_SUCCESS( Status )) { NtClose( Handle ); } } } // // Create a new value for the link. // ObjectAttributes.Attributes |= OBJ_PERMANENT; RtlInitString( &AnsiString, argv[2] ); Status = RtlAnsiStringToUnicodeString( &LinkValue, &AnsiString, TRUE ); Status = NtCreateSymbolicLinkObject( &Handle, SYMBOLIC_LINK_ALL_ACCESS, &ObjectAttributes, &LinkValue ); if (!NT_SUCCESS( Status )) { printf( "Error creating symbolic link %wZ => %wZ\n", &LinkName, &LinkValue ); printf( "Error status was: %X\n", Status ); } else { NtClose( Handle ); } return TRUE; }