You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
159 lines
4.8 KiB
159 lines
4.8 KiB
/*++
|
|
|
|
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 <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
#include <windows.h>
|
|
#include <stdio.h>
|
|
#include <tools.h>
|
|
|
|
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;
|
|
}
|