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.

521 lines
15 KiB

  1. // setoid.c
  2. // based on code from \nt\base\fs\ntfs\tests\objectid\setoid.
  3. //
  4. #include <stdio.h>
  5. #include <string.h>
  6. #include <nt.h>
  7. #include <ntrtl.h>
  8. #include <nturtl.h>
  9. #include <windows.h>
  10. #include <ntioapi.h>
  11. #define ID_OPTIONS (FILE_OPEN_FOR_BACKUP_INTENT | \
  12. FILE_SEQUENTIAL_ONLY | \
  13. FILE_OPEN_NO_RECALL | \
  14. FILE_OPEN_REPARSE_POINT | \
  15. FILE_OPEN_BY_FILE_ID)
  16. int
  17. FsTestDeleteOid(
  18. IN HANDLE File
  19. )
  20. {
  21. IO_STATUS_BLOCK IoStatusBlock;
  22. NTSTATUS Status;
  23. Status = NtFsControlFile( File, // file handle
  24. NULL, // event
  25. NULL, // apc routine
  26. NULL, // apc context
  27. &IoStatusBlock, // iosb
  28. FSCTL_DELETE_OBJECT_ID, // FsControlCode
  29. NULL, // input buffer
  30. 0, // input buffer length
  31. NULL, // OutputBuffer for data from the FS
  32. 0 // OutputBuffer Length
  33. );
  34. if (!NT_SUCCESS(Status)) {
  35. printf( "Error deleting OID. Status: %x\n", Status );
  36. }
  37. return Status;
  38. }
  39. int
  40. FsTestGetOid(
  41. IN HANDLE hFile,
  42. IN FILE_OBJECTID_BUFFER *ObjectIdBuffer
  43. )
  44. {
  45. IO_STATUS_BLOCK IoStatusBlock;
  46. NTSTATUS Status;
  47. Status = NtFsControlFile( hFile, // file handle
  48. NULL, // event
  49. NULL, // apc routine
  50. NULL, // apc context
  51. &IoStatusBlock, // iosb
  52. FSCTL_GET_OBJECT_ID, // FsControlCode
  53. &hFile, // input buffer
  54. sizeof(HANDLE), // input buffer length
  55. ObjectIdBuffer, // OutputBuffer for data from the FS
  56. sizeof(FILE_OBJECTID_BUFFER) ); // OutputBuffer Length
  57. if (Status == STATUS_SUCCESS) {
  58. printf( "\nOid for this file is %s", ObjectIdBuffer->ObjectId );
  59. //FsTestHexDump( ObjectIdBuffer->ObjectId, 16 );
  60. printf( "\nObjectId:%08x %08x %08x %08x\n",
  61. *((PULONG)&ObjectIdBuffer->ObjectId[12]),
  62. *((PULONG)&ObjectIdBuffer->ObjectId[8]),
  63. *((PULONG)&ObjectIdBuffer->ObjectId[4]),
  64. *((PULONG)&ObjectIdBuffer->ObjectId[0]) );
  65. printf( "\nExtended info is %s\n", ObjectIdBuffer->ExtendedInfo );
  66. //FsTestHexDump( ObjectIdBuffer->ExtendedInfo, 48 );
  67. }
  68. return Status;
  69. }
  70. int
  71. FsTestSetOid(
  72. IN HANDLE hFile,
  73. IN FILE_OBJECTID_BUFFER ObjectIdBuffer
  74. )
  75. {
  76. IO_STATUS_BLOCK IoStatusBlock;
  77. NTSTATUS Status;
  78. Status = NtFsControlFile( hFile, // file handle
  79. NULL, // event
  80. NULL, // apc routine
  81. NULL, // apc context
  82. &IoStatusBlock, // iosb
  83. FSCTL_SET_OBJECT_ID, // FsControlCode
  84. &ObjectIdBuffer, // input buffer
  85. sizeof(ObjectIdBuffer), // input buffer length
  86. NULL, // OutputBuffer for data from the FS
  87. 0 // OutputBuffer Length
  88. );
  89. if (!NT_SUCCESS(Status)) {
  90. printf( "Error setting OID. Status: %x\n", Status );
  91. }
  92. return Status;
  93. }
  94. //
  95. // Build with USE_RELATIVE_OPEN set to one to use relative opens for
  96. // object IDs. Build with USE_RELATIVE_OPEN set to zero to use a device
  97. // path open for object IDs.
  98. // Opens by File ID always use a relative open.
  99. //
  100. #define USE_RELATIVE_OPEN 1
  101. #define VOLUME_PATH L"\\\\.\\H:"
  102. #define VOLUME_DRIVE_LETTER_INDEX 4
  103. #define FULL_PATH L"\\??\\H:\\1234567890123456"
  104. #define FULL_DRIVE_LETTER_INDEX 4
  105. #define DEVICE_PREFIX_LEN 14
  106. HANDLE
  107. FsTestOpenRelativeToVolume (
  108. IN PWCHAR ArgFile, // no device prefix for relative open.
  109. IN PWCHAR DriveLetter,
  110. IN PWCHAR ArgFullFile // Full file name.
  111. )
  112. {
  113. HANDLE File;
  114. IO_STATUS_BLOCK IoStatusBlock;
  115. NTSTATUS Status;
  116. NTSTATUS GetNameStatus;
  117. NTSTATUS CloseStatus;
  118. OBJECT_ATTRIBUTES ObjectAttributes;
  119. UNICODE_STRING str;
  120. WCHAR mybuffer[32768];
  121. PFILE_NAME_INFORMATION FileName;
  122. HANDLE VolumeHandle;
  123. DWORD WStatus;
  124. WCHAR Volume[] = VOLUME_PATH; // Arrays of WCHAR's aren't constants
  125. FILE_OBJECTID_BUFFER ObjectIdBuffer;
  126. NTSTATUS GetFrsStatus;
  127. FILE_INTERNAL_INFORMATION InternalInfo;
  128. File = CreateFileW( ArgFullFile,
  129. FILE_READ_ATTRIBUTES,
  130. FILE_SHARE_READ | FILE_SHARE_WRITE,
  131. NULL,
  132. OPEN_EXISTING,
  133. FILE_FLAG_BACKUP_SEMANTICS,
  134. NULL );
  135. if ( File == INVALID_HANDLE_VALUE ) {
  136. printf( "Error opening file '%ws' %x\n", ArgFullFile, GetLastError() );
  137. return INVALID_HANDLE_VALUE;
  138. }
  139. //
  140. // Get the File ID.
  141. //
  142. GetFrsStatus = NtQueryInformationFile( File,
  143. &IoStatusBlock,
  144. &InternalInfo,
  145. sizeof(InternalInfo),
  146. FileInternalInformation );
  147. if (!NT_SUCCESS( GetFrsStatus )) {
  148. printf( "Get File ID failed: 0x%08x \n", GetFrsStatus );
  149. NtClose( File );
  150. return INVALID_HANDLE_VALUE;
  151. } else {
  152. printf( "FID is: (highpart lowpart) %08x %08x\n",
  153. InternalInfo.IndexNumber.HighPart, InternalInfo.IndexNumber.LowPart );
  154. }
  155. CloseHandle( File );
  156. //
  157. // Open the volume for relative opens.
  158. //
  159. RtlCopyMemory( &Volume[VOLUME_DRIVE_LETTER_INDEX], DriveLetter, sizeof(WCHAR) );
  160. printf( "\nOpening volume handle (%ws)\n", Volume );
  161. VolumeHandle = CreateFileW( (PUSHORT) &Volume,
  162. GENERIC_READ | GENERIC_WRITE,
  163. FILE_SHARE_READ | FILE_SHARE_WRITE,
  164. NULL,
  165. OPEN_EXISTING,
  166. 0,
  167. NULL );
  168. if (VolumeHandle == INVALID_HANDLE_VALUE) {
  169. WStatus = GetLastError();
  170. printf( "Unable to open %ws volume\n", &Volume );
  171. printf( "Error from CreateFile: %d", WStatus );
  172. return INVALID_HANDLE_VALUE;
  173. }
  174. //
  175. // Open the file by ID.
  176. //
  177. str.Length = 8;
  178. str.MaximumLength = 8;
  179. str.Buffer = (PWCHAR) &InternalInfo.IndexNumber.QuadPart;
  180. InitializeObjectAttributes( &ObjectAttributes,
  181. &str,
  182. OBJ_CASE_INSENSITIVE,
  183. VolumeHandle,
  184. NULL );
  185. Status = NtCreateFile( &File,
  186. GENERIC_WRITE,
  187. &ObjectAttributes,
  188. &IoStatusBlock,
  189. NULL, // AllocationSize
  190. FILE_ATTRIBUTE_NORMAL,
  191. FILE_SHARE_READ | FILE_SHARE_WRITE,
  192. FILE_OPEN,
  193. ID_OPTIONS,
  194. NULL, // EaBuffer
  195. 0 );
  196. if (NT_SUCCESS( Status )) {
  197. FileName = (PFILE_NAME_INFORMATION) &mybuffer[0];
  198. FileName->FileNameLength = sizeof(mybuffer) - sizeof(ULONG);
  199. GetNameStatus = NtQueryInformationFile( File,
  200. &IoStatusBlock,
  201. FileName,
  202. sizeof(mybuffer),
  203. FileNameInformation );
  204. if (!NT_SUCCESS( GetNameStatus )) {
  205. printf( "\nGetNameStatus failed: 0x%08x \n", GetNameStatus );
  206. NtClose( File );
  207. File = INVALID_HANDLE_VALUE;
  208. } else {
  209. printf( "File name is: %ws\n", FileName->FileName );
  210. }
  211. } else {
  212. printf( "Error opening file by FID - 0x%08x\n", Status );
  213. File = INVALID_HANDLE_VALUE;
  214. }
  215. if (VolumeHandle != NULL) {
  216. CloseHandle( VolumeHandle );
  217. }
  218. return File;
  219. }
  220. NTSTATUS
  221. SetupOnePrivilege (
  222. ULONG Privilege,
  223. PUCHAR PrivilegeName
  224. )
  225. {
  226. BOOLEAN PreviousPrivilegeState;
  227. NTSTATUS Status;
  228. Status = RtlAdjustPrivilege(Privilege, TRUE, FALSE, &PreviousPrivilegeState);
  229. if (!NT_SUCCESS(Status)) {
  230. printf("Your login does not have `%s' privilege.\n", PrivilegeName);
  231. if (Status != STATUS_PRIVILEGE_NOT_HELD) {
  232. printf("RtlAdjustPrivilege failed : 0x%08x\n", Status);
  233. }
  234. printf("Update your: User Manager -> Policies -> User Rights.\n");
  235. return Status;
  236. }
  237. printf("Added `%s' privilege (previous: %s)\n",
  238. PrivilegeName, (PreviousPrivilegeState ? "Enabled" : "Disabled"));
  239. return Status;
  240. }
  241. VOID
  242. StrToGuid(
  243. IN PCHAR s,
  244. OUT GUID *pGuid
  245. )
  246. /*++
  247. Routine Description:
  248. Convert a string in GUID display format to an object ID that
  249. can be used to lookup a file.
  250. based on a routine by Mac McLain
  251. Arguments:
  252. pGuid - ptr to the GUID.
  253. s - The input character buffer in display guid format.
  254. e.g.: b81b486b-c338-11d0-ba4f0000f80007df
  255. Must be at least GUID_CHAR_LEN (35 bytes) long.
  256. Function Return Value:
  257. None.
  258. --*/
  259. {
  260. if (pGuid != NULL) {
  261. sscanf( s, "%08lx-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x",
  262. &pGuid->Data1,
  263. &pGuid->Data2,
  264. &pGuid->Data3,
  265. &pGuid->Data4[0],
  266. &pGuid->Data4[1],
  267. &pGuid->Data4[2],
  268. &pGuid->Data4[3],
  269. &pGuid->Data4[4],
  270. &pGuid->Data4[5],
  271. &pGuid->Data4[6],
  272. &pGuid->Data4[7] );
  273. } else {
  274. sprintf( s, "<ptr-null>" );
  275. }
  276. }
  277. #if 0
  278. VOID
  279. FsTestObOidHelp(
  280. char *ExeName
  281. )
  282. {
  283. printf( "This program opens a file by its file id or object id (ntfs only).\n\n" );
  284. printf( "usage: %s x: [FileID | Raw ObjectId | Guid Display Format ObjectID]\n", ExeName );
  285. printf( "Where x: is the drive letter\n" );
  286. printf( "A FileID is a string of 16 hex digits with a space between each\n"
  287. "group of 8. E.G. oboid 00010000 00000024\n\n" );
  288. printf( "A raw object ID is a string of 32 hex digits with a space\n"
  289. "between each group of 8\n"
  290. "E.G. ObjectId:df0700f8 00004fba 11d0c338 b81b485f\n\n" );
  291. printf( "A GUID display format object ID is a string of the form \n"
  292. "b81b486b-c338-11d0-ba4f0000f80007df\n"
  293. "See the struct def for GUID in sdk\\inc\\winnt.h for byte layout.\n" );
  294. }
  295. VOID
  296. _cdecl
  297. main(
  298. int argc,
  299. char *argv[]
  300. )
  301. {
  302. ULONG ObjectId[4];
  303. ULONG Length;
  304. WCHAR Drive;
  305. //
  306. // Get parameters.
  307. //
  308. if (argc < 3) {
  309. FsTestObOidHelp( argv[0] );
  310. return;
  311. }
  312. RtlZeroBytes( ObjectId,
  313. sizeof( ObjectId ) );
  314. Length = strlen( argv[2] );
  315. if ((argc == 3) && (Length == 35) && (argv[2][8] == '-')) {
  316. StrToGuid( argv[2], (GUID *)ObjectId );
  317. printf( "\nUsing ObjectId: %08x %08x %08x %08x\n",
  318. ObjectId[3], ObjectId[2], ObjectId[1], ObjectId[0] );
  319. Length = 32;
  320. } else if (argc == 6) {
  321. sscanf( argv[2], "%08x", &ObjectId[3] );
  322. sscanf( argv[3], "%08x", &ObjectId[2] );
  323. sscanf( argv[4], "%08x", &ObjectId[1] );
  324. sscanf( argv[5], "%08x", &ObjectId[0] );
  325. printf( "\nUsing ObjectId: %08x %08x %08x %08x\n",
  326. ObjectId[3], ObjectId[2], ObjectId[1], ObjectId[0] );
  327. Length = 32;
  328. } else if (argc == 4) {
  329. sscanf( argv[2], "%08x", &ObjectId[1] );
  330. sscanf( argv[3], "%08x", &ObjectId[0] );
  331. printf( "\nUsing FileId: %08x %08x\n", ObjectId[1], ObjectId[0] );
  332. Length = 16;
  333. } else {
  334. printf("Arg (%s) invalid format.\n\n", argv[2]);
  335. FsTestObOidHelp( argv[0] );
  336. }
  337. Drive = *argv[1];
  338. FsTestOpenByOid( (PUCHAR) ObjectId, Length, &Drive );
  339. return;
  340. }
  341. #endif
  342. VOID
  343. _cdecl
  344. main(
  345. int argc,
  346. char *argv[]
  347. )
  348. {
  349. HANDLE File;
  350. FILE_OBJECTID_BUFFER ObjectIdBuffer;
  351. IO_STATUS_BLOCK IoStatusBlock;
  352. NTSTATUS Status;
  353. OBJECT_ATTRIBUTES ObjAttr;
  354. ANSI_STRING AnsiName;
  355. UNICODE_STRING UnicodeName;
  356. char DriveNameBuffer[3200];
  357. //
  358. // Get parameters.
  359. //
  360. if (argc < 3) {
  361. printf("This program sets an object id for a file (ntfs only).\n\n");
  362. printf("usage: %s filename ObjectId \n", argv[0]);
  363. printf(" object ID is a string of the form b81b486b-c338-11d0-ba4f0000f80007df\n"
  364. " See the struct def for GUID in sdk\\inc\\winnt.h for byte layout.\n\n"
  365. " The filename must contain the complete path including drive letter.\n"
  366. " e.g. D:\\test\\foo\\bar.txt\n");
  367. return;
  368. }
  369. AnsiName.Length = (USHORT) strlen(argv[1]);
  370. AnsiName.Buffer = argv[1];
  371. Status = RtlAnsiStringToUnicodeString( &UnicodeName, &AnsiName, TRUE );
  372. if (!NT_SUCCESS(Status)) {
  373. printf( "Error initalizing strings" );
  374. return;
  375. }
  376. Status = SetupOnePrivilege(SE_BACKUP_PRIVILEGE, "Backup");
  377. if (!NT_SUCCESS(Status)) {
  378. printf( "ERROR - Failed to get Backup privilege. 0x%08x\n", Status);
  379. return ;
  380. }
  381. //
  382. // Need restore priv to use FSCTL_SET_OBJECT_ID
  383. //
  384. Status = SetupOnePrivilege(SE_RESTORE_PRIVILEGE, "Restore");
  385. if (!NT_SUCCESS(Status)) {
  386. printf( "ERROR - Failed to get Restore privilege. 0x%08x\n", Status);
  387. return;
  388. }
  389. File = FsTestOpenRelativeToVolume(&UnicodeName.Buffer[2],
  390. &UnicodeName.Buffer[0],
  391. &UnicodeName.Buffer[0]);
  392. RtlZeroBytes( &ObjectIdBuffer, sizeof( ObjectIdBuffer ) );
  393. StrToGuid( argv[2], (GUID *)&ObjectIdBuffer );
  394. printf( "\nUsing file:%s, ObjectId:%s\n", argv[1], argv[2]);
  395. FsTestDeleteOid( File );
  396. FsTestSetOid( File, ObjectIdBuffer );
  397. CloseHandle( File );
  398. return;
  399. }