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.

563 lines
12 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. objectid.c
  5. Abstract:
  6. This file contains code for commands that affect object ids.
  7. Author:
  8. Wesley Witt [wesw] 1-March-2000
  9. Revision History:
  10. --*/
  11. #include <precomp.h>
  12. INT
  13. ObjectIdHelp(
  14. IN INT argc,
  15. IN PWSTR argv[]
  16. )
  17. {
  18. DisplayMsg( MSG_USAGE_OBJECTID );
  19. return EXIT_CODE_SUCCESS;
  20. }
  21. VOID
  22. PrintObjectId(
  23. PFILE_OBJECTID_BUFFER lpOutBuffer
  24. )
  25. {
  26. INT Index;
  27. DisplayMsg( MSG_OBJECTID_TEXT );
  28. for ( Index = 0 ; Index < 16 ; Index++ ) {
  29. wprintf( L"%02x", lpOutBuffer->ObjectId[Index] );
  30. }
  31. wprintf( L"\n" );
  32. DisplayMsg( MSG_BIRTHVOLID_TEXT );
  33. for ( Index = 0 ; Index < 16 ; Index++ ) {
  34. wprintf( L"%02x", lpOutBuffer->BirthVolumeId[Index] );
  35. }
  36. wprintf( L"\n" );
  37. DisplayMsg( MSG_BIRTHOBJECTID_TEXT );
  38. for ( Index = 0 ; Index < 16 ; Index++ ) {
  39. wprintf( L"%02x", lpOutBuffer->BirthObjectId[Index] );
  40. }
  41. wprintf( L"\n" );
  42. DisplayMsg( MSG_DOMAINID_TEXT );
  43. for ( Index = 0 ; Index < 16 ; Index++ ) {
  44. wprintf( L"%02x", lpOutBuffer->DomainId[Index] );
  45. }
  46. wprintf( L"\n" );
  47. }
  48. UCHAR
  49. GetNibbleValue(
  50. IN OUT PCWSTR *String
  51. )
  52. {
  53. UCHAR v;
  54. WCHAR c;
  55. c = *(*String)++;
  56. c = (UCHAR) toupper( c );
  57. if (isdigit( c )) {
  58. v = c - L'0';
  59. } else if (isalpha( c ) && c <= L'F') {
  60. v = c - L'A' + 10;
  61. } else {
  62. (*String)--;
  63. return 0;
  64. }
  65. return v;
  66. }
  67. UCHAR
  68. GetByteValue(
  69. IN OUT PCWSTR *String
  70. )
  71. {
  72. UCHAR v = GetNibbleValue( String );
  73. v *= 16;
  74. v += GetNibbleValue( String );
  75. return v;
  76. }
  77. BOOL
  78. ConvertStringToHexData(
  79. IN PCWSTR Arg,
  80. OUT PUCHAR Buffer
  81. )
  82. {
  83. int i;
  84. for (i = 0; i < 16; i++) {
  85. Buffer[i] = GetByteValue( &Arg );
  86. }
  87. return *Arg == L'\0';
  88. }
  89. INT
  90. SetObjectId(
  91. IN INT argc,
  92. IN PWSTR argv[]
  93. )
  94. /*++
  95. Routine Description:
  96. This routine sets the objectID for the file specified.
  97. Arguments:
  98. argc - The argument count.
  99. argv - Array of Strings of the form :
  100. ' fscutl setoid <oid=val> <bvid=val> <boid=val> <did=val> <pathname>'.
  101. Return Value:
  102. None
  103. --*/
  104. {
  105. PWSTR Filename = NULL;
  106. HANDLE FileHandle = INVALID_HANDLE_VALUE;
  107. PFILE_OBJECTID_BUFFER lpInBuffer = NULL;
  108. BOOL Status;
  109. DWORD nInBufferSize;
  110. DWORD BytesReturned;
  111. INT ExitCode = EXIT_CODE_SUCCESS;
  112. try {
  113. if (argc != 5) {
  114. DisplayMsg( MSG_USAGE_SETOBJECTID );
  115. if (argc != 0) {
  116. ExitCode = EXIT_CODE_FAILURE;
  117. }
  118. leave;
  119. }
  120. Filename = GetFullPath( argv[4] );
  121. if (!Filename) {
  122. DisplayError();
  123. ExitCode = EXIT_CODE_FAILURE;
  124. leave;
  125. }
  126. if (!IsVolumeLocalNTFS( Filename[0] )) {
  127. DisplayMsg( MSG_NTFS_REQUIRED );
  128. ExitCode = EXIT_CODE_FAILURE;
  129. leave;
  130. }
  131. nInBufferSize = sizeof(FILE_OBJECTID_BUFFER);
  132. lpInBuffer = (PFILE_OBJECTID_BUFFER) malloc ( nInBufferSize );
  133. if (lpInBuffer == NULL) {
  134. DisplayErrorMsg( ERROR_NOT_ENOUGH_MEMORY );
  135. ExitCode = EXIT_CODE_FAILURE;
  136. leave;
  137. }
  138. //
  139. // Convert the input strings into the correct data
  140. //
  141. if (!ConvertStringToHexData( argv[0], lpInBuffer->ObjectId)
  142. || !ConvertStringToHexData( argv[1], lpInBuffer->BirthVolumeId)
  143. || !ConvertStringToHexData( argv[2], lpInBuffer->BirthObjectId)
  144. || !ConvertStringToHexData( argv[3], lpInBuffer->DomainId)) {
  145. DisplayMsg( MSG_USAGE_SETOBJECTID );
  146. ExitCode = EXIT_CODE_FAILURE;
  147. leave;
  148. }
  149. EnablePrivilege( SE_RESTORE_NAME );
  150. FileHandle = CreateFile(
  151. Filename,
  152. GENERIC_WRITE,
  153. FILE_SHARE_READ | FILE_SHARE_WRITE,
  154. NULL,
  155. OPEN_EXISTING,
  156. FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS,
  157. NULL
  158. );
  159. if (FileHandle == INVALID_HANDLE_VALUE) {
  160. DisplayError();
  161. ExitCode = EXIT_CODE_FAILURE;
  162. leave;
  163. }
  164. Status = DeviceIoControl(
  165. FileHandle,
  166. FSCTL_SET_OBJECT_ID,
  167. (LPVOID) lpInBuffer,
  168. nInBufferSize,
  169. NULL,
  170. 0,
  171. &BytesReturned,
  172. (LPOVERLAPPED)NULL
  173. );
  174. if (!Status) {
  175. DisplayError();
  176. ExitCode = EXIT_CODE_FAILURE;
  177. leave;
  178. }
  179. } finally {
  180. if (FileHandle != INVALID_HANDLE_VALUE) {
  181. CloseHandle( FileHandle );
  182. }
  183. free(lpInBuffer);
  184. free( Filename );
  185. }
  186. return ExitCode;
  187. }
  188. INT
  189. GetObjectId(
  190. IN INT argc,
  191. IN PWSTR argv[]
  192. )
  193. /*++
  194. Routine Description:
  195. This routine gets the objectID associated with the file specified.
  196. Arguments:
  197. argc - The argument count.
  198. argv - Array of Strings of the form :
  199. ' fscutl getoid <pathname> '.
  200. Return Value:
  201. None
  202. --*/
  203. {
  204. HANDLE FileHandle = INVALID_HANDLE_VALUE;
  205. PWSTR Filename = NULL;
  206. PFILE_OBJECTID_BUFFER lpOutBuffer = NULL;
  207. BOOL Status;
  208. DWORD nOutBufferSize;
  209. DWORD BytesReturned;
  210. INT ExitCode = EXIT_CODE_SUCCESS;
  211. try {
  212. if (argc != 1) {
  213. DisplayMsg( MSG_USAGE_GETOBJECTID );
  214. if (argc != 0) {
  215. ExitCode = EXIT_CODE_FAILURE;
  216. }
  217. leave;
  218. }
  219. Filename = GetFullPath( argv[0] );
  220. if (!Filename) {
  221. DisplayError();
  222. ExitCode = EXIT_CODE_FAILURE;
  223. leave;
  224. }
  225. if (!IsVolumeNTFS( Filename )) {
  226. DisplayMsg( MSG_NTFS_REQUIRED );
  227. ExitCode = EXIT_CODE_FAILURE;
  228. leave;
  229. }
  230. nOutBufferSize = sizeof(FILE_OBJECTID_BUFFER);
  231. lpOutBuffer = (PFILE_OBJECTID_BUFFER) malloc ( nOutBufferSize );
  232. if (lpOutBuffer == NULL) {
  233. DisplayErrorMsg( ERROR_NOT_ENOUGH_MEMORY );
  234. ExitCode = EXIT_CODE_FAILURE;
  235. leave;
  236. }
  237. FileHandle = CreateFile(
  238. Filename,
  239. GENERIC_READ,
  240. FILE_SHARE_READ | FILE_SHARE_WRITE,
  241. NULL,
  242. OPEN_EXISTING,
  243. FILE_ATTRIBUTE_NORMAL,
  244. NULL
  245. );
  246. if (FileHandle == INVALID_HANDLE_VALUE) {
  247. DisplayError();
  248. ExitCode = EXIT_CODE_FAILURE;
  249. leave;
  250. }
  251. Status = DeviceIoControl(
  252. FileHandle,
  253. FSCTL_GET_OBJECT_ID,
  254. NULL,
  255. 0,
  256. (LPVOID) lpOutBuffer,
  257. nOutBufferSize,
  258. &BytesReturned,
  259. (LPOVERLAPPED)NULL
  260. );
  261. if (!Status) {
  262. if (GetLastError( ) == ERROR_FILE_NOT_FOUND) {
  263. DisplayMsg( MSG_NO_OBJECT_ID );
  264. } else {
  265. DisplayError();
  266. ExitCode = EXIT_CODE_FAILURE;
  267. }
  268. leave;
  269. }
  270. PrintObjectId( lpOutBuffer );
  271. } finally {
  272. if (FileHandle != INVALID_HANDLE_VALUE) {
  273. CloseHandle( FileHandle );
  274. }
  275. free(lpOutBuffer);
  276. free( Filename );
  277. }
  278. return ExitCode;
  279. }
  280. INT
  281. CreateOrGetObjectId(
  282. IN INT argc,
  283. IN PWSTR argv[]
  284. )
  285. /*++
  286. Routine Description:
  287. This routine gets the objectID for the file, if it exists, else
  288. creates an objectID and returns it.
  289. Arguments:
  290. argc - The argument count.
  291. argv - Array of Strings of the form :
  292. ' fscutl crgetoid <pathname>'.
  293. Return Value:
  294. None
  295. --*/
  296. {
  297. PWSTR Filename = NULL;
  298. HANDLE FileHandle = INVALID_HANDLE_VALUE;
  299. PFILE_OBJECTID_BUFFER lpOutBuffer = NULL;
  300. BOOL Status;
  301. DWORD nOutBufferSize;
  302. DWORD BytesReturned;
  303. INT ExitCode = EXIT_CODE_SUCCESS;
  304. try {
  305. if (argc != 1) {
  306. DisplayMsg( MSG_USAGE_CREATEOBJECTID );
  307. if (argc != 0) {
  308. ExitCode = EXIT_CODE_FAILURE;
  309. }
  310. leave;
  311. }
  312. Filename = GetFullPath( argv[0] );
  313. if (!Filename) {
  314. DisplayError();
  315. ExitCode = EXIT_CODE_FAILURE;
  316. leave;
  317. }
  318. if (!IsVolumeLocalNTFS( Filename[0] )) {
  319. DisplayMsg( MSG_NTFS_REQUIRED );
  320. ExitCode = EXIT_CODE_FAILURE;
  321. leave;
  322. }
  323. nOutBufferSize = sizeof(FILE_OBJECTID_BUFFER);
  324. lpOutBuffer = (PFILE_OBJECTID_BUFFER) malloc ( nOutBufferSize );
  325. if (lpOutBuffer == NULL) {
  326. DisplayErrorMsg( ERROR_NOT_ENOUGH_MEMORY );
  327. ExitCode = EXIT_CODE_FAILURE;
  328. leave;
  329. }
  330. FileHandle = CreateFile(
  331. Filename,
  332. GENERIC_READ | GENERIC_WRITE,
  333. FILE_SHARE_READ | FILE_SHARE_WRITE,
  334. NULL,
  335. OPEN_EXISTING,
  336. FILE_ATTRIBUTE_NORMAL,
  337. NULL
  338. );
  339. if (FileHandle == INVALID_HANDLE_VALUE) {
  340. DisplayError();
  341. ExitCode = EXIT_CODE_FAILURE;
  342. leave;
  343. }
  344. Status = DeviceIoControl(
  345. FileHandle,
  346. FSCTL_CREATE_OR_GET_OBJECT_ID,
  347. NULL,
  348. 0,
  349. (LPVOID) lpOutBuffer,
  350. nOutBufferSize,
  351. &BytesReturned,
  352. (LPOVERLAPPED)NULL
  353. );
  354. if (!Status) {
  355. DisplayError();
  356. ExitCode = EXIT_CODE_FAILURE;
  357. leave;
  358. }
  359. PrintObjectId( lpOutBuffer );
  360. } finally {
  361. if (FileHandle != INVALID_HANDLE_VALUE) {
  362. CloseHandle( FileHandle );
  363. }
  364. if (lpOutBuffer) {
  365. free(lpOutBuffer);
  366. }
  367. if (Filename) {
  368. free( Filename );
  369. }
  370. }
  371. return ExitCode;
  372. }
  373. INT
  374. DeleteObjectId(
  375. IN INT argc,
  376. IN PWSTR argv[]
  377. )
  378. /*++
  379. Routine Description:
  380. This routine deletes the objectID associated with the file
  381. specified.
  382. Arguments:
  383. argc - The argument count.
  384. argv - Array of Strings of the form :
  385. ' fscutl deloid <pathname>'.
  386. Return Value:
  387. None
  388. --*/
  389. {
  390. HANDLE FileHandle = INVALID_HANDLE_VALUE;
  391. PWSTR Filename = NULL;
  392. BOOL Status;
  393. DWORD BytesReturned;
  394. INT ExitCode = EXIT_CODE_SUCCESS;
  395. try {
  396. if (argc != 1) {
  397. DisplayMsg( MSG_USAGE_DELETEOBJECTID );
  398. if (argc != 0) {
  399. ExitCode = EXIT_CODE_FAILURE;}
  400. leave;
  401. }
  402. Filename = GetFullPath( argv[0] );
  403. if (!Filename) {
  404. DisplayError();
  405. if (argc != 0) {
  406. ExitCode = EXIT_CODE_FAILURE;
  407. }
  408. leave;
  409. }
  410. if (!IsVolumeLocalNTFS( Filename[0] )) {
  411. DisplayMsg( MSG_NTFS_REQUIRED );
  412. ExitCode = EXIT_CODE_FAILURE;
  413. leave;
  414. }
  415. FileHandle = CreateFile(
  416. Filename,
  417. GENERIC_WRITE,
  418. FILE_SHARE_READ | FILE_SHARE_WRITE,
  419. NULL,
  420. OPEN_EXISTING,
  421. FILE_ATTRIBUTE_NORMAL,
  422. NULL
  423. );
  424. if (FileHandle == INVALID_HANDLE_VALUE) {
  425. DisplayError();
  426. ExitCode = EXIT_CODE_FAILURE;
  427. leave;
  428. }
  429. Status = DeviceIoControl(
  430. FileHandle,
  431. FSCTL_DELETE_OBJECT_ID,
  432. NULL,
  433. 0,
  434. NULL,
  435. 0,
  436. &BytesReturned,
  437. (LPOVERLAPPED)NULL
  438. );
  439. if (!Status) {
  440. DisplayError();
  441. ExitCode = EXIT_CODE_FAILURE;
  442. leave;
  443. }
  444. } finally {
  445. if (FileHandle != INVALID_HANDLE_VALUE) {
  446. CloseHandle( FileHandle );
  447. }
  448. free( Filename );
  449. }
  450. return ExitCode;
  451. }