160 lines
4.6 KiB
C
160 lines
4.6 KiB
C
|
/*++
|
||
|
|
||
|
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;
|
||
|
}
|