Leaked source code of windows server 2003
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

  1. /*++
  2. Copyright (c) 1990-2003 Microsoft Corporation
  3. Module Name:
  4. setlink.c
  5. Abstract:
  6. Utility to display or change the value of a symbolic link.
  7. // @@BEGIN_DDKSPLIT
  8. Author:
  9. Darryl E. Havens (DarrylH) 9-Nov-1990
  10. Revision History:
  11. // @@END_DDKSPLIT
  12. --*/
  13. #include "precomp.h"
  14. #pragma hdrstop
  15. BOOL
  16. MakeLink(
  17. LPWSTR pOldDosDeviceName,
  18. LPWSTR pNewDosDeviceName,
  19. LPWSTR *ppOldNtDeviceName,
  20. LPWSTR pNewNtDeviceName,
  21. SECURITY_DESCRIPTOR *pSecurityDescriptor
  22. )
  23. {
  24. NTSTATUS Status;
  25. STRING AnsiString;
  26. UNICODE_STRING OldDosDeviceName;
  27. UNICODE_STRING NewDosDeviceName;
  28. UNICODE_STRING PreviousNtDeviceName;
  29. UNICODE_STRING NewNtDeviceName;
  30. HANDLE Handle, Handle1;
  31. OBJECT_ATTRIBUTES ObjectAttributes;
  32. WCHAR Buffer[MAX_PATH];
  33. RtlInitUnicodeString( &OldDosDeviceName, pOldDosDeviceName);
  34. ASSERT( NT_SUCCESS( Status ) );
  35. InitializeObjectAttributes( &ObjectAttributes,
  36. &OldDosDeviceName,
  37. OBJ_CASE_INSENSITIVE,
  38. (HANDLE) NULL,
  39. (PSECURITY_DESCRIPTOR) NULL );
  40. // Try to open \DosDevices\LPT1
  41. Status = NtOpenSymbolicLinkObject( &Handle,
  42. SYMBOLIC_LINK_ALL_ACCESS,
  43. &ObjectAttributes );
  44. if (!NT_SUCCESS( Status )) {
  45. DBGMSG( DBG_WARNING, ("Symbolic link %ws does not exist\n", pOldDosDeviceName ));
  46. return FALSE;
  47. }
  48. memset(Buffer, 0, sizeof(Buffer));
  49. PreviousNtDeviceName.Length = 0;
  50. PreviousNtDeviceName.MaximumLength = sizeof( Buffer );
  51. PreviousNtDeviceName.Buffer = Buffer;
  52. // Get \Device\Parallel0 into Buffer
  53. Status = NtQuerySymbolicLinkObject( Handle,
  54. &PreviousNtDeviceName,
  55. NULL );
  56. if (!NT_SUCCESS( Status )) {
  57. SetLastError(Status);
  58. NtClose(Handle);
  59. return FALSE;
  60. }
  61. *ppOldNtDeviceName = AllocSplStr(Buffer);
  62. // Mark this object as temporary so when we close it it will be deleted
  63. Status = NtMakeTemporaryObject( Handle );
  64. if (NT_SUCCESS( Status )) {
  65. NtClose( Handle );
  66. }
  67. ObjectAttributes.Attributes |= OBJ_PERMANENT;
  68. RtlInitUnicodeString( &NewNtDeviceName, pNewNtDeviceName );
  69. // Make \DosDevices\LPT1 point to \Device\NamedPipe\Spooler\LPT1
  70. Status = NtCreateSymbolicLinkObject( &Handle,
  71. SYMBOLIC_LINK_ALL_ACCESS,
  72. &ObjectAttributes,
  73. &NewNtDeviceName );
  74. if (!NT_SUCCESS( Status )) {
  75. DBGMSG( DBG_WARNING, ("Error creating symbolic link %ws => %ws\n",
  76. pOldDosDeviceName,
  77. pNewNtDeviceName ));
  78. DBGMSG( DBG_WARNING, ("Error status was: %X\n", Status ));
  79. return FALSE;
  80. } else {
  81. NtClose( Handle );
  82. }
  83. RtlInitUnicodeString( &NewDosDeviceName, pNewDosDeviceName);
  84. ASSERT( NT_SUCCESS( Status ) );
  85. InitializeObjectAttributes( &ObjectAttributes,
  86. &NewDosDeviceName,
  87. OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
  88. (HANDLE) NULL,
  89. pSecurityDescriptor );
  90. // Finally make \DosDevices\NONSPOOLED_LPT1 => \Device\Parallel0
  91. Status = NtCreateSymbolicLinkObject(&Handle,
  92. SYMBOLIC_LINK_ALL_ACCESS,
  93. &ObjectAttributes,
  94. &PreviousNtDeviceName);
  95. if (NT_SUCCESS(Status))
  96. NtClose(Handle);
  97. return TRUE;
  98. }
  99. BOOL
  100. RemoveLink(
  101. LPWSTR pOldDosDeviceName,
  102. LPWSTR pNewDosDeviceName,
  103. LPWSTR *ppOldNtDeviceName
  104. )
  105. {
  106. NTSTATUS Status;
  107. STRING AnsiString;
  108. UNICODE_STRING OldDosDeviceName;
  109. UNICODE_STRING NewDosDeviceName;
  110. UNICODE_STRING PreviousNtDeviceName;
  111. UNICODE_STRING OldNtDeviceName;
  112. HANDLE Handle, Handle1;
  113. OBJECT_ATTRIBUTES ObjectAttributes;
  114. RtlInitUnicodeString( &NewDosDeviceName, pNewDosDeviceName);
  115. ASSERT( NT_SUCCESS( Status ) );
  116. InitializeObjectAttributes( &ObjectAttributes,
  117. &NewDosDeviceName,
  118. OBJ_CASE_INSENSITIVE,
  119. (HANDLE) NULL,
  120. (PSECURITY_DESCRIPTOR) NULL );
  121. // Try to open \DosDevices\NONSPOOLED_LPT1
  122. Status = NtOpenSymbolicLinkObject( &Handle,
  123. SYMBOLIC_LINK_ALL_ACCESS,
  124. &ObjectAttributes );
  125. if (!NT_SUCCESS( Status )) {
  126. DBGMSG( DBG_ERROR, ("Symbolic link %ws does not exist\n", pNewDosDeviceName ));
  127. return FALSE;
  128. }
  129. // Mark this object as temporary so when we close it it will be deleted
  130. Status = NtMakeTemporaryObject( Handle );
  131. if (NT_SUCCESS( Status )) {
  132. NtClose( Handle );
  133. }
  134. RtlInitUnicodeString( &OldDosDeviceName, pOldDosDeviceName);
  135. ASSERT( NT_SUCCESS( Status ) );
  136. InitializeObjectAttributes( &ObjectAttributes,
  137. &OldDosDeviceName,
  138. OBJ_CASE_INSENSITIVE,
  139. (HANDLE) NULL,
  140. (PSECURITY_DESCRIPTOR) NULL );
  141. // Try to open \DosDevices\LPT1
  142. Status = NtOpenSymbolicLinkObject( &Handle,
  143. SYMBOLIC_LINK_ALL_ACCESS,
  144. &ObjectAttributes );
  145. if (!NT_SUCCESS( Status )) {
  146. DBGMSG( DBG_ERROR, ("Symbolic link %ws does not exist\n", pOldDosDeviceName ));
  147. return FALSE;
  148. }
  149. // Mark this object as temporary so when we close it it will be deleted
  150. Status = NtMakeTemporaryObject( Handle );
  151. if (NT_SUCCESS( Status )) {
  152. NtClose( Handle );
  153. }
  154. ObjectAttributes.Attributes |= OBJ_PERMANENT;
  155. RtlInitUnicodeString( &OldNtDeviceName, *ppOldNtDeviceName );
  156. // Make \DosDevices\LPT1 point to \Device\Parallel0
  157. Status = NtCreateSymbolicLinkObject( &Handle,
  158. SYMBOLIC_LINK_ALL_ACCESS,
  159. &ObjectAttributes,
  160. &OldNtDeviceName );
  161. if (!NT_SUCCESS( Status )) {
  162. DBGMSG( DBG_WARNING, ("Error creating symbolic link %ws => %ws\n",
  163. pOldDosDeviceName,
  164. *ppOldNtDeviceName ));
  165. DBGMSG( DBG_WARNING, ("Error status was: %X\n", Status ));
  166. } else {
  167. NtClose( Handle );
  168. }
  169. FreeSplStr(*ppOldNtDeviceName);
  170. *ppOldNtDeviceName = NULL;
  171. return TRUE;
  172. }