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.
234 lines
6.9 KiB
234 lines
6.9 KiB
/*++
|
|
|
|
Copyright (c) 1990-2003 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
setlink.c
|
|
|
|
Abstract:
|
|
|
|
Utility to display or change the value of a symbolic link.
|
|
|
|
// @@BEGIN_DDKSPLIT
|
|
Author:
|
|
|
|
Darryl E. Havens (DarrylH) 9-Nov-1990
|
|
|
|
Revision History:
|
|
// @@END_DDKSPLIT
|
|
--*/
|
|
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
|
|
BOOL
|
|
MakeLink(
|
|
LPWSTR pOldDosDeviceName,
|
|
LPWSTR pNewDosDeviceName,
|
|
LPWSTR *ppOldNtDeviceName,
|
|
LPWSTR pNewNtDeviceName,
|
|
SECURITY_DESCRIPTOR *pSecurityDescriptor
|
|
)
|
|
{
|
|
NTSTATUS Status;
|
|
STRING AnsiString;
|
|
UNICODE_STRING OldDosDeviceName;
|
|
UNICODE_STRING NewDosDeviceName;
|
|
UNICODE_STRING PreviousNtDeviceName;
|
|
UNICODE_STRING NewNtDeviceName;
|
|
HANDLE Handle, Handle1;
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
WCHAR Buffer[MAX_PATH];
|
|
|
|
RtlInitUnicodeString( &OldDosDeviceName, pOldDosDeviceName);
|
|
|
|
ASSERT( NT_SUCCESS( Status ) );
|
|
InitializeObjectAttributes( &ObjectAttributes,
|
|
&OldDosDeviceName,
|
|
OBJ_CASE_INSENSITIVE,
|
|
(HANDLE) NULL,
|
|
(PSECURITY_DESCRIPTOR) NULL );
|
|
|
|
// Try to open \DosDevices\LPT1
|
|
|
|
Status = NtOpenSymbolicLinkObject( &Handle,
|
|
SYMBOLIC_LINK_ALL_ACCESS,
|
|
&ObjectAttributes );
|
|
|
|
if (!NT_SUCCESS( Status )) {
|
|
|
|
DBGMSG( DBG_WARNING, ("Symbolic link %ws does not exist\n", pOldDosDeviceName ));
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
memset(Buffer, 0, sizeof(Buffer));
|
|
|
|
PreviousNtDeviceName.Length = 0;
|
|
PreviousNtDeviceName.MaximumLength = sizeof( Buffer );
|
|
PreviousNtDeviceName.Buffer = Buffer;
|
|
|
|
// Get \Device\Parallel0 into Buffer
|
|
|
|
Status = NtQuerySymbolicLinkObject( Handle,
|
|
&PreviousNtDeviceName,
|
|
NULL );
|
|
|
|
if (!NT_SUCCESS( Status )) {
|
|
SetLastError(Status);
|
|
NtClose(Handle);
|
|
return FALSE;
|
|
}
|
|
|
|
*ppOldNtDeviceName = AllocSplStr(Buffer);
|
|
|
|
// Mark this object as temporary so when we close it it will be deleted
|
|
|
|
Status = NtMakeTemporaryObject( Handle );
|
|
if (NT_SUCCESS( Status )) {
|
|
NtClose( Handle );
|
|
}
|
|
|
|
ObjectAttributes.Attributes |= OBJ_PERMANENT;
|
|
RtlInitUnicodeString( &NewNtDeviceName, pNewNtDeviceName );
|
|
|
|
// Make \DosDevices\LPT1 point to \Device\NamedPipe\Spooler\LPT1
|
|
|
|
Status = NtCreateSymbolicLinkObject( &Handle,
|
|
SYMBOLIC_LINK_ALL_ACCESS,
|
|
&ObjectAttributes,
|
|
&NewNtDeviceName );
|
|
|
|
if (!NT_SUCCESS( Status )) {
|
|
DBGMSG( DBG_WARNING, ("Error creating symbolic link %ws => %ws\n",
|
|
pOldDosDeviceName,
|
|
pNewNtDeviceName ));
|
|
DBGMSG( DBG_WARNING, ("Error status was: %X\n", Status ));
|
|
return FALSE;
|
|
} else {
|
|
NtClose( Handle );
|
|
}
|
|
|
|
RtlInitUnicodeString( &NewDosDeviceName, pNewDosDeviceName);
|
|
|
|
ASSERT( NT_SUCCESS( Status ) );
|
|
InitializeObjectAttributes( &ObjectAttributes,
|
|
&NewDosDeviceName,
|
|
OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
|
|
(HANDLE) NULL,
|
|
pSecurityDescriptor );
|
|
|
|
// Finally make \DosDevices\NONSPOOLED_LPT1 => \Device\Parallel0
|
|
|
|
Status = NtCreateSymbolicLinkObject(&Handle,
|
|
SYMBOLIC_LINK_ALL_ACCESS,
|
|
&ObjectAttributes,
|
|
&PreviousNtDeviceName);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
NtClose(Handle);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
RemoveLink(
|
|
LPWSTR pOldDosDeviceName,
|
|
LPWSTR pNewDosDeviceName,
|
|
LPWSTR *ppOldNtDeviceName
|
|
)
|
|
{
|
|
NTSTATUS Status;
|
|
STRING AnsiString;
|
|
UNICODE_STRING OldDosDeviceName;
|
|
UNICODE_STRING NewDosDeviceName;
|
|
UNICODE_STRING PreviousNtDeviceName;
|
|
UNICODE_STRING OldNtDeviceName;
|
|
HANDLE Handle, Handle1;
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
|
|
RtlInitUnicodeString( &NewDosDeviceName, pNewDosDeviceName);
|
|
|
|
ASSERT( NT_SUCCESS( Status ) );
|
|
InitializeObjectAttributes( &ObjectAttributes,
|
|
&NewDosDeviceName,
|
|
OBJ_CASE_INSENSITIVE,
|
|
(HANDLE) NULL,
|
|
(PSECURITY_DESCRIPTOR) NULL );
|
|
|
|
// Try to open \DosDevices\NONSPOOLED_LPT1
|
|
|
|
Status = NtOpenSymbolicLinkObject( &Handle,
|
|
SYMBOLIC_LINK_ALL_ACCESS,
|
|
&ObjectAttributes );
|
|
|
|
if (!NT_SUCCESS( Status )) {
|
|
|
|
DBGMSG( DBG_ERROR, ("Symbolic link %ws does not exist\n", pNewDosDeviceName ));
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
// Mark this object as temporary so when we close it it will be deleted
|
|
|
|
Status = NtMakeTemporaryObject( Handle );
|
|
if (NT_SUCCESS( Status )) {
|
|
NtClose( Handle );
|
|
}
|
|
|
|
RtlInitUnicodeString( &OldDosDeviceName, pOldDosDeviceName);
|
|
|
|
ASSERT( NT_SUCCESS( Status ) );
|
|
InitializeObjectAttributes( &ObjectAttributes,
|
|
&OldDosDeviceName,
|
|
OBJ_CASE_INSENSITIVE,
|
|
(HANDLE) NULL,
|
|
(PSECURITY_DESCRIPTOR) NULL );
|
|
|
|
// Try to open \DosDevices\LPT1
|
|
|
|
Status = NtOpenSymbolicLinkObject( &Handle,
|
|
SYMBOLIC_LINK_ALL_ACCESS,
|
|
&ObjectAttributes );
|
|
|
|
if (!NT_SUCCESS( Status )) {
|
|
|
|
DBGMSG( DBG_ERROR, ("Symbolic link %ws does not exist\n", pOldDosDeviceName ));
|
|
return FALSE;
|
|
}
|
|
|
|
// Mark this object as temporary so when we close it it will be deleted
|
|
|
|
Status = NtMakeTemporaryObject( Handle );
|
|
if (NT_SUCCESS( Status )) {
|
|
NtClose( Handle );
|
|
}
|
|
|
|
ObjectAttributes.Attributes |= OBJ_PERMANENT;
|
|
|
|
RtlInitUnicodeString( &OldNtDeviceName, *ppOldNtDeviceName );
|
|
|
|
// Make \DosDevices\LPT1 point to \Device\Parallel0
|
|
|
|
Status = NtCreateSymbolicLinkObject( &Handle,
|
|
SYMBOLIC_LINK_ALL_ACCESS,
|
|
&ObjectAttributes,
|
|
&OldNtDeviceName );
|
|
|
|
if (!NT_SUCCESS( Status )) {
|
|
DBGMSG( DBG_WARNING, ("Error creating symbolic link %ws => %ws\n",
|
|
pOldDosDeviceName,
|
|
*ppOldNtDeviceName ));
|
|
DBGMSG( DBG_WARNING, ("Error status was: %X\n", Status ));
|
|
} else {
|
|
NtClose( Handle );
|
|
}
|
|
|
|
FreeSplStr(*ppOldNtDeviceName);
|
|
|
|
*ppOldNtDeviceName = NULL;
|
|
|
|
return TRUE;
|
|
}
|