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.

337 lines
7.9 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. reparse.c
  5. Abstract:
  6. This file contains code for commands that affect
  7. reparse points.
  8. Author:
  9. Wesley Witt [wesw] 1-March-2000
  10. Revision History:
  11. --*/
  12. #include <precomp.h>
  13. INT
  14. ReparseHelp(
  15. IN INT argc,
  16. IN PWSTR argv[]
  17. )
  18. {
  19. DisplayMsg( MSG_USAGE_REPARSEPOINT );
  20. return EXIT_CODE_SUCCESS;
  21. }
  22. //
  23. // Microsoft tags for reparse points.
  24. //
  25. #define MAX_REPARSE_DATA 0x1000
  26. INT
  27. GetReparsePoint(
  28. IN INT argc,
  29. IN PWSTR argv[]
  30. )
  31. /*++
  32. Routine Description:
  33. This routine gets the reparse point for the file specified.
  34. Arguments:
  35. argc - The argument count.
  36. argv - Array of Strings of the form :
  37. ' fscutl getrp <pathname>'.
  38. Return Value:
  39. None
  40. --*/
  41. {
  42. PWSTR Filename = NULL;
  43. HANDLE FileHandle = INVALID_HANDLE_VALUE;
  44. PREPARSE_GUID_DATA_BUFFER lpOutBuffer = NULL;
  45. BOOL Status;
  46. DWORD nOutBufferSize;
  47. DWORD BytesReturned;
  48. ULONG ulMask;
  49. WCHAR Buffer[256];
  50. LPWSTR GuidStr;
  51. INT ExitCode = EXIT_CODE_SUCCESS;
  52. try {
  53. if (argc != 1) {
  54. DisplayMsg( MSG_USAGE_GETREPARSE );
  55. if (argc != 0) {
  56. ExitCode = EXIT_CODE_FAILURE;
  57. }
  58. leave;
  59. }
  60. Filename = GetFullPath( argv[0] );
  61. if (!Filename) {
  62. DisplayError();
  63. ExitCode = EXIT_CODE_FAILURE;
  64. leave;
  65. }
  66. if (!IsVolumeLocalNTFS( Filename[0] )) {
  67. DisplayMsg( MSG_NTFS_REQUIRED );
  68. ExitCode = EXIT_CODE_FAILURE;
  69. leave;
  70. }
  71. nOutBufferSize = REPARSE_GUID_DATA_BUFFER_HEADER_SIZE + MAX_REPARSE_DATA;
  72. lpOutBuffer = (PREPARSE_GUID_DATA_BUFFER) malloc ( nOutBufferSize );
  73. if (lpOutBuffer == NULL) {
  74. DisplayErrorMsg( ERROR_NOT_ENOUGH_MEMORY );
  75. ExitCode = EXIT_CODE_FAILURE;
  76. leave;
  77. }
  78. FileHandle = CreateFile(
  79. Filename,
  80. GENERIC_READ,
  81. FILE_SHARE_READ | FILE_SHARE_WRITE,
  82. NULL,
  83. OPEN_EXISTING,
  84. FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS,
  85. NULL
  86. );
  87. if (FileHandle == INVALID_HANDLE_VALUE) {
  88. DisplayError();
  89. ExitCode = EXIT_CODE_FAILURE;
  90. leave;
  91. }
  92. Status = DeviceIoControl(
  93. FileHandle,
  94. FSCTL_GET_REPARSE_POINT,
  95. NULL,
  96. 0,
  97. (LPVOID) lpOutBuffer,
  98. nOutBufferSize,
  99. &BytesReturned,
  100. (LPOVERLAPPED)NULL
  101. );
  102. if (!Status) {
  103. DisplayError();
  104. ExitCode = EXIT_CODE_FAILURE;
  105. leave;
  106. }
  107. DisplayMsg( MSG_GETREPARSE_TAGVAL, lpOutBuffer->ReparseTag );
  108. if (IsReparseTagMicrosoft( lpOutBuffer->ReparseTag )) {
  109. DisplayMsg( MSG_TAG_MICROSOFT );
  110. }
  111. if (IsReparseTagNameSurrogate( lpOutBuffer->ReparseTag )) {
  112. DisplayMsg( MSG_TAG_NAME_SURROGATE );
  113. }
  114. if (lpOutBuffer->ReparseTag == IO_REPARSE_TAG_SYMBOLIC_LINK) {
  115. DisplayMsg( MSG_TAG_SYMBOLIC_LINK );
  116. }
  117. if (lpOutBuffer->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) {
  118. DisplayMsg( MSG_TAG_MOUNT_POINT );
  119. }
  120. if (lpOutBuffer->ReparseTag == IO_REPARSE_TAG_HSM) {
  121. DisplayMsg( MSG_TAG_HSM );
  122. }
  123. if (lpOutBuffer->ReparseTag == IO_REPARSE_TAG_SIS) {
  124. DisplayMsg( MSG_TAG_SIS );
  125. }
  126. if (lpOutBuffer->ReparseTag == IO_REPARSE_TAG_FILTER_MANAGER) {
  127. DisplayMsg( MSG_TAG_FILTER_MANAGER );
  128. }
  129. Status = StringFromIID( &lpOutBuffer->ReparseGuid, &GuidStr );
  130. if (Status != S_OK) {
  131. DisplayErrorMsg( Status );
  132. ExitCode = EXIT_CODE_FAILURE;
  133. leave;
  134. }
  135. DisplayMsg( MSG_GETREPARSE_GUID, GuidStr, lpOutBuffer->ReparseDataLength );
  136. if (lpOutBuffer->ReparseDataLength != 0) {
  137. int i, j;
  138. WCHAR Buf[17];
  139. DisplayMsg( MSG_GETREPARSE_DATA );
  140. for (i = 0; i < lpOutBuffer->ReparseDataLength; i += 16 ) {
  141. wprintf( L"%04x: ", i );
  142. for (j = 0; j < 16 && j + i < lpOutBuffer->ReparseDataLength; j++) {
  143. UCHAR c = lpOutBuffer->GenericReparseBuffer.DataBuffer[ i + j ];
  144. if (c >= 0x20 && c <= 0x7F) {
  145. Buf[j] = c;
  146. } else {
  147. Buf[j] = L'.';
  148. }
  149. wprintf( L" %02x", c );
  150. }
  151. Buf[j] = L'\0';
  152. for ( ; j < 16; j++ ) {
  153. wprintf( L" " );
  154. }
  155. wprintf( L" %s\n", Buf );
  156. }
  157. }
  158. CoTaskMemFree(GuidStr);
  159. } finally {
  160. if (FileHandle != INVALID_HANDLE_VALUE) {
  161. CloseHandle( FileHandle );
  162. }
  163. free( lpOutBuffer );
  164. free( Filename );
  165. }
  166. return ExitCode;
  167. }
  168. INT
  169. DeleteReparsePoint(
  170. IN INT argc,
  171. IN PWSTR argv[]
  172. )
  173. /*++
  174. Routine Description:
  175. This routine deletes the reparse point associated with
  176. the file specified.
  177. Arguments:
  178. argc - The argument count.
  179. argv - Array of Strings of the form :
  180. ' fscutl delrp <pathname>'.
  181. Return Value:
  182. None
  183. --*/
  184. {
  185. BOOL Status;
  186. PWSTR Filename = NULL;
  187. HANDLE FileHandle = INVALID_HANDLE_VALUE;
  188. PREPARSE_GUID_DATA_BUFFER lpInOutBuffer = NULL;
  189. DWORD nInOutBufferSize;
  190. DWORD BytesReturned;
  191. INT ExitCode = EXIT_CODE_SUCCESS;
  192. try {
  193. if (argc != 1) {
  194. DisplayMsg( MSG_DELETE_REPARSE );
  195. if (argc != 0) {
  196. ExitCode = EXIT_CODE_FAILURE;
  197. }
  198. leave;
  199. }
  200. Filename = GetFullPath( argv[0] );
  201. if (!Filename) {
  202. DisplayError();
  203. ExitCode = EXIT_CODE_FAILURE;
  204. leave;
  205. }
  206. if (!IsVolumeLocalNTFS( Filename[0] )) {
  207. DisplayMsg( MSG_NTFS_REQUIRED );
  208. ExitCode = EXIT_CODE_FAILURE;
  209. leave;
  210. }
  211. nInOutBufferSize = REPARSE_GUID_DATA_BUFFER_HEADER_SIZE + MAX_REPARSE_DATA;
  212. lpInOutBuffer = (PREPARSE_GUID_DATA_BUFFER) malloc ( nInOutBufferSize );
  213. if (lpInOutBuffer == NULL) {
  214. DisplayErrorMsg( ERROR_NOT_ENOUGH_MEMORY );
  215. ExitCode = EXIT_CODE_FAILURE;
  216. leave;
  217. }
  218. FileHandle = CreateFile(
  219. Filename,
  220. GENERIC_WRITE,
  221. FILE_SHARE_READ | FILE_SHARE_WRITE,
  222. NULL,
  223. OPEN_EXISTING,
  224. FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS,
  225. NULL
  226. );
  227. if (FileHandle == INVALID_HANDLE_VALUE) {
  228. DisplayError();
  229. ExitCode = EXIT_CODE_FAILURE;
  230. leave;
  231. }
  232. Status = DeviceIoControl(
  233. FileHandle,
  234. FSCTL_GET_REPARSE_POINT,
  235. NULL,
  236. 0,
  237. (LPVOID) lpInOutBuffer,
  238. nInOutBufferSize,
  239. &BytesReturned,
  240. (LPOVERLAPPED)NULL
  241. );
  242. if (!Status) {
  243. DisplayError();
  244. ExitCode = EXIT_CODE_FAILURE;
  245. leave;
  246. }
  247. lpInOutBuffer->ReparseDataLength = 0;
  248. Status = DeviceIoControl(
  249. FileHandle,
  250. FSCTL_DELETE_REPARSE_POINT,
  251. (LPVOID) lpInOutBuffer,
  252. REPARSE_GUID_DATA_BUFFER_HEADER_SIZE,
  253. NULL,
  254. 0,
  255. &BytesReturned,
  256. (LPOVERLAPPED)NULL
  257. );
  258. if (!Status) {
  259. DisplayError();
  260. ExitCode = EXIT_CODE_FAILURE;
  261. }
  262. } finally {
  263. if (FileHandle != INVALID_HANDLE_VALUE) {
  264. CloseHandle( FileHandle );
  265. }
  266. free( lpInOutBuffer );
  267. free( Filename );
  268. }
  269. return ExitCode;
  270. }