Source code of Windows XP (NT5)
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.6 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. setlink.c
  5. Abstract:
  6. Utility to display or change the value of a symbolic link.
  7. Author:
  8. Darryl E. Havens (DarrylH) 9-Nov-1990
  9. Revision History:
  10. --*/
  11. #include <nt.h>
  12. #include <ntrtl.h>
  13. #include <nturtl.h>
  14. #include <windows.h>
  15. #include <stdio.h>
  16. #include <tools.h>
  17. BOOLEAN
  18. __cdecl main(
  19. IN ULONG argc,
  20. IN PCHAR argv[]
  21. )
  22. {
  23. NTSTATUS Status;
  24. STRING AnsiString;
  25. UNICODE_STRING LinkName;
  26. UNICODE_STRING LinkValue;
  27. HANDLE Handle;
  28. OBJECT_ATTRIBUTES ObjectAttributes;
  29. WCHAR Buffer[256];
  30. PWSTR s;
  31. ULONG ReturnedLength;
  32. //
  33. // Check to see whether or not this utility was invoked with the correct
  34. // number of parameters. If not, bail out now.
  35. //
  36. ConvertAppToOem( argc, argv );
  37. if (argc < 2 || argc > 3) {
  38. printf( "Useage: setlink symbolic-link-name [symbolic-link-value]\n" );
  39. return FALSE;
  40. }
  41. //
  42. // Begin by attempting to open the existing symbolic link name specified.
  43. //
  44. RtlInitString( &AnsiString, argv[1] );
  45. Status = RtlAnsiStringToUnicodeString( &LinkName,
  46. &AnsiString,
  47. TRUE );
  48. ASSERT( NT_SUCCESS( Status ) );
  49. InitializeObjectAttributes( &ObjectAttributes,
  50. &LinkName,
  51. OBJ_CASE_INSENSITIVE,
  52. (HANDLE) NULL,
  53. (PSECURITY_DESCRIPTOR) NULL );
  54. Status = NtOpenSymbolicLinkObject( &Handle,
  55. argc == 2 ? SYMBOLIC_LINK_QUERY :
  56. SYMBOLIC_LINK_ALL_ACCESS,
  57. &ObjectAttributes );
  58. //
  59. // Determine what should be done based on the number of parameters that
  60. // were given to the program.
  61. //
  62. if (argc == 2) {
  63. //
  64. // Only one parameter was specified, so display the value of the
  65. // symbolic link if it exists.
  66. //
  67. if (!NT_SUCCESS( Status )) {
  68. printf( "Symbolic link %wZ does not exist\n", &LinkName );
  69. return FALSE;
  70. } else {
  71. LinkValue.Length = 0;
  72. LinkValue.MaximumLength = sizeof( Buffer );
  73. LinkValue.Buffer = Buffer;
  74. ReturnedLength = 0;
  75. Status = NtQuerySymbolicLinkObject( Handle,
  76. &LinkValue,
  77. &ReturnedLength
  78. );
  79. NtClose( Handle );
  80. if (!NT_SUCCESS( Status )) {
  81. printf( "Error reading symbolic link %wZ\n", &LinkName );
  82. printf( "Error status was: %X\n", Status );
  83. return FALSE;
  84. } else {
  85. printf( "Value of %wZ => %wZ", &LinkName, &LinkValue );
  86. s = LinkValue.Buffer + ((LinkValue.Length / sizeof( WCHAR )) + 1);
  87. while (ReturnedLength > LinkValue.MaximumLength) {
  88. printf( " ; %ws", s );
  89. while (*s++) {
  90. ReturnedLength -= 2;
  91. }
  92. ReturnedLength -= 2;
  93. }
  94. printf( "\n", s );
  95. return TRUE;
  96. }
  97. }
  98. } else {
  99. //
  100. // Three parameters were supplied, so assign a new value to the
  101. // symbolic link if it exists by first deleting the existing link
  102. // (mark it temporary and close the handle). If it doesn't exist
  103. // yet, then it will simply be created.
  104. //
  105. if (NT_SUCCESS( Status )) {
  106. Status = NtMakeTemporaryObject( Handle );
  107. if (NT_SUCCESS( Status )) {
  108. NtClose( Handle );
  109. }
  110. }
  111. }
  112. //
  113. // Create a new value for the link.
  114. //
  115. ObjectAttributes.Attributes |= OBJ_PERMANENT;
  116. RtlInitString( &AnsiString, argv[2] );
  117. Status = RtlAnsiStringToUnicodeString( &LinkValue,
  118. &AnsiString,
  119. TRUE );
  120. Status = NtCreateSymbolicLinkObject( &Handle,
  121. SYMBOLIC_LINK_ALL_ACCESS,
  122. &ObjectAttributes,
  123. &LinkValue );
  124. if (!NT_SUCCESS( Status )) {
  125. printf( "Error creating symbolic link %wZ => %wZ\n",
  126. &LinkName,
  127. &LinkValue );
  128. printf( "Error status was: %X\n", Status );
  129. } else {
  130. NtClose( Handle );
  131. }
  132. return TRUE;
  133. }